ufairiya / mongoose

Automatically exported from code.google.com/p/mongoose
MIT License
0 stars 0 forks source link

setsockopt problem on windows #155

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
In the function "mg_open_listening_port" the setsockopt(sock, SOL_SOCKET, 
SO_REUSEADDR, (char *) &on, sizeof(on)) allows tow or more processes to bind to 
the same port; this behavior does not occur on unix and is tied to the windows 
driver; therefor, if you had apache running on 8080, then start mongoose on 
8080, you'd get some strange behavior on windows. On windows it is recommend 
that the SO_REUSEADDR only be used with UDP for broadcast mode.

We rewrote the function as follows:

/*
 * Setup listening socket on given address, return socket.
 * Address format: [local_ip_address:]port_number
 */
static SOCKET
mg_open_listening_port(struct mg_context *ctx, const char *str, struct usa *usa)
{
    int     error = 0;
    SOCKET      sock;
    int     on = 1, a, b, c, d, port;

    /* MacOS needs that. If we do not zero it, bind() will fail. */
    (void) memset(usa, 0, sizeof(*usa));

    if (sscanf(str, "%d.%d.%d.%d:%d", &a, &b, &c, &d, &port) == 5) {
        /* IP address to bind to is specified */
        usa->u.sin.sin_addr.s_addr =
            htonl((a << 24) | (b << 16) | (c << 8) | d);
    } else if (sscanf(str, "%d", &port) == 1) {
        /* Only port number is specified. Bind to all addresses */
        usa->u.sin.sin_addr.s_addr = htonl(INADDR_ANY);
    } else {
        return (INVALID_SOCKET);
    }

    usa->len            = sizeof(usa->u.sin);
    usa->u.sin.sin_family       = AF_INET;
    usa->u.sin.sin_port     = htons((uint16_t) port);

    sock = socket(PF_INET, SOCK_STREAM, 6);
    if ( sock == INVALID_SOCKET ){
        error = TRUE;
    }

#ifndef _WIN32
    if( !error ){
        error = (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) != 0);
    }
#endif /* _WIN32 */

    if( !error ){
        error = (bind(sock, &usa->u.sa, usa->len) != 0 );
    }

    if( !error ){
        error = (listen(sock, 128) != 0);
    }

    if( !error ){
        /* Success */
        set_close_on_exec(sock);
    }
    else {
        /* Error */
        cry(fc(ctx), "%s(%d): %s", __func__, port, strerror(ERRNO));
        if (sock != INVALID_SOCKET)
            (void) closesocket(sock);
        sock = INVALID_SOCKET;
    }

    /****************
    if (() != INVALID_SOCKET &&
         == 0 &&
         == 0 &&
         == 0) {
        set_close_on_exec(sock);
    } else {
        cry(fc(ctx), "%s(%d): %s", __func__, port, strerror(ERRNO));
        if (sock != INVALID_SOCKET)
            (void) closesocket(sock);
        sock = INVALID_SOCKET;
    }
    ********************/ 

    return (sock);
}

Original issue reported on code.google.com by luzsun2...@gmail.com on 23 Jun 2010 at 11:57

GoogleCodeExporter commented 9 years ago

Original comment by valenok on 23 Aug 2010 at 8:41