help-smalltalk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-smalltalk] [PATCH] Fix multiple binds to the same port


From: Paolo Bonzini
Subject: Re: [Help-smalltalk] [PATCH] Fix multiple binds to the same port
Date: Wed, 19 Jan 2011 18:13:19 +0100
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101209 Fedora/3.1.7-0.35.b3pre.fc14 Lightning/1.0b3pre Mnenhy/0.8.3 Thunderbird/3.1.7

On 01/19/2011 05:24 PM, Holger Hans Peter Freyther wrote:
Hi,

this is fixing the issue that binding the same port seems to work but in
reality the socket will be auto bound to another port. Instead of checking for
soError we will now just check errno.

Ok, now I can reproduce it, but it seems a bug to me. This is a self-contained C reproducer:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>

#define PORT 6666

int main()
{
        struct sockaddr_in sin;
        int val;
        socklen_t sz;
        int s1, s2, rc;

        memset(&sin, 0, sizeof(sin));
        sin.sin_family = AF_INET;
        sin.sin_addr.s_addr = INADDR_ANY;
        sin.sin_port = htons(PORT);

        s1 = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (s1 == -1) { perror ("socket"); exit (1); }
        s2 = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (s2 == -1) { perror ("socket"); exit (1); }

        val = 1;
        setsockopt (s1, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
        val = 1;
        setsockopt (s2, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));

        rc = bind(s1, (struct sockaddr *) &sin, sizeof(sin));
        if (rc == -1) { perror ("bind"); exit (1); }
        rc = listen (s1, 5);
        if (rc == -1) { perror ("listen"); exit (1); }

        errno = 0;
        rc = bind(s2, (struct sockaddr *) &sin, sizeof(sin));
        if (rc != -1) { perror ("bind"); exit (1); }

        printf ("bind (errno): %s\n", strerror (errno));
        sz = sizeof(val);
        getsockopt(s2, SOL_SOCKET, SO_ERROR, &val, &sz);
        printf ("bind (SO_ERROR): %s\n", strerror (val));
        if (val == 0) exit (1);

        exit (0);
}

You're right. Using errno is thread-unsafe since Smalltalk threads share the errno and you could have an interrupt at exactly "that" time.

I'll have to fix it.

Paolo



reply via email to

[Prev in Thread] Current Thread [Next in Thread]