From: Paul Gofman pgofman@codeweavers.com
--- dlls/ws2_32/tests/sock.c | 4 ++-- server/sock.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 33e99e7df83..0015aae67a5 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -14218,7 +14218,7 @@ static void test_broadcast(void) ok(ret == -1, "got %d, error %u.\n", ret, WSAGetLastError());
ret = connect(s, (struct sockaddr *)&bcast, sizeof(bcast)); - todo_wine ok(!ret, "got error %u.\n", WSAGetLastError()); + ok(!ret, "got error %u.\n", WSAGetLastError()); val = 1; len = sizeof(val); ret = getsockopt(s, SOL_SOCKET, SO_BROADCAST, (char*)&val, &len); @@ -14227,7 +14227,7 @@ static void test_broadcast(void) ret = sendto(s, "test", 4, 0, (struct sockaddr *)&bcast, sizeof(bcast)); ok(ret == -1, "got %d, error %u.\n", ret, WSAGetLastError()); ret = send(s, "test", 4, 0); - todo_wine ok(ret == 4, "got %d, error %u.\n", ret, WSAGetLastError()); + ok(ret == 4, "got %d, error %u.\n", ret, WSAGetLastError()); closesocket(s);
s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); diff --git a/server/sock.c b/server/sock.c index 06ffd1b81f8..4d159768478 100644 --- a/server/sock.c +++ b/server/sock.c @@ -2668,6 +2668,25 @@ static void sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) ret = connect( unix_fd, &unix_addr.addr, unix_len ); }
+ if (ret < 0 && errno == EACCES && sock->state == SOCK_CONNECTIONLESS && unix_addr.addr.sa_family == AF_INET) + { + int broadcast, saved_errno; + socklen_t len = sizeof(broadcast); + + broadcast = 1; + getsockopt( unix_fd, SOL_SOCKET, SO_BROADCAST, &broadcast, &len ); + if (!broadcast) + { + broadcast = 1; + setsockopt( unix_fd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast) ); + ret = connect( unix_fd, &unix_addr.addr, unix_len ); + saved_errno = errno; + broadcast = 0; + setsockopt( unix_fd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast) ); + errno = saved_errno; + } + } + if (ret < 0 && errno != EINPROGRESS) { set_error( sock_get_ntstatus( errno ) );