Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- dlls/ntdll/unix/socket.c | 26 ++++++++++++++++++++++++++ dlls/ws2_32/socket.c | 7 +++++++ dlls/ws2_32/tests/sock.c | 12 +++--------- include/wine/afd.h | 2 ++ 4 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c index f9576a44eef..480d8b4f490 100644 --- a/dlls/ntdll/unix/socket.c +++ b/dlls/ntdll/unix/socket.c @@ -426,6 +426,16 @@ static int convert_control_headers(struct msghdr *hdr, WSABUF *control) } #endif /* IP_PKTINFO */
+#if defined(IP_TOS) + case IP_TOS: + { + ptr = fill_control_message( WS_IPPROTO_IP, WS_IP_TOS, ptr, &ctlsize, + CMSG_DATA(cmsg_unix), sizeof(INT) ); + if (!ptr) goto error; + break; + } +#endif /* IP_TOS */ + #if defined(IP_TTL) case IP_TTL: { @@ -1845,6 +1855,22 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc } #endif
+#ifdef IP_RECVTOS + case IOCTL_AFD_WINE_GET_IP_RECVTOS: + { + int sock_type = get_sock_type( handle ); + if (sock_type != SOCK_DGRAM && sock_type != SOCK_RAW) return STATUS_INVALID_PARAMETER; + return do_getsockopt( handle, io, IPPROTO_IP, IP_RECVTOS, out_buffer, out_size ); + } + + case IOCTL_AFD_WINE_SET_IP_RECVTOS: + { + int sock_type = get_sock_type( handle ); + if (sock_type != SOCK_DGRAM && sock_type != SOCK_RAW) return STATUS_INVALID_PARAMETER; + return do_setsockopt( handle, io, IPPROTO_IP, IP_RECVTOS, in_buffer, in_size ); + } +#endif + #ifdef IP_RECVTTL case IOCTL_AFD_WINE_GET_IP_RECVTTL: { diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 8085a1c2d35..b353b08390b 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -295,6 +295,7 @@ static inline const char *debugstr_sockopt(int level, int optname) DEBUG_SOCKOPT(IP_OPTIONS); DEBUG_SOCKOPT(IP_PKTINFO); DEBUG_SOCKOPT(IP_RECEIVE_BROADCAST); + DEBUG_SOCKOPT(IP_RECVTCLASS); DEBUG_SOCKOPT(IP_RECVTTL); DEBUG_SOCKOPT(IP_TOS); DEBUG_SOCKOPT(IP_TTL); @@ -1694,6 +1695,9 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl case IP_PKTINFO: return server_getsockopt( s, IOCTL_AFD_WINE_GET_IP_PKTINFO, optval, optlen );
+ case IP_RECVTCLASS: + return server_getsockopt( s, IOCTL_AFD_WINE_GET_IP_RECVTOS, optval, optlen ); + case IP_RECVTTL: return server_getsockopt( s, IOCTL_AFD_WINE_GET_IP_RECVTTL, optval, optlen );
@@ -2912,6 +2916,9 @@ int WINAPI setsockopt( SOCKET s, int level, int optname, const char *optval, int case IP_PKTINFO: return server_setsockopt( s, IOCTL_AFD_WINE_SET_IP_PKTINFO, optval, optlen );
+ case IP_RECVTCLASS: + return server_setsockopt( s, IOCTL_AFD_WINE_SET_IP_RECVTOS, optval, optlen ); + case IP_RECVTTL: return server_setsockopt( s, IOCTL_AFD_WINE_SET_IP_RECVTTL, optval, optlen );
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index e7717f0cc1e..cc5072ec8d6 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -2067,14 +2067,11 @@ static void test_ipv4_cmsg(void) memset(control, 0, sizeof(control)); msg.Control.len = sizeof(control); rc = setsockopt(server, IPPROTO_IP, IP_RECVTCLASS, (const char *)&on, sizeof(on)); -todo_wine ok(!rc, "failed to set IP_RECVTCLASS, error %u\n", WSAGetLastError()); state = 0; count = sizeof(state); rc = getsockopt(server, IPPROTO_IP, IP_RECVTCLASS, (char *)&state, (INT *)&count); -todo_wine ok(!rc, "failed to get IP_RECVTCLASS, error %u\n", WSAGetLastError()); -todo_wine ok(state == 1, "expected 1, got %u\n", state); rc = send(client, payload, sizeof(payload), 0); ok(rc == sizeof(payload), "send failed, error %u\n", WSAGetLastError()); @@ -2082,15 +2079,12 @@ todo_wine ok(!rc, "WSARecvMsg failed, error %u\n", WSAGetLastError()); ok(count == sizeof(payload), "expected length %i, got %i\n", (INT)sizeof(payload), count); ok(header->cmsg_level == IPPROTO_IP, "expected IPPROTO_IP, got %i\n", header->cmsg_level); -todo_wine ok(header->cmsg_type == IP_TOS || broken(header->cmsg_type == IP_TCLASS) /* win8 */, "expected IP_TOS, got %i\n", header->cmsg_type); -todo_wine ok(header->cmsg_len == sizeof(*header) + sizeof(INT), "expected length %i, got %i\n", (INT)(sizeof(*header) + sizeof(INT)), (INT)header->cmsg_len); ok(*int_data == 0, "expected 0, got %i\n", *int_data); rc = setsockopt(server, IPPROTO_IP, IP_RECVTCLASS, (const char *)&off, sizeof(off)); -todo_wine ok(!rc, "failed to clear IP_RECVTCLASS, error %u\n", WSAGetLastError());
closesocket(server); @@ -11617,7 +11611,7 @@ static void test_sockopt_validity(void) { IP_RTHDR, 0, 0, TRUE }, { IP_GET_IFLIST, WSAEINVAL, 0, TRUE }, { IP_RECVRTHDR, WSAEINVAL, 0, TRUE }, - { IP_RECVTCLASS, WSAEINVAL, 0, TRUE }, + { IP_RECVTCLASS, WSAEINVAL }, { IP_ORIGINAL_ARRIVAL_IF, WSAEINVAL, 0, TRUE }, { IP_ECN, WSAEINVAL, 0, TRUE }, { IP_PKTINFO_EX, WSAEINVAL, 0, TRUE }, @@ -11652,7 +11646,7 @@ static void test_sockopt_validity(void) { IP_RTHDR, 0, 0, TRUE }, { IP_GET_IFLIST, WSAEINVAL, 0, TRUE }, { IP_RECVRTHDR, 0, 0, TRUE }, - { IP_RECVTCLASS, 0, 0, TRUE }, + { IP_RECVTCLASS }, { IP_ORIGINAL_ARRIVAL_IF, 0, 0, TRUE }, { IP_ECN, 0, 0, TRUE }, { IP_PKTINFO_EX, 0, 0, TRUE }, @@ -11687,7 +11681,7 @@ static void test_sockopt_validity(void) { IP_RTHDR, 0, 0, TRUE }, { IP_GET_IFLIST, WSAEINVAL, 0, TRUE }, { IP_RECVRTHDR, 0, 0, TRUE }, - { IP_RECVTCLASS, 0, 0, TRUE }, + { IP_RECVTCLASS }, { IP_ORIGINAL_ARRIVAL_IF, 0, 0, TRUE }, { IP_ECN, 0, 0, TRUE }, { IP_PKTINFO_EX, 0, 0, TRUE }, diff --git a/include/wine/afd.h b/include/wine/afd.h index 8ffce81ab6f..3b8bdcb9e5d 100644 --- a/include/wine/afd.h +++ b/include/wine/afd.h @@ -236,6 +236,8 @@ struct afd_get_events_params #define IOCTL_AFD_WINE_GET_SO_CONNECT_TIME WINE_AFD_IOC(292) #define IOCTL_AFD_WINE_GET_IP_RECVTTL WINE_AFD_IOC(293) #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)
struct afd_create_params {