[PATCH 1/5] ws2_32: Hook up IPV6_RECVTCLASS

Alex Henrie alexhenrie24 at gmail.com
Fri Aug 13 00:56:13 CDT 2021


Signed-off-by: Alex Henrie <alexhenrie24 at gmail.com>
---
 dlls/ntdll/unix/socket.c | 18 ++++++++++++++++++
 dlls/ws2_32/socket.c     |  7 +++++++
 dlls/ws2_32/tests/sock.c | 26 ++++++++++++++++++++++++--
 include/wine/afd.h       |  2 ++
 4 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c
index 35c846eb7ae..4f0c83597df 100644
--- a/dlls/ntdll/unix/socket.c
+++ b/dlls/ntdll/unix/socket.c
@@ -462,6 +462,16 @@ static int convert_control_headers(struct msghdr *hdr, WSABUF *control)
                     }
 #endif /* IPV6_PKTINFO */
 
+#if defined(IPV6_TCLASS)
+                    case IPV6_TCLASS:
+                    {
+                        ptr = fill_control_message( WS_IPPROTO_IPV6, WS_IPV6_TCLASS, ptr, &ctlsize,
+                                                    CMSG_DATA(cmsg_unix), sizeof(INT) );
+                        if (!ptr) goto error;
+                        break;
+                    }
+#endif /* IPV6_TCLASS */
+
                     default:
                         FIXME("Unhandled IPPROTO_IPV6 message header type %d\n", cmsg_unix->cmsg_type);
                         break;
@@ -1916,6 +1926,14 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc
             return do_setsockopt( handle, io, IPPROTO_IPV6, IPV6_RECVPKTINFO, in_buffer, in_size );
 #endif
 
+#ifdef IPV6_RECVTCLASS
+        case IOCTL_AFD_WINE_GET_IPV6_RECVTCLASS:
+            return do_getsockopt( handle, io, IPPROTO_IPV6, IPV6_RECVTCLASS, out_buffer, out_size );
+
+        case IOCTL_AFD_WINE_SET_IPV6_RECVTCLASS:
+            return do_setsockopt( handle, io, IPPROTO_IPV6, IPV6_RECVTCLASS, in_buffer, in_size );
+#endif
+
         case IOCTL_AFD_WINE_GET_IPV6_UNICAST_HOPS:
             return do_getsockopt( handle, io, IPPROTO_IPV6, IPV6_UNICAST_HOPS, out_buffer, out_size );
 
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 8f0ab12303a..3d88e45c66e 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -311,6 +311,7 @@ static inline const char *debugstr_sockopt(int level, int optname)
             DEBUG_SOCKOPT(IPV6_MULTICAST_HOPS);
             DEBUG_SOCKOPT(IPV6_MULTICAST_LOOP);
             DEBUG_SOCKOPT(IPV6_PKTINFO);
+            DEBUG_SOCKOPT(IPV6_RECVTCLASS);
             DEBUG_SOCKOPT(IPV6_UNICAST_HOPS);
             DEBUG_SOCKOPT(IPV6_V6ONLY);
             DEBUG_SOCKOPT(IPV6_UNICAST_IF);
@@ -1734,6 +1735,9 @@ int WINAPI getsockopt( SOCKET s, int level, int optname, char *optval, int *optl
         case IPV6_PKTINFO:
             return server_getsockopt( s, IOCTL_AFD_WINE_GET_IPV6_RECVPKTINFO, optval, optlen );
 
+        case IPV6_RECVTCLASS:
+            return server_getsockopt( s, IOCTL_AFD_WINE_GET_IPV6_RECVTCLASS, optval, optlen );
+
         case IPV6_UNICAST_HOPS:
             return server_getsockopt( s, IOCTL_AFD_WINE_GET_IPV6_UNICAST_HOPS, optval, optlen );
 
@@ -2942,6 +2946,9 @@ int WINAPI setsockopt( SOCKET s, int level, int optname, const char *optval, int
             FIXME("IPV6_PROTECTION_LEVEL is ignored!\n");
             return 0;
 
+        case IPV6_RECVTCLASS:
+            return server_setsockopt( s, IOCTL_AFD_WINE_SET_IPV6_RECVTCLASS, optval, optlen );
+
         case IPV6_UNICAST_HOPS:
             return server_setsockopt( s, IOCTL_AFD_WINE_SET_IPV6_UNICAST_HOPS, optval, optlen );
 
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index dd8c83374d0..6693c469dce 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -2002,7 +2002,7 @@ static void test_ipv6_cmsg(void)
     WSAMSG msg = {NULL, 0, &payload_buf, 1, {sizeof(control), control}, 0};
     WSACMSGHDR *header = (WSACMSGHDR *)control;
     LPFN_WSARECVMSG pWSARecvMsg;
-    INT *hop_limit = (INT *)WSA_CMSG_DATA(header);
+    INT *int_data = (INT *)WSA_CMSG_DATA(header);
     IN6_PKTINFO *pkt_info = (IN6_PKTINFO *)WSA_CMSG_DATA(header);
     DWORD count, state;
     int rc;
@@ -2043,7 +2043,7 @@ static void test_ipv6_cmsg(void)
     ok(header->cmsg_type == IPV6_HOPLIMIT, "expected IPV6_HOPLIMIT, got %i\n", header->cmsg_type);
     ok(header->cmsg_len == sizeof(*header) + sizeof(INT),
        "expected length %i, got %i\n", (INT)(sizeof(*header) + sizeof(INT)), (INT)header->cmsg_len);
-    ok(*hop_limit >= 32, "expected at least 32, got %i\n", *hop_limit);
+    ok(*int_data >= 32, "expected at least 32, got %i\n", *int_data);
     setsockopt(server, IPPROTO_IPV6, IPV6_HOPLIMIT, (const char *)&off, sizeof(off));
     ok(!rc, "failed to clear IPV6_HOPLIMIT, error %u\n", WSAGetLastError());
 
@@ -2069,6 +2069,28 @@ static void test_ipv6_cmsg(void)
     rc = setsockopt(server, IPPROTO_IPV6, IPV6_PKTINFO, (const char *)&off, sizeof(off));
     ok(!rc, "failed to clear IPV6_PKTINFO, error %u\n", WSAGetLastError());
 
+    memset(control, 0, sizeof(control));
+    msg.Control.len = sizeof(control);
+    rc = setsockopt(server, IPPROTO_IPV6, IPV6_RECVTCLASS, (const char *)&on, sizeof(on));
+    ok(!rc, "failed to set IPV6_RECVTCLASS, error %u\n", WSAGetLastError());
+    state = 0;
+    count = sizeof(state);
+    rc = getsockopt(server, IPPROTO_IPV6, IPV6_RECVTCLASS, (char *)&state, (INT *)&count);
+    ok(!rc, "failed to get IPV6_RECVTCLASS, error %u\n", WSAGetLastError());
+    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());
+    rc = pWSARecvMsg(server, &msg, &count, NULL, NULL);
+    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_IPV6, "expected IPPROTO_IPV6, got %i\n", header->cmsg_level);
+    ok(header->cmsg_type == IPV6_TCLASS, "expected IPV6_TCLASS, got %i\n", header->cmsg_type);
+    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_IPV6, IPV6_RECVTCLASS, (const char *)&off, sizeof(off));
+    ok(!rc, "failed to clear IPV6_RECVTCLASS, error %u\n", WSAGetLastError());
+
     closesocket(server);
     closesocket(client);
 }
diff --git a/include/wine/afd.h b/include/wine/afd.h
index 3936dbd87b1..49bbcccd3af 100644
--- a/include/wine/afd.h
+++ b/include/wine/afd.h
@@ -231,6 +231,8 @@ struct afd_get_events_params
 #define IOCTL_AFD_WINE_SET_IPV6_RECVHOPLIMIT            WINE_AFD_IOC(287)
 #define IOCTL_AFD_WINE_GET_IPV6_RECVPKTINFO             WINE_AFD_IOC(288)
 #define IOCTL_AFD_WINE_SET_IPV6_RECVPKTINFO             WINE_AFD_IOC(289)
+#define IOCTL_AFD_WINE_GET_IPV6_RECVTCLASS              WINE_AFD_IOC(290)
+#define IOCTL_AFD_WINE_SET_IPV6_RECVTCLASS              WINE_AFD_IOC(291)
 
 struct afd_create_params
 {
-- 
2.32.0




More information about the wine-devel mailing list