Exemplo n.º 1
0
Arquivo: mcs.c Projeto: MediaMath/moxi
int mcs_connect(const char *hostname, int portnum,
                int *errno_out, bool blocking) {
    if (errno_out != NULL) {
        *errno_out = -1;
    }

    int ret = -1;

    struct addrinfo *ai   = NULL;
    struct addrinfo *next = NULL;
    struct addrinfo hints = { .ai_flags = AI_PASSIVE,
                              .ai_socktype = SOCK_STREAM,
                              .ai_family = AF_UNSPEC };

    char port[50];
    snprintf(port, sizeof(port), "%d", portnum);

    int error = getaddrinfo(hostname, port, &hints, &ai);
    if (error != 0) {
        if (error != EAI_SYSTEM) {
            // settings.extensions.logger->log(EXTENSION_LOG_WARNING, NULL,
            //                                 "getaddrinfo(): %s\n", gai_strerror(error));
        } else {
            // settings.extensions.logger->log(EXTENSION_LOG_WARNING, NULL,
            //                                 "getaddrinfo(): %s\n", strerror(error));
        }

        return -1;
    }

    for (next = ai; next; next = next->ai_next) {
        int sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
        if (sock == -1) {
            // settings.extensions.logger->log(EXTENSION_LOG_WARNING, NULL,
            //                                 "Failed to create socket: %s\n",
            //                                 strerror(errno));
            continue;
        }

        // If the caller wants non-blocking, set the sock options
        // now so even the connect() becomes non-blocking.
        //
        if (!blocking && (mcs_set_sock_opt(sock) != MCS_SUCCESS)) {
            close(sock);
            continue;
        }

        if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
            int errno_last = errno;
            if (errno_out != NULL) {
                *errno_out = errno_last;
            }

            if (!blocking && (errno_last == EINPROGRESS)) {
                ret = sock;
                break;
            }

            // settings.extensions.logger->log(EXTENSION_LOG_WARNING, NULL,
            //                                 "Failed to connect socket: %s\n",
            //                                 strerror(errno));
            close(sock);
            continue;
        }

        if (mcs_set_sock_opt(sock) == MCS_SUCCESS) {
            ret = sock;
            break;
        }

        close(sock);
    }

    freeaddrinfo(ai);

    return ret;
}
Exemplo n.º 2
0
Arquivo: mcs.c Projeto: pacinodev/moxi
SOCKET mcs_connect(const char *hostname, int portnum,
                   int *errno_out, bool blocking) {
    SOCKET ret = INVALID_SOCKET;
    struct addrinfo *ai   = NULL;
    struct addrinfo *next = NULL;
    struct addrinfo hints;
    char port[50];
    int error;

    if (errno_out != NULL) {
        *errno_out = -1;
    }

    memset(&hints, 0, sizeof(0));
    hints.ai_flags = AI_PASSIVE;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_family = AF_UNSPEC;

    snprintf(port, sizeof(port), "%d", portnum);

    error = getaddrinfo(hostname, port, &hints, &ai);
    if (error != 0) {
#if 0
        if (error != EAI_SYSTEM) {
            /* settings.extensions.logger->log(EXTENSION_LOG_WARNING, NULL, */
            /*                                 "getaddrinfo(): %s\n", gai_strerror(error)); */
        } else {
            /* settings.extensions.logger->log(EXTENSION_LOG_WARNING, NULL, */
            /*                                 "getaddrinfo(): %s\n", strerror(error)); */
        }
#endif
        return INVALID_SOCKET;
    }

    for (next = ai; next; next = next->ai_next) {
        SOCKET sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
        if (sock == INVALID_SOCKET) {
            /* settings.extensions.logger->log(EXTENSION_LOG_WARNING, NULL, */
            /*                                 "Failed to create socket: %s\n", */
            /*                                 strerror(errno)); */
            continue;
        }

        /* If the caller wants non-blocking, set the sock options */
        /* now so even the connect() becomes non-blocking. */

        if (!blocking && (mcs_set_sock_opt(sock) != MCS_SUCCESS)) {
            closesocket(sock);
            continue;
        }

        if (connect(sock, ai->ai_addr, (socklen_t)ai->ai_addrlen) == SOCKET_ERROR) {
#ifdef WIN32
            DWORD errno_last = WSAGetLastError();
#else
            int errno_last = errno;
#endif
            if (errno_out != NULL) {
                *errno_out = errno_last;
            }

            if (!blocking && (is_in_progress(errno_last) ||
                              is_blocking(errno_last))) {
                ret = sock;
                break;
            }

            /* settings.extensions.logger->log(EXTENSION_LOG_WARNING, NULL, */
            /*                                 "Failed to connect socket: %s\n", */
            /*                                 strerror(errno)); */
            closesocket(sock);
            continue;
        }

        if (mcs_set_sock_opt(sock) == MCS_SUCCESS) {
            ret = sock;
            break;
        }

        closesocket(sock);
    }

    freeaddrinfo(ai);

    return ret;
}