src/mca/oob/tcp/oob_tcp_listener.c
/*
 * Create an IPv4 listen socket and bind to all interfaces.
 *
 * At one time, this also registered a callback with the event library
 * for when connections were received on the listen socket.  This is
 * no longer the case -- the caller must register any events required.
 *
 * Called by both the threaded and event based listen modes.
 */
Create an IPv4 listen socket and bind to all interfaces.
At one time, this also registered a callback with the event library
for when connections were received on the listen socket.  This is
no longer the case -- the caller must register any events required.

Called by both the threaded and event based listen modes.
Create an IPv4 listen socket and bind to all interfaces . At one time this also registered a callback with the event library for when connections were received on the listen socket . This is no longer the case -- the caller must register any events required . Called by both the threaded and event based listen modes .
static int create_listen(void)
{
    int flags, i;
    uint16_t port = 0;
    struct sockaddr_storage inaddr;
    prte_socklen_t addrlen;
    char **ports = NULL;
    int sd = -1;
    char *tconn;
    prte_oob_tcp_listener_t *conn;
    if (NULL != prte_oob_tcp_component.tcp_static_ports) {
        prte_argv_append_nosize(&ports, prte_oob_tcp_component.tcp_static_ports[0]);
        prte_static_ports = true;
    } else if (NULL != prte_oob_tcp_component.tcp_dyn_ports) {
        ports = prte_argv_copy(prte_oob_tcp_component.tcp_dyn_ports);
        prte_static_ports = false;
    } else {
        prte_argv_append_nosize(&ports, "0");
        prte_static_ports = false;
    }
    if (NULL == ports) {
        return PRTE_ERROR;
    }
    memset(&inaddr, 0, sizeof(inaddr));
    ((struct sockaddr_in *) &inaddr)->sin_family = AF_INET;
    ((struct sockaddr_in *) &inaddr)->sin_addr.s_addr = INADDR_ANY;
    addrlen = sizeof(struct sockaddr_in);
    for (i = 0; i < prte_argv_count(ports); i++) {
        prte_output_verbose(5, prte_oob_base_framework.framework_output,
                            "%s attempting to bind to IPv4 port %s",
                            PRTE_NAME_PRINT(PRTE_PROC_MY_NAME), ports[i]);
        port = strtol(ports[i], NULL, 10);
        port = htons(port);
        ((struct sockaddr_in *) &inaddr)->sin_port = port;
        sd = socket(AF_INET, SOCK_STREAM, 0);
        if (sd < 0) {
            if (EAFNOSUPPORT != prte_socket_errno) {
                prte_output(0, "prte_oob_tcp_component_init: socket() failed: %s (%d)",
                            strerror(prte_socket_errno), prte_socket_errno);
            }
            prte_argv_free(ports);
            return PRTE_ERR_IN_ERRNO;
        }
        if (prte_static_ports) {
            flags = 1;
        } else {
            flags = 0;
        }
        if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (const char *) &flags, sizeof(flags)) < 0) {
            prte_output(0,
                        "prte_oob_tcp_create_listen: unable to set the "
                        "SO_REUSEADDR option (%s:%d)\n",
                        strerror(prte_socket_errno), prte_socket_errno);
            CLOSE_THE_SOCKET(sd);
            prte_argv_free(ports);
            return PRTE_ERROR;
        }
        if (prte_fd_set_cloexec(sd) != PRTE_SUCCESS) {
            prte_output(0,
                        "prte_oob_tcp_create_listen: unable to set the "
                        "listening socket to CLOEXEC (%s:%d)\n",
                        strerror(prte_socket_errno), prte_socket_errno);
            CLOSE_THE_SOCKET(sd);
            prte_argv_free(ports);
            return PRTE_ERROR;
        }
        if (bind(sd, (struct sockaddr *) &inaddr, addrlen) < 0) {
            if ((EADDRINUSE == prte_socket_errno) || (EADDRNOTAVAIL == prte_socket_errno)) {
                continue;
            }
            prte_output(0, "%s bind() failed for port %d: %s (%d)",
                        PRTE_NAME_PRINT(PRTE_PROC_MY_NAME), (int) ntohs(port),
                        strerror(prte_socket_errno), prte_socket_errno);
            CLOSE_THE_SOCKET(sd);
            prte_argv_free(ports);
            return PRTE_ERROR;
        }
        if (getsockname(sd, (struct sockaddr *) &inaddr, &addrlen) < 0) {
            prte_output(0, "prte_oob_tcp_create_listen: getsockname(): %s (%d)",
                        strerror(prte_socket_errno), prte_socket_errno);
            CLOSE_THE_SOCKET(sd);
            prte_argv_free(ports);
            return PRTE_ERROR;
        }
        if (listen(sd, SOMAXCONN) < 0) {
            prte_output(0, "prte_oob_tcp_component_init: listen(): %s (%d)",
                        strerror(prte_socket_errno), prte_socket_errno);
            CLOSE_THE_SOCKET(sd);
            prte_argv_free(ports);
            return PRTE_ERROR;
        }
        if ((flags = fcntl(sd, F_GETFL, 0)) < 0) {
            prte_output(0, "prte_oob_tcp_component_init: fcntl(F_GETFL) failed: %s (%d)",
                        strerror(prte_socket_errno), prte_socket_errno);
            CLOSE_THE_SOCKET(sd);
            prte_argv_free(ports);
            return PRTE_ERROR;
        }
        flags |= O_NONBLOCK;
        if (fcntl(sd, F_SETFL, flags) < 0) {
            prte_output(0, "prte_oob_tcp_component_init: fcntl(F_SETFL) failed: %s (%d)",
                        strerror(prte_socket_errno), prte_socket_errno);
            CLOSE_THE_SOCKET(sd);
            prte_argv_free(ports);
            return PRTE_ERROR;
        }
        conn = PRTE_NEW(prte_oob_tcp_listener_t);
        conn->sd = sd;
        conn->port = ntohs(((struct sockaddr_in *) &inaddr)->sin_port);
        if (0 == prte_process_info.my_port) {
            prte_process_info.my_port = conn->port;
        }
        prte_list_append(&prte_oob_tcp_component.listeners, &conn->item);
        prte_asprintf(&tconn, "%d", ntohs(((struct sockaddr_in *) &inaddr)->sin_port));
        prte_argv_append_nosize(&prte_oob_tcp_component.ipv4ports, tconn);
        free(tconn);
        if (OOB_TCP_DEBUG_CONNECT
            <= prte_output_get_verbosity(prte_oob_base_framework.framework_output)) {
            port = ntohs(((struct sockaddr_in *) &inaddr)->sin_port);
            prte_output(0, "%s assigned IPv4 port %d", PRTE_NAME_PRINT(PRTE_PROC_MY_NAME), port);
        }
        if (!PRTE_PROC_IS_MASTER) {
            break;
        }
    }
    prte_argv_free(ports);
    if (0 == prte_list_get_size(&prte_oob_tcp_component.listeners)) {
        if (0 <= sd) {
            CLOSE_THE_SOCKET(sd);
        }
        return PRTE_ERR_SOCKET_NOT_AVAILABLE;
    }
    return PRTE_SUCCESS;
}
static int create_listen ( void ) { int flags , i ; uint16_t port = 0 ; struct sockaddr_storage inaddr ; prte_socklen_t addrlen ; char * * ports = NULL ; int sd = -1 ; char * tconn ; prte_oob_tcp_listener_t * conn ; if ( NULL != prte_oob_tcp_component . tcp_static_ports ) { prte_argv_append_nosize ( & ports , prte_oob_tcp_component . tcp_static_ports [ 0 ] ) ; prte_static_ports = true ; } else if ( NULL != prte_oob_tcp_component . tcp_dyn_ports ) { ports = prte_argv_copy ( prte_oob_tcp_component . tcp_dyn_ports ) ; prte_static_ports = false ; } else { prte_argv_append_nosize ( & ports , " " ) ; prte_static_ports = false ; } if ( NULL == ports ) { return PRTE_ERROR ; } memset ( & inaddr , 0 , sizeof ( inaddr ) ) ; ( ( struct sockaddr_in * ) & inaddr ) -> sin_family = AF_INET ; ( ( struct sockaddr_in * ) & inaddr ) -> sin_addr . s_addr = INADDR_ANY ; addrlen = sizeof ( struct sockaddr_in ) ; for ( i = 0 ; i < prte_argv_count ( ports ) ; i ++ ) { prte_output_verbose ( 5 , prte_oob_base_framework . framework_output , " " , PRTE_NAME_PRINT ( PRTE_PROC_MY_NAME ) , ports [ i ] ) ; port = strtol ( ports [ i ] , NULL , 10 ) ; port = htons ( port ) ; ( ( struct sockaddr_in * ) & inaddr ) -> sin_port = port ; sd = socket ( AF_INET , SOCK_STREAM , 0 ) ; if ( sd < 0 ) { if ( EAFNOSUPPORT != prte_socket_errno ) { prte_output ( 0 , " " , strerror ( prte_socket_errno ) , prte_socket_errno ) ; } prte_argv_free ( ports ) ; return PRTE_ERR_IN_ERRNO ; } if ( prte_static_ports ) { flags = 1 ; } else { flags = 0 ; } if ( setsockopt ( sd , SOL_SOCKET , SO_REUSEADDR , ( const char * ) & flags , sizeof ( flags ) ) < 0 ) { prte_output ( 0 , " " " \n " , strerror ( prte_socket_errno ) , prte_socket_errno ) ; CLOSE_THE_SOCKET ( sd ) ; prte_argv_free ( ports ) ; return PRTE_ERROR ; } if ( prte_fd_set_cloexec ( sd ) != PRTE_SUCCESS ) { prte_output ( 0 , " " " \n " , strerror ( prte_socket_errno ) , prte_socket_errno ) ; CLOSE_THE_SOCKET ( sd ) ; prte_argv_free ( ports ) ; return PRTE_ERROR ; } if ( bind ( sd , ( struct sockaddr * ) & inaddr , addrlen ) < 0 ) { if ( ( EADDRINUSE == prte_socket_errno ) || ( EADDRNOTAVAIL == prte_socket_errno ) ) { continue ; } prte_output ( 0 , " " , PRTE_NAME_PRINT ( PRTE_PROC_MY_NAME ) , ( int ) ntohs ( port ) , strerror ( prte_socket_errno ) , prte_socket_errno ) ; CLOSE_THE_SOCKET ( sd ) ; prte_argv_free ( ports ) ; return PRTE_ERROR ; } if ( getsockname ( sd , ( struct sockaddr * ) & inaddr , & addrlen ) < 0 ) { prte_output ( 0 , " " , strerror ( prte_socket_errno ) , prte_socket_errno ) ; CLOSE_THE_SOCKET ( sd ) ; prte_argv_free ( ports ) ; return PRTE_ERROR ; } if ( listen ( sd , SOMAXCONN ) < 0 ) { prte_output ( 0 , " " , strerror ( prte_socket_errno ) , prte_socket_errno ) ; CLOSE_THE_SOCKET ( sd ) ; prte_argv_free ( ports ) ; return PRTE_ERROR ; } if ( ( flags = fcntl ( sd , F_GETFL , 0 ) ) < 0 ) { prte_output ( 0 , " " , strerror ( prte_socket_errno ) , prte_socket_errno ) ; CLOSE_THE_SOCKET ( sd ) ; prte_argv_free ( ports ) ; return PRTE_ERROR ; } flags |= O_NONBLOCK ; if ( fcntl ( sd , F_SETFL , flags ) < 0 ) { prte_output ( 0 , " " , strerror ( prte_socket_errno ) , prte_socket_errno ) ; CLOSE_THE_SOCKET ( sd ) ; prte_argv_free ( ports ) ; return PRTE_ERROR ; } conn = PRTE_NEW ( prte_oob_tcp_listener_t ) ; conn -> sd = sd ; conn -> port = ntohs ( ( ( struct sockaddr_in * ) & inaddr ) -> sin_port ) ; if ( 0 == prte_process_info . my_port ) { prte_process_info . my_port = conn -> port ; } prte_list_append ( & prte_oob_tcp_component . listeners , & conn -> item ) ; prte_asprintf ( & tconn , " " , ntohs ( ( ( struct sockaddr_in * ) & inaddr ) -> sin_port ) ) ; prte_argv_append_nosize ( & prte_oob_tcp_component . ipv4ports , tconn ) ; free ( tconn ) ; if ( OOB_TCP_DEBUG_CONNECT <= prte_output_get_verbosity ( prte_oob_base_framework . framework_output ) ) { port = ntohs ( ( ( struct sockaddr_in * ) & inaddr ) -> sin_port ) ; prte_output ( 0 , " " , PRTE_NAME_PRINT ( PRTE_PROC_MY_NAME ) , port ) ; } if ( ! PRTE_PROC_IS_MASTER ) { break ; } } prte_argv_free ( ports ) ; if ( 0 == prte_list_get_size ( & prte_oob_tcp_component . listeners ) ) { if ( 0 <= sd ) { CLOSE_THE_SOCKET ( sd ) ; } return PRTE_ERR_SOCKET_NOT_AVAILABLE ; } return PRTE_SUCCESS ; }
Create an IPv4 listen socket and bind to all interfaces.
Create an IPv4 listen socket and bind to all interfaces .
/* If an explicit range of ports was given, find the first open
     * port in the range.  Otherwise, tcp_port_min will be 0, which
     * means "pick any port"
     */ /* if static ports were provided, take the
         * first entry in the list
         */ /* flag that we are using static ports */ /* take the entire range */ /* flag the system to dynamically take any available port */ /* bozo check - this should be impossible, but... */ /* get the address info for this interface */ /* loop across all the specified ports, establishing a socket
     * for each one - note that application procs will ONLY have
     * one socket, but that prun and daemons will have multiple
     * sockets to support more flexible wireup protocols
     */ /* get the port number */ /* convert it to network-byte-order */ /* create a listen socket for incoming connections on this port */ /* Enable/disable reusing ports */ /* Set the socket to close-on-exec so that no children inherit
           this FD */ /* resolve assigned port */ /* setup listen backlog to maximum allowed by kernel */ /* set socket up to be non-blocking, otherwise accept could block */ /* add this port to our connections */ /* save the first one */ /* and to our ports */ /* only the HNP binds to multiple ports */ /* done with this, so release it */ /* cleanup */