-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/ch3/util/sock/ch3u_connect_sock.c
        -:    0:Graph:ch3u_connect_sock.gcno
        -:    0:Data:ch3u_connect_sock.gcda
        -:    0:Runs:3459
        -:    0:Programs:899
        -:    1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
        -:    2:/*
        -:    3: *  (C) 2001 by Argonne National Laboratory.
        -:    4: *      See COPYRIGHT in top-level directory.
        -:    5: */
        -:    6:
        -:    7:#include "mpidi_ch3_impl.h"
        -:    8:#ifdef USE_PMI2_API
        -:    9:#include "pmi2.h"
        -:   10:#else
        -:   11:#include "pmi.h"
        -:   12:#endif
        -:   13:
        -:   14:#include "mpidu_sock.h"
        -:   15:
        -:   16:#include "ch3usock.h"
        -:   17:
        -:   18:/* Private packet types used only within this file */
        -:   19:/* Note that these must be smaller than the PktGeneric type and 
        -:   20:   their MPIDI_CH3_Pkt_type_t values are arbitrary (but must be
        -:   21:   consistent) */
        -:   22:/* FIXME - We need a little security here to avoid having a random port scan 
        -:   23:   crash the process.  Perhaps a "secret" value for each process could be 
        -:   24:   published in the key-val space and subsequently sent in the open pkt. */
        -:   25:typedef struct
        -:   26:{
        -:   27:    MPIDI_CH3_Pkt_type_t type;
        -:   28:    int pg_id_len;
        -:   29:    int pg_rank;
        -:   30:}
        -:   31:MPIDI_CH3I_Pkt_sc_open_req_t;
        -:   32:
        -:   33:typedef struct
        -:   34:{
        -:   35:    MPIDI_CH3_Pkt_type_t type;
        -:   36:    int ack;
        -:   37:}
        -:   38:MPIDI_CH3I_Pkt_sc_open_resp_t;
        -:   39:
        -:   40:typedef struct
        -:   41:{
        -:   42:    MPIDI_CH3_Pkt_type_t type;
        -:   43:    int port_name_tag;
        -:   44:}
        -:   45:MPIDI_CH3I_Pkt_sc_conn_accept_t;
        -:   46:
        -:   47:#ifdef HAVE_NETDB_H
        -:   48:#include <netdb.h>
        -:   49:#endif
        -:   50:#ifdef HAVE_SYS_SOCKET_H
        -:   51:/* Include this for AF_INET */
        -:   52:#include <sys/socket.h>
        -:   53:#endif
        -:   54:#ifdef HAVE_ARPA_INET_H
        -:   55:/* Include this for inet_pton prototype */
        -:   56:#include <arpa/inet.h>
        -:   57:#endif
        -:   58:
        -:   59:/* FIXME: Describe what these routines do */
        -:   60:
        -:   61:/* FIXME: Clean up use of private packets (open/accept) */
        -:   62:
        -:   63:/* Partial description: 
        -:   64:   This file contains the routines that are used to create socket connections,
        -:   65:   including the routines used to encode/decode the description of a connection
        -:   66:   into/out of the "business card".
        -:   67:
        -:   68:   ToDo: change the "host description" to an "interface address" so that
        -:   69:   socket connections are targeted at particularly interfaces, not
        -:   70:   compute nodes, and that the address is in ready-to-use IP address format, 
        -:   71:   and does not require a gethostbyname lookup.  - Partially done
        -:   72: */
        -:   73:
        -:   74:/*
        -:   75: * Manage the connection information that is exported to other processes
        -:   76: * 
        -:   77: */
        -:   78:#define MPIDI_CH3I_HOST_DESCRIPTION_KEY  "description"
        -:   79:#define MPIDI_CH3I_PORT_KEY              "port"
        -:   80:#define MPIDI_CH3I_IFNAME_KEY            "ifname"
        -:   81:
        -:   82:/*
        -:   83: * Routines for establishing a listener socket on the socket set that
        -:   84: * is used for all communication.  These should be called from the
        -:   85: * channel init and finalize routines.
        -:   86: */
        -:   87:static int MPIDI_CH3I_listener_port = 0;
        -:   88:static MPIDI_CH3I_Connection_t * MPIDI_CH3I_listener_conn = NULL;
        -:   89:
        -:   90:/* Required for (socket version) upcall to Connect_to_root (see FIXME) */
        -:   91:extern MPIDU_Sock_set_t MPIDI_CH3I_sock_set;
        -:   92:
        -:   93:#undef FUNCNAME
        -:   94:#define FUNCNAME MPIDU_CH3I_SetupListener
        -:   95:#undef FCNAME
        -:   96:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:   97:int MPIDU_CH3I_SetupListener( MPIDU_Sock_set_t sock_set )
     3459:   98:{
     3459:   99:    int mpi_errno = MPI_SUCCESS;
        -:  100:    MPIDU_Sock_t sock;
        -:  101:
     3459:  102:    mpi_errno = MPIDI_CH3I_Connection_alloc(&MPIDI_CH3I_listener_conn);
     3459:  103:    if (mpi_errno != MPI_SUCCESS) {
    #####:  104:	return mpi_errno;
        -:  105:    }
        -:  106:
        -:  107:    MPIU_DBG_MSG(CH3_CONNECT,TYPICAL,
        -:  108:		 "Setting listener connect state to CONN_STATE_LISTENING");
     3459:  109:    MPIDI_CH3I_listener_conn->sock	  = NULL;
     3459:  110:    MPIDI_CH3I_listener_conn->vc	  = NULL;
     3459:  111:    MPIDI_CH3I_listener_conn->state	  = CONN_STATE_LISTENING;
     3459:  112:    MPIDI_CH3I_listener_conn->send_active = NULL;
     3459:  113:    MPIDI_CH3I_listener_conn->recv_active = NULL;
        -:  114:    
     3459:  115:    mpi_errno = MPIDU_Sock_listen(sock_set, MPIDI_CH3I_listener_conn,
        -:  116:				  &MPIDI_CH3I_listener_port, &sock);
     3459:  117:    if (mpi_errno) return mpi_errno;
        -:  118:
        -:  119:    MPIU_DBG_MSG_D(CH3_CONNECT,VERBOSE,"Listener port %d",
        -:  120:		   MPIDI_CH3I_listener_port );
        -:  121:
     3459:  122:    MPIDI_CH3I_listener_conn->sock = sock;
        -:  123:
     3459:  124:    return mpi_errno;
        -:  125:}
        -:  126:
        -:  127:#undef FUNCNAME
        -:  128:#define FUNCNAME MPIDU_CH3I_ShutdownListener
        -:  129:#undef FCNAME
        -:  130:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  131:int MPIDU_CH3I_ShutdownListener( void )
     3453:  132:{
        -:  133:    int mpi_errno;
        -:  134:    MPID_Progress_state progress_state;
        -:  135:
        -:  136:    MPIU_DBG_MSG(CH3_DISCONNECT,TYPICAL,"Closing listener sock (Post_close)");
     3453:  137:    mpi_errno = MPIDU_Sock_post_close(MPIDI_CH3I_listener_conn->sock);
     3453:  138:    if (mpi_errno != MPI_SUCCESS) {
    #####:  139:	return mpi_errno;
        -:  140:    }
        -:  141:    
     3453:  142:    MPID_Progress_start(&progress_state);
    10359:  143:    while(MPIDI_CH3I_listener_conn != NULL)
        -:  144:    {
     3453:  145:	mpi_errno = MPID_Progress_wait(&progress_state);
        -:  146:	
        -:  147:    }
        -:  148:    MPID_Progress_end(&progress_state);
        -:  149:
     3453:  150:    return mpi_errno;
        -:  151:}
        -:  152:
        -:  153:/* Allocates a connection and the pg_id field for a connection only.
        -:  154:   Does not initialize any connection fields other than pg_id.
        -:  155:   Called by routines that create connections, used in this
        -:  156:   file and in ch3_progress*.c in various channels.
        -:  157:*/
        -:  158:#undef FUNCNAME
        -:  159:#define FUNCNAME MPIDI_CH3I_Connection_alloc
        -:  160:#undef FCNAME
        -:  161:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  162:int MPIDI_CH3I_Connection_alloc(MPIDI_CH3I_Connection_t ** connp)
    16954:  163:{
    16954:  164:    int mpi_errno = MPI_SUCCESS;
    16954:  165:    MPIDI_CH3I_Connection_t * conn = NULL;
        -:  166:    int id_sz;
        -:  167:    int pmi_errno;
    16954:  168:    MPIU_CHKPMEM_DECL(2);
        -:  169:    MPIDI_STATE_DECL(MPID_STATE_CONNECTION_ALLOC);
        -:  170:
        -:  171:    MPIDI_FUNC_ENTER(MPID_STATE_CONNECTION_ALLOC);
        -:  172:
    16954:  173:    MPIU_CHKPMEM_MALLOC(conn,MPIDI_CH3I_Connection_t*,
        -:  174:			sizeof(MPIDI_CH3I_Connection_t),mpi_errno,"conn");
        -:  175:
        -:  176:    /* FIXME: This size is unchanging, so get it only once (at most); 
        -:  177:       we might prefer for connections to simply point at the single process
        -:  178:       group to which the remote process belong */
        -:  179:#ifdef USE_PMI2_API
        -:  180:    id_sz = MPID_MAX_JOBID_LEN;
        -:  181:#else
    16954:  182:    pmi_errno = PMI_Get_id_length_max(&id_sz);
    16954:  183:    MPIU_ERR_CHKANDJUMP1(pmi_errno, mpi_errno,MPI_ERR_OTHER, 
        -:  184:			     "**pmi_get_id_length_max",
        -:  185:			     "**pmi_get_id_length_max %d", pmi_errno);
        -:  186:#endif
    16954:  187:    MPIU_CHKPMEM_MALLOC(conn->pg_id,char*,id_sz + 1,mpi_errno,"conn->pg_id");
    16954:  188:    conn->pg_id[0] = 0;           /* Be careful about pg_id in case a later 
        -:  189:				     error */
    16954:  190:    *connp = conn;
        -:  191:
    16954:  192:  fn_exit:
        -:  193:    MPIDI_FUNC_EXIT(MPID_STATE_CONNECTION_ALLOC);
    16954:  194:    return mpi_errno;
        -:  195:  fn_fail:
    #####:  196:    MPIU_CHKPMEM_REAP();
        -:  197:    goto fn_exit;
        -:  198:}
        -:  199:
        -:  200:
        -:  201:/* FIXME: Why does the name include "to_root"?  */
        -:  202:
        -:  203:/* FIXME: Describe the algorithm for the connection logic */
        -:  204:#undef FUNCNAME
        -:  205:#define FUNCNAME  MPIDI_CH3I_Connect_to_root_sock
        -:  206:#undef FCNAME
        -:  207:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  208:int MPIDI_CH3I_Connect_to_root_sock(const char * port_name, 
        -:  209:				    MPIDI_VC_t ** new_vc)
      669:  210:{
      669:  211:    int mpi_errno = MPI_SUCCESS;
        -:  212:    MPIDI_VC_t * vc;
        -:  213:    MPIDI_CH3I_VC *vcch;
      669:  214:    MPIU_CHKPMEM_DECL(1);
        -:  215:    char host_description[MAX_HOST_DESCRIPTION_LEN];
        -:  216:    int port, port_name_tag;
        -:  217:    MPIDU_Sock_ifaddr_t ifaddr;
      669:  218:    int hasIfaddr = 0;
        -:  219:    MPIDI_CH3I_Connection_t * conn;
        -:  220:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3I_CONNECT_TO_ROOT_SOCK);
        -:  221:
        -:  222:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_CONNECT_TO_ROOT_SOCK);
        -:  223:
        -:  224:    /* First, create a new vc (we may use this to pass to a generic
        -:  225:       connection routine) */
      669:  226:    MPIU_CHKPMEM_MALLOC(vc,MPIDI_VC_t *,sizeof(MPIDI_VC_t),mpi_errno,"vc");
        -:  227:    /* FIXME - where does this vc get freed? */
        -:  228:
      669:  229:    *new_vc = vc;
        -:  230:
        -:  231:    /* FIXME: There may need to be an additional routine here, to ensure that the
        -:  232:       channel is initialized for this pair of process groups (this process
        -:  233:       and the remote process to which the vc will connect). */
      669:  234:    MPIDI_VC_Init(vc, NULL, 0);
        -:  235:
        -:  236:    MPIU_DBG_MSG_S(CH3_CONNECT,VERBOSE,"Connect to root with portstring %s",
        -:  237:		   port_name );
        -:  238:
      669:  239:    mpi_errno = MPIDU_Sock_get_conninfo_from_bc( port_name, host_description,
        -:  240:						 sizeof(host_description),
        -:  241:						 &port, &ifaddr, &hasIfaddr );
      669:  242:    if (mpi_errno) {
        1:  243:	MPIU_ERR_POP(mpi_errno);
        -:  244:    }
      668:  245:    mpi_errno = MPIDI_GetTagFromPort(port_name, &port_name_tag);
      668:  246:    if (mpi_errno != MPIU_STR_SUCCESS) {
    #####:  247:	MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**argstr_port_name_tag");
        -:  248:    }
        -:  249:
        -:  250:    MPIU_DBG_MSG_D(CH3_CONNECT,VERBOSE,"port tag %d",port_name_tag);
        -:  251:
      668:  252:    mpi_errno = MPIDI_CH3I_Connection_alloc(&conn);
      668:  253:    if (mpi_errno != MPI_SUCCESS) {
    #####:  254:	MPIU_ERR_POP(mpi_errno);
        -:  255:    }
        -:  256:
        -:  257:    /* conn->pg_id is not used for this conection */
        -:  258:
        -:  259:    /* FIXME: To avoid this global (MPIDI_CH3I_sock_set) which is 
        -:  260:       used only in ch3_progress.c and ch3_progress_connect.c in the channels,
        -:  261:       this should be a call into the channel, asking it to setup the
        -:  262:       socket for a connection and return the connection.  That will
        -:  263:       keep the socket set out of the general ch3 code, even if this
        -:  264:       is the socket utility functions. */
        -:  265:    MPIU_DBG_MSG_FMT(CH3_CONNECT,VERBOSE,(MPIU_DBG_FDEST,
        -:  266:	  "posting connect to host %s, port %d", host_description, port ));
      668:  267:    mpi_errno = MPIDU_Sock_post_connect(MPIDI_CH3I_sock_set, conn, 
        -:  268:					host_description, port, &conn->sock);
      668:  269:    if (mpi_errno == MPI_SUCCESS)
        -:  270:    {
        -:  271:	MPIDI_CH3I_Pkt_sc_conn_accept_t *acceptpkt = 
      668:  272:	    (MPIDI_CH3I_Pkt_sc_conn_accept_t *)&conn->pkt.type;
      668:  273:    	vcch = (MPIDI_CH3I_VC *)vc->channel_private;
      668:  274:	vcch->sock = conn->sock;
      668:  275:        vcch->conn = conn;
      668:  276:        vcch->state = MPIDI_CH3I_VC_STATE_CONNECTING;
      668:  277:        conn->vc = vc;
        -:  278:	MPIU_DBG_CONNSTATECHANGE(vc,conn,CONN_STATE_CONNECT_ACCEPT);
      668:  279:        conn->state = CONN_STATE_CONNECT_ACCEPT;
      668:  280:        conn->send_active = NULL;
      668:  281:        conn->recv_active = NULL;
        -:  282:
        -:  283:        /* place the port name tag in the pkt that will eventually be sent to 
        -:  284:	   the other side */
      668:  285:        acceptpkt->port_name_tag = port_name_tag;
        -:  286:    }
        -:  287:    /* --BEGIN ERROR HANDLING-- */
        -:  288:    else
        -:  289:    {
    #####:  290:	if (MPIR_ERR_GET_CLASS(mpi_errno) == MPIDU_SOCK_ERR_BAD_HOST)
        -:  291:        { 
    #####:  292:            mpi_errno = MPIR_Err_create_code(
        -:  293:		MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**ch3|sock|badhost",
        -:  294:		"**ch3|sock|badhost %s %d %s", conn->pg_id, conn->vc->pg_rank, port_name);
        -:  295:        }
    #####:  296:        else if (MPIR_ERR_GET_CLASS(mpi_errno) == MPIDU_SOCK_ERR_CONN_FAILED)
        -:  297:        { 
    #####:  298:            mpi_errno = MPIR_Err_create_code(
        -:  299:		MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**ch3|sock|connrefused",
        -:  300:		"**ch3|sock|connrefused %s %d %s", conn->pg_id, conn->vc->pg_rank, port_name);
        -:  301:        }
        -:  302:        else
        -:  303:        {
    #####:  304:	    MPIU_ERR_POP(mpi_errno);
        -:  305:	}
    #####:  306:    	vcch = (MPIDI_CH3I_VC *)vc->channel_private;
    #####:  307:        vcch->state = MPIDI_CH3I_VC_STATE_FAILED;
    #####:  308:        MPIU_Free(conn);
    #####:  309:        goto fn_fail;
        -:  310:    }
        -:  311:    /* --END ERROR HANDLING-- */
        -:  312:
      669:  313: fn_exit:
        -:  314:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_CONNECT_TO_ROOT_SOCK);
      669:  315:    return mpi_errno;
        -:  316: fn_fail:
        1:  317:    MPIU_CHKPMEM_REAP();
        -:  318:    goto fn_exit;
        -:  319:}
        -:  320:
        -:  321:/* ------------------------------------------------------------------------- */
        -:  322:/* Business card management.  These routines insert or extract connection
        -:  323:   information when using sockets from the business card */
        -:  324:/* ------------------------------------------------------------------------- */
        -:  325:
        -:  326:/* FIXME: These are small routines; we may want to bring them together 
        -:  327:   into a more specific post-connection-for-sock */
        -:  328:
        -:  329:/* The host_description should be of length MAX_HOST_DESCRIPTION_LEN */
        -:  330:
        -:  331:#undef FUNCNAME
        -:  332:#define FUNCNAME MPIDU_Sock_get_conninfo_from_bc
        -:  333:#undef FCNAME
        -:  334:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  335:int MPIDU_Sock_get_conninfo_from_bc( const char *bc, 
        -:  336:				     char *host_description, int maxlen,
        -:  337:				     int *port, MPIDU_Sock_ifaddr_t *ifaddr, 
        -:  338:				     int *hasIfaddr )
     6747:  339:{
     6747:  340:    int mpi_errno = MPI_SUCCESS;
        -:  341:    int str_errno;
        -:  342:#if !defined(HAVE_WINDOWS_H) && defined(HAVE_INET_PTON)
        -:  343:    char ifname[256];
        -:  344:#endif
        -:  345:    MPIDI_STATE_DECL(MPID_STATE_MPIDU_SOCK_GET_CONNINFO_FROM_BC);
        -:  346:
        -:  347:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_SOCK_GET_CONNINFO_FROM_BC);
        -:  348:
     6747:  349:    str_errno = MPIU_Str_get_string_arg(bc, MPIDI_CH3I_HOST_DESCRIPTION_KEY, 
        -:  350:				 host_description, maxlen);
     6747:  351:    if (str_errno != MPIU_STR_SUCCESS) {
        -:  352:	/* --BEGIN ERROR HANDLING */
        1:  353:	if (str_errno == MPIU_STR_FAIL) {
        1:  354:	    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**argstr_missinghost");
        -:  355:	}
        -:  356:	else {
        -:  357:	    /* MPIU_STR_TRUNCATED or MPIU_STR_NONEM */
    #####:  358:	    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**argstr_hostd");
        -:  359:	}
        -:  360:	/* --END ERROR HANDLING-- */
        -:  361:    }
     6746:  362:    str_errno = MPIU_Str_get_int_arg(bc, MPIDI_CH3I_PORT_KEY, port);
     6746:  363:    if (str_errno != MPIU_STR_SUCCESS) {
        -:  364:	/* --BEGIN ERROR HANDLING */
    #####:  365:	if (str_errno == MPIU_STR_FAIL) {
    #####:  366:	    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**argstr_missingport");
        -:  367:	}
        -:  368:	else {
        -:  369:	    /* MPIU_STR_TRUNCATED or MPIU_STR_NONEM */
    #####:  370:	    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**argstr_port");
        -:  371:	}
        -:  372:	/* --END ERROR HANDLING-- */
        -:  373:    }
        -:  374:    /* ifname is optional */
        -:  375:    /* FIXME: This is a hack to allow Windows to continue to use
        -:  376:       the host description string instead of the interface address
        -:  377:       bytes when posting a socket connection.  This should be fixed 
        -:  378:       by changing the Sock_post_connect to only accept interface
        -:  379:       address.  Note also that Windows does not have the inet_pton 
        -:  380:       routine; the Windows version of this routine will need to 
        -:  381:       be identified or written.  See also channels/sock/ch3_progress.c and
        -:  382:       channels/ssm/ch3_progress_connect.c */
     6746:  383:    *hasIfaddr = 0;
        -:  384:#if !defined(HAVE_WINDOWS_H) && defined(HAVE_INET_PTON)
     6746:  385:    str_errno = MPIU_Str_get_string_arg(bc, MPIDI_CH3I_IFNAME_KEY, 
        -:  386:					ifname, sizeof(ifname) );
     6746:  387:    if (str_errno == MPIU_STR_SUCCESS) {
        -:  388:	/* Convert ifname into 4-byte ip address */
        -:  389:	/* Use AF_INET6 for IPv6 (inet_pton may still be used).
        -:  390:	   An address with more than 3 :'s is an IPv6 address */
        -:  391:	
     6746:  392:	int rc = inet_pton( AF_INET, (const char *)ifname, ifaddr->ifaddr );
     6746:  393:	if (rc == 0) {
    #####:  394:	    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**ifnameinvalid");
        -:  395:	}
     6746:  396:	else if (rc < 0) {
        -:  397:	    /* af_inet not supported */
    #####:  398:	    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**afinetinvalid");
        -:  399:	}
        -:  400:	else {
        -:  401:	    /* Success */
     6746:  402:	    *hasIfaddr = 1;
     6746:  403:	    ifaddr->len = 4;  /* IPv4 address */
     6746:  404:	    ifaddr->type = AF_INET;
        -:  405:	}
        -:  406:    }
        -:  407:#endif
        -:  408:    
     6747:  409: fn_exit:
        -:  410:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_SOCK_GET_CONNINFO_FROM_BC);
     6747:  411:    return mpi_errno;
        -:  412: fn_fail:
        -:  413:    goto fn_exit;
        -:  414:}
        -:  415:
        -:  416:
        -:  417:/*  MPIDI_CH3U_Get_business_card_sock - does socket specific portion of 
        -:  418: *  setting up a business card
        -:  419: *  
        -:  420: *  Parameters:
        -:  421: *     bc_val_p     - business card value buffer pointer, updated to the next 
        -:  422: *                    available location or freed if published.
        -:  423: *     val_max_sz_p - ptr to maximum value buffer size reduced by the number 
        -:  424: *                    of characters written
        -:  425: *                               
        -:  426: */
        -:  427:
        -:  428:#undef FUNCNAME
        -:  429:#define FUNCNAME MPIDI_CH3U_Get_business_card_sock
        -:  430:#undef FCNAME
        -:  431:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  432:int MPIDI_CH3U_Get_business_card_sock(int myRank, 
        -:  433:				      char **bc_val_p, int *val_max_sz_p)
     3831:  434:{
     3831:  435:    int mpi_errno = MPI_SUCCESS;
        -:  436:    MPIDU_Sock_ifaddr_t ifaddr;
        -:  437:    char ifnamestr[MAX_HOST_DESCRIPTION_LEN];
     3831:  438:    char *bc_orig = *bc_val_p;
        -:  439:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3U_GET_BUSINESS_CARD_SOCK);
        -:  440:
        -:  441:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3U_GET_BUSINESS_CARD_SOCK);
        -:  442:
     3831:  443:    MPIDU_CH3U_GetSockInterfaceAddr( myRank, ifnamestr, sizeof(ifnamestr), &ifaddr );
        -:  444:
     3831:  445:    mpi_errno = MPIU_Str_add_int_arg(bc_val_p, val_max_sz_p, 
        -:  446:			     MPIDI_CH3I_PORT_KEY, MPIDI_CH3I_listener_port);
        -:  447:    /* --BEGIN ERROR HANDLING-- */
     3831:  448:    if (mpi_errno != MPIU_STR_SUCCESS)
        -:  449:    {
    #####:  450:	if (mpi_errno == MPIU_STR_NOMEM) {
    #####:  451:	    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**buscard_len");
        -:  452:	}
        -:  453:	else {
    #####:  454:	    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**buscard");
        -:  455:	}
        -:  456:    }
        -:  457:    /* --END ERROR HANDLING-- */
        -:  458:    
     3831:  459:    mpi_errno = MPIU_Str_add_string_arg(bc_val_p, val_max_sz_p, 
        -:  460:			   MPIDI_CH3I_HOST_DESCRIPTION_KEY, ifnamestr );
        -:  461:    /* --BEGIN ERROR HANDLING-- */
     3831:  462:    if (mpi_errno != MPIU_STR_SUCCESS)
        -:  463:    {
    #####:  464:	if (mpi_errno == MPIU_STR_NOMEM) {
    #####:  465:	    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**buscard_len");
        -:  466:	}
        -:  467:	else {
    #####:  468:	    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**buscard");
        -:  469:	}
        -:  470:	return mpi_errno;
        -:  471:    }
        -:  472:    /* --END ERROR HANDLING-- */
        -:  473:
        -:  474:    /* Look up the interface address cooresponding to this host description */
        -:  475:    /* FIXME: We should start switching to getaddrinfo instead of 
        -:  476:       gethostbyname */
        -:  477:    /* FIXME: We don't make use of the ifname in Windows in order to 
        -:  478:       provide backward compatibility with the (undocumented) host
        -:  479:       description string used by the socket connection routine 
        -:  480:       MPIDU_Sock_post_connect.  We need to change to an interface-address
        -:  481:       (already resolved) based description for better scalability and
        -:  482:       to eliminate reliance on fragile DNS services. Note that this is
        -:  483:       also more scalable, since the DNS server may serialize address 
        -:  484:       requests.  On most systems, asking for the host info of yourself
        -:  485:       is resolved locally (i.e., perfectly parallel).  Regrettably, not
        -:  486:       all systems do this (e.g., some versions of FreeBSD).
        -:  487:    */
        -:  488:#if 0
        -:  489:#ifndef HAVE_WINDOWS_H
        -:  490:    {
        -:  491:	struct hostent *info;
        -:  492:	char ifname[256];
        -:  493:	unsigned char *p;
        -:  494:	info = gethostbyname( ifname );
        -:  495:	if (info && info->h_addr_list) {
        -:  496:	    p = (unsigned char *)(info->h_addr_list[0]);
        -:  497:	    MPIU_Snprintf( ifname, sizeof(ifname), "%u.%u.%u.%u", 
        -:  498:			   p[0], p[1], p[2], p[3] );
        -:  499:	    MPIU_DBG_MSG_S(CH3_CONNECT,VERBOSE,"ifname = %s",ifname );
        -:  500:	    mpi_errno = MPIU_Str_add_string_arg( bc_val_p, 
        -:  501:						 val_max_sz_p, 
        -:  502:						 MPIDI_CH3I_IFNAME_KEY,
        -:  503:						 ifname );
        -:  504:	    if (mpi_errno != MPIU_STR_SUCCESS) {
        -:  505:		if (mpi_errno == MPIU_STR_NOMEM) {
        -:  506:		    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**buscard_len");
        -:  507:		}
        -:  508:		else {
        -:  509:		    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**buscard");
        -:  510:		}
        -:  511:	    }
        -:  512:	}
        -:  513:    }
        -:  514:#endif
        -:  515:#endif 
        -:  516:
        -:  517:    {
        -:  518:	char ifname[256];
        -:  519:	unsigned char *p;
     3831:  520:	if (ifaddr.len > 0 && ifaddr.type == AF_INET) {
     3831:  521:	    p = (unsigned char *)(ifaddr.ifaddr);
     3831:  522:	    MPIU_Snprintf( ifname, sizeof(ifname), "%u.%u.%u.%u", 
        -:  523:			   p[0], p[1], p[2], p[3] );
        -:  524:	    MPIU_DBG_MSG_S(CH3_CONNECT,VERBOSE,"ifname = %s",ifname );
     3831:  525:	    mpi_errno = MPIU_Str_add_string_arg( bc_val_p, 
        -:  526:						 val_max_sz_p, 
        -:  527:						 MPIDI_CH3I_IFNAME_KEY,
        -:  528:						 ifname );
     3831:  529:	    if (mpi_errno != MPIU_STR_SUCCESS) {
    #####:  530:		if (mpi_errno == MPIU_STR_NOMEM) {
    #####:  531:		    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**buscard_len");
        -:  532:		}
        -:  533:		else {
    #####:  534:		    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**buscard");
        -:  535:		}
        -:  536:	    }
        -:  537:	}
        -:  538:    }
        -:  539:
        -:  540:    MPIU_DBG_MSG_S(CH3_CONNECT,TYPICAL,"business card is %s\n", bc_orig );
        -:  541:
     3831:  542: fn_exit:
        -:  543:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3U_GET_BUSINESS_CARD_SOCK);
     3831:  544:    return mpi_errno;
        -:  545: fn_fail:
        -:  546:    goto fn_exit;
        -:  547:}
        -:  548:
        -:  549:/* ------------------------------------------------------------------------- */
        -:  550:/* Below will be/is the code that is used to create a connection and
        -:  551: * to handle changes to the state of a connection.  
        -:  552: */
        -:  553:/* ------------------------------------------------------------------------- */
        -:  554:static int connection_post_recv_pkt(MPIDI_CH3I_Connection_t * conn);
        -:  555:static int connection_post_send_pkt(MPIDI_CH3I_Connection_t * conn);
        -:  556:static int connection_post_send_pkt_and_pgid(MPIDI_CH3I_Connection_t * conn);
        -:  557:static int connection_post_sendq_req(MPIDI_CH3I_Connection_t * conn);
        -:  558:static void connection_destroy(MPIDI_CH3I_Connection_t * conn);
        -:  559:
        -:  560:/* This routine is called in response to an MPIDU_SOCK_OP_ACCEPT event 
        -:  561:   in ch3_progress */
        -:  562:#undef FUNCNAME
        -:  563:#define FUNCNAME MPIDI_CH3_Sockconn_handle_accept_event
        -:  564:#undef FCNAME
        -:  565:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  566:int MPIDI_CH3_Sockconn_handle_accept_event( void )
     6749:  567:{
     6749:  568:    int mpi_errno = MPI_SUCCESS;
        -:  569:    MPIDI_CH3I_Connection_t * conn;
        -:  570:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_ACCEPT_EVENT);
        -:  571:
        -:  572:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_ACCEPT_EVENT);
        -:  573:    
     6749:  574:    mpi_errno = MPIDI_CH3I_Connection_alloc(&conn);
     6749:  575:    if (mpi_errno != MPI_SUCCESS) {
    #####:  576:	MPIU_ERR_POP(mpi_errno);
        -:  577:    }
     6749:  578:    mpi_errno = MPIDU_Sock_accept(MPIDI_CH3I_listener_conn->sock, 
        -:  579:				  MPIDI_CH3I_sock_set, conn, &conn->sock);
     6749:  580:    if (mpi_errno != MPI_SUCCESS) {
    #####:  581:	MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**ch3|sock|accept");
        -:  582:    }
        -:  583:    
     6749:  584:    conn->vc = NULL;
        -:  585:    MPIU_DBG_CONNSTATECHANGE(conn->vc,conn,CONN_STATE_OPEN_LRECV_PKT);
     6749:  586:    conn->state = CONN_STATE_OPEN_LRECV_PKT;
     6749:  587:    conn->send_active = NULL;
     6749:  588:    conn->recv_active = NULL;
        -:  589:    
     6749:  590:    mpi_errno = connection_post_recv_pkt(conn);
     6749:  591:    if (mpi_errno != MPI_SUCCESS) {
    #####:  592:	MPIU_ERR_POP(mpi_errno);
        -:  593:    }
        -:  594:
     6749:  595: fn_exit:
        -:  596:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_ACCEPT_EVENT);
        -:  597:
     6749:  598:    return mpi_errno;
        -:  599: fn_fail:
        -:  600:    goto fn_exit;
        -:  601:}
        -:  602:
        -:  603:#undef FUNCNAME
        -:  604:#define FUNCNAME MPIDI_CH3_Sockconn_handle_connect_event
        -:  605:#undef FCNAME
        -:  606:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  607:int MPIDI_CH3_Sockconn_handle_connect_event( MPIDI_CH3I_Connection_t *conn, 
        -:  608:					     int event_error )
     6746:  609:{
     6746:  610:    int mpi_errno = MPI_SUCCESS;
        -:  611:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_CONNECT_EVENT);
        -:  612:
        -:  613:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_CONNECT_EVENT);
        -:  614:    
        -:  615:    /* --BEGIN ERROR HANDLING-- */
     6746:  616:    if (event_error != MPI_SUCCESS) {
        -:  617:	/* If the connection fails, conn->vc etc is probably invalid,
        -:  618:	   so we can only report that the connection failed */
    #####:  619:	mpi_errno = event_error;
    #####:  620:	MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**ch3|sock|connfailed" );
        -:  621:    }
        -:  622:    /* --END ERROR HANDLING-- */
        -:  623:
     6746:  624:    if (conn->state == CONN_STATE_CONNECTING) {
        -:  625:	MPIDI_CH3I_Pkt_sc_open_req_t *openpkt = 
     6078:  626:	    (MPIDI_CH3I_Pkt_sc_open_req_t *)&conn->pkt.type;
        -:  627:	MPIU_DBG_CONNSTATECHANGE(conn->vc,conn,CONN_STATE_OPEN_CSEND);
     6078:  628:	conn->state = CONN_STATE_OPEN_CSEND;
     6078:  629:	MPIDI_Pkt_init(openpkt, MPIDI_CH3I_PKT_SC_OPEN_REQ);
     6078:  630:	openpkt->pg_id_len = (int) strlen(MPIDI_Process.my_pg->id) + 1;
     6078:  631:	openpkt->pg_rank = MPIR_Process.comm_world->rank;
        -:  632:	
     6078:  633:	mpi_errno = connection_post_send_pkt_and_pgid(conn);
     6078:  634:	if (mpi_errno) { MPIU_ERR_POP(mpi_errno); }
        -:  635:    }
        -:  636:    else {
        -:  637:	/* CONN_STATE_CONNECT_ACCEPT */
        -:  638:	int port_name_tag;
        -:  639:	MPIDI_CH3I_Pkt_sc_conn_accept_t *acceptpkt = 
      668:  640:	    (MPIDI_CH3I_Pkt_sc_conn_accept_t *)&conn->pkt.type;
        -:  641:
      668:  642:	MPIU_Assert(conn->state == CONN_STATE_CONNECT_ACCEPT);
        -:  643:	MPIU_DBG_CONNSTATECHANGE(conn->vc,conn,CONN_STATE_OPEN_CSEND);
      668:  644:	conn->state = CONN_STATE_OPEN_CSEND;
        -:  645:	
        -:  646:	/* pkt contains port name tag. In memory debugging mode, 
        -:  647:	   MPIDI_Pkt_init resets the packet contents. Therefore,
        -:  648:	   save the port name tag and then add it back. */
      668:  649:	port_name_tag = acceptpkt->port_name_tag;
      668:  650:	MPIDI_Pkt_init(acceptpkt, MPIDI_CH3I_PKT_SC_CONN_ACCEPT);
      668:  651:	acceptpkt->port_name_tag = port_name_tag;
        -:  652:	
      668:  653:	mpi_errno = connection_post_send_pkt(conn);
      668:  654:	if (mpi_errno != MPI_SUCCESS) {
    #####:  655:	    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_INTERN,
        -:  656:				"**ch3|sock|scconnaccept");
        -:  657:	}
        -:  658:    }
        -:  659:
     6746:  660: fn_exit:
        -:  661:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_CONNECT_EVENT);
     6746:  662:    return mpi_errno;
        -:  663: fn_fail:
        -:  664:    goto fn_exit;
        -:  665:}
        -:  666:
        -:  667:#undef FUNCNAME
        -:  668:#define FUNCNAME MPIDI_CH3_Sockconn_handle_close_event
        -:  669:#undef FCNAME
        -:  670:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  671:int MPIDI_CH3_Sockconn_handle_close_event( MPIDI_CH3I_Connection_t * conn )
    16943:  672:{
    16943:  673:    int mpi_errno = MPI_SUCCESS;
        -:  674:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_CLOSE_EVENT);
        -:  675:
        -:  676:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_CLOSE_EVENT);
        -:  677:
        -:  678:    /* If the conn pointer is NULL then the close was intentional */
        -:  679:    /* FIXME: What does the above comment mean? */
    16943:  680:    if (conn != NULL) {
    16943:  681:	if (conn->state == CONN_STATE_CLOSING) {
    13490:  682:	    MPIU_Assert(conn->send_active == NULL);
    13490:  683:	    MPIU_Assert(conn->recv_active == NULL);
    13490:  684:	    if (conn->vc != NULL) {
    12244:  685:		MPIDI_CH3I_VC *vcch = (MPIDI_CH3I_VC *)conn->vc->channel_private;
        -:  686:
    12244:  687:                conn->sock = MPIDU_SOCK_INVALID_SOCK;
        -:  688:                MPIU_DBG_CONNSTATECHANGE(conn->vc,conn,CONN_STATE_CLOSED);
    12244:  689:                conn->state = CONN_STATE_CLOSED;
        -:  690:
        -:  691:                /* Only manipulate vcch if conn was not the loser in a
        -:  692:                   head-to-head resolution.  */
    12244:  693:                if (vcch && vcch->conn == conn) {
        -:  694:                    MPIU_DBG_VCCHSTATECHANGE(conn->vc,VC_STATE_UNCONNECTED);
    12244:  695:                    vcch->state = MPIDI_CH3I_VC_STATE_UNCONNECTED;
    12244:  696:                    vcch->sock  = MPIDU_SOCK_INVALID_SOCK;
        -:  697:
        -:  698:                    /* This step is important; without this, test
        -:  699:                       disconnect_reconnect fails because the vc->ch.conn 
        -:  700:                       connection will continue to be used, even though
        -:  701:                       the memory has been freed */
    12244:  702:                    vcch->conn = NULL;
        -:  703:
        -:  704:                    /* Handle_connection takes care of updating the state on the VC */
    12244:  705:                    mpi_errno = MPIDI_CH3U_Handle_connection(conn->vc, MPIDI_VC_EVENT_TERMINATED);
    12244:  706:                    if (mpi_errno) MPIU_ERR_POP(mpi_errno);
        -:  707:                }
        -:  708:            }
        -:  709:
        -:  710:            /* The VC was likely freed in the _Handle_connection call and should
        -:  711:               not be referenced anymore in any case. */
    13490:  712:            conn->vc = NULL;
        -:  713:	}
        -:  714:	else {
     3453:  715:	    MPIU_Assert(conn->state == CONN_STATE_LISTENING);
     3453:  716:	    MPIDI_CH3I_listener_conn = NULL;
     3453:  717:	    MPIDI_CH3I_listener_port = 0;
        -:  718:	    
     3453:  719:	    MPIDI_CH3_Progress_signal_completion();
        -:  720:	}
        -:  721:
    16943:  722:	connection_destroy(conn); 
        -:  723:    }
    16943:  724: fn_exit:
        -:  725:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_CLOSE_EVENT);
    16943:  726:    return mpi_errno;
        -:  727: fn_fail:
        -:  728:    goto fn_exit;
        -:  729:}
        -:  730:
        -:  731:/* Cycle through the connection setup states */
        -:  732:/* FIXME: separate out the accept and connect sides to make it easier
        -:  733:   to follow the logic */
        -:  734:#undef FUNCNAME
        -:  735:#define FUNCNAME MPIDI_CH3_Sockconn_handle_conn_event
        -:  736:#undef FCNAME
        -:  737:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  738:int MPIDI_CH3_Sockconn_handle_conn_event( MPIDI_CH3I_Connection_t * conn )
    13495:  739:{
    13495:  740:    int mpi_errno = MPI_SUCCESS;
        -:  741:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_CONN_EVENT);
        -:  742:
        -:  743:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_CONN_EVENT);
        -:  744:
        -:  745:    /* FIXME: Is there an assumption about conn->state? */
        -:  746:
    13495:  747:    if (conn->pkt.type == MPIDI_CH3I_PKT_SC_OPEN_REQ) {
        -:  748:	MPIDI_CH3I_Pkt_sc_open_req_t *openpkt = 
     6081:  749:	    (MPIDI_CH3I_Pkt_sc_open_req_t *)&conn->pkt.type;
        -:  750:	/* Answer to fixme: it appears from the control flow that this is
        -:  751:	   the required state) */
     6081:  752:	MPIU_Assert( conn->state == CONN_STATE_OPEN_LRECV_PKT);
        -:  753:	MPIU_DBG_CONNSTATECHANGE(conn->vc,conn,CONN_STATE_OPEN_LRECV_DATA);
     6081:  754:	conn->state = CONN_STATE_OPEN_LRECV_DATA;
     6081:  755:	mpi_errno = MPIDU_Sock_post_read(conn->sock, conn->pg_id, 
        -:  756:					 openpkt->pg_id_len, 
        -:  757:					 openpkt->pg_id_len, NULL);   
     6081:  758:	if (mpi_errno != MPI_SUCCESS) {
    #####:  759:	    MPIU_ERR_POP(mpi_errno);
        -:  760:	}
        -:  761:    }
     7414:  762:    else if (conn->pkt.type == MPIDI_CH3I_PKT_SC_CONN_ACCEPT) {
        -:  763:	MPIDI_VC_t *vc; 
        -:  764:	MPIDI_CH3I_VC *vcch;
        -:  765:	int port_name_tag;
        -:  766:	MPIDI_CH3I_Pkt_sc_conn_accept_t *acceptpkt = 
      668:  767:	    (MPIDI_CH3I_Pkt_sc_conn_accept_t *)&conn->pkt.type;
        -:  768:	MPIDI_CH3I_Pkt_sc_open_resp_t *openresp = 
      668:  769:	    (MPIDI_CH3I_Pkt_sc_open_resp_t *)&conn->pkt.type;
        -:  770:
      668:  771:	vc = (MPIDI_VC_t *) MPIU_Malloc(sizeof(MPIDI_VC_t));
        -:  772:	/* --BEGIN ERROR HANDLING-- */
      668:  773:	if (vc == NULL) {
    #####:  774:	    mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER,
        -:  775:					     "**nomem", NULL);
    #####:  776:	    goto fn_fail;
        -:  777:	}
        -:  778:	/* --END ERROR HANDLING-- */
        -:  779:	/* FIXME - where does this vc get freed? */
        -:  780:
      668:  781:	MPIDI_VC_Init(vc, NULL, 0);
        -:  782:
      668:  783:	vcch = (MPIDI_CH3I_VC *)vc->channel_private;
        -:  784:	MPIU_DBG_VCCHSTATECHANGE(vc,VC_STATE_CONNECTING);
      668:  785:	vcch->state = MPIDI_CH3I_VC_STATE_CONNECTING;
      668:  786:	vcch->sock = conn->sock;
      668:  787:	vcch->conn = conn;
      668:  788:	conn->vc   = vc;
      668:  789:	port_name_tag = acceptpkt->port_name_tag;
        -:  790:	
      668:  791:	MPIDI_Pkt_init(openresp, MPIDI_CH3I_PKT_SC_OPEN_RESP);
      668:  792:	openresp->ack = TRUE;
        -:  793:	
        -:  794:	/* FIXME: Possible ambiguous state (two ways to get to OPEN_LSEND) */
        -:  795:	MPIU_DBG_CONNSTATECHANGE(conn->vc,conn,CONN_STATE_OPEN_LSEND);
      668:  796:	conn->state = CONN_STATE_OPEN_LSEND;
      668:  797:	mpi_errno = connection_post_send_pkt(conn);
      668:  798:	if (mpi_errno != MPI_SUCCESS) {
    #####:  799:	    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_INTERN,
        -:  800:				"**ch3|sock|scconnaccept");
        -:  801:	}
        -:  802:	
        -:  803:	/* ENQUEUE vc */
      668:  804:	MPIDI_CH3I_Acceptq_enqueue(vc, port_name_tag);
        -:  805:
        -:  806:    }
     6746:  807:    else if (conn->pkt.type == MPIDI_CH3I_PKT_SC_OPEN_RESP) {
        -:  808:	MPIDI_CH3I_Pkt_sc_open_resp_t *openpkt = 
     6746:  809:	    (MPIDI_CH3I_Pkt_sc_open_resp_t *)&conn->pkt.type;
        -:  810:	/* FIXME: is this the correct assert? */
     6746:  811:	MPIU_Assert( conn->state == CONN_STATE_OPEN_CRECV );
     6746:  812:	if (openpkt->ack) {
     6123:  813:	    MPIDI_CH3I_VC *vcch = (MPIDI_CH3I_VC *)conn->vc->channel_private;
        -:  814:	    MPIU_DBG_CONNSTATECHANGE(conn->vc,conn,CONN_STATE_CONNECTED);
     6123:  815:	    conn->state = CONN_STATE_CONNECTED;
     6123:  816:	    vcch->state = MPIDI_CH3I_VC_STATE_CONNECTED;
     6123:  817:	    MPIU_Assert(vcch->conn == conn);
     6123:  818:	    MPIU_Assert(vcch->sock == conn->sock);
        -:  819:	    
     6123:  820:	    mpi_errno = connection_post_recv_pkt(conn);
     6123:  821:	    if (mpi_errno != MPI_SUCCESS) {
    #####:  822:		MPIU_ERR_POP(mpi_errno);
        -:  823:	    }
     6123:  824:	    mpi_errno = connection_post_sendq_req(conn);
     6123:  825:	    if (mpi_errno != MPI_SUCCESS) {
    #####:  826:		MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_INTERN,
        -:  827:				    "**ch3|sock|scopenresp");
        -:  828:	    }
        -:  829:	}
        -:  830:	else {
      623:  831:	    MPIDI_CH3I_VC *vcch = (MPIDI_CH3I_VC *)conn->vc->channel_private;
        -:  832:	    /* FIXME: Should conn->vc be freed? Who allocated? Why not? */
        -:  833:	    /* FIXME: Should probably reduce ref count on conn->vc */
        -:  834:	    /* FIXME: What happens to the state of the associated VC? 
        -:  835:	       Why isn't it changed?  Is there an assert here, 
        -:  836:	       such as conn->vc->conn != conn (there is another connection 
        -:  837:	       chosen for the vc)? */
        -:  838:	    /* MPIU_Assert( conn->vc->ch.conn != conn ); */
        -:  839:	    /* Set the candidate vc for this connection to NULL (we
        -:  840:	       are discarding this connection because (I think) we
        -:  841:	       are performing a head-to-head connection, and this
        -:  842:	       connection is being rejected in favor of the connection
        -:  843:	       from the other side. */
      623:  844:	    if (vcch->conn == conn) vcch->conn = NULL;
        -:  845:	    MPIU_DBG_CONNSTATECHANGE_MSG(conn->vc,conn,CONN_STATE_CLOSING,
        -:  846:					"because ack on OPEN_CRECV was false");
      623:  847:	    conn->vc = NULL;
      623:  848:	    conn->state = CONN_STATE_CLOSING;
        -:  849:	    /* FIXME: What does post close do here? */
        -:  850:	    MPIU_DBG_MSG(CH3_DISCONNECT,TYPICAL,"CLosing sock (Post_close)");
      623:  851:	    mpi_errno = MPIDU_Sock_post_close(conn->sock);
      623:  852:	    if (mpi_errno != MPI_SUCCESS) {
    #####:  853:		MPIU_ERR_POP(mpi_errno);
        -:  854:	    }
        -:  855:	}
        -:  856:    }
        -:  857:    /* --BEGIN ERROR HANDLING-- */
        -:  858:    else {
        -:  859:	MPIU_DBG_STMT(CH3_CONNECT,VERBOSE,MPIDI_DBG_Print_packet(&conn->pkt));
    #####:  860:	mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_INTERN,
        -:  861:					 "**ch3|sock|badpacket", "**ch3|sock|badpacket %d", conn->pkt.type);
    #####:  862:	goto fn_fail;
        -:  863:    }
        -:  864:    /* --END ERROR HANDLING-- */
        -:  865:
        -:  866:
    13495:  867: fn_exit:
        -:  868:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_CONN_EVENT);
    13495:  869:    return mpi_errno;
        -:  870: fn_fail:
        -:  871:    goto fn_exit;
        -:  872:}
        -:  873:
        -:  874:/* FIXME: This should really be combined with handle_conn_event */
        -:  875:#undef FUNCNAME
        -:  876:#define FUNCNAME MPIDI_CH3_Sockconn_handle_connopen_event
        -:  877:#undef FCNAME
        -:  878:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  879:int MPIDI_CH3_Sockconn_handle_connopen_event( MPIDI_CH3I_Connection_t * conn )
     6081:  880:{
     6081:  881:    int mpi_errno = MPI_SUCCESS;
        -:  882:    MPIDI_PG_t * pg;
        -:  883:    int pg_rank;
        -:  884:    MPIDI_VC_t * vc;
        -:  885:    MPIDI_CH3I_VC *vcch;
        -:  886:    MPIDI_CH3I_Pkt_sc_open_req_t *openpkt = 
     6081:  887:	(MPIDI_CH3I_Pkt_sc_open_req_t *)&conn->pkt.type;
        -:  888:    MPIDI_CH3I_Pkt_sc_open_resp_t *openresp = 
     6081:  889:	(MPIDI_CH3I_Pkt_sc_open_resp_t *)&conn->pkt.type;
        -:  890:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_CONNOPEN_EVENT);
        -:  891:
        -:  892:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_CONNOPEN_EVENT);
        -:  893:
        -:  894:    /* Look up pg based on conn->pg_id */
     6081:  895:    mpi_errno = MPIDI_PG_Find(conn->pg_id, &pg);
     6081:  896:    if (pg == NULL) {
    #####:  897:	MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER,
        -:  898:			     "**pglookup", 
        -:  899:			     "**pglookup %s", conn->pg_id);
        -:  900:    }
        -:  901:    
        -:  902:    /* We require that the packet be the open_req type */
     6081:  903:    pg_rank = openpkt->pg_rank;
     6081:  904:    MPIDI_PG_Get_vc_set_active(pg, pg_rank, &vc);
     6081:  905:    MPIU_Assert(vc->pg_rank == pg_rank);
        -:  906:    
     6081:  907:    vcch = (MPIDI_CH3I_VC *)vc->channel_private;
     6081:  908:    if (vcch->conn == NULL) {
        -:  909:	/* no head-to-head connects, accept the connection */
        -:  910:	MPIU_DBG_VCCHSTATECHANGE(vc,VC_STATE_CONNECTING);
     4996:  911:	vcch->state = MPIDI_CH3I_VC_STATE_CONNECTING;
     4996:  912:	vcch->sock = conn->sock;
     4996:  913:	vcch->conn = conn;
     4996:  914:	conn->vc = vc;
        -:  915:	
     4996:  916:	MPIDI_Pkt_init(openresp, MPIDI_CH3I_PKT_SC_OPEN_RESP);
     4996:  917:	openresp->ack = TRUE;
        -:  918:    }
        -:  919:    else {
        -:  920:	/* head to head situation */
     1085:  921:	if (pg == MPIDI_Process.my_pg) {
        -:  922:	    /* the other process is in the same comm_world; just compare the 
        -:  923:	       ranks */
     1079:  924:	    if (MPIR_Process.comm_world->rank < pg_rank) {
        -:  925:		MPIU_DBG_MSG_FMT(CH3_CONNECT,TYPICAL,(MPIU_DBG_FDEST,
        -:  926:                "vc=%p,conn=%p:Accept head-to-head connection (my process group), discarding vcch->conn=%p",vc,conn, vcch->conn));
        -:  927:
        -:  928:		/* accept connection */
        -:  929:		MPIU_DBG_VCCHSTATECHANGE(vc,VC_STATE_CONNECTING);
      459:  930:		vcch->state = MPIDI_CH3I_VC_STATE_CONNECTING;
      459:  931:		vcch->sock = conn->sock;
      459:  932:		vcch->conn = conn;
      459:  933:		conn->vc = vc;
        -:  934:		
      459:  935:		MPIDI_Pkt_init(openresp, MPIDI_CH3I_PKT_SC_OPEN_RESP);
      459:  936:		openresp->ack = TRUE;
        -:  937:	    }
        -:  938:	    else {
        -:  939:		/* refuse connection */
        -:  940:		MPIU_DBG_MSG_FMT(CH3_CONNECT,TYPICAL,(MPIU_DBG_FDEST,
        -:  941:                "vc=%p,conn=%p:Refuse head-to-head connection (my process group)",vc,conn));
      620:  942:		MPIDI_Pkt_init(openresp, MPIDI_CH3I_PKT_SC_OPEN_RESP);
      620:  943:		openresp->ack = FALSE;
        -:  944:	    }
        -:  945:	}
        -:  946:	else {
        -:  947:	    /* the two processes are in different comm_worlds; compare their 
        -:  948:	       unique pg_ids. */
        6:  949:	    if (strcmp(MPIDI_Process.my_pg->id, pg->id) < 0) {
        -:  950:		MPIU_DBG_MSG_FMT(CH3_CONNECT,TYPICAL,(MPIU_DBG_FDEST,
        -:  951:                "vc=%p,conn=%p:Accept head-to-head connection (two process groups), discarding vcch->conn=%p",vc,conn, vcch->conn));
        -:  952:		/* accept connection */
        -:  953:		MPIU_DBG_VCCHSTATECHANGE(vc,VC_STATE_CONNECTING);
        3:  954:		vcch->state = MPIDI_CH3I_VC_STATE_CONNECTING;
        3:  955:		vcch->sock = conn->sock;
        3:  956:		vcch->conn = conn;
        3:  957:		conn->vc = vc;
        -:  958:		
        3:  959:		MPIDI_Pkt_init(openresp, MPIDI_CH3I_PKT_SC_OPEN_RESP);
        3:  960:		openresp->ack = TRUE;
        -:  961:	    }
        -:  962:	    else {
        -:  963:		/* refuse connection */
        -:  964:		MPIU_DBG_MSG_FMT(CH3_CONNECT,TYPICAL,(MPIU_DBG_FDEST,
        -:  965:			"vc=%p,conn=%p:Refuse head-to-head connection (two process groups)",vc,conn));
        3:  966:		MPIDI_Pkt_init(openresp, MPIDI_CH3I_PKT_SC_OPEN_RESP);
        3:  967:		openresp->ack = FALSE;
        -:  968:	    }
        -:  969:	}
        -:  970:    }
        -:  971:    
        -:  972:    MPIU_DBG_CONNSTATECHANGE(conn->vc,conn,CONN_STATE_OPEN_LSEND);
     6081:  973:    conn->state = CONN_STATE_OPEN_LSEND;
     6081:  974:    mpi_errno = connection_post_send_pkt(conn);
     6081:  975:    if (mpi_errno != MPI_SUCCESS) {
    #####:  976:	MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_INTERN,
        -:  977:			    "**ch3|sock|open_lrecv_data");
        -:  978:    }
        -:  979:
     6081:  980: fn_exit:
        -:  981:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_CONNOPEN_EVENT);
     6081:  982:    return mpi_errno;
        -:  983: fn_fail:
        -:  984:    goto fn_exit;
        -:  985:}
        -:  986:
        -:  987:/* FIXME: This routine is called when?  What is valid in conn? */
        -:  988:#undef FUNCNAME
        -:  989:#define FUNCNAME MPIDI_CH3_Sockconn_handle_connwrite
        -:  990:#undef FCNAME
        -:  991:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:  992:int MPIDI_CH3_Sockconn_handle_connwrite( MPIDI_CH3I_Connection_t * conn )
    13495:  993:{
    13495:  994:    int mpi_errno = MPI_SUCCESS;
        -:  995:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_CONNWRITE);
        -:  996:
        -:  997:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_CONNWRITE);
        -:  998:
    13495:  999:    if (conn->state == CONN_STATE_OPEN_CSEND) {
        -: 1000:	/* finished sending open request packet */
        -: 1001:	/* post receive for open response packet */
        -: 1002:	MPIU_DBG_CONNSTATECHANGE(conn->vc,conn,CONN_STATE_OPEN_CRECV);
     6746: 1003:	conn->state = CONN_STATE_OPEN_CRECV;
     6746: 1004:	mpi_errno = connection_post_recv_pkt(conn);
     6746: 1005:	if (mpi_errno != MPI_SUCCESS) {
    #####: 1006:	    MPIU_ERR_POP(mpi_errno);
        -: 1007:	}
        -: 1008:    }
     6749: 1009:    else if (conn->state == CONN_STATE_OPEN_LSEND) {
        -: 1010:	MPIDI_CH3I_Pkt_sc_open_resp_t *openresp = 
     6749: 1011:	    (MPIDI_CH3I_Pkt_sc_open_resp_t *)&conn->pkt.type;
        -: 1012:	/* finished sending open response packet */
     6749: 1013:	if (openresp->ack == TRUE) {
     6126: 1014:	    MPIDI_CH3I_VC *vcch = (MPIDI_CH3I_VC *)conn->vc->channel_private;
        -: 1015:	    /* post receive for packet header */
        -: 1016:	    MPIU_DBG_CONNSTATECHANGE(conn->vc,conn,CONN_STATE_CONNECTED);
     6126: 1017:	    conn->state = CONN_STATE_CONNECTED;
        -: 1018:	    MPIU_DBG_VCCHSTATECHANGE(conn->vc,VC_STATE_CONNECTED);
     6126: 1019:	    vcch->state = MPIDI_CH3I_VC_STATE_CONNECTED;
     6126: 1020:	    mpi_errno = connection_post_recv_pkt(conn);
     6126: 1021:	    if (mpi_errno != MPI_SUCCESS) {
    #####: 1022:		MPIU_ERR_POP(mpi_errno);
        -: 1023:	    }
        -: 1024:	    
     6126: 1025:	    mpi_errno = connection_post_sendq_req(conn);
     6126: 1026:	    if (mpi_errno != MPI_SUCCESS) {
    #####: 1027:		MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_INTERN,
        -: 1028:				    "**ch3|sock|openlsend");
        -: 1029:	    }
        -: 1030:	}
        -: 1031:	else {
        -: 1032:	    /* head-to-head connections - close this connection */
        -: 1033:	    MPIU_DBG_CONNSTATECHANGE(conn->vc,conn,CONN_STATE_CLOSING);
        -: 1034:	    /* FIXME: the connect side of this sets conn->vc to NULL. Why is
        -: 1035:	       this different? The code that checks CONN_STATE_CLOSING uses
        -: 1036:	       conn == NULL to identify intentional close, which this 
        -: 1037:	       appears to be. */
      623: 1038:	    conn->state = CONN_STATE_CLOSING;
        -: 1039:
        -: 1040:            /* zero out the vc to prevent trouble in _handle_close_event */
      623: 1041:            conn->vc = NULL;
        -: 1042:
        -: 1043:	    MPIU_DBG_MSG(CH3_DISCONNECT,TYPICAL,"Closing sock2 (Post_close)");
      623: 1044:	    mpi_errno = MPIDU_Sock_post_close(conn->sock);
      623: 1045:	    if (mpi_errno != MPI_SUCCESS) {
    #####: 1046:		MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,
        -: 1047:				    "**sock_post_close");
        -: 1048:	    }
        -: 1049:	}
        -: 1050:    }
        -: 1051:
    13495: 1052: fn_exit:
        -: 1053:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_SOCKCONN_HANDLE_CONNWRITE);
    13495: 1054:    return mpi_errno;
        -: 1055: fn_fail:
        -: 1056:    goto fn_exit;
        -: 1057:}
        -: 1058:
        -: 1059:/* ----------------------------------------------------------------------- */
        -: 1060:/* FIXME: What does this do? */
        -: 1061:#undef FUNCNAME
        -: 1062:#define FUNCNAME MPIDI_CH3I_VC_post_sockconnect
        -: 1063:#undef FCNAME
        -: 1064:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -: 1065:int MPIDI_CH3I_VC_post_sockconnect(MPIDI_VC_t * vc)
     6078: 1066:{
     6078: 1067:    int mpi_errno = MPI_SUCCESS;
        -: 1068:    char val[MPIDI_MAX_KVS_VALUE_LEN];
     6078: 1069:    MPIDI_CH3I_VC *vcch = (MPIDI_CH3I_VC *)vc->channel_private;
        -: 1070:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3I_VC_POST_SOCKCONNECT);
        -: 1071:
        -: 1072:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_VC_POST_SOCKCONNECT);
        -: 1073:
        -: 1074:    /* MPIDI_PG_GetConnString() can block & release the lock for 
        -: 1075:     * the current thread. Prevent other threads from trying to
        -: 1076:     * obtain the ConnString by setting the VC to *CONNECTING.
        -: 1077:     */
     6078: 1078:    if(vcch->state == MPIDI_CH3I_VC_STATE_UNCONNECTED){ 
        -: 1079:    	MPIU_DBG_VCCHSTATECHANGE(vc,VC_STATE_CONNECTING);
     6078: 1080:    	vcch->state = MPIDI_CH3I_VC_STATE_CONNECTING;
        -: 1081:	MPIU_DBG_MSG_P(CH3_CONNECT,TYPICAL,"vc=(%p) Going ahead to obtain connstring", vc);
        -: 1082:    }else{
        -: 1083:	MPIU_DBG_MSG_P(CH3_CONNECT,TYPICAL,"MT: vc=(%p) is already connecting/ed", vc);
        -: 1084:	MPIU_DBG_MSG(CH3_CONNECT,TYPICAL,"Aborting posting a connect");
        -: 1085:	/*************** MT *****************/
        -: 1086:	/* There are 3 cases here,
        -: 1087:         * 1) Another thread posted a connect while the current thread
        -: 1088:         *    was blocked in MPIDI_PG_GetConnString()
        -: 1089:         *    VC state = MPIDI_CH3I_VC_STATE_CONNECTING
        -: 1090:         * 2) Another thread posted a connect and completed the 
        -: 1091:         *    connection while the current thread was blocked in 
        -: 1092:         *    MPIDI_PG_GetConnString()
        -: 1093:         *    VC state = MPIDI_CH3I_VC_STATE_CONNECTED
        -: 1094:         * 3) Another thread received a connect from the same proc we
        -: 1095:         *    are connecting to and opened a connection while the 
        -: 1096:         *    current thread was blocked in MPIDI_PG_GetConnString()
        -: 1097:         *    VC state = MPIDI_CH3I_VC_STATE_CONNECTING or
        -: 1098:         *    VC state = MPIDI_CH3I_VC_STATE_CONNECTED
        -: 1099:         * If we bail out here, in all the cases above the other thread
        -: 1100:         * will handle the connection. In particular in the 3rd case
        -: 1101:         * if we proceed to post a connect before the VC state is set
        -: 1102:         * by the thread processing the remote connect,
        -: 1103:         * the code for head-to-head conn resolution will take care of
        -: 1104:         * discarding one of the connections
        -: 1105:         */
    #####: 1106:	 mpi_errno = MPI_SUCCESS;
    #####: 1107:         goto fn_exit;
        -: 1108:    }
     6078: 1109:    mpi_errno = MPIDI_PG_GetConnString( vc->pg, vc->pg_rank, val, sizeof(val));
     6078: 1110:    if (mpi_errno != MPI_SUCCESS) {
    #####: 1111:	MPIU_ERR_POP(mpi_errno);
        -: 1112:    }
        -: 1113:
     6078: 1114:    mpi_errno = MPIDI_CH3I_Sock_connect( vc, val, sizeof(val) );
        -: 1115:
     6078: 1116:  fn_exit:
        -: 1117:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_VC_POST_SOCKCONNECT);
     6078: 1118:    return mpi_errno;
        -: 1119: fn_fail:
        -: 1120:    goto fn_exit;
        -: 1121:    /* --END ERROR HANDLING-- */
        -: 1122:}
        -: 1123:/* end MPIDI_CH3I_VC_post_sockconnect() */
        -: 1124:
        -: 1125:/* Given a connection string, start the process of creating a socket 
        -: 1126:   connection to that designated interface (on a node).  This routine 
        -: 1127:   is used both in MPIDI_CH3I_VC_post_sockconnect and in 
        -: 1128:   MPIDI_CH3I_VC_post_connect in the ch3:ssm channel. 
        -: 1129:
        -: 1130:   vallen = sizeof(val)
        -: 1131:*/
        -: 1132:#undef FUNCNAME
        -: 1133:#define FUNCNAME MPIDI_CH3I_Sock_connect
        -: 1134:#undef FCNAME
        -: 1135:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -: 1136:int MPIDI_CH3I_Sock_connect( MPIDI_VC_t *vc, const char val[], int vallen )
     6078: 1137:{
        -: 1138:    char host_description[MAX_HOST_DESCRIPTION_LEN];
        -: 1139:    MPIDU_Sock_ifaddr_t ifaddr;
     6078: 1140:    int hasIfaddr = 0, port;
     6078: 1141:    MPIDI_CH3I_Connection_t * conn = 0;
     6078: 1142:    int mpi_errno = MPI_SUCCESS;
     6078: 1143:    MPIDI_CH3I_VC *vcch = (MPIDI_CH3I_VC *)vc->channel_private;
        -: 1144:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3I_SOCK_CONNECT);
        -: 1145:
        -: 1146:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_SOCK_CONNECT);
        -: 1147:    
     6078: 1148:    if(vcch->state == MPIDI_CH3I_VC_STATE_CONNECTING){ 
        -: 1149:	MPIU_DBG_MSG_P(CH3_CONNECT,TYPICAL,"Posting a connect for vc=(%p)", vc);
        -: 1150:    }else{
        -: 1151:	MPIU_DBG_MSG_P(CH3_CONNECT,TYPICAL,"MT: vc=(%p) is already connected", vc);
        -: 1152:	MPIU_DBG_MSG(CH3_CONNECT,TYPICAL,"Aborting posting a connect");
        -: 1153:	/*************** MT *****************/
        -: 1154:        /* 1) Another thread received a connect from the same proc
        -: 1155:         *    the current thread is connecting to and opened a 
        -: 1156:	 *    connection while the current thread was blocked in 
        -: 1157:	 *    MPIDI_PG_GetConnString()
        -: 1158:         *    VC state = MPIDI_CH3I_VC_STATE_CONNECTED
        -: 1159:         * If we bail out here, the other thread will handle the connection. 
        -: 1160:         * if we proceed to post a connect before the VC state is set
        -: 1161:         * by the thread processing the remote connect,
        -: 1162:         * the code for head-to-head conn resolution will take care of
        -: 1163:         * discarding one of the connections
        -: 1164:         */
    #####: 1165:	 mpi_errno = MPI_SUCCESS;
    #####: 1166:         goto fn_exit;
        -: 1167:    }
        -: 1168:
     6078: 1169:    mpi_errno = MPIDU_Sock_get_conninfo_from_bc( val, host_description,
        -: 1170:						 sizeof(host_description),
        -: 1171:						 &port, &ifaddr, &hasIfaddr );
     6078: 1172:    if (mpi_errno) {
    #####: 1173:	MPIU_ERR_POP(mpi_errno);
        -: 1174:    }
        -: 1175:
     6078: 1176:    mpi_errno = MPIDI_CH3I_Connection_alloc(&conn);
     6078: 1177:    if (mpi_errno == MPI_SUCCESS)
        -: 1178:    {
        -: 1179:	/* FIXME: This is a hack to allow Windows to continue to use
        -: 1180:	   the host description string instead of the interface address
        -: 1181:	   bytes when posting a socket connection.  This should be fixed 
        -: 1182:	   by changing the Sock_post_connect to only accept interface
        -: 1183:	   address.  See also channels/ssm/ch3_progress_connect.c */
        -: 1184:#ifndef HAVE_WINDOWS_H
     6078: 1185:	if (hasIfaddr) {
     6078: 1186:	    mpi_errno = MPIDU_Sock_post_connect_ifaddr(MPIDI_CH3I_sock_set, 
        -: 1187:						       conn, &ifaddr, port, 
        -: 1188:						       &conn->sock);
        -: 1189:	}
        -: 1190:	else 
        -: 1191:#endif
        -: 1192:	{
    #####: 1193:	    mpi_errno = MPIDU_Sock_post_connect(MPIDI_CH3I_sock_set, conn, 
        -: 1194:						host_description, port, 
        -: 1195:						&conn->sock);
        -: 1196:	}
     6078: 1197:	if (mpi_errno == MPI_SUCCESS)
        -: 1198:	{
        -: 1199:	    MPIU_DBG_CONNSTATECHANGE(vc,conn,CONN_STATE_CONNECTING);
     6078: 1200:	    vcch->sock = conn->sock;
     6078: 1201:	    vcch->conn = conn;
     6078: 1202:	    conn->vc = vc;
     6078: 1203:	    conn->state = CONN_STATE_CONNECTING;
     6078: 1204:	    conn->send_active = NULL;
     6078: 1205:	    conn->recv_active = NULL;
        -: 1206:	}
        -: 1207:	/* --BEGIN ERROR HANDLING-- */
        -: 1208:	else
        -: 1209:	{
        -: 1210:	    MPIU_DBG_VCCHSTATECHANGE(vc,VC_STATE_FAILED);
    #####: 1211:	    vcch->state = MPIDI_CH3I_VC_STATE_FAILED;
    #####: 1212:	    mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER, "**ch3|sock|postconnect",
        -: 1213:		"**ch3|sock|postconnect %d %d %s", MPIR_Process.comm_world->rank, vc->pg_rank, val);
    #####: 1214:	    goto fn_fail;
        -: 1215:	}
        -: 1216:	/* --END ERROR HANDLING-- */
        -: 1217:    }
        -: 1218:    else {
    #####: 1219:	MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER, "**ch3|sock|connalloc");
        -: 1220:    }
        -: 1221:
     6078: 1222: fn_exit:
        -: 1223:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_SOCK_CONNECT);
     6078: 1224:    return mpi_errno;
    #####: 1225: fn_fail:
        -: 1226:    /* --BEGIN ERROR HANDLING-- */
    #####: 1227:    if (conn) {
    #####: 1228:	connection_destroy(conn);
        -: 1229:    }
        -: 1230:    goto fn_exit;
        -: 1231:    /* --END ERROR HANDLING-- */
        -: 1232:}
        -: 1233:
        -: 1234:
        -: 1235:/* FIXME: What does this do? */
        -: 1236:/* Guess: Setup a wait-to-read on the socket that was set after the accept 
        -: 1237:   was handled */
        -: 1238:/* Wrong guess.  */
        -: 1239:#undef FUNCNAME
        -: 1240:#define FUNCNAME connection_post_recv_pkt
        -: 1241:#undef FCNAME
        -: 1242:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -: 1243:static int connection_post_recv_pkt(MPIDI_CH3I_Connection_t * conn)
    25744: 1244:{
    25744: 1245:    int mpi_errno = MPI_SUCCESS;
        -: 1246:    MPIDI_STATE_DECL(MPID_STATE_CONNECTION_POST_RECV_PKT);
        -: 1247:
        -: 1248:    MPIDI_FUNC_ENTER(MPID_STATE_CONNECTION_POST_RECV_PKT);
        -: 1249:
    25744: 1250:    mpi_errno = MPIDU_Sock_post_read(conn->sock, &conn->pkt, sizeof(conn->pkt),
        -: 1251:				     sizeof(conn->pkt), NULL);
    25744: 1252:    if (mpi_errno != MPI_SUCCESS) {
    #####: 1253:	MPIU_ERR_POP(mpi_errno);
        -: 1254:    }
        -: 1255:
    25744: 1256: fn_fail:    
        -: 1257:    MPIDI_FUNC_EXIT(MPID_STATE_CONNECTION_POST_RECV_PKT);
    25744: 1258:    return mpi_errno;
        -: 1259:}
        -: 1260:
        -: 1261:
        -: 1262:#undef FUNCNAME
        -: 1263:#define FUNCNAME connection_post_send_pkt
        -: 1264:#undef FCNAME
        -: 1265:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -: 1266:static int connection_post_send_pkt(MPIDI_CH3I_Connection_t * conn)
     7417: 1267:{
     7417: 1268:    int mpi_errno = MPI_SUCCESS;
        -: 1269:    MPIDI_STATE_DECL(MPID_STATE_CONNECTION_POST_SEND_PKT);
        -: 1270:
        -: 1271:    MPIDI_FUNC_ENTER(MPID_STATE_CONNECTION_POST_SEND_PKT);
        -: 1272: 
        -: 1273:    MPIU_DBG_PKT(conn,&conn->pkt,"connect");
     7417: 1274:    mpi_errno = MPIDU_Sock_post_write(conn->sock, &conn->pkt, sizeof(conn->pkt),
        -: 1275:				      sizeof(conn->pkt), NULL);
     7417: 1276:    if (mpi_errno != MPI_SUCCESS) {
    #####: 1277:	MPIU_ERR_POP(mpi_errno);
        -: 1278:    }
        -: 1279:    
     7417: 1280: fn_fail:
        -: 1281:    MPIDI_FUNC_EXIT(MPID_STATE_CONNECTION_POST_SEND_PKT);
     7417: 1282:    return mpi_errno;
        -: 1283:}
        -: 1284:
        -: 1285:#undef FUNCNAME
        -: 1286:#define FUNCNAME connection_post_send_pkt_and_pgid
        -: 1287:#undef FCNAME
        -: 1288:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -: 1289:static int connection_post_send_pkt_and_pgid(MPIDI_CH3I_Connection_t * conn)
     6078: 1290:{
        -: 1291:    int mpi_errno;
        -: 1292:    MPIDI_STATE_DECL(MPID_STATE_CONNECTION_POST_SEND_PKT_AND_PGID);
        -: 1293:
        -: 1294:    MPIDI_FUNC_ENTER(MPID_STATE_CONNECTION_POST_SEND_PKT_AND_PGID);
        -: 1295:    
     6078: 1296:    conn->iov[0].MPID_IOV_BUF = (MPID_IOV_BUF_CAST) &conn->pkt;
     6078: 1297:    conn->iov[0].MPID_IOV_LEN = (int) sizeof(conn->pkt);
        -: 1298:
     6078: 1299:    conn->iov[1].MPID_IOV_BUF = (MPID_IOV_BUF_CAST) MPIDI_Process.my_pg->id;
     6078: 1300:    conn->iov[1].MPID_IOV_LEN = (int) strlen(MPIDI_Process.my_pg->id) + 1;
        -: 1301:
        -: 1302:    MPIU_DBG_PKT(conn,&conn->pkt,"connect-pgid");
     6078: 1303:    mpi_errno = MPIDU_Sock_post_writev(conn->sock, conn->iov, 2, NULL);
     6078: 1304:    if (mpi_errno != MPI_SUCCESS) {
    #####: 1305:	MPIU_ERR_POP(mpi_errno);
        -: 1306:    }
        -: 1307:    
     6078: 1308: fn_fail:
        -: 1309:    MPIDI_FUNC_EXIT(MPID_STATE_CONNECTION_POST_SEND_PKT_AND_PGID);
     6078: 1310:    return mpi_errno;
        -: 1311:}
        -: 1312:
        -: 1313:/* FIXME: This function also used in channels/sock/src/ch3_progress.c */
        -: 1314:#undef FUNCNAME
        -: 1315:#define FUNCNAME connection_post_sendq_req
        -: 1316:#undef FCNAME
        -: 1317:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -: 1318:static int connection_post_sendq_req(MPIDI_CH3I_Connection_t * conn)
    12249: 1319:{
    12249: 1320:    int mpi_errno = MPI_SUCCESS;
    12249: 1321:    MPIDI_CH3I_VC *vcch = (MPIDI_CH3I_VC *)conn->vc->channel_private;
        -: 1322:    MPIDI_STATE_DECL(MPID_STATE_CONNECTION_POST_SENDQ_REQ);
        -: 1323:
        -: 1324:    MPIDI_FUNC_ENTER(MPID_STATE_CONNECTION_POST_SENDQ_REQ);
        -: 1325:
        -: 1326:    /* post send of next request on the send queue */
    12249: 1327:    conn->send_active = MPIDI_CH3I_SendQ_head(vcch); /* MT */
    12249: 1328:    if (conn->send_active != NULL)
        -: 1329:    {
        -: 1330:	MPIU_DBG_MSG_P(CH3_CONNECT,TYPICAL,"conn=%p: Posting message from connection send queue", conn );
     6753: 1331:	mpi_errno = MPIDU_Sock_post_writev(conn->sock, 
        -: 1332:					   conn->send_active->dev.iov, 
        -: 1333:					   conn->send_active->dev.iov_count, 
        -: 1334:					   NULL);
     6753: 1335:	if (mpi_errno != MPI_SUCCESS) {
    #####: 1336:	    MPIU_ERR_POP(mpi_errno);
        -: 1337:	}
        -: 1338:    }
        -: 1339:    
    12249: 1340: fn_fail:
        -: 1341:    MPIDI_FUNC_EXIT(MPID_STATE_CONNECTION_POST_SENDQ_REQ);
    12249: 1342:    return mpi_errno;
        -: 1343:}
        -: 1344:
        -: 1345:
        -: 1346:/* This routine frees all of the memory associated with a connection.
        -: 1347:   It is named destroy instead of free because routines with name "free" 
        -: 1348:   should have MPI semantics - free means to 
        -: 1349:   decrement reference count and free if reference count is zero */
        -: 1350:#undef FUNCNAME
        -: 1351:#define FUNCNAME connection_destroy
        -: 1352:#undef FCNAME
        -: 1353:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -: 1354:static void connection_destroy(MPIDI_CH3I_Connection_t * conn)
    16943: 1355:{
        -: 1356:    MPIDI_STATE_DECL(MPID_STATE_CONNECTION_DESTROY);
        -: 1357:
        -: 1358:    MPIDI_FUNC_ENTER(MPID_STATE_CONNECTION_DESTROY);
        -: 1359:
    16943: 1360:    MPIU_Free(conn->pg_id);
    16943: 1361:    MPIU_Free(conn);
        -: 1362:    
        -: 1363:    MPIDI_FUNC_EXIT(MPID_STATE_CONNECTION_DESTROY);
    16943: 1364:}
        -: 1365:
        -: 1366:
        -: 1367:#ifdef USE_DBG_LOGGING
        -: 1368:const char * MPIDI_CH3_VC_SockGetStateString( struct MPIDI_VC *vc )
        -: 1369:{
        -: 1370:    const char *name = "unknown";
        -: 1371:    static char asdigits[20];
        -: 1372:    MPIDI_CH3I_VC *vcch = (MPIDI_CH3I_VC *)vc->channel_private;
        -: 1373:    int    state = vcch->state;
        -: 1374:    
        -: 1375:    switch (state) {
        -: 1376:    case MPIDI_CH3I_VC_STATE_UNCONNECTED: name = "CH3I_VC_STATE_UNCONNECTED"; break;
        -: 1377:    case MPIDI_CH3I_VC_STATE_CONNECTING:  name = "CH3I_VC_STATE_CONNECTING"; break;
        -: 1378:    case MPIDI_CH3I_VC_STATE_CONNECTED:   name = "CH3I_VC_STATE_CONNECTED"; break;
        -: 1379:    case MPIDI_CH3I_VC_STATE_FAILED:      name = "CH3I_VC_STATE_FAILED"; break;
        -: 1380:    default:
        -: 1381:	MPIU_Snprintf( asdigits, sizeof(asdigits), "%d", state );
        -: 1382:	asdigits[20-1] = 0;
        -: 1383:	name = (const char *)asdigits;
        -: 1384:    }
        -: 1385:    return name;
        -: 1386:}
        -: 1387:#endif