mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-01 18:58:29 +00:00
ws2_32: Track SO_EXCLUSIVEADDRUSE option value.
This commit is contained in:
parent
1178a9dd3a
commit
d656cb2024
|
@ -1818,6 +1818,11 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl
|
|||
if (!ret && *optlen < sizeof(DWORD)) *optlen = 1;
|
||||
return ret;
|
||||
|
||||
case SO_EXCLUSIVEADDRUSE:
|
||||
ret = server_getsockopt( s, IOCTL_AFD_WINE_GET_SO_EXCLUSIVEADDRUSE, optval, optlen );
|
||||
if (!ret && *optlen < sizeof(DWORD)) *optlen = 1;
|
||||
return ret;
|
||||
|
||||
case SO_SNDBUF:
|
||||
if (*optlen < sizeof(DWORD) || !optval)
|
||||
{
|
||||
|
@ -3215,6 +3220,15 @@ int WINAPI setsockopt( SOCKET s, int level, int optname, const char *optval, int
|
|||
memcpy( &value, optval, min( optlen, sizeof(value) ));
|
||||
return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_REUSEADDR, (char *)&value, sizeof(value) );
|
||||
|
||||
case SO_EXCLUSIVEADDRUSE:
|
||||
if (!optval)
|
||||
{
|
||||
SetLastError( WSAEFAULT );
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
memcpy( &value, optval, min( optlen, sizeof(value) ));
|
||||
return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_EXCLUSIVEADDRUSE, (char *)&value, sizeof(value) );
|
||||
|
||||
case SO_SNDBUF:
|
||||
if (optlen < 0) optlen = 4;
|
||||
return server_setsockopt( s, IOCTL_AFD_WINE_SET_SO_SNDBUF, optval, optlen );
|
||||
|
@ -3240,12 +3254,6 @@ int WINAPI setsockopt( SOCKET s, int level, int optname, const char *optval, int
|
|||
SetLastError( ERROR_SUCCESS );
|
||||
return 0;
|
||||
|
||||
/* Stops two sockets from being bound to the same port. Always happens
|
||||
* on unix systems, so just drop it. */
|
||||
case SO_EXCLUSIVEADDRUSE:
|
||||
TRACE("Ignoring SO_EXCLUSIVEADDRUSE, is always set.\n");
|
||||
return 0;
|
||||
|
||||
/* After a ConnectEx call succeeds, the socket can't be used with half of the
|
||||
* normal winsock functions on windows. We don't have that problem. */
|
||||
case SO_UPDATE_CONNECT_CONTEXT:
|
||||
|
|
|
@ -1209,6 +1209,7 @@ static void test_set_getsockopt(void)
|
|||
{AF_INET, SOCK_STREAM, SOL_SOCKET, SO_DONTROUTE, TRUE, {1, 1, 1}, {0}, TRUE},
|
||||
{AF_INET, SOCK_STREAM, SOL_SOCKET, SO_RCVTIMEO, FALSE, {1, 2, 4}, {0}, TRUE},
|
||||
{AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE},
|
||||
{AF_INET, SOCK_STREAM, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, TRUE, {1, 1, 4}, {0, 0xdead0001, 0}, TRUE, TRUE},
|
||||
{AF_INET, SOCK_STREAM, SOL_SOCKET, SO_SNDBUF, FALSE, {1, 2, 4}, {0xdeadbe00, 0xdead0000}, TRUE},
|
||||
{AF_INET, SOCK_STREAM, SOL_SOCKET, SO_SNDTIMEO, FALSE, {1, 2, 4}, {0}, TRUE},
|
||||
{AF_INET, SOCK_STREAM, SOL_SOCKET, SO_OPENTYPE, FALSE, {1, 2, 4}, {0}, TRUE},
|
||||
|
|
|
@ -283,6 +283,8 @@ C_ASSERT( sizeof(struct afd_get_events_params) == 56 );
|
|||
#define IOCTL_AFD_WINE_SET_IP_RECVTTL WINE_AFD_IOC(294)
|
||||
#define IOCTL_AFD_WINE_GET_IP_RECVTOS WINE_AFD_IOC(295)
|
||||
#define IOCTL_AFD_WINE_SET_IP_RECVTOS WINE_AFD_IOC(296)
|
||||
#define IOCTL_AFD_WINE_GET_SO_EXCLUSIVEADDRUSE WINE_AFD_IOC(297)
|
||||
#define IOCTL_AFD_WINE_SET_SO_EXCLUSIVEADDRUSE WINE_AFD_IOC(298)
|
||||
|
||||
struct afd_iovec
|
||||
{
|
||||
|
|
|
@ -256,6 +256,7 @@ struct sock
|
|||
unsigned int bound : 1; /* is the socket bound? */
|
||||
unsigned int reset : 1; /* did we get a TCP reset? */
|
||||
unsigned int reuseaddr : 1; /* winsock SO_REUSEADDR option value */
|
||||
unsigned int exclusiveaddruse : 1; /* winsock SO_EXCLUSIVEADDRUSE option value */
|
||||
};
|
||||
|
||||
static int is_tcp_socket( struct sock *sock )
|
||||
|
@ -1697,6 +1698,7 @@ static struct sock *create_socket(void)
|
|||
sock->bound = 0;
|
||||
sock->reset = 0;
|
||||
sock->reuseaddr = 0;
|
||||
sock->exclusiveaddruse = 0;
|
||||
sock->rcvbuf = 0;
|
||||
sock->sndbuf = 0;
|
||||
sock->rcvtimeo = 0;
|
||||
|
@ -3103,6 +3105,21 @@ static void sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
|
|||
return;
|
||||
}
|
||||
|
||||
case IOCTL_AFD_WINE_SET_SO_EXCLUSIVEADDRUSE:
|
||||
{
|
||||
int exclusive;
|
||||
|
||||
if (get_req_data_size() < sizeof(exclusive))
|
||||
{
|
||||
set_error( STATUS_BUFFER_TOO_SMALL );
|
||||
return;
|
||||
}
|
||||
|
||||
exclusive = *(int *)get_req_data();
|
||||
sock->exclusiveaddruse = !!exclusive;
|
||||
return;
|
||||
}
|
||||
|
||||
case IOCTL_AFD_WINE_GET_SO_SNDBUF:
|
||||
{
|
||||
int sndbuf = sock->sndbuf;
|
||||
|
@ -3205,6 +3222,21 @@ static void sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
|
|||
return;
|
||||
}
|
||||
|
||||
case IOCTL_AFD_WINE_GET_SO_EXCLUSIVEADDRUSE:
|
||||
{
|
||||
int exclusive;
|
||||
|
||||
if (!get_reply_max_size())
|
||||
{
|
||||
set_error( STATUS_BUFFER_TOO_SMALL );
|
||||
return;
|
||||
}
|
||||
|
||||
exclusive = sock->exclusiveaddruse;
|
||||
set_reply_data( &exclusive, min( sizeof(exclusive), get_reply_max_size() ));
|
||||
return;
|
||||
}
|
||||
|
||||
case IOCTL_AFD_POLL:
|
||||
{
|
||||
if (get_reply_max_size() < get_req_data_size())
|
||||
|
|
Loading…
Reference in a new issue