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

vipconnectrequest.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 <stdlib.h>
00014 #include <string.h>
00015 
00016 #include "vipl_priv.h"
00017 
00018 
00086 VIP_ENTRY_POINT VIP_RETURN
00087 VipConnectRequest (VIP_VI_HANDLE ViHandle,
00088                    VIP_NET_ADDRESS * LocalAddr,
00089                    VIP_NET_ADDRESS * RemoteAddr,
00090                    VIP_ULONG Timeout, VIP_VI_ATTRIBUTES * RemoteViAttribs)
00091 {
00092   VIP_VI *vip_vi_ptr;
00093   VIP_GM *vip_gm_ptr;
00094   VIP_NIC *vip_nic_ptr;
00095   VIP_CONN *vip_conn_ptr;
00096   VIP_UINT32 remote_gm_id;
00097   VIP_UINT32 conn_mgr_node_id;
00098   VIP_SEND_REQ *vip_send_req_ptr;
00099   VIP_PACKET_CONN_LIST *pkt_list_ptr;
00100   VIP_PACKET_CONN_ACK *pkt_ack_ptr;
00101   VIP_RETURN vip_status = VIP_SUCCESS;
00102   gm_status_t gm_status;
00103   VIP_DEBUG_LABEL (("VipConnectRequest"));
00104 
00105 
00106   if (LocalAddr == NULL)
00107     {
00108       VIP_DEBUG (("LocalAddr is NULL"));
00109       return VIP_INVALID_PARAMETER;
00110     }
00111 
00112   if (RemoteAddr == NULL)
00113     {
00114       VIP_DEBUG (("RemoteAddr is NULL"));
00115       return VIP_INVALID_PARAMETER;
00116     }
00117 
00118   if (RemoteViAttribs == NULL)
00119     {
00120       VIP_DEBUG (("RemoteViAttribs is NULL"));
00121       return VIP_INVALID_PARAMETER;
00122     }
00123 
00124   if (Timeout == 0)
00125     {
00126       VIP_DEBUG (("Timeout 0"));
00127       return VIP_INVALID_PARAMETER;
00128     }
00129 
00130   /* check local address (host part) */
00131   if (LocalAddr->HostAddressLen != VI_GM_MAC_ADDRESS_LEN)
00132     {
00133       VIP_DEBUG (("Local Host Address Length is invalid (should be %d)",
00134                   VI_GM_MAC_ADDRESS_LEN));
00135       return VIP_INVALID_PARAMETER;
00136     }
00137 
00138   /* check local address (discriminator part) */
00139   if (LocalAddr->DiscriminatorLen > VI_GM_MAX_DISCRIMINATOR_LEN)
00140     {
00141       VIP_DEBUG (("Local Discriminator Length is too large (max=%d)",
00142                   VI_GM_MAX_DISCRIMINATOR_LEN));
00143       return VIP_INVALID_PARAMETER;
00144     }
00145 
00146   /* check remote address (host part) */
00147   if (RemoteAddr->HostAddressLen != VI_GM_MAC_ADDRESS_LEN)
00148     {
00149       VIP_DEBUG (("Remote Host Address Length is invalid (should be %d)",
00150                   VI_GM_MAC_ADDRESS_LEN));
00151       return VIP_INVALID_PARAMETER;
00152     }
00153 
00154   /* check remote address (discriminator part) */
00155   if (RemoteAddr->DiscriminatorLen > VI_GM_MAX_DISCRIMINATOR_LEN)
00156     {
00157       VIP_DEBUG (("Remote Discriminator Length is too large (max=%d)",
00158                   VI_GM_MAX_DISCRIMINATOR_LEN));
00159       return VIP_INVALID_PARAMETER;
00160     }
00161 
00162   /* check VI handle */
00163   vip_vi_ptr = (VIP_VI *) ViHandle;
00164   if (VIP_INVALID_VI_HANDLE (vip_vi_ptr))
00165     {
00166       VIP_DEBUG (("Invalid VI handle"));
00167       return VIP_INVALID_PARAMETER;
00168     }
00169   vip_nic_ptr = vip_vi_ptr->handle.vip_nic_ptr;
00170   vip_gm_ptr = vip_nic_ptr->vip_gm_ptr;
00171   VIP_MUTEX_LOCK (&(vip_gm_ptr->lock));
00172   VIP_PROGRESSION (vip_gm_ptr);
00173   VIP_MUTEX_LOCK (&(vip_nic_ptr->lock));
00174 
00175   /* check VI state */
00176   if (vip_vi_ptr->state != VIP_STATE_IDLE)
00177     {
00178       VIP_DEBUG (("VI is not in IDLE state"));
00179       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00180       VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00181       return VIP_INVALID_STATE;
00182     }
00183 
00184   /* check NIC address consistency */
00185   if (memcmp (vip_gm_ptr->mac_address,
00186               LocalAddr->HostAddress, LocalAddr->HostAddressLen) != 0)
00187     {
00188       VIP_DEBUG (("Host Address does not match NIC id"));
00189       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00190       VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00191       return VIP_INVALID_PARAMETER;
00192     }
00193 
00194   /* check remote address validity */
00195   VIP_ENTER_IOCTL (vip_gm_ptr);
00196   gm_status = gm_unique_id_to_node_id (vip_gm_ptr->gm_port,
00197                                        RemoteAddr->HostAddress,
00198                                        &remote_gm_id);
00199   VIP_EXIT_IOCTL (vip_gm_ptr);
00200 
00201   if (gm_status != GM_SUCCESS)
00202     {
00203       VIP_DEBUG_GM (("Unable to get the GM id of the remote Myrinet board"));
00204       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00205       VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00206       return VIP_INVALID_PARAMETER;
00207     }
00208 
00209   if (remote_gm_id == GM_NO_SUCH_NODE_ID)
00210     {
00211       VIP_DEBUG (("Remote Host Address is unknown from the Myrinet map"));
00212       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00213       VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00214       return VIP_INVALID_PARAMETER;
00215     }
00216 
00217   VIP_MUTEX_LOCK (&vip_gm_host_name_lock);
00218   if (strchr (gm_node_id_to_host_name (vip_gm_ptr->gm_port,
00219                                        remote_gm_id), ':') != NULL)
00220     {
00221       VIP_UCHAR gm_name[GM_MAX_HOST_NAME_LEN];
00222 
00223       strcpy (gm_name, gm_node_id_to_host_name (vip_gm_ptr->gm_port,
00224                                                 remote_gm_id));
00225       *strchr (gm_name, ':') = '\0';
00226       conn_mgr_node_id = gm_host_name_to_node_id (vip_gm_ptr->gm_port,
00227                                                   gm_name);
00228       if (conn_mgr_node_id == GM_NO_SUCH_NODE_ID)
00229         {
00230           VIP_MUTEX_UNLOCK (&vip_gm_host_name_lock);
00231           VIP_DEBUG (("Unable to get the GM id of the remote Myrinet board 0"));
00232           VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00233           VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00234           return VIP_INVALID_PARAMETER;
00235         }
00236     }
00237   else
00238     {
00239       conn_mgr_node_id = remote_gm_id;
00240     }
00241   VIP_MUTEX_UNLOCK (&vip_gm_host_name_lock);
00242 
00243   /* allocate conn handle */
00244   vip_conn_ptr = (VIP_CONN *)
00245     vip_allocate_handle (&(vip_nic_ptr->vip_conn_set));
00246   if (vip_conn_ptr == NULL)
00247     {
00248       VIP_DEBUG (("VIP_CONN alloc failed"));
00249       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00250       VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00251       return VIP_ERROR_RESOURCE;
00252     }
00253 
00254   /* allocate a send buffer */
00255   vip_send_req_ptr =
00256     vip_allocate_packet (vip_gm_ptr, sizeof (VIP_PACKET_CONN_LIST));
00257   if (vip_send_req_ptr == NULL)
00258     {
00259       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00260       VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00261       return VIP_ERROR_RESOURCE;
00262     }
00263 
00264   vip_conn_ptr->waiting_list = VIP_FALSE;
00265   vip_conn_ptr->remote_vi_attribs.ReliabilityLevel = vip_vi_ptr->reliability;
00266   vip_conn_ptr->remote_vi_attribs.MaxTransferSize = vip_vi_ptr->mtu;
00267   vip_conn_ptr->remote_vi_attribs.QoS = vip_vi_ptr->qos;
00268   vip_conn_ptr->remote_vi_attribs.EnableRdmaRead = VIP_FALSE;
00269   vip_conn_ptr->locale_disc_len = LocalAddr->DiscriminatorLen;
00270   memcpy (vip_conn_ptr->locale_net_addr, LocalAddr->HostAddress,
00271           VI_GM_MAC_ADDRESS_LEN + LocalAddr->DiscriminatorLen);
00272   vip_conn_ptr->remote_disc_len = RemoteAddr->DiscriminatorLen;
00273   memcpy (vip_conn_ptr->remote_net_addr, RemoteAddr->HostAddress,
00274           VI_GM_MAC_ADDRESS_LEN + RemoteAddr->DiscriminatorLen);
00275   vip_conn_ptr->remote_gm_id = remote_gm_id;
00276   vip_conn_ptr->remote_port_id = 1;
00277   vip_conn_ptr->type = VIP_CONN_TYPE_CLIENT;
00278   vip_conn_ptr->status = VIP_NOT_DONE;
00279   vip_conn_ptr->vip_vi_ptr = vip_vi_ptr;
00280   VIP_EVENT_INIT (&(vip_conn_ptr->event));
00281   vip_vi_ptr->state = VIP_STATE_CONNECT_PENDING;
00282   vip_vi_ptr->conn_ptr = vip_conn_ptr;
00283 
00284   /* fill the packet and send it */
00285   pkt_list_ptr = (VIP_PACKET_CONN_LIST *) (vip_send_req_ptr->ptr);
00286   pkt_list_ptr->type = VIP_HTON_UCHAR (VIP_CONN_LIST_REQ_PKT);
00287   memcpy(pkt_list_ptr->gm_unique_id, RemoteAddr->HostAddress, 6);
00288   pkt_list_ptr->clt_seq_num = VIP_HTON_UINT16 (vip_conn_ptr->handle.seq_num);
00289   pkt_list_ptr->clt_conn_ptr = 
00290     VIP_HTON_UINT64 (vip_addr2addrbits (vip_conn_ptr));
00291 
00292   vip_send_req_ptr->type |= VIP_SEND_REQ_RELIABLE;
00293   vip_send_req_ptr->dest_port_id = VI_GM_PORT_CONN_MANAGER;
00294   vip_send_req_ptr->dest_gm_id = conn_mgr_node_id;
00295   vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
00296   vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
00297   vip_send_data (vip_send_req_ptr);
00298 
00299   /* blocks */
00300   VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00301   vip_status = vip_wait_for_notification (Timeout,
00302                                           (VIP_HANDLE *) vip_conn_ptr,
00303                                           &(vip_conn_ptr->event),
00304                                           &vip_is_conn_notified,
00305                                           vip_conn_ptr);
00306   VIP_MUTEX_LOCK (&(vip_nic_ptr->lock));
00307 
00308   /* check return code of blocking time */
00309   switch (vip_status)
00310     {
00311     case VIP_SUCCESS:
00312       break;
00313 
00314     case VIP_INVALID_PARAMETER:
00315       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00316       VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00317       return VIP_INVALID_PARAMETER;
00318 
00319     case VIP_TIMEOUT:
00320       VIP_ASSERT (vip_conn_ptr->status == VIP_NOT_DONE);
00321       if (vip_vi_ptr->state == VIP_STATE_CONNECT_PENDING)
00322         {
00323           vip_vi_ptr->state = VIP_STATE_IDLE;
00324         }
00325       vip_free_handle (&(vip_nic_ptr->vip_conn_set),
00326                        (VIP_HANDLE *) vip_conn_ptr);
00327       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00328       VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00329       return VIP_TIMEOUT;
00330 
00331     default:
00332       VIP_ABORT (("Blocking wait return code is invalid"));
00333     }
00334 
00335   /* process the status of the connection handle */
00336   vip_status = vip_conn_ptr->status;
00337   switch (vip_status)
00338     {
00339     case VIP_SUCCESS:
00340       /* connection established */
00341       *RemoteViAttribs = vip_conn_ptr->remote_vi_attribs;
00342 
00343       /* allocate a send buffer */
00344       vip_send_req_ptr =
00345         vip_allocate_packet (vip_gm_ptr, sizeof (VIP_PACKET_CONN_ACK));
00346       if (vip_send_req_ptr == NULL)
00347         {
00348           vip_vi_ptr->state = VIP_STATE_IDLE;
00349           vip_free_handle (&(vip_nic_ptr->vip_conn_set),
00350                            (VIP_HANDLE *) vip_conn_ptr);
00351           VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00352           VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00353           return VIP_ERROR_RESOURCE;
00354         }
00355 
00356       pkt_ack_ptr = (VIP_PACKET_CONN_ACK *) (vip_send_req_ptr->ptr);
00357       pkt_ack_ptr->type = VIP_HTON_UCHAR (VIP_CONN_ACK_PKT);
00358       pkt_ack_ptr->status = VIP_HTON_UCHAR (VIP_SUCCESS);
00359       pkt_ack_ptr->srv_seq_num = vip_conn_ptr->net_remote_seq_num;
00360       pkt_ack_ptr->srv_conn_ptr = vip_conn_ptr->net_remote_conn_ptr;
00361       pkt_ack_ptr->net_local_nic_index = VIP_HTON_UINT16 (vip_nic_ptr->index);
00362       pkt_ack_ptr->net_local_vi_index = VIP_HTON_UINT16 (vip_vi_ptr->index);
00363 
00364       vip_send_req_ptr->type |= VIP_SEND_REQ_RELIABLE;
00365       vip_send_req_ptr->dest_port_id = vip_conn_ptr->remote_port_id;
00366       vip_send_req_ptr->dest_gm_id = vip_conn_ptr->remote_gm_id;
00367       vip_send_req_ptr->vip_nic_ptr = vip_nic_ptr;
00368       vip_send_req_ptr->vip_vi_ptr = vip_vi_ptr;
00369       vip_send_data (vip_send_req_ptr);
00370 
00371       vip_free_handle (&(vip_nic_ptr->vip_conn_set),
00372                        (VIP_HANDLE *) vip_conn_ptr);
00373       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00374       VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00375       VIP_DEBUG (("Success: Connection established"));
00376       return VIP_SUCCESS;
00377 
00378     case VIP_REJECT:
00379       /* connection rejected by the server side */
00380       VIP_DEBUG (("Rejected"));
00381       if (vip_vi_ptr->state == VIP_STATE_CONNECT_PENDING)
00382         {
00383           vip_vi_ptr->state = VIP_STATE_IDLE;
00384         }
00385       vip_free_handle (&(vip_nic_ptr->vip_conn_set),
00386                        (VIP_HANDLE *) vip_conn_ptr);
00387       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00388       VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00389       return VIP_REJECT;
00390 
00391     case VIP_NO_MATCH:
00392       /* no matching connection waiting on the server */
00393       VIP_DEBUG (("No match"));
00394       if (vip_vi_ptr->state == VIP_STATE_CONNECT_PENDING)
00395         {
00396           vip_vi_ptr->state = VIP_STATE_IDLE;
00397         }
00398       vip_free_handle (&(vip_nic_ptr->vip_conn_set),
00399                        (VIP_HANDLE *) vip_conn_ptr);
00400       VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00401       VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00402       return VIP_NO_MATCH;
00403 
00404     default:
00405       VIP_ABORT (("Connect request return wrong status"));
00406     }
00407 
00408   VIP_MUTEX_UNLOCK (&(vip_nic_ptr->lock));
00409   VIP_MUTEX_UNLOCK (&(vip_gm_ptr->lock));
00410   return vip_status;
00411 }
VI-GM-1.3 by Myricom © 1997-2006. Documentation generated on 20 May 2006 by doxygen 1.4.4.