Main Page | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

vipconnectpeerrequest.c

Go to the documentation of this file.
00001 /********************************************************
00002  * Myricom VI-GM  networking software and documentation *
00003  * Copyright (c) 2001 by Myricom, Inc.                  *
00004  * All rights reserved.                                 *
00005  * See the file `COPYING' for copyright notice.         *
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   /* check local address (host part) */
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   /* check local address (discriminator part) */
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   /* check remote address (host part) */
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   /* check remote address (discriminator part) */
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   /* check VI handle */
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   /* check VI state */
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   /* check NIC address consistency */
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   /* allocate conn handle */
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   /* insert connection in the waiting list */
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   /* look if we know the remote end */
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   /* check if we really know it, gm_unique_id_to_node_id is not reliable */
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   /* we know the remote NIC, try to connect */
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   /* allocate a send buffer */
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   /* fill the packet and send it */
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 }
VI-GM-1.3 by Myricom © 1997-2006. Documentation generated on 20 May 2006 by doxygen 1.4.4.