00001
00002
00003
00004
00005
00006
00007
00013 #include <string.h>
00014
00015 #include "vipl_priv.h"
00016
00017
00063 VIP_ENTRY_POINT VIP_RETURN
00064 VipConnectPeerRequest (VIP_VI_HANDLE ViHandle,
00065 VIP_NET_ADDRESS * LocalAddr,
00066 VIP_NET_ADDRESS * RemoteAddr, VIP_ULONG Timeout)
00067 {
00068 VIP_VI *vip_vi_ptr;
00069 VIP_GM *vip_gm_ptr;
00070 VIP_NIC *vip_nic_ptr;
00071 VIP_CONN *vip_conn_ptr;
00072 VIP_UINT32 remote_gm_id;
00073 VIP_UINT32 conn_mgr_node_id;
00074 VIP_UCHAR *gm_name_ptr;
00075 VIP_UCHAR gm_name[GM_MAX_HOST_NAME_LEN];
00076 VIP_SEND_REQ *vip_send_req_ptr;
00077 VIP_PACKET_CONN_LIST *pkt_list_ptr;
00078 gm_status_t gm_status;
00079 VIP_DEBUG_LABEL (("VipConnectPeerRequest"));
00080
00081
00082 if (LocalAddr == NULL)
00083 {
00084 VIP_DEBUG (("LocalAddr is NULL"));
00085 return VIP_INVALID_PARAMETER;
00086 }
00087
00088 if (RemoteAddr == NULL)
00089 {
00090 VIP_DEBUG (("RemoteAddr is NULL"));
00091 return VIP_INVALID_PARAMETER;
00092 }
00093
00094 if (Timeout == 0)
00095 {
00096 VIP_DEBUG (("Timeout 0"));
00097 return VIP_INVALID_PARAMETER;
00098 }
00099
00100
00101 if (LocalAddr->HostAddressLen != VI_GM_MAC_ADDRESS_LEN)
00102 {
00103 VIP_DEBUG (("Local Host Address Length is invalid (should be %d)",
00104 VI_GM_MAC_ADDRESS_LEN));
00105 return VIP_INVALID_PARAMETER;
00106 }
00107
00108
00109 if (LocalAddr->DiscriminatorLen > VI_GM_MAX_DISCRIMINATOR_LEN)
00110 {
00111 VIP_DEBUG (("Local Discriminator Length is too large (max=%d)",
00112 VI_GM_MAX_DISCRIMINATOR_LEN));
00113 return VIP_INVALID_PARAMETER;
00114 }
00115
00116
00117 if (RemoteAddr->HostAddressLen != VI_GM_MAC_ADDRESS_LEN)
00118 {
00119 VIP_DEBUG (("Remote Host Address Length is invalid (should be %d)",
00120 VI_GM_MAC_ADDRESS_LEN));
00121 return VIP_INVALID_PARAMETER;
00122 }
00123
00124
00125 if (RemoteAddr->DiscriminatorLen > VI_GM_MAX_DISCRIMINATOR_LEN)
00126 {
00127 VIP_DEBUG (("Remote Discriminator Length is too large (max=%d)",
00128 VI_GM_MAX_DISCRIMINATOR_LEN));
00129 return VIP_INVALID_PARAMETER;
00130 }
00131
00132
00133 vip_vi_ptr = (VIP_VI *) ViHandle;
00134 if (VIP_INVALID_VI_HANDLE (vip_vi_ptr))
00135 {
00136 VIP_DEBUG (("Invalid VI handle"));
00137 return VIP_INVALID_PARAMETER;
00138 }
00139 vip_nic_ptr = vip_vi_ptr->handle.vip_nic_ptr;
00140 vip_gm_ptr = vip_nic_ptr->vip_gm_ptr;
00141 VIP_MUTEX_LOCK (&(vip_gm_ptr->lock));
00142 VIP_PROGRESSION (vip_gm_ptr);
00143 VIP_MUTEX_LOCK (&(vip_nic_ptr->lock));
00144
00145
00146 if (vip_vi_ptr->state != VIP_STATE_IDLE)
00147 {
00148 VIP_DEBUG (("VI is not in IDLE state"));
00149 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00150 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00151 return VIP_INVALID_STATE;
00152 }
00153
00154
00155 if (memcmp (vip_gm_ptr->mac_address,
00156 LocalAddr->HostAddress, LocalAddr->HostAddressLen) != 0)
00157 {
00158 VIP_DEBUG (("Host Address does not match NIC id"));
00159 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00160 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00161 return VIP_INVALID_PARAMETER;
00162 }
00163
00164
00165 vip_conn_ptr = (VIP_CONN *)
00166 vip_allocate_handle (&(vip_nic_ptr->vip_conn_set));
00167 if (vip_conn_ptr == NULL)
00168 {
00169 VIP_DEBUG (("VIP_CONN alloc failed"));
00170 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00171 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00172 return VIP_ERROR_RESOURCE;
00173 }
00174
00175 vip_conn_ptr->next_waiting_conn_ptr = NULL;
00176 vip_conn_ptr->remote_vi_attribs.ReliabilityLevel = vip_vi_ptr->reliability;
00177 vip_conn_ptr->remote_vi_attribs.MaxTransferSize = vip_vi_ptr->mtu;
00178 vip_conn_ptr->remote_vi_attribs.QoS = vip_vi_ptr->qos;
00179 vip_conn_ptr->remote_vi_attribs.EnableRdmaRead = VIP_FALSE;
00180 vip_conn_ptr->locale_disc_len = LocalAddr->DiscriminatorLen;
00181 memcpy (vip_conn_ptr->locale_net_addr, LocalAddr->HostAddress,
00182 VI_GM_MAC_ADDRESS_LEN + LocalAddr->DiscriminatorLen);
00183 vip_conn_ptr->remote_disc_len = RemoteAddr->DiscriminatorLen;
00184 memcpy (vip_conn_ptr->remote_net_addr, RemoteAddr->HostAddress,
00185 VI_GM_MAC_ADDRESS_LEN + RemoteAddr->DiscriminatorLen);
00186 vip_conn_ptr->remote_port_id = 1;
00187 vip_conn_ptr->type = VIP_CONN_TYPE_PEER;
00188 vip_conn_ptr->status = VIP_NOT_DONE;
00189 vip_conn_ptr->vip_vi_ptr = vip_vi_ptr;
00190 VIP_EVENT_INIT (&(vip_conn_ptr->event));
00191
00192 gm_initialize_alarm (&(vip_conn_ptr->peer_timeout_alarm));
00193
00194
00195 if (vip_gm_ptr->head_waiting_conn_ptr == NULL)
00196 {
00197 VIP_ASSERT (vip_gm_ptr->tail_waiting_conn_ptr == NULL);
00198 vip_gm_ptr->head_waiting_conn_ptr = vip_conn_ptr;
00199 vip_gm_ptr->tail_waiting_conn_ptr = vip_conn_ptr;
00200 vip_conn_ptr->prev_waiting_conn_ptr = NULL;
00201 }
00202 else
00203 {
00204 VIP_ASSERT (vip_gm_ptr->tail_waiting_conn_ptr != NULL);
00205 vip_gm_ptr->tail_waiting_conn_ptr->next_waiting_conn_ptr = vip_conn_ptr;
00206 vip_conn_ptr->prev_waiting_conn_ptr = vip_gm_ptr->tail_waiting_conn_ptr;
00207 vip_gm_ptr->tail_waiting_conn_ptr = vip_conn_ptr;
00208 }
00209 vip_conn_ptr->waiting_list = VIP_TRUE;
00210
00211 vip_vi_ptr->conn_ptr = vip_conn_ptr;
00212 vip_vi_ptr->state = VIP_STATE_CONNECT_PENDING;
00213
00214
00215 VIP_ENTER_IOCTL (vip_gm_ptr);
00216 gm_status = gm_unique_id_to_node_id (vip_gm_ptr->gm_port,
00217 RemoteAddr->HostAddress,
00218 &remote_gm_id);
00219
00220 if ((remote_gm_id == GM_NO_SUCH_NODE_ID) || (gm_status != GM_SUCCESS))
00221 {
00222 goto out_with_unknown_remote_endpoint;
00223 }
00224
00225 VIP_MUTEX_LOCK (&vip_gm_host_name_lock);
00226 gm_name_ptr = gm_node_id_to_host_name (vip_gm_ptr->gm_port, remote_gm_id);
00227
00228
00229 if (gm_name_ptr == NULL)
00230 {
00231 VIP_MUTEX_UNLOCK (&vip_gm_host_name_lock);
00232 goto out_with_unknown_remote_endpoint;
00233 }
00234
00235
00236 if (strchr (gm_name_ptr, ':') != NULL)
00237 {
00238 strcpy (gm_name, gm_name_ptr);
00239 *(strchr (gm_name, ':')) = '\0';
00240 conn_mgr_node_id = gm_host_name_to_node_id (vip_gm_ptr->gm_port,
00241 gm_name);
00242 if (conn_mgr_node_id == GM_NO_SUCH_NODE_ID)
00243 {
00244 VIP_MUTEX_UNLOCK (&vip_gm_host_name_lock);
00245 goto out_with_unknown_remote_endpoint;
00246 }
00247 }
00248 else
00249 {
00250 conn_mgr_node_id = remote_gm_id;
00251 }
00252 vip_conn_ptr->remote_gm_id = remote_gm_id;
00253 VIP_MUTEX_UNLOCK (&vip_gm_host_name_lock);
00254 VIP_EXIT_IOCTL (vip_gm_ptr);
00255
00256
00257 vip_send_req_ptr = vip_allocate_packet (vip_gm_ptr,
00258 sizeof (VIP_PACKET_CONN_LIST));
00259 if (vip_send_req_ptr == NULL)
00260 {
00261 vip_remove_conn_waiting_list (vip_gm_ptr, vip_conn_ptr);
00262 vip_free_handle (&(vip_nic_ptr->vip_conn_set),
00263 (VIP_HANDLE *) vip_conn_ptr);
00264 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00265 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00266 return VIP_ERROR_RESOURCE;
00267 }
00268
00269
00270 pkt_list_ptr = (VIP_PACKET_CONN_LIST *) (vip_send_req_ptr->ptr);
00271 pkt_list_ptr->type = VIP_HTON_UCHAR (VIP_CONN_LIST_REQ_PKT);
00272 memcpy(pkt_list_ptr->gm_unique_id, RemoteAddr->HostAddress, 6);
00273 pkt_list_ptr->clt_seq_num = VIP_HTON_UINT16 (vip_conn_ptr->handle.seq_num);
00274 pkt_list_ptr->clt_conn_ptr =
00275 VIP_HTON_UINT64 (vip_addr2addrbits (vip_conn_ptr));
00276
00277 vip_send_req_ptr->type |= VIP_SEND_REQ_RELIABLE;
00278 vip_send_req_ptr->dest_port_id = VI_GM_PORT_CONN_MANAGER;
00279 vip_send_req_ptr->dest_gm_id = conn_mgr_node_id;
00280 vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
00281 vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
00282 vip_send_data (vip_send_req_ptr);
00283
00284 gm_set_alarm (vip_gm_ptr->gm_port, &(vip_conn_ptr->peer_timeout_alarm),
00285 (Timeout * 1000), vip_conn_peer_request_alarm_callback,
00286 vip_conn_ptr);
00287
00288 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00289 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00290 VIP_DEBUG (("Success"));
00291 return VIP_SUCCESS;
00292
00293 out_with_unknown_remote_endpoint:
00294 VIP_EXIT_IOCTL (vip_gm_ptr);
00295 gm_set_alarm (vip_gm_ptr->gm_port, &(vip_conn_ptr->peer_timeout_alarm),
00296 (Timeout * 1000), vip_conn_peer_request_alarm_callback,
00297 vip_conn_ptr);
00298
00299 VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00300 VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00301 VIP_DEBUG (("Remote endpoint is unknown, connection will never complete"));
00302 return VIP_SUCCESS;
00303 }