diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c index 549981388c7..38cb80997ff 100644 --- a/dlls/ntdll/unix/socket.c +++ b/dlls/ntdll/unix/socket.c @@ -1655,6 +1655,26 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc case IOCTL_AFD_WINE_GET_SO_REUSEADDR: return do_getsockopt( handle, io, SOL_SOCKET, SO_REUSEADDR, out_buffer, out_size ); + /* BSD socket SO_REUSEADDR is not 100% compatible to winsock semantics; + * however, using it the BSD way fixes bug 8513 and seems to be what + * most programmers assume, anyway */ + case IOCTL_AFD_WINE_SET_SO_REUSEADDR: + { + int fd, needs_close = FALSE; + NTSTATUS status; + int ret; + + if ((status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL ))) + return status; + + ret = setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, in_buffer, in_size ); +#ifdef __APPLE__ + if (!ret) ret = setsockopt( fd, SOL_SOCKET, SO_REUSEPORT, in_buffer, in_size ); +#endif + if (needs_close) close( fd ); + return ret ? sock_errno_to_status( errno ) : STATUS_SUCCESS; + } + default: { if ((code >> 16) == FILE_DEVICE_NETWORK) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 11e6719fcb0..89fb7d3462b 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3572,6 +3572,9 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname, case WS_SO_RCVTIMEO: return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_RCVTIMEO, optval, optlen ); + case WS_SO_REUSEADDR: + return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_REUSEADDR, optval, optlen ); + /* Some options need some conversion before they can be sent to * setsockopt. The conversions are done here, then they will fall through * to the general case. Special options that are not passed to @@ -3588,16 +3591,6 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname, convert_sockopt(&level, &optname); break; - /* The options listed here don't need any special handling. Thanks to - * the conversion happening above, options from there will fall through - * to this, too.*/ - /* BSD socket SO_REUSEADDR is not 100% compatible to winsock semantics. - * however, using it the BSD way fixes bug 8513 and seems to be what - * most programmers assume, anyway */ - case WS_SO_REUSEADDR: - convert_sockopt(&level, &optname); - break; - /* SO_DEBUG is a privileged operation, ignore it. */ case WS_SO_DEBUG: TRACE("Ignoring SO_DEBUG\n"); diff --git a/include/wine/afd.h b/include/wine/afd.h index f337ec361b2..d522b8a289f 100644 --- a/include/wine/afd.h +++ b/include/wine/afd.h @@ -174,6 +174,7 @@ struct afd_get_events_params #define IOCTL_AFD_WINE_SET_SO_RCVTIMEO CTL_CODE(FILE_DEVICE_NETWORK, 231, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_GET_SO_RCVTIMEO CTL_CODE(FILE_DEVICE_NETWORK, 232, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_AFD_WINE_GET_SO_REUSEADDR CTL_CODE(FILE_DEVICE_NETWORK, 233, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_AFD_WINE_SET_SO_REUSEADDR CTL_CODE(FILE_DEVICE_NETWORK, 234, METHOD_BUFFERED, FILE_ANY_ACCESS) struct afd_create_params {