[PATCH] server: Use SO_BINDTODEVICE in bind_to_index() if possible.

Zebediah Figura (she/her) zfigura at codeweavers.com
Tue Oct 12 12:58:41 CDT 2021



On 10/12/21 11:55, Paul Gofman wrote:
> Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
> ---
>      Using SO_REUSEADDR is currently problematic when more than one UDP socket is bound
>      to different interfaces. While that succeeds, it is unspecified which socket will
>      receive a packet coming to INADDR_ANY. The filter being installed for each socket
>      with SO_ATTACH_FILTER can only reject the packet coming for another interface but
>      that rejected packed doesn't arrive to another socket.
> 
>      SO_BINDTODEVICE seems to do exactly what we want without installing any socket
>      filters and without requiring SO_REUSEADDR or SO_REUSEPORT. It originally considered
>      for implementing broadcast listen on interface bound sockets but it wasn't much
>      useful by that time as the SO_BINDTODEVICE required CAP_NET_RAW privilege which
>      is normally not available for a non-root user. However, that changed since Linux 5.7
>      [2].
> 
>      This patch uses SO_BINDTODEVICE but falls back to the previous way if that fails.
> 
>      1. https://www.winehq.org/pipermail/wine-devel/2011-October/092681.html
>      2. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/?id=c427bfec18f2190b8f4718785ee8ed2db4f84ee6
> 
>   server/sock.c | 28 ++++++++++++++++++++++------
>   1 file changed, 22 insertions(+), 6 deletions(-)
> 
> diff --git a/server/sock.c b/server/sock.c
> index 03716cba90f..af08cd6be24 100644
> --- a/server/sock.c
> +++ b/server/sock.c
> @@ -1756,12 +1756,14 @@ static int accept_into_socket( struct sock *sock, struct sock *acceptsock )
>   
>   #ifdef IP_BOUND_IF
>   
> -static int bind_to_index( int fd, in_addr_t bind_addr, unsigned int index )
> +static int bind_to_index( int fd, in_addr_t bind_addr, const char *name, unsigned int index, BOOL *need_reuse_addr )

Perhaps we should rename bind_to_index to bind_to_iface or something, then?

Actually, for that matter, should we just pass the name, and call 
if_nametoindex() only as needed?

Also, do we really need to return a bool? Can we just call SO_REUSEADDR 
in bind_to_index() instead? That strikes me as cleaner, despite 
duplicating the call.



More information about the wine-devel mailing list