[PATCH] Fix multiple binds to the same port

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] Fix multiple binds to the same port

Holger Freyther
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.

I think the same issue (if it is one) exists for accept: calls as well...


regards
        holger

_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk

0001-sockets-Make-ServerSocket-fail-if-one-attempts-to-bi.patch (2K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

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

Paolo Bonzini-2
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

_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

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

Holger Freyther
On 01/19/2011 06:13 PM, Paolo Bonzini wrote:

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


The autobinding to a port? Yeah it was a bit surprising but then started to
make sense.


>
> 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.

Ah, you are right. The two options i see is to either just raise an exception
without knowing the specific issue, or as you said put syscall and errno into
a critical section (eeek...)

_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

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

Paolo Bonzini-2
On 01/19/2011 08:06 PM, Holger Hans Peter Freyther wrote:
> Ah, you are right. The two options i see is to either just raise an exception
> without knowing the specific issue, or as you said put syscall and errno into
> a critical section (eeek...)

Or store errno into a Process at context-switch time.

Paolo

_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk