Binding a UDP Socket to a specific interface

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

Binding a UDP Socket to a specific interface

Sven Van Caekenberghe-2
Today we spent some time figuring out how to bind a UDP Socket to a specific interface, as opposed to any or 0.0.0.0. This special case is needed when a server holds multiple IP addresses. If you do not bind to a specific one, you will of course still receive incoming datagrams on any interface, but when you answer you could use a different server source address than the one the client sent to in the first place. That might lead to trouble, as it did for us.

We had to read through the (Linux) socket plugin code [1] to figure this out (and it might not work on other platforms). It turns out that Socket>>#primSocket: aHandle listenOn: portNumber backlogSize: backlog interface: ifAddr does not just work for TCP but also for UDP (we left backlog size to 1, it is not used).

In code (on a private helper class):

UDPListener>>#port: port bindingAddress: address
        self socket: Socket newUDP.
        self socket
                primSocket: self socket socketHandle
                listenOn: port
                backlogSize: 1
                interface: address

And yes, this is ugly.

Sven

[1] https://github.com/pharo-project/pharo-vm/blob/master/platforms/unix/plugins/SocketPlugin/sqUnixSocket.c


Reply | Threaded
Open this post in threaded view
|

Re: Binding a UDP Socket to a specific interface

philippeback
Nice to know!

On Wed, Aug 12, 2015 at 5:25 PM, Sven Van Caekenberghe <[hidden email]> wrote:
Today we spent some time figuring out how to bind a UDP Socket to a specific interface, as opposed to any or 0.0.0.0. This special case is needed when a server holds multiple IP addresses. If you do not bind to a specific one, you will of course still receive incoming datagrams on any interface, but when you answer you could use a different server source address than the one the client sent to in the first place. That might lead to trouble, as it did for us.

We had to read through the (Linux) socket plugin code [1] to figure this out (and it might not work on other platforms). It turns out that Socket>>#primSocket: aHandle listenOn: portNumber backlogSize: backlog interface: ifAddr does not just work for TCP but also for UDP (we left backlog size to 1, it is not used).

In code (on a private helper class):

UDPListener>>#port: port bindingAddress: address
        self socket: Socket newUDP.
        self socket
                primSocket: self socket socketHandle
                listenOn: port
                backlogSize: 1
                interface: address

And yes, this is ugly.

Sven

[1] https://github.com/pharo-project/pharo-vm/blob/master/platforms/unix/plugins/SocketPlugin/sqUnixSocket.c



Reply | Threaded
Open this post in threaded view
|

Re: Binding a UDP Socket to a specific interface

Levente Uzonyi-2
In reply to this post by Sven Van Caekenberghe-2
You might be interested in this one too:
http://lists.squeakfoundation.org/pipermail/vm-dev/2014-December/017383.html

Levente

P.S.: This belongs to the vm-dev list, doesn't it?

On Wed, 12 Aug 2015, Sven Van Caekenberghe wrote:

> Today we spent some time figuring out how to bind a UDP Socket to a specific interface, as opposed to any or 0.0.0.0. This special case is needed when a server holds multiple IP addresses. If you do not bind to a specific one, you will of course still receive incoming datagrams on any interface, but when you answer you could use a different server source address than the one the client sent to in the first place. That might lead to trouble, as it did for us.
>
> We had to read through the (Linux) socket plugin code [1] to figure this out (and it might not work on other platforms). It turns out that Socket>>#primSocket: aHandle listenOn: portNumber backlogSize: backlog interface: ifAddr does not just work for TCP but also for UDP (we left backlog size to 1, it is not used).
>
> In code (on a private helper class):
>
> UDPListener>>#port: port bindingAddress: address
> self socket: Socket newUDP.
> self socket
> primSocket: self socket socketHandle
> listenOn: port
> backlogSize: 1
> interface: address
>
> And yes, this is ugly.
>
> Sven
>
> [1] https://github.com/pharo-project/pharo-vm/blob/master/platforms/unix/plugins/SocketPlugin/sqUnixSocket.c
>
>
>