authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-10 19:00:53-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-05-10 19:00:53-04:00
log55d235dc389635f16f4c38f70ad685677d04e6e5
treed528bf8e150274efc436ca60749a8b3eb009486c
parent2e4a48ef295fee2180079a01c59b47e47a414efb
parent0d0edd23a81a195947950d4daa9c40a30fd5dfc9
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #8711 from lithdew/master

std/os, x/os/socket: windows support, socket helpers, getpeername()

21 files changed, 2797 insertions(+), 585 deletions(-)

lib/std/c.zig+1
...@@ -151,6 +151,7 @@ pub extern "c" fn bind(socket: fd_t, address: ?*const sockaddr, address_len: soc...@@ -151,6 +151,7 @@ pub extern "c" fn bind(socket: fd_t, address: ?*const sockaddr, address_len: soc
151pub extern "c" fn socketpair(domain: c_uint, sock_type: c_uint, protocol: c_uint, sv: *[2]fd_t) c_int;151pub extern "c" fn socketpair(domain: c_uint, sock_type: c_uint, protocol: c_uint, sv: *[2]fd_t) c_int;
152pub extern "c" fn listen(sockfd: fd_t, backlog: c_uint) c_int;152pub extern "c" fn listen(sockfd: fd_t, backlog: c_uint) c_int;
153pub extern "c" fn getsockname(sockfd: fd_t, noalias addr: *sockaddr, noalias addrlen: *socklen_t) c_int;153pub extern "c" fn getsockname(sockfd: fd_t, noalias addr: *sockaddr, noalias addrlen: *socklen_t) c_int;
154pub extern "c" fn getpeername(sockfd: fd_t, noalias addr: *sockaddr, noalias addrlen: *socklen_t) c_int;
154pub extern "c" fn connect(sockfd: fd_t, sock_addr: *const sockaddr, addrlen: socklen_t) c_int;155pub extern "c" fn connect(sockfd: fd_t, sock_addr: *const sockaddr, addrlen: socklen_t) c_int;
155pub extern "c" fn accept(sockfd: fd_t, noalias addr: ?*sockaddr, noalias addrlen: ?*socklen_t) c_int;156pub extern "c" fn accept(sockfd: fd_t, noalias addr: ?*sockaddr, noalias addrlen: ?*socklen_t) c_int;
156pub extern "c" fn accept4(sockfd: fd_t, noalias addr: ?*sockaddr, noalias addrlen: ?*socklen_t, flags: c_uint) c_int;157pub extern "c" fn accept4(sockfd: fd_t, noalias addr: ?*sockaddr, noalias addrlen: ?*socklen_t, flags: c_uint) c_int;
lib/std/os.zig+33-4
...@@ -2758,9 +2758,9 @@ pub const ShutdownHow = enum { recv, send, both };...@@ -2758,9 +2758,9 @@ pub const ShutdownHow = enum { recv, send, both };
2758pub fn shutdown(sock: socket_t, how: ShutdownHow) ShutdownError!void {2758pub fn shutdown(sock: socket_t, how: ShutdownHow) ShutdownError!void {
2759 if (builtin.os.tag == .windows) {2759 if (builtin.os.tag == .windows) {
2760 const result = windows.ws2_32.shutdown(sock, switch (how) {2760 const result = windows.ws2_32.shutdown(sock, switch (how) {
2761 .recv => windows.SD_RECEIVE,2761 .recv => windows.ws2_32.SD_RECEIVE,
2762 .send => windows.SD_SEND,2762 .send => windows.ws2_32.SD_SEND,
2763 .both => windows.SD_BOTH,2763 .both => windows.ws2_32.SD_BOTH,
2764 });2764 });
2765 if (0 != result) switch (windows.ws2_32.WSAGetLastError()) {2765 if (0 != result) switch (windows.ws2_32.WSAGetLastError()) {
2766 .WSAECONNABORTED => return error.ConnectionAborted,2766 .WSAECONNABORTED => return error.ConnectionAborted,
...@@ -3217,6 +3217,35 @@ pub fn getsockname(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSock...@@ -3217,6 +3217,35 @@ pub fn getsockname(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSock
3217 }3217 }
3218}3218}
32193219
3220pub fn getpeername(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSockNameError!void {
3221 if (builtin.os.tag == .windows) {
3222 const rc = windows.getpeername(sock, addr, addrlen);
3223 if (rc == windows.ws2_32.SOCKET_ERROR) {
3224 switch (windows.ws2_32.WSAGetLastError()) {
3225 .WSANOTINITIALISED => unreachable,
3226 .WSAENETDOWN => return error.NetworkSubsystemFailed,
3227 .WSAEFAULT => unreachable, // addr or addrlen have invalid pointers or addrlen points to an incorrect value
3228 .WSAENOTSOCK => return error.FileDescriptorNotASocket,
3229 .WSAEINVAL => return error.SocketNotBound,
3230 else => |err| return windows.unexpectedWSAError(err),
3231 }
3232 }
3233 return;
3234 } else {
3235 const rc = system.getpeername(sock, addr, addrlen);
3236 switch (errno(rc)) {
3237 0 => return,
3238 else => |err| return unexpectedErrno(err),
3239
3240 EBADF => unreachable, // always a race condition
3241 EFAULT => unreachable,
3242 EINVAL => unreachable, // invalid parameters
3243 ENOTSOCK => return error.FileDescriptorNotASocket,
3244 ENOBUFS => return error.SystemResources,
3245 }
3246 }
3247}
3248
3220pub const ConnectError = error{3249pub const ConnectError = error{
3221 /// For UNIX domain sockets, which are identified by pathname: Write permission is denied on the socket3250 /// For UNIX domain sockets, which are identified by pathname: Write permission is denied on the socket
3222 /// file, or search permission is denied for one of the directories in the path prefix.3251 /// file, or search permission is denied for one of the directories in the path prefix.
...@@ -5722,7 +5751,7 @@ pub const SetSockOptError = error{...@@ -5722,7 +5751,7 @@ pub const SetSockOptError = error{
5722/// Set a socket's options.5751/// Set a socket's options.
5723pub fn setsockopt(fd: socket_t, level: u32, optname: u32, opt: []const u8) SetSockOptError!void {5752pub fn setsockopt(fd: socket_t, level: u32, optname: u32, opt: []const u8) SetSockOptError!void {
5724 if (builtin.os.tag == .windows) {5753 if (builtin.os.tag == .windows) {
5725 const rc = windows.ws2_32.setsockopt(fd, level, optname, opt.ptr, @intCast(socklen_t, opt.len));5754 const rc = windows.ws2_32.setsockopt(fd, @intCast(i32, level), @intCast(i32, optname), opt.ptr, @intCast(i32, opt.len));
5726 if (rc == windows.ws2_32.SOCKET_ERROR) {5755 if (rc == windows.ws2_32.SOCKET_ERROR) {
5727 switch (windows.ws2_32.WSAGetLastError()) {5756 switch (windows.ws2_32.WSAGetLastError()) {
5728 .WSANOTINITIALISED => unreachable,5757 .WSANOTINITIALISED => unreachable,
lib/std/os/bits/darwin.zig+7
...@@ -23,6 +23,13 @@ pub const sockaddr = extern struct {...@@ -23,6 +23,13 @@ pub const sockaddr = extern struct {
23 family: sa_family_t,23 family: sa_family_t,
24 data: [14]u8,24 data: [14]u8,
25};25};
26pub const sockaddr_storage = extern struct {
27 len: u8,
28 family: sa_family_t,
29 __pad1: [5]u8,
30 __align: i64,
31 __pad2: [112]u8,
32};
26pub const sockaddr_in = extern struct {33pub const sockaddr_in = extern struct {
27 len: u8 = @sizeOf(sockaddr_in),34 len: u8 = @sizeOf(sockaddr_in),
28 family: sa_family_t = AF_INET,35 family: sa_family_t = AF_INET,
lib/std/os/bits/dragonfly.zig+9-1
...@@ -380,6 +380,14 @@ pub const sockaddr = extern struct {...@@ -380,6 +380,14 @@ pub const sockaddr = extern struct {
380 sa_data: [14]u8,380 sa_data: [14]u8,
381};381};
382382
383pub const sockaddr_storage = extern struct {
384 len: u8,
385 family: sa_family_t,
386 __pad1: [5]u8,
387 __align: i64,
388 __pad2: [112]u8,
389};
390
383pub const Kevent = extern struct {391pub const Kevent = extern struct {
384 ident: usize,392 ident: usize,
385 filter: c_short,393 filter: c_short,
...@@ -640,7 +648,7 @@ pub const socklen_t = c_uint;...@@ -640,7 +648,7 @@ pub const socklen_t = c_uint;
640pub const sockaddr_storage = extern struct {648pub const sockaddr_storage = extern struct {
641 ss_len: u8,649 ss_len: u8,
642 ss_family: sa_family_t,650 ss_family: sa_family_t,
643 __ss_pad1: [6]u8,651 __ss_pad1: [5]u8,
644 __ss_align: i64,652 __ss_align: i64,
645 __ss_pad2: [112]u8,653 __ss_pad2: [112]u8,
646};654};
lib/std/os/bits/freebsd.zig+8
...@@ -206,6 +206,14 @@ pub const sockaddr = extern struct {...@@ -206,6 +206,14 @@ pub const sockaddr = extern struct {
206 data: [14]u8,206 data: [14]u8,
207};207};
208208
209pub const sockaddr_storage = extern struct {
210 len: u8,
211 family: sa_family_t,
212 __pad1: [5]u8,
213 __align: i64,
214 __pad2: [112]u8,
215};
216
209pub const sockaddr_in = extern struct {217pub const sockaddr_in = extern struct {
210 len: u8 = @sizeOf(sockaddr_in),218 len: u8 = @sizeOf(sockaddr_in),
211 family: sa_family_t = AF_INET,219 family: sa_family_t = AF_INET,
lib/std/os/bits/haiku.zig+8
...@@ -239,6 +239,14 @@ pub const sockaddr = extern struct {...@@ -239,6 +239,14 @@ pub const sockaddr = extern struct {
239 data: [14]u8,239 data: [14]u8,
240};240};
241241
242pub const sockaddr_storage = extern struct {
243 len: u8,
244 family: sa_family_t,
245 __pad1: [5]u8,
246 __align: i64,
247 __pad2: [112]u8,
248};
249
242pub const sockaddr_in = extern struct {250pub const sockaddr_in = extern struct {
243 len: u8 = @sizeOf(sockaddr_in),251 len: u8 = @sizeOf(sockaddr_in),
244 family: sa_family_t = AF_INET,252 family: sa_family_t = AF_INET,
lib/std/os/bits/linux.zig+7
...@@ -1149,6 +1149,13 @@ pub const sockaddr = extern struct {...@@ -1149,6 +1149,13 @@ pub const sockaddr = extern struct {
1149 data: [14]u8,1149 data: [14]u8,
1150};1150};
11511151
1152pub const sockaddr_storage = extern struct {
1153 family: sa_family_t,
1154 __pad1: [6]u8,
1155 __align: i64,
1156 __pad2: [112]u8,
1157};
1158
1152/// IPv4 socket address1159/// IPv4 socket address
1153pub const sockaddr_in = extern struct {1160pub const sockaddr_in = extern struct {
1154 family: sa_family_t = AF_INET,1161 family: sa_family_t = AF_INET,
lib/std/os/bits/netbsd.zig+8
...@@ -226,6 +226,14 @@ pub const sockaddr = extern struct {...@@ -226,6 +226,14 @@ pub const sockaddr = extern struct {
226 data: [14]u8,226 data: [14]u8,
227};227};
228228
229pub const sockaddr_storage = extern struct {
230 len: u8,
231 family: sa_family_t,
232 __pad1: [5]u8,
233 __align: i64,
234 __pad2: [112]u8,
235};
236
229pub const sockaddr_in = extern struct {237pub const sockaddr_in = extern struct {
230 len: u8 = @sizeOf(sockaddr_in),238 len: u8 = @sizeOf(sockaddr_in),
231 family: sa_family_t = AF_INET,239 family: sa_family_t = AF_INET,
lib/std/os/bits/openbsd.zig+8
...@@ -246,6 +246,14 @@ pub const sockaddr = extern struct {...@@ -246,6 +246,14 @@ pub const sockaddr = extern struct {
246 data: [14]u8,246 data: [14]u8,
247};247};
248248
249pub const sockaddr_storage = extern struct {
250 len: u8,
251 family: sa_family_t,
252 __pad1: [5]u8,
253 __align: i64,
254 __pad2: [112]u8,
255};
256
249pub const sockaddr_in = extern struct {257pub const sockaddr_in = extern struct {
250 len: u8 = @sizeOf(sockaddr_in),258 len: u8 = @sizeOf(sockaddr_in),
251 family: sa_family_t = AF_INET,259 family: sa_family_t = AF_INET,
lib/std/os/bits/windows.zig+2
...@@ -321,3 +321,5 @@ pub const O_NOATIME = 0o1000000;...@@ -321,3 +321,5 @@ pub const O_NOATIME = 0o1000000;
321pub const O_PATH = 0o10000000;321pub const O_PATH = 0o10000000;
322pub const O_TMPFILE = 0o20200000;322pub const O_TMPFILE = 0o20200000;
323pub const O_NDELAY = O_NONBLOCK;323pub const O_NDELAY = O_NONBLOCK;
324
325pub const IFNAMESIZE = 30;
lib/std/os/windows.zig+95
...@@ -389,6 +389,43 @@ pub fn GetQueuedCompletionStatus(...@@ -389,6 +389,43 @@ pub fn GetQueuedCompletionStatus(
389 return GetQueuedCompletionStatusResult.Normal;389 return GetQueuedCompletionStatusResult.Normal;
390}390}
391391
392pub const GetQueuedCompletionStatusError = error{
393 Aborted,
394 Cancelled,
395 EOF,
396 Timeout,
397} || std.os.UnexpectedError;
398
399pub fn GetQueuedCompletionStatusEx(
400 completion_port: HANDLE,
401 completion_port_entries: []OVERLAPPED_ENTRY,
402 timeout_ms: ?DWORD,
403 alertable: bool,
404) GetQueuedCompletionStatusError!u32 {
405 var num_entries_removed: u32 = 0;
406
407 const success = kernel32.GetQueuedCompletionStatusEx(
408 completion_port,
409 completion_port_entries.ptr,
410 @intCast(ULONG, completion_port_entries.len),
411 &num_entries_removed,
412 timeout_ms orelse INFINITE,
413 @boolToInt(alertable),
414 );
415
416 if (success == FALSE) {
417 return switch (kernel32.GetLastError()) {
418 .ABANDONED_WAIT_0 => error.Aborted,
419 .OPERATION_ABORTED => error.Cancelled,
420 .HANDLE_EOF => error.EOF,
421 .IMEOUT => error.Timeout,
422 else => |err| unexpectedError(err),
423 };
424 }
425
426 return num_entries_removed;
427}
428
392pub fn CloseHandle(hObject: HANDLE) void {429pub fn CloseHandle(hObject: HANDLE) void {
393 assert(ntdll.NtClose(hObject) == .SUCCESS);430 assert(ntdll.NtClose(hObject) == .SUCCESS);
394}431}
...@@ -1291,6 +1328,10 @@ pub fn getsockname(s: ws2_32.SOCKET, name: *ws2_32.sockaddr, namelen: *ws2_32.so...@@ -1291,6 +1328,10 @@ pub fn getsockname(s: ws2_32.SOCKET, name: *ws2_32.sockaddr, namelen: *ws2_32.so
1291 return ws2_32.getsockname(s, name, @ptrCast(*i32, namelen));1328 return ws2_32.getsockname(s, name, @ptrCast(*i32, namelen));
1292}1329}
12931330
1331pub fn getpeername(s: ws2_32.SOCKET, name: *ws2_32.sockaddr, namelen: *ws2_32.socklen_t) i32 {
1332 return ws2_32.getpeername(s, name, @ptrCast(*i32, namelen));
1333}
1334
1294pub fn sendmsg(1335pub fn sendmsg(
1295 s: ws2_32.SOCKET,1336 s: ws2_32.SOCKET,
1296 msg: *const ws2_32.WSAMSG,1337 msg: *const ws2_32.WSAMSG,
...@@ -1404,6 +1445,28 @@ pub fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) SetCon...@@ -1404,6 +1445,28 @@ pub fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) SetCon
1404 }1445 }
1405}1446}
14061447
1448pub fn SetConsoleCtrlHandler(handler_routine: ?HANDLER_ROUTINE, add: bool) !void {
1449 const success = kernel32.SetConsoleCtrlHandler(
1450 handler_routine,
1451 if (add) TRUE else FALSE,
1452 );
1453
1454 if (success == FALSE) {
1455 return switch (kernel32.GetLastError()) {
1456 else => |err| unexpectedError(err),
1457 };
1458 }
1459}
1460
1461pub fn SetFileCompletionNotificationModes(handle: HANDLE, flags: UCHAR) !void {
1462 const success = kernel32.SetFileCompletionNotificationModes(handle, flags);
1463 if (success == FALSE) {
1464 return switch (kernel32.GetLastError()) {
1465 else => |err| unexpectedError(err),
1466 };
1467 }
1468}
1469
1407pub const GetEnvironmentStringsError = error{OutOfMemory};1470pub const GetEnvironmentStringsError = error{OutOfMemory};
14081471
1409pub fn GetEnvironmentStringsW() GetEnvironmentStringsError![*:0]u16 {1472pub fn GetEnvironmentStringsW() GetEnvironmentStringsError![*:0]u16 {
...@@ -1686,6 +1749,38 @@ fn MAKELANGID(p: c_ushort, s: c_ushort) callconv(.Inline) LANGID {...@@ -1686,6 +1749,38 @@ fn MAKELANGID(p: c_ushort, s: c_ushort) callconv(.Inline) LANGID {
1686 return (s << 10) | p;1749 return (s << 10) | p;
1687}1750}
16881751
1752/// Loads a Winsock extension function in runtime specified by a GUID.
1753pub fn loadWinsockExtensionFunction(comptime T: type, sock: ws2_32.SOCKET, guid: GUID) !T {
1754 var function: T = undefined;
1755 var num_bytes: DWORD = undefined;
1756
1757 const rc = ws2_32.WSAIoctl(
1758 sock,
1759 ws2_32.SIO_GET_EXTENSION_FUNCTION_POINTER,
1760 @ptrCast(*const c_void, &guid),
1761 @sizeOf(GUID),
1762 &function,
1763 @sizeOf(T),
1764 &num_bytes,
1765 null,
1766 null,
1767 );
1768
1769 if (rc == ws2_32.SOCKET_ERROR) {
1770 return switch (ws2_32.WSAGetLastError()) {
1771 .WSAEOPNOTSUPP => error.OperationNotSupported,
1772 .WSAENOTSOCK => error.FileDescriptorNotASocket,
1773 else => |err| unexpectedWSAError(err),
1774 };
1775 }
1776
1777 if (num_bytes != @sizeOf(T)) {
1778 return error.ShortRead;
1779 }
1780
1781 return function;
1782}
1783
1689/// Call this when you made a windows DLL call or something that does SetLastError1784/// Call this when you made a windows DLL call or something that does SetLastError
1690/// and you get an unexpected error.1785/// and you get an unexpected error.
1691pub fn unexpectedError(err: Win32Error) std.os.UnexpectedError {1786pub fn unexpectedError(err: Win32Error) std.os.UnexpectedError {
lib/std/os/windows/bits.zig+11-4
...@@ -1619,10 +1619,6 @@ pub const MOUNTMGR_MOUNT_POINTS = extern struct {...@@ -1619,10 +1619,6 @@ pub const MOUNTMGR_MOUNT_POINTS = extern struct {
1619};1619};
1620pub const IOCTL_MOUNTMGR_QUERY_POINTS: ULONG = 0x6d0008;1620pub const IOCTL_MOUNTMGR_QUERY_POINTS: ULONG = 0x6d0008;
16211621
1622pub const SD_RECEIVE = 0;
1623pub const SD_SEND = 1;
1624pub const SD_BOTH = 2;
1625
1626pub const OBJECT_INFORMATION_CLASS = extern enum {1622pub const OBJECT_INFORMATION_CLASS = extern enum {
1627 ObjectBasicInformation = 0,1623 ObjectBasicInformation = 0,
1628 ObjectNameInformation = 1,1624 ObjectNameInformation = 1,
...@@ -1642,3 +1638,14 @@ pub const SRWLOCK = usize;...@@ -1642,3 +1638,14 @@ pub const SRWLOCK = usize;
1642pub const SRWLOCK_INIT: SRWLOCK = 0;1638pub const SRWLOCK_INIT: SRWLOCK = 0;
1643pub const CONDITION_VARIABLE = usize;1639pub const CONDITION_VARIABLE = usize;
1644pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = 0;1640pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = 0;
1641
1642pub const FILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 0x1;
1643pub const FILE_SKIP_SET_EVENT_ON_HANDLE = 0x2;
1644
1645pub const CTRL_C_EVENT: DWORD = 0;
1646pub const CTRL_BREAK_EVENT: DWORD = 1;
1647pub const CTRL_CLOSE_EVENT: DWORD = 2;
1648pub const CTRL_LOGOFF_EVENT: DWORD = 5;
1649pub const CTRL_SHUTDOWN_EVENT: DWORD = 6;
1650
1651pub const HANDLER_ROUTINE = fn (dwCtrlType: DWORD) callconv(.C) BOOL;
lib/std/os/windows/kernel32.zig+18
...@@ -140,6 +140,14 @@ pub extern "kernel32" fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERL...@@ -140,6 +140,14 @@ pub extern "kernel32" fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERL
140140
141pub extern "kernel32" fn GetProcessHeap() callconv(WINAPI) ?HANDLE;141pub extern "kernel32" fn GetProcessHeap() callconv(WINAPI) ?HANDLE;
142pub extern "kernel32" fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) callconv(WINAPI) BOOL;142pub extern "kernel32" fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) callconv(WINAPI) BOOL;
143pub extern "kernel32" fn GetQueuedCompletionStatusEx(
144 CompletionPort: HANDLE,
145 lpCompletionPortEntries: [*]OVERLAPPED_ENTRY,
146 ulCount: ULONG,
147 ulNumEntriesRemoved: *ULONG,
148 dwMilliseconds: DWORD,
149 fAlertable: BOOL,
150) callconv(WINAPI) BOOL;
143151
144pub extern "kernel32" fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) callconv(WINAPI) void;152pub extern "kernel32" fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) callconv(WINAPI) void;
145pub extern "kernel32" fn GetSystemTimeAsFileTime(*FILETIME) callconv(WINAPI) void;153pub extern "kernel32" fn GetSystemTimeAsFileTime(*FILETIME) callconv(WINAPI) void;
...@@ -197,6 +205,16 @@ pub extern "kernel32" fn RemoveDirectoryW(lpPathName: [*:0]const u16) callconv(W...@@ -197,6 +205,16 @@ pub extern "kernel32" fn RemoveDirectoryW(lpPathName: [*:0]const u16) callconv(W
197205
198pub extern "kernel32" fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) callconv(WINAPI) BOOL;206pub extern "kernel32" fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) callconv(WINAPI) BOOL;
199207
208pub extern "kernel32" fn SetConsoleCtrlHandler(
209 HandlerRoutine: ?HANDLER_ROUTINE,
210 Add: BOOL,
211) callconv(WINAPI) BOOL;
212
213pub extern "kernel32" fn SetFileCompletionNotificationModes(
214 FileHandle: HANDLE,
215 Flags: UCHAR,
216) callconv(WINAPI) BOOL;
217
200pub extern "kernel32" fn SetFilePointerEx(218pub extern "kernel32" fn SetFilePointerEx(
201 in_fFile: HANDLE,219 in_fFile: HANDLE,
202 in_liDistanceToMove: LARGE_INTEGER,220 in_liDistanceToMove: LARGE_INTEGER,
lib/std/os/windows/ws2_32.zig+1668-246
...@@ -7,10 +7,929 @@ usingnamespace @import("bits.zig");...@@ -7,10 +7,929 @@ usingnamespace @import("bits.zig");
77
8pub const SOCKET = *opaque {};8pub const SOCKET = *opaque {};
9pub const INVALID_SOCKET = @intToPtr(SOCKET, ~@as(usize, 0));9pub const INVALID_SOCKET = @intToPtr(SOCKET, ~@as(usize, 0));
10pub const SOCKET_ERROR = -1;
1110
11pub const GROUP = u32;
12pub const ADDRESS_FAMILY = u16;
13pub const WSAEVENT = HANDLE;
14
15// Microsoft use the signed c_int for this, but it should never be negative
16pub const socklen_t = u32;
17
18pub const LM_HB_Extension = 128;
19pub const LM_HB1_PnP = 1;
20pub const LM_HB1_PDA_Palmtop = 2;
21pub const LM_HB1_Computer = 4;
22pub const LM_HB1_Printer = 8;
23pub const LM_HB1_Modem = 16;
24pub const LM_HB1_Fax = 32;
25pub const LM_HB1_LANAccess = 64;
26pub const LM_HB2_Telephony = 1;
27pub const LM_HB2_FileServer = 2;
28pub const ATMPROTO_AALUSER = 0;
29pub const ATMPROTO_AAL1 = 1;
30pub const ATMPROTO_AAL2 = 2;
31pub const ATMPROTO_AAL34 = 3;
32pub const ATMPROTO_AAL5 = 5;
33pub const SAP_FIELD_ABSENT = 4294967294;
34pub const SAP_FIELD_ANY = 4294967295;
35pub const SAP_FIELD_ANY_AESA_SEL = 4294967290;
36pub const SAP_FIELD_ANY_AESA_REST = 4294967291;
37pub const ATM_E164 = 1;
38pub const ATM_NSAP = 2;
39pub const ATM_AESA = 2;
40pub const ATM_ADDR_SIZE = 20;
41pub const BLLI_L2_ISO_1745 = 1;
42pub const BLLI_L2_Q921 = 2;
43pub const BLLI_L2_X25L = 6;
44pub const BLLI_L2_X25M = 7;
45pub const BLLI_L2_ELAPB = 8;
46pub const BLLI_L2_HDLC_ARM = 9;
47pub const BLLI_L2_HDLC_NRM = 10;
48pub const BLLI_L2_HDLC_ABM = 11;
49pub const BLLI_L2_LLC = 12;
50pub const BLLI_L2_X75 = 13;
51pub const BLLI_L2_Q922 = 14;
52pub const BLLI_L2_USER_SPECIFIED = 16;
53pub const BLLI_L2_ISO_7776 = 17;
54pub const BLLI_L3_X25 = 6;
55pub const BLLI_L3_ISO_8208 = 7;
56pub const BLLI_L3_X223 = 8;
57pub const BLLI_L3_SIO_8473 = 9;
58pub const BLLI_L3_T70 = 10;
59pub const BLLI_L3_ISO_TR9577 = 11;
60pub const BLLI_L3_USER_SPECIFIED = 16;
61pub const BLLI_L3_IPI_SNAP = 128;
62pub const BLLI_L3_IPI_IP = 204;
63pub const BHLI_ISO = 0;
64pub const BHLI_UserSpecific = 1;
65pub const BHLI_HighLayerProfile = 2;
66pub const BHLI_VendorSpecificAppId = 3;
67pub const AAL5_MODE_MESSAGE = 1;
68pub const AAL5_MODE_STREAMING = 2;
69pub const AAL5_SSCS_NULL = 0;
70pub const AAL5_SSCS_SSCOP_ASSURED = 1;
71pub const AAL5_SSCS_SSCOP_NON_ASSURED = 2;
72pub const AAL5_SSCS_FRAME_RELAY = 4;
73pub const BCOB_A = 1;
74pub const BCOB_C = 3;
75pub const BCOB_X = 16;
76pub const TT_NOIND = 0;
77pub const TT_CBR = 4;
78pub const TT_VBR = 8;
79pub const TR_NOIND = 0;
80pub const TR_END_TO_END = 1;
81pub const TR_NO_END_TO_END = 2;
82pub const CLIP_NOT = 0;
83pub const CLIP_SUS = 32;
84pub const UP_P2P = 0;
85pub const UP_P2MP = 1;
86pub const BLLI_L2_MODE_NORMAL = 64;
87pub const BLLI_L2_MODE_EXT = 128;
88pub const BLLI_L3_MODE_NORMAL = 64;
89pub const BLLI_L3_MODE_EXT = 128;
90pub const BLLI_L3_PACKET_16 = 4;
91pub const BLLI_L3_PACKET_32 = 5;
92pub const BLLI_L3_PACKET_64 = 6;
93pub const BLLI_L3_PACKET_128 = 7;
94pub const BLLI_L3_PACKET_256 = 8;
95pub const BLLI_L3_PACKET_512 = 9;
96pub const BLLI_L3_PACKET_1024 = 10;
97pub const BLLI_L3_PACKET_2048 = 11;
98pub const BLLI_L3_PACKET_4096 = 12;
99pub const PI_ALLOWED = 0;
100pub const PI_RESTRICTED = 64;
101pub const PI_NUMBER_NOT_AVAILABLE = 128;
102pub const SI_USER_NOT_SCREENED = 0;
103pub const SI_USER_PASSED = 1;
104pub const SI_USER_FAILED = 2;
105pub const SI_NETWORK = 3;
106pub const CAUSE_LOC_USER = 0;
107pub const CAUSE_LOC_PRIVATE_LOCAL = 1;
108pub const CAUSE_LOC_PUBLIC_LOCAL = 2;
109pub const CAUSE_LOC_TRANSIT_NETWORK = 3;
110pub const CAUSE_LOC_PUBLIC_REMOTE = 4;
111pub const CAUSE_LOC_PRIVATE_REMOTE = 5;
112pub const CAUSE_LOC_INTERNATIONAL_NETWORK = 7;
113pub const CAUSE_LOC_BEYOND_INTERWORKING = 10;
114pub const CAUSE_UNALLOCATED_NUMBER = 1;
115pub const CAUSE_NO_ROUTE_TO_TRANSIT_NETWORK = 2;
116pub const CAUSE_NO_ROUTE_TO_DESTINATION = 3;
117pub const CAUSE_VPI_VCI_UNACCEPTABLE = 10;
118pub const CAUSE_NORMAL_CALL_CLEARING = 16;
119pub const CAUSE_USER_BUSY = 17;
120pub const CAUSE_NO_USER_RESPONDING = 18;
121pub const CAUSE_CALL_REJECTED = 21;
122pub const CAUSE_NUMBER_CHANGED = 22;
123pub const CAUSE_USER_REJECTS_CLIR = 23;
124pub const CAUSE_DESTINATION_OUT_OF_ORDER = 27;
125pub const CAUSE_INVALID_NUMBER_FORMAT = 28;
126pub const CAUSE_STATUS_ENQUIRY_RESPONSE = 30;
127pub const CAUSE_NORMAL_UNSPECIFIED = 31;
128pub const CAUSE_VPI_VCI_UNAVAILABLE = 35;
129pub const CAUSE_NETWORK_OUT_OF_ORDER = 38;
130pub const CAUSE_TEMPORARY_FAILURE = 41;
131pub const CAUSE_ACCESS_INFORMAION_DISCARDED = 43;
132pub const CAUSE_NO_VPI_VCI_AVAILABLE = 45;
133pub const CAUSE_RESOURCE_UNAVAILABLE = 47;
134pub const CAUSE_QOS_UNAVAILABLE = 49;
135pub const CAUSE_USER_CELL_RATE_UNAVAILABLE = 51;
136pub const CAUSE_BEARER_CAPABILITY_UNAUTHORIZED = 57;
137pub const CAUSE_BEARER_CAPABILITY_UNAVAILABLE = 58;
138pub const CAUSE_OPTION_UNAVAILABLE = 63;
139pub const CAUSE_BEARER_CAPABILITY_UNIMPLEMENTED = 65;
140pub const CAUSE_UNSUPPORTED_TRAFFIC_PARAMETERS = 73;
141pub const CAUSE_INVALID_CALL_REFERENCE = 81;
142pub const CAUSE_CHANNEL_NONEXISTENT = 82;
143pub const CAUSE_INCOMPATIBLE_DESTINATION = 88;
144pub const CAUSE_INVALID_ENDPOINT_REFERENCE = 89;
145pub const CAUSE_INVALID_TRANSIT_NETWORK_SELECTION = 91;
146pub const CAUSE_TOO_MANY_PENDING_ADD_PARTY = 92;
147pub const CAUSE_AAL_PARAMETERS_UNSUPPORTED = 93;
148pub const CAUSE_MANDATORY_IE_MISSING = 96;
149pub const CAUSE_UNIMPLEMENTED_MESSAGE_TYPE = 97;
150pub const CAUSE_UNIMPLEMENTED_IE = 99;
151pub const CAUSE_INVALID_IE_CONTENTS = 100;
152pub const CAUSE_INVALID_STATE_FOR_MESSAGE = 101;
153pub const CAUSE_RECOVERY_ON_TIMEOUT = 102;
154pub const CAUSE_INCORRECT_MESSAGE_LENGTH = 104;
155pub const CAUSE_PROTOCOL_ERROR = 111;
156pub const CAUSE_COND_UNKNOWN = 0;
157pub const CAUSE_COND_PERMANENT = 1;
158pub const CAUSE_COND_TRANSIENT = 2;
159pub const CAUSE_REASON_USER = 0;
160pub const CAUSE_REASON_IE_MISSING = 4;
161pub const CAUSE_REASON_IE_INSUFFICIENT = 8;
162pub const CAUSE_PU_PROVIDER = 0;
163pub const CAUSE_PU_USER = 8;
164pub const CAUSE_NA_NORMAL = 0;
165pub const CAUSE_NA_ABNORMAL = 4;
166pub const QOS_CLASS0 = 0;
167pub const QOS_CLASS1 = 1;
168pub const QOS_CLASS2 = 2;
169pub const QOS_CLASS3 = 3;
170pub const QOS_CLASS4 = 4;
171pub const TNS_TYPE_NATIONAL = 64;
172pub const TNS_PLAN_CARRIER_ID_CODE = 1;
173pub const SIO_GET_NUMBER_OF_ATM_DEVICES = 1343619073;
174pub const SIO_GET_ATM_ADDRESS = 3491102722;
175pub const SIO_ASSOCIATE_PVC = 2417360899;
176pub const SIO_GET_ATM_CONNECTION_ID = 1343619076;
177pub const RIO_MSG_DONT_NOTIFY = 1;
178pub const RIO_MSG_DEFER = 2;
179pub const RIO_MSG_WAITALL = 4;
180pub const RIO_MSG_COMMIT_ONLY = 8;
181pub const RIO_MAX_CQ_SIZE = 134217728;
182pub const RIO_CORRUPT_CQ = 4294967295;
183pub const WINDOWS_AF_IRDA = 26;
184pub const WCE_AF_IRDA = 22;
185pub const IRDA_PROTO_SOCK_STREAM = 1;
186pub const SOL_IRLMP = 255;
187pub const IRLMP_ENUMDEVICES = 16;
188pub const IRLMP_IAS_SET = 17;
189pub const IRLMP_IAS_QUERY = 18;
190pub const IRLMP_SEND_PDU_LEN = 19;
191pub const IRLMP_EXCLUSIVE_MODE = 20;
192pub const IRLMP_IRLPT_MODE = 21;
193pub const IRLMP_9WIRE_MODE = 22;
194pub const IRLMP_TINYTP_MODE = 23;
195pub const IRLMP_PARAMETERS = 24;
196pub const IRLMP_DISCOVERY_MODE = 25;
197pub const IRLMP_SHARP_MODE = 32;
198pub const IAS_ATTRIB_NO_CLASS = 16;
199pub const IAS_ATTRIB_NO_ATTRIB = 0;
200pub const IAS_ATTRIB_INT = 1;
201pub const IAS_ATTRIB_OCTETSEQ = 2;
202pub const IAS_ATTRIB_STR = 3;
203pub const IAS_MAX_USER_STRING = 256;
204pub const IAS_MAX_OCTET_STRING = 1024;
205pub const IAS_MAX_CLASSNAME = 64;
206pub const IAS_MAX_ATTRIBNAME = 256;
207pub const LmCharSetASCII = 0;
208pub const LmCharSetISO_8859_1 = 1;
209pub const LmCharSetISO_8859_2 = 2;
210pub const LmCharSetISO_8859_3 = 3;
211pub const LmCharSetISO_8859_4 = 4;
212pub const LmCharSetISO_8859_5 = 5;
213pub const LmCharSetISO_8859_6 = 6;
214pub const LmCharSetISO_8859_7 = 7;
215pub const LmCharSetISO_8859_8 = 8;
216pub const LmCharSetISO_8859_9 = 9;
217pub const LmCharSetUNICODE = 255;
218pub const LM_BAUD_1200 = 1200;
219pub const LM_BAUD_2400 = 2400;
220pub const LM_BAUD_9600 = 9600;
221pub const LM_BAUD_19200 = 19200;
222pub const LM_BAUD_38400 = 38400;
223pub const LM_BAUD_57600 = 57600;
224pub const LM_BAUD_115200 = 115200;
225pub const LM_BAUD_576K = 576000;
226pub const LM_BAUD_1152K = 1152000;
227pub const LM_BAUD_4M = 4000000;
228pub const LM_BAUD_16M = 16000000;
229pub const IPX_PTYPE = 16384;
230pub const IPX_FILTERPTYPE = 16385;
231pub const IPX_STOPFILTERPTYPE = 16387;
232pub const IPX_DSTYPE = 16386;
233pub const IPX_EXTENDED_ADDRESS = 16388;
234pub const IPX_RECVHDR = 16389;
235pub const IPX_MAXSIZE = 16390;
236pub const IPX_ADDRESS = 16391;
237pub const IPX_GETNETINFO = 16392;
238pub const IPX_GETNETINFO_NORIP = 16393;
239pub const IPX_SPXGETCONNECTIONSTATUS = 16395;
240pub const IPX_ADDRESS_NOTIFY = 16396;
241pub const IPX_MAX_ADAPTER_NUM = 16397;
242pub const IPX_RERIPNETNUMBER = 16398;
243pub const IPX_RECEIVE_BROADCAST = 16399;
244pub const IPX_IMMEDIATESPXACK = 16400;
245pub const IPPROTO_RM = 113;
246pub const MAX_MCAST_TTL = 255;
247pub const RM_OPTIONSBASE = 1000;
248pub const RM_RATE_WINDOW_SIZE = 1001;
249pub const RM_SET_MESSAGE_BOUNDARY = 1002;
250pub const RM_FLUSHCACHE = 1003;
251pub const RM_SENDER_WINDOW_ADVANCE_METHOD = 1004;
252pub const RM_SENDER_STATISTICS = 1005;
253pub const RM_LATEJOIN = 1006;
254pub const RM_SET_SEND_IF = 1007;
255pub const RM_ADD_RECEIVE_IF = 1008;
256pub const RM_DEL_RECEIVE_IF = 1009;
257pub const RM_SEND_WINDOW_ADV_RATE = 1010;
258pub const RM_USE_FEC = 1011;
259pub const RM_SET_MCAST_TTL = 1012;
260pub const RM_RECEIVER_STATISTICS = 1013;
261pub const RM_HIGH_SPEED_INTRANET_OPT = 1014;
262pub const SENDER_DEFAULT_RATE_KBITS_PER_SEC = 56;
263pub const SENDER_DEFAULT_WINDOW_ADV_PERCENTAGE = 15;
264pub const MAX_WINDOW_INCREMENT_PERCENTAGE = 25;
265pub const SENDER_DEFAULT_LATE_JOINER_PERCENTAGE = 0;
266pub const SENDER_MAX_LATE_JOINER_PERCENTAGE = 75;
267pub const BITS_PER_BYTE = 8;
268pub const LOG2_BITS_PER_BYTE = 3;
269
270pub const SOCKET_DEFAULT2_QM_POLICY = GUID.parse("{aec2ef9c-3a4d-4d3e-8842-239942e39a47}");
271pub const REAL_TIME_NOTIFICATION_CAPABILITY = GUID.parse("{6b59819a-5cae-492d-a901-2a3c2c50164f}");
272pub const REAL_TIME_NOTIFICATION_CAPABILITY_EX = GUID.parse("{6843da03-154a-4616-a508-44371295f96b}");
273pub const ASSOCIATE_NAMERES_CONTEXT = GUID.parse("{59a38b67-d4fe-46e1-ba3c-87ea74ca3049}");
274
275pub const WSAID_CONNECTEX = GUID{
276 .Data1 = 0x25a207b9,
277 .Data2 = 0xddf3,
278 .Data3 = 0x4660,
279 .Data4 = [8]u8{ 0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e },
280};
281
282pub const WSAID_ACCEPTEX = GUID{
283 .Data1 = 0xb5367df1,
284 .Data2 = 0xcbac,
285 .Data3 = 0x11cf,
286 .Data4 = [8]u8{ 0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 },
287};
288
289pub const WSAID_GETACCEPTEXSOCKADDRS = GUID{
290 .Data1 = 0xb5367df2,
291 .Data2 = 0xcbac,
292 .Data3 = 0x11cf,
293 .Data4 = [8]u8{ 0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 },
294};
295
296pub const WSAID_WSARECVMSG = GUID{
297 .Data1 = 0xf689d7c8,
298 .Data2 = 0x6f1f,
299 .Data3 = 0x436b,
300 .Data4 = [8]u8{ 0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22 },
301};
302
303pub const WSAID_WSAPOLL = GUID{
304 .Data1 = 0x18C76F85,
305 .Data2 = 0xDC66,
306 .Data3 = 0x4964,
307 .Data4 = [8]u8{ 0x97, 0x2E, 0x23, 0xC2, 0x72, 0x38, 0x31, 0x2B },
308};
309
310pub const WSAID_WSASENDMSG = GUID{
311 .Data1 = 0xa441e712,
312 .Data2 = 0x754f,
313 .Data3 = 0x43ca,
314 .Data4 = [8]u8{ 0x84, 0xa7, 0x0d, 0xee, 0x44, 0xcf, 0x60, 0x6d },
315};
316
317pub const TCP_INITIAL_RTO_DEFAULT_RTT = 0;
318pub const TCP_INITIAL_RTO_DEFAULT_MAX_SYN_RETRANSMISSIONS = 0;
319pub const SOCKET_SETTINGS_GUARANTEE_ENCRYPTION = 1;
320pub const SOCKET_SETTINGS_ALLOW_INSECURE = 2;
321pub const SOCKET_SETTINGS_IPSEC_SKIP_FILTER_INSTANTIATION = 1;
322pub const SOCKET_SETTINGS_IPSEC_OPTIONAL_PEER_NAME_VERIFICATION = 2;
323pub const SOCKET_SETTINGS_IPSEC_ALLOW_FIRST_INBOUND_PKT_UNENCRYPTED = 4;
324pub const SOCKET_SETTINGS_IPSEC_PEER_NAME_IS_RAW_FORMAT = 8;
325pub const SOCKET_QUERY_IPSEC2_ABORT_CONNECTION_ON_FIELD_CHANGE = 1;
326pub const SOCKET_QUERY_IPSEC2_FIELD_MASK_MM_SA_ID = 1;
327pub const SOCKET_QUERY_IPSEC2_FIELD_MASK_QM_SA_ID = 2;
328pub const SOCKET_INFO_CONNECTION_SECURED = 1;
329pub const SOCKET_INFO_CONNECTION_ENCRYPTED = 2;
330pub const SOCKET_INFO_CONNECTION_IMPERSONATED = 4;
331pub const IN4ADDR_LOOPBACK = 16777343;
332pub const IN4ADDR_LOOPBACKPREFIX_LENGTH = 8;
333pub const IN4ADDR_LINKLOCALPREFIX_LENGTH = 16;
334pub const IN4ADDR_MULTICASTPREFIX_LENGTH = 4;
335pub const IFF_UP = 1;
336pub const IFF_BROADCAST = 2;
337pub const IFF_LOOPBACK = 4;
338pub const IFF_POINTTOPOINT = 8;
339pub const IFF_MULTICAST = 16;
340pub const IP_OPTIONS = 1;
341pub const IP_HDRINCL = 2;
342pub const IP_TOS = 3;
343pub const IP_TTL = 4;
344pub const IP_MULTICAST_IF = 9;
345pub const IP_MULTICAST_TTL = 10;
346pub const IP_MULTICAST_LOOP = 11;
347pub const IP_ADD_MEMBERSHIP = 12;
348pub const IP_DROP_MEMBERSHIP = 13;
349pub const IP_DONTFRAGMENT = 14;
350pub const IP_ADD_SOURCE_MEMBERSHIP = 15;
351pub const IP_DROP_SOURCE_MEMBERSHIP = 16;
352pub const IP_BLOCK_SOURCE = 17;
353pub const IP_UNBLOCK_SOURCE = 18;
354pub const IP_PKTINFO = 19;
355pub const IP_HOPLIMIT = 21;
356pub const IP_RECVTTL = 21;
357pub const IP_RECEIVE_BROADCAST = 22;
358pub const IP_RECVIF = 24;
359pub const IP_RECVDSTADDR = 25;
360pub const IP_IFLIST = 28;
361pub const IP_ADD_IFLIST = 29;
362pub const IP_DEL_IFLIST = 30;
363pub const IP_UNICAST_IF = 31;
364pub const IP_RTHDR = 32;
365pub const IP_GET_IFLIST = 33;
366pub const IP_RECVRTHDR = 38;
367pub const IP_TCLASS = 39;
368pub const IP_RECVTCLASS = 40;
369pub const IP_RECVTOS = 40;
370pub const IP_ORIGINAL_ARRIVAL_IF = 47;
371pub const IP_ECN = 50;
372pub const IP_PKTINFO_EX = 51;
373pub const IP_WFP_REDIRECT_RECORDS = 60;
374pub const IP_WFP_REDIRECT_CONTEXT = 70;
375pub const IP_MTU_DISCOVER = 71;
376pub const IP_MTU = 73;
377pub const IP_NRT_INTERFACE = 74;
378pub const IP_RECVERR = 75;
379pub const IP_USER_MTU = 76;
380pub const IP_UNSPECIFIED_TYPE_OF_SERVICE = -1;
381pub const IN6ADDR_LINKLOCALPREFIX_LENGTH = 64;
382pub const IN6ADDR_MULTICASTPREFIX_LENGTH = 8;
383pub const IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_LENGTH = 104;
384pub const IN6ADDR_V4MAPPEDPREFIX_LENGTH = 96;
385pub const IN6ADDR_6TO4PREFIX_LENGTH = 16;
386pub const IN6ADDR_TEREDOPREFIX_LENGTH = 32;
387pub const MCAST_JOIN_GROUP = 41;
388pub const MCAST_LEAVE_GROUP = 42;
389pub const MCAST_BLOCK_SOURCE = 43;
390pub const MCAST_UNBLOCK_SOURCE = 44;
391pub const MCAST_JOIN_SOURCE_GROUP = 45;
392pub const MCAST_LEAVE_SOURCE_GROUP = 46;
393pub const IPV6_HOPOPTS = 1;
394pub const IPV6_HDRINCL = 2;
395pub const IPV6_UNICAST_HOPS = 4;
396pub const IPV6_MULTICAST_IF = 9;
397pub const IPV6_MULTICAST_HOPS = 10;
398pub const IPV6_MULTICAST_LOOP = 11;
399pub const IPV6_ADD_MEMBERSHIP = 12;
400pub const IPV6_DROP_MEMBERSHIP = 13;
401pub const IPV6_DONTFRAG = 14;
402pub const IPV6_PKTINFO = 19;
403pub const IPV6_HOPLIMIT = 21;
404pub const IPV6_PROTECTION_LEVEL = 23;
405pub const IPV6_RECVIF = 24;
406pub const IPV6_RECVDSTADDR = 25;
407pub const IPV6_CHECKSUM = 26;
408pub const IPV6_V6ONLY = 27;
409pub const IPV6_IFLIST = 28;
410pub const IPV6_ADD_IFLIST = 29;
411pub const IPV6_DEL_IFLIST = 30;
412pub const IPV6_UNICAST_IF = 31;
413pub const IPV6_RTHDR = 32;
414pub const IPV6_GET_IFLIST = 33;
415pub const IPV6_RECVRTHDR = 38;
416pub const IPV6_TCLASS = 39;
417pub const IPV6_RECVTCLASS = 40;
418pub const IPV6_ECN = 50;
419pub const IPV6_PKTINFO_EX = 51;
420pub const IPV6_WFP_REDIRECT_RECORDS = 60;
421pub const IPV6_WFP_REDIRECT_CONTEXT = 70;
422pub const IPV6_MTU_DISCOVER = 71;
423pub const IPV6_MTU = 72;
424pub const IPV6_NRT_INTERFACE = 74;
425pub const IPV6_RECVERR = 75;
426pub const IPV6_USER_MTU = 76;
427pub const IP_UNSPECIFIED_HOP_LIMIT = -1;
428pub const PROTECTION_LEVEL_UNRESTRICTED = 10;
429pub const PROTECTION_LEVEL_EDGERESTRICTED = 20;
430pub const PROTECTION_LEVEL_RESTRICTED = 30;
431pub const INET_ADDRSTRLEN = 22;
432pub const INET6_ADDRSTRLEN = 65;
433pub const TCP_OFFLOAD_NO_PREFERENCE = 0;
434pub const TCP_OFFLOAD_NOT_PREFERRED = 1;
435pub const TCP_OFFLOAD_PREFERRED = 2;
436pub const TCP_EXPEDITED_1122 = 2;
437pub const TCP_KEEPALIVE = 3;
438pub const TCP_MAXSEG = 4;
439pub const TCP_MAXRT = 5;
440pub const TCP_STDURG = 6;
441pub const TCP_NOURG = 7;
442pub const TCP_ATMARK = 8;
443pub const TCP_NOSYNRETRIES = 9;
444pub const TCP_TIMESTAMPS = 10;
445pub const TCP_OFFLOAD_PREFERENCE = 11;
446pub const TCP_CONGESTION_ALGORITHM = 12;
447pub const TCP_DELAY_FIN_ACK = 13;
448pub const TCP_MAXRTMS = 14;
449pub const TCP_FASTOPEN = 15;
450pub const TCP_KEEPCNT = 16;
451pub const TCP_KEEPINTVL = 17;
452pub const TCP_FAIL_CONNECT_ON_ICMP_ERROR = 18;
453pub const TCP_ICMP_ERROR_INFO = 19;
454pub const UDP_SEND_MSG_SIZE = 2;
455pub const UDP_RECV_MAX_COALESCED_SIZE = 3;
456pub const UDP_COALESCED_INFO = 3;
457pub const AF_UNSPEC = 0;
458pub const AF_UNIX = 1;
459pub const AF_INET = 2;
460pub const AF_IMPLINK = 3;
461pub const AF_PUP = 4;
462pub const AF_CHAOS = 5;
463pub const AF_NS = 6;
464pub const AF_ISO = 7;
465pub const AF_ECMA = 8;
466pub const AF_DATAKIT = 9;
467pub const AF_CCITT = 10;
468pub const AF_SNA = 11;
469pub const AF_DECnet = 12;
470pub const AF_DLI = 13;
471pub const AF_LAT = 14;
472pub const AF_HYLINK = 15;
473pub const AF_APPLETALK = 16;
474pub const AF_NETBIOS = 17;
475pub const AF_VOICEVIEW = 18;
476pub const AF_FIREFOX = 19;
477pub const AF_UNKNOWN1 = 20;
478pub const AF_BAN = 21;
479pub const AF_ATM = 22;
480pub const AF_INET6 = 23;
481pub const AF_CLUSTER = 24;
482pub const AF_12844 = 25;
483pub const AF_IRDA = 26;
484pub const AF_NETDES = 28;
485pub const AF_MAX = 29;
486pub const AF_TCNPROCESS = 29;
487pub const AF_TCNMESSAGE = 30;
488pub const AF_ICLFXBM = 31;
489pub const AF_LINK = 33;
490pub const AF_HYPERV = 34;
491pub const SOCK_STREAM = 1;
492pub const SOCK_DGRAM = 2;
493pub const SOCK_RAW = 3;
494pub const SOCK_RDM = 4;
495pub const SOCK_SEQPACKET = 5;
496pub const SOL_SOCKET = 65535;
497pub const SO_DEBUG = 1;
498pub const SO_ACCEPTCONN = 2;
499pub const SO_REUSEADDR = 4;
500pub const SO_KEEPALIVE = 8;
501pub const SO_DONTROUTE = 16;
502pub const SO_BROADCAST = 32;
503pub const SO_USELOOPBACK = 64;
504pub const SO_LINGER = 128;
505pub const SO_OOBINLINE = 256;
506pub const SO_SNDBUF = 4097;
507pub const SO_RCVBUF = 4098;
508pub const SO_SNDLOWAT = 4099;
509pub const SO_RCVLOWAT = 4100;
510pub const SO_SNDTIMEO = 4101;
511pub const SO_RCVTIMEO = 4102;
512pub const SO_ERROR = 4103;
513pub const SO_TYPE = 4104;
514pub const SO_BSP_STATE = 4105;
515pub const SO_GROUP_ID = 8193;
516pub const SO_GROUP_PRIORITY = 8194;
517pub const SO_MAX_MSG_SIZE = 8195;
518pub const SO_CONDITIONAL_ACCEPT = 12290;
519pub const SO_PAUSE_ACCEPT = 12291;
520pub const SO_COMPARTMENT_ID = 12292;
521pub const SO_RANDOMIZE_PORT = 12293;
522pub const SO_PORT_SCALABILITY = 12294;
523pub const SO_REUSE_UNICASTPORT = 12295;
524pub const SO_REUSE_MULTICASTPORT = 12296;
525pub const SO_ORIGINAL_DST = 12303;
526pub const WSK_SO_BASE = 16384;
527pub const TCP_NODELAY = 1;
528pub const IOC_UNIX = 0;
529pub const IOC_WS2 = 134217728;
530pub const IOC_PROTOCOL = 268435456;
531pub const IOC_VENDOR = 402653184;
532pub const SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_OUT | IOC_IN | IOC_WS2 | 6;
533pub const SIO_BSP_HANDLE = IOC_OUT | IOC_WS2 | 27;
534pub const SIO_BSP_HANDLE_SELECT = IOC_OUT | IOC_WS2 | 28;
535pub const SIO_BSP_HANDLE_POLL = IOC_OUT | IOC_WS2 | 29;
536pub const SIO_BASE_HANDLE = IOC_OUT | IOC_WS2 | 34;
537pub const IPPROTO_IP = 0;
538pub const IPPORT_TCPMUX = 1;
539pub const IPPORT_ECHO = 7;
540pub const IPPORT_DISCARD = 9;
541pub const IPPORT_SYSTAT = 11;
542pub const IPPORT_DAYTIME = 13;
543pub const IPPORT_NETSTAT = 15;
544pub const IPPORT_QOTD = 17;
545pub const IPPORT_MSP = 18;
546pub const IPPORT_CHARGEN = 19;
547pub const IPPORT_FTP_DATA = 20;
548pub const IPPORT_FTP = 21;
549pub const IPPORT_TELNET = 23;
550pub const IPPORT_SMTP = 25;
551pub const IPPORT_TIMESERVER = 37;
552pub const IPPORT_NAMESERVER = 42;
553pub const IPPORT_WHOIS = 43;
554pub const IPPORT_MTP = 57;
555pub const IPPORT_TFTP = 69;
556pub const IPPORT_RJE = 77;
557pub const IPPORT_FINGER = 79;
558pub const IPPORT_TTYLINK = 87;
559pub const IPPORT_SUPDUP = 95;
560pub const IPPORT_POP3 = 110;
561pub const IPPORT_NTP = 123;
562pub const IPPORT_EPMAP = 135;
563pub const IPPORT_NETBIOS_NS = 137;
564pub const IPPORT_NETBIOS_DGM = 138;
565pub const IPPORT_NETBIOS_SSN = 139;
566pub const IPPORT_IMAP = 143;
567pub const IPPORT_SNMP = 161;
568pub const IPPORT_SNMP_TRAP = 162;
569pub const IPPORT_IMAP3 = 220;
570pub const IPPORT_LDAP = 389;
571pub const IPPORT_HTTPS = 443;
572pub const IPPORT_MICROSOFT_DS = 445;
573pub const IPPORT_EXECSERVER = 512;
574pub const IPPORT_LOGINSERVER = 513;
575pub const IPPORT_CMDSERVER = 514;
576pub const IPPORT_EFSSERVER = 520;
577pub const IPPORT_BIFFUDP = 512;
578pub const IPPORT_WHOSERVER = 513;
579pub const IPPORT_ROUTESERVER = 520;
580pub const IPPORT_RESERVED = 1024;
581pub const IPPORT_REGISTERED_MAX = 49151;
582pub const IPPORT_DYNAMIC_MIN = 49152;
583pub const IPPORT_DYNAMIC_MAX = 65535;
584pub const IN_CLASSA_NET = 4278190080;
585pub const IN_CLASSA_NSHIFT = 24;
586pub const IN_CLASSA_HOST = 16777215;
587pub const IN_CLASSA_MAX = 128;
588pub const IN_CLASSB_NET = 4294901760;
589pub const IN_CLASSB_NSHIFT = 16;
590pub const IN_CLASSB_HOST = 65535;
591pub const IN_CLASSB_MAX = 65536;
592pub const IN_CLASSC_NET = 4294967040;
593pub const IN_CLASSC_NSHIFT = 8;
594pub const IN_CLASSC_HOST = 255;
595pub const IN_CLASSD_NET = 4026531840;
596pub const IN_CLASSD_NSHIFT = 28;
597pub const IN_CLASSD_HOST = 268435455;
598pub const INADDR_LOOPBACK = 2130706433;
599pub const INADDR_NONE = 4294967295;
600pub const IOCPARM_MASK = 127;
601pub const IOC_VOID = 536870912;
602pub const IOC_OUT = 1073741824;
603pub const IOC_IN = 2147483648;
604pub const MSG_TRUNC = 256;
605pub const MSG_CTRUNC = 512;
606pub const MSG_BCAST = 1024;
607pub const MSG_MCAST = 2048;
608pub const MSG_ERRQUEUE = 4096;
609pub const AI_PASSIVE = 1;
610pub const AI_CANONNAME = 2;
611pub const AI_NUMERICHOST = 4;
612pub const AI_NUMERICSERV = 8;
613pub const AI_DNS_ONLY = 16;
614pub const AI_ALL = 256;
615pub const AI_ADDRCONFIG = 1024;
616pub const AI_V4MAPPED = 2048;
617pub const AI_NON_AUTHORITATIVE = 16384;
618pub const AI_SECURE = 32768;
619pub const AI_RETURN_PREFERRED_NAMES = 65536;
620pub const AI_FQDN = 131072;
621pub const AI_FILESERVER = 262144;
622pub const AI_DISABLE_IDN_ENCODING = 524288;
623pub const AI_EXTENDED = 2147483648;
624pub const AI_RESOLUTION_HANDLE = 1073741824;
625pub const FIONBIO = -2147195266;
626pub const ADDRINFOEX_VERSION_2 = 2;
627pub const ADDRINFOEX_VERSION_3 = 3;
628pub const ADDRINFOEX_VERSION_4 = 4;
629pub const NS_ALL = 0;
630pub const NS_SAP = 1;
631pub const NS_NDS = 2;
632pub const NS_PEER_BROWSE = 3;
633pub const NS_SLP = 5;
634pub const NS_DHCP = 6;
635pub const NS_TCPIP_LOCAL = 10;
636pub const NS_TCPIP_HOSTS = 11;
637pub const NS_DNS = 12;
638pub const NS_NETBT = 13;
639pub const NS_WINS = 14;
640pub const NS_NLA = 15;
641pub const NS_NBP = 20;
642pub const NS_MS = 30;
643pub const NS_STDA = 31;
644pub const NS_NTDS = 32;
645pub const NS_EMAIL = 37;
646pub const NS_X500 = 40;
647pub const NS_NIS = 41;
648pub const NS_NISPLUS = 42;
649pub const NS_WRQ = 50;
650pub const NS_NETDES = 60;
651pub const NI_NOFQDN = 1;
652pub const NI_NUMERICHOST = 2;
653pub const NI_NAMEREQD = 4;
654pub const NI_NUMERICSERV = 8;
655pub const NI_DGRAM = 16;
656pub const NI_MAXHOST = 1025;
657pub const NI_MAXSERV = 32;
658pub const INCL_WINSOCK_API_PROTOTYPES = 1;
659pub const INCL_WINSOCK_API_TYPEDEFS = 0;
660pub const FD_SETSIZE = 64;
661pub const IMPLINK_IP = 155;
662pub const IMPLINK_LOWEXPER = 156;
663pub const IMPLINK_HIGHEXPER = 158;
12pub const WSADESCRIPTION_LEN = 256;664pub const WSADESCRIPTION_LEN = 256;
13pub const WSASYS_STATUS_LEN = 128;665pub const WSASYS_STATUS_LEN = 128;
666pub const SOCKET_ERROR = -1;
667pub const FROM_PROTOCOL_INFO = -1;
668pub const SO_PROTOCOL_INFOA = 8196;
669pub const SO_PROTOCOL_INFOW = 8197;
670pub const PVD_CONFIG = 12289;
671pub const SOMAXCONN = 2147483647;
672pub const MSG_PEEK = 2;
673pub const MSG_WAITALL = 8;
674pub const MSG_PUSH_IMMEDIATE = 32;
675pub const MSG_PARTIAL = 32768;
676pub const MSG_INTERRUPT = 16;
677pub const MSG_MAXIOVLEN = 16;
678pub const MAXGETHOSTSTRUCT = 1024;
679pub const FD_READ_BIT = 0;
680pub const FD_WRITE_BIT = 1;
681pub const FD_OOB_BIT = 2;
682pub const FD_ACCEPT_BIT = 3;
683pub const FD_CONNECT_BIT = 4;
684pub const FD_CLOSE_BIT = 5;
685pub const FD_QOS_BIT = 6;
686pub const FD_GROUP_QOS_BIT = 7;
687pub const FD_ROUTING_INTERFACE_CHANGE_BIT = 8;
688pub const FD_ADDRESS_LIST_CHANGE_BIT = 9;
689pub const FD_MAX_EVENTS = 10;
690pub const CF_ACCEPT = 0;
691pub const CF_REJECT = 1;
692pub const CF_DEFER = 2;
693pub const SD_RECEIVE = 0;
694pub const SD_SEND = 1;
695pub const SD_BOTH = 2;
696pub const SG_UNCONSTRAINED_GROUP = 1;
697pub const SG_CONSTRAINED_GROUP = 2;
698pub const MAX_PROTOCOL_CHAIN = 7;
699pub const BASE_PROTOCOL = 1;
700pub const LAYERED_PROTOCOL = 0;
701pub const WSAPROTOCOL_LEN = 255;
702pub const PFL_MULTIPLE_PROTO_ENTRIES = 1;
703pub const PFL_RECOMMENDED_PROTO_ENTRY = 2;
704pub const PFL_HIDDEN = 4;
705pub const PFL_MATCHES_PROTOCOL_ZERO = 8;
706pub const PFL_NETWORKDIRECT_PROVIDER = 16;
707pub const XP1_CONNECTIONLESS = 1;
708pub const XP1_GUARANTEED_DELIVERY = 2;
709pub const XP1_GUARANTEED_ORDER = 4;
710pub const XP1_MESSAGE_ORIENTED = 8;
711pub const XP1_PSEUDO_STREAM = 16;
712pub const XP1_GRACEFUL_CLOSE = 32;
713pub const XP1_EXPEDITED_DATA = 64;
714pub const XP1_CONNECT_DATA = 128;
715pub const XP1_DISCONNECT_DATA = 256;
716pub const XP1_SUPPORT_BROADCAST = 512;
717pub const XP1_SUPPORT_MULTIPOINT = 1024;
718pub const XP1_MULTIPOINT_CONTROL_PLANE = 2048;
719pub const XP1_MULTIPOINT_DATA_PLANE = 4096;
720pub const XP1_QOS_SUPPORTED = 8192;
721pub const XP1_INTERRUPT = 16384;
722pub const XP1_UNI_SEND = 32768;
723pub const XP1_UNI_RECV = 65536;
724pub const XP1_IFS_HANDLES = 131072;
725pub const XP1_PARTIAL_MESSAGE = 262144;
726pub const XP1_SAN_SUPPORT_SDP = 524288;
727pub const BIGENDIAN = 0;
728pub const LITTLEENDIAN = 1;
729pub const SECURITY_PROTOCOL_NONE = 0;
730pub const JL_SENDER_ONLY = 1;
731pub const JL_RECEIVER_ONLY = 2;
732pub const JL_BOTH = 4;
733pub const WSA_FLAG_OVERLAPPED = 1;
734pub const WSA_FLAG_MULTIPOINT_C_ROOT = 2;
735pub const WSA_FLAG_MULTIPOINT_C_LEAF = 4;
736pub const WSA_FLAG_MULTIPOINT_D_ROOT = 8;
737pub const WSA_FLAG_MULTIPOINT_D_LEAF = 16;
738pub const WSA_FLAG_ACCESS_SYSTEM_SECURITY = 64;
739pub const WSA_FLAG_NO_HANDLE_INHERIT = 128;
740pub const WSA_FLAG_REGISTERED_IO = 256;
741pub const TH_NETDEV = 1;
742pub const TH_TAPI = 2;
743pub const SERVICE_MULTIPLE = 1;
744pub const NS_LOCALNAME = 19;
745pub const RES_UNUSED_1 = 1;
746pub const RES_FLUSH_CACHE = 2;
747pub const RES_SERVICE = 4;
748pub const LUP_DEEP = 1;
749pub const LUP_CONTAINERS = 2;
750pub const LUP_NOCONTAINERS = 4;
751pub const LUP_NEAREST = 8;
752pub const LUP_RETURN_NAME = 16;
753pub const LUP_RETURN_TYPE = 32;
754pub const LUP_RETURN_VERSION = 64;
755pub const LUP_RETURN_COMMENT = 128;
756pub const LUP_RETURN_ADDR = 256;
757pub const LUP_RETURN_BLOB = 512;
758pub const LUP_RETURN_ALIASES = 1024;
759pub const LUP_RETURN_QUERY_STRING = 2048;
760pub const LUP_RETURN_ALL = 4080;
761pub const LUP_RES_SERVICE = 32768;
762pub const LUP_FLUSHCACHE = 4096;
763pub const LUP_FLUSHPREVIOUS = 8192;
764pub const LUP_NON_AUTHORITATIVE = 16384;
765pub const LUP_SECURE = 32768;
766pub const LUP_RETURN_PREFERRED_NAMES = 65536;
767pub const LUP_DNS_ONLY = 131072;
768pub const LUP_ADDRCONFIG = 1048576;
769pub const LUP_DUAL_ADDR = 2097152;
770pub const LUP_FILESERVER = 4194304;
771pub const LUP_DISABLE_IDN_ENCODING = 8388608;
772pub const LUP_API_ANSI = 16777216;
773pub const LUP_RESOLUTION_HANDLE = 2147483648;
774pub const RESULT_IS_ALIAS = 1;
775pub const RESULT_IS_ADDED = 16;
776pub const RESULT_IS_CHANGED = 32;
777pub const RESULT_IS_DELETED = 64;
778pub const POLLRDNORM = 256;
779pub const POLLRDBAND = 512;
780pub const POLLPRI = 1024;
781pub const POLLWRNORM = 16;
782pub const POLLWRBAND = 32;
783pub const POLLERR = 1;
784pub const POLLHUP = 2;
785pub const POLLNVAL = 4;
786pub const SO_CONNDATA = 28672;
787pub const SO_CONNOPT = 28673;
788pub const SO_DISCDATA = 28674;
789pub const SO_DISCOPT = 28675;
790pub const SO_CONNDATALEN = 28676;
791pub const SO_CONNOPTLEN = 28677;
792pub const SO_DISCDATALEN = 28678;
793pub const SO_DISCOPTLEN = 28679;
794pub const SO_OPENTYPE = 28680;
795pub const SO_SYNCHRONOUS_ALERT = 16;
796pub const SO_SYNCHRONOUS_NONALERT = 32;
797pub const SO_MAXDG = 28681;
798pub const SO_MAXPATHDG = 28682;
799pub const SO_UPDATE_ACCEPT_CONTEXT = 28683;
800pub const SO_CONNECT_TIME = 28684;
801pub const SO_UPDATE_CONNECT_CONTEXT = 28688;
802pub const TCP_BSDURGENT = 28672;
803pub const TF_DISCONNECT = 1;
804pub const TF_REUSE_SOCKET = 2;
805pub const TF_WRITE_BEHIND = 4;
806pub const TF_USE_DEFAULT_WORKER = 0;
807pub const TF_USE_SYSTEM_THREAD = 16;
808pub const TF_USE_KERNEL_APC = 32;
809pub const TP_ELEMENT_MEMORY = 1;
810pub const TP_ELEMENT_FILE = 2;
811pub const TP_ELEMENT_EOP = 4;
812pub const NLA_ALLUSERS_NETWORK = 1;
813pub const NLA_FRIENDLY_NAME = 2;
814pub const WSPDESCRIPTION_LEN = 255;
815pub const WSS_OPERATION_IN_PROGRESS = 259;
816pub const LSP_SYSTEM = 2147483648;
817pub const LSP_INSPECTOR = 1;
818pub const LSP_REDIRECTOR = 2;
819pub const LSP_PROXY = 4;
820pub const LSP_FIREWALL = 8;
821pub const LSP_INBOUND_MODIFY = 16;
822pub const LSP_OUTBOUND_MODIFY = 32;
823pub const LSP_CRYPTO_COMPRESS = 64;
824pub const LSP_LOCAL_CACHE = 128;
825pub const IPPROTO_ICMP = 1;
826pub const IPPROTO_IGMP = 2;
827pub const IPPROTO_GGP = 3;
828pub const IPPROTO_TCP = 6;
829pub const IPPROTO_PUP = 12;
830pub const IPPROTO_UDP = 17;
831pub const IPPROTO_IDP = 22;
832pub const IPPROTO_ND = 77;
833pub const IPPROTO_RAW = 255;
834pub const IPPROTO_MAX = 256;
835pub const IP_DEFAULT_MULTICAST_TTL = 1;
836pub const IP_DEFAULT_MULTICAST_LOOP = 1;
837pub const IP_MAX_MEMBERSHIPS = 20;
838pub const AF_IPX = 6;
839pub const FD_READ = 1;
840pub const FD_WRITE = 2;
841pub const FD_OOB = 4;
842pub const FD_ACCEPT = 8;
843pub const FD_CONNECT = 16;
844pub const FD_CLOSE = 32;
845pub const SERVICE_RESOURCE = 1;
846pub const SERVICE_SERVICE = 2;
847pub const SERVICE_LOCAL = 4;
848pub const SERVICE_FLAG_DEFER = 1;
849pub const SERVICE_FLAG_HARD = 2;
850pub const PROP_COMMENT = 1;
851pub const PROP_LOCALE = 2;
852pub const PROP_DISPLAY_HINT = 4;
853pub const PROP_VERSION = 8;
854pub const PROP_START_TIME = 16;
855pub const PROP_MACHINE = 32;
856pub const PROP_ADDRESSES = 256;
857pub const PROP_SD = 512;
858pub const PROP_ALL = 2147483648;
859pub const SERVICE_ADDRESS_FLAG_RPC_CN = 1;
860pub const SERVICE_ADDRESS_FLAG_RPC_DG = 2;
861pub const SERVICE_ADDRESS_FLAG_RPC_NB = 4;
862pub const NS_DEFAULT = 0;
863pub const NS_VNS = 50;
864pub const NSTYPE_HIERARCHICAL = 1;
865pub const NSTYPE_DYNAMIC = 2;
866pub const NSTYPE_ENUMERABLE = 4;
867pub const NSTYPE_WORKGROUP = 8;
868pub const XP_CONNECTIONLESS = 1;
869pub const XP_GUARANTEED_DELIVERY = 2;
870pub const XP_GUARANTEED_ORDER = 4;
871pub const XP_MESSAGE_ORIENTED = 8;
872pub const XP_PSEUDO_STREAM = 16;
873pub const XP_GRACEFUL_CLOSE = 32;
874pub const XP_EXPEDITED_DATA = 64;
875pub const XP_CONNECT_DATA = 128;
876pub const XP_DISCONNECT_DATA = 256;
877pub const XP_SUPPORTS_BROADCAST = 512;
878pub const XP_SUPPORTS_MULTICAST = 1024;
879pub const XP_BANDWIDTH_ALLOCATION = 2048;
880pub const XP_FRAGMENTATION = 4096;
881pub const XP_ENCRYPTS = 8192;
882pub const RES_SOFT_SEARCH = 1;
883pub const RES_FIND_MULTIPLE = 2;
884pub const SET_SERVICE_PARTIAL_SUCCESS = 1;
885pub const UDP_NOCHECKSUM = 1;
886pub const UDP_CHECKSUM_COVERAGE = 20;
887pub const GAI_STRERROR_BUFFER_SIZE = 1024;
888
889pub const LPCONDITIONPROC = fn (
890 lpCallerId: *WSABUF,
891 lpCallerData: *WSABUF,
892 lpSQOS: *QOS,
893 lpGQOS: *QOS,
894 lpCalleeId: *WSABUF,
895 lpCalleeData: *WSABUF,
896 g: *u32,
897 dwCallbackData: usize,
898) callconv(WINAPI) i32;
899
900pub const LPWSAOVERLAPPED_COMPLETION_ROUTINE = fn (
901 dwError: u32,
902 cbTransferred: u32,
903 lpOverlapped: *OVERLAPPED,
904 dwFlags: u32,
905) callconv(WINAPI) void;
906
907pub const FLOWSPEC = extern struct {
908 TokenRate: u32,
909 TokenBucketSize: u32,
910 PeakBandwidth: u32,
911 Latency: u32,
912 DelayVariation: u32,
913 ServiceType: u32,
914 MaxSduSize: u32,
915 MinimumPolicedSize: u32,
916};
917
918pub const QOS = extern struct {
919 SendingFlowspec: FLOWSPEC,
920 ReceivingFlowspec: FLOWSPEC,
921 ProviderSpecific: WSABUF,
922};
923
924pub const SOCKET_ADDRESS = extern struct {
925 lpSockaddr: *sockaddr,
926 iSockaddrLength: i32,
927};
928
929pub const SOCKET_ADDRESS_LIST = extern struct {
930 iAddressCount: i32,
931 Address: [1]SOCKET_ADDRESS,
932};
14933
15pub const WSADATA = if (@sizeOf(usize) == @sizeOf(u64))934pub const WSADATA = if (@sizeOf(usize) == @sizeOf(u64))
16 extern struct {935 extern struct {
...@@ -33,15 +952,11 @@ else...@@ -33,15 +952,11 @@ else
33 lpVendorInfo: *u8,952 lpVendorInfo: *u8,
34 };953 };
35954
36pub const MAX_PROTOCOL_CHAIN = 7;
37
38pub const WSAPROTOCOLCHAIN = extern struct {955pub const WSAPROTOCOLCHAIN = extern struct {
39 ChainLen: c_int,956 ChainLen: c_int,
40 ChainEntries: [MAX_PROTOCOL_CHAIN]DWORD,957 ChainEntries: [MAX_PROTOCOL_CHAIN]DWORD,
41};958};
42959
43pub const WSAPROTOCOL_LEN = 255;
44
45pub const WSAPROTOCOL_INFOA = extern struct {960pub const WSAPROTOCOL_INFOA = extern struct {
46 dwServiceFlags1: DWORD,961 dwServiceFlags1: DWORD,
47 dwServiceFlags2: DWORD,962 dwServiceFlags2: DWORD,
...@@ -88,20 +1003,20 @@ pub const WSAPROTOCOL_INFOW = extern struct {...@@ -88,20 +1003,20 @@ pub const WSAPROTOCOL_INFOW = extern struct {
88 szProtocol: [WSAPROTOCOL_LEN + 1]WCHAR,1003 szProtocol: [WSAPROTOCOL_LEN + 1]WCHAR,
89};1004};
901005
91pub const GROUP = u32;1006pub const sockproto = extern struct {
921007 sp_family: u16,
93pub const SG_UNCONSTRAINED_GROUP = 0x1;1008 sp_protocol: u16,
94pub const SG_CONSTRAINED_GROUP = 0x2;1009};
951010
96pub const WSA_FLAG_OVERLAPPED = 0x01;1011pub const linger = extern struct {
97pub const WSA_FLAG_MULTIPOINT_C_ROOT = 0x02;1012 l_onoff: u16,
98pub const WSA_FLAG_MULTIPOINT_C_LEAF = 0x04;1013 l_linger: u16,
99pub const WSA_FLAG_MULTIPOINT_D_ROOT = 0x08;1014};
100pub const WSA_FLAG_MULTIPOINT_D_LEAF = 0x10;
101pub const WSA_FLAG_ACCESS_SYSTEM_SECURITY = 0x40;
102pub const WSA_FLAG_NO_HANDLE_INHERIT = 0x80;
1031015
104pub const WSAEVENT = HANDLE;1016pub const WSANETWORKEVENTS = extern struct {
1017 lNetworkEvents: i32,
1018 iErrorCode: [10]i32,
1019};
1051020
106pub const WSAOVERLAPPED = extern struct {1021pub const WSAOVERLAPPED = extern struct {
107 Internal: DWORD,1022 Internal: DWORD,
...@@ -111,82 +1026,9 @@ pub const WSAOVERLAPPED = extern struct {...@@ -111,82 +1026,9 @@ pub const WSAOVERLAPPED = extern struct {
111 hEvent: ?WSAEVENT,1026 hEvent: ?WSAEVENT,
112};1027};
1131028
114pub const WSAOVERLAPPED_COMPLETION_ROUTINE = fn (dwError: DWORD, cbTransferred: DWORD, lpOverlapped: *WSAOVERLAPPED, dwFlags: DWORD) callconv(.C) void;1029pub const addrinfo = addrinfoa;
115
116pub const ADDRESS_FAMILY = u16;
117
118// Microsoft use the signed c_int for this, but it should never be negative
119pub const socklen_t = u32;
1201030
121pub const AF_UNSPEC = 0;1031pub const addrinfoa = extern struct {
122pub const AF_UNIX = 1;
123pub const AF_INET = 2;
124pub const AF_IMPLINK = 3;
125pub const AF_PUP = 4;
126pub const AF_CHAOS = 5;
127pub const AF_NS = 6;
128pub const AF_IPX = AF_NS;
129pub const AF_ISO = 7;
130pub const AF_OSI = AF_ISO;
131pub const AF_ECMA = 8;
132pub const AF_DATAKIT = 9;
133pub const AF_CCITT = 10;
134pub const AF_SNA = 11;
135pub const AF_DECnet = 12;
136pub const AF_DLI = 13;
137pub const AF_LAT = 14;
138pub const AF_HYLINK = 15;
139pub const AF_APPLETALK = 16;
140pub const AF_NETBIOS = 17;
141pub const AF_VOICEVIEW = 18;
142pub const AF_FIREFOX = 19;
143pub const AF_UNKNOWN1 = 20;
144pub const AF_BAN = 21;
145pub const AF_ATM = 22;
146pub const AF_INET6 = 23;
147pub const AF_CLUSTER = 24;
148pub const AF_12844 = 25;
149pub const AF_IRDA = 26;
150pub const AF_NETDES = 28;
151pub const AF_TCNPROCESS = 29;
152pub const AF_TCNMESSAGE = 30;
153pub const AF_ICLFXBM = 31;
154pub const AF_BTH = 32;
155pub const AF_MAX = 33;
156
157pub const SOCK_STREAM = 1;
158pub const SOCK_DGRAM = 2;
159pub const SOCK_RAW = 3;
160pub const SOCK_RDM = 4;
161pub const SOCK_SEQPACKET = 5;
162
163pub const IPPROTO_ICMP = 1;
164pub const IPPROTO_IGMP = 2;
165pub const BTHPROTO_RFCOMM = 3;
166pub const IPPROTO_TCP = 6;
167pub const IPPROTO_UDP = 17;
168pub const IPPROTO_ICMPV6 = 58;
169pub const IPPROTO_RM = 113;
170
171pub const AI_PASSIVE = 0x00001;
172pub const AI_CANONNAME = 0x00002;
173pub const AI_NUMERICHOST = 0x00004;
174pub const AI_NUMERICSERV = 0x00008;
175pub const AI_ADDRCONFIG = 0x00400;
176pub const AI_V4MAPPED = 0x00800;
177pub const AI_NON_AUTHORITATIVE = 0x04000;
178pub const AI_SECURE = 0x08000;
179pub const AI_RETURN_PREFERRED_NAMES = 0x10000;
180pub const AI_DISABLE_IDN_ENCODING = 0x80000;
181
182pub const FIONBIO = -2147195266;
183
184pub const sockaddr = extern struct {
185 family: ADDRESS_FAMILY,
186 data: [14]u8,
187};
188
189pub const addrinfo = extern struct {
190 flags: i32,1032 flags: i32,
191 family: i32,1033 family: i32,
192 socktype: i32,1034 socktype: i32,
...@@ -197,6 +1039,32 @@ pub const addrinfo = extern struct {...@@ -197,6 +1039,32 @@ pub const addrinfo = extern struct {
197 next: ?*addrinfo,1039 next: ?*addrinfo,
198};1040};
1991041
1042pub const addrinfoexA = extern struct {
1043 ai_flags: i32,
1044 ai_family: i32,
1045 ai_socktype: i32,
1046 ai_protocol: i32,
1047 ai_addrlen: usize,
1048 ai_canonname: [*:0]u8,
1049 ai_addr: *sockaddr,
1050 ai_blob: *c_void,
1051 ai_bloblen: usize,
1052 ai_provider: *GUID,
1053 ai_next: *addrinfoexA,
1054};
1055
1056pub const sockaddr = extern struct {
1057 family: ADDRESS_FAMILY,
1058 data: [14]u8,
1059};
1060
1061pub const sockaddr_storage = extern struct {
1062 family: ADDRESS_FAMILY,
1063 __pad1: [6]u8,
1064 __align: i64,
1065 __pad2: [112]u8,
1066};
1067
200/// IPv4 socket address1068/// IPv4 socket address
201pub const sockaddr_in = extern struct {1069pub const sockaddr_in = extern struct {
202 family: ADDRESS_FAMILY = AF_INET,1070 family: ADDRESS_FAMILY = AF_INET,
...@@ -225,7 +1093,10 @@ pub const WSABUF = extern struct {...@@ -225,7 +1093,10 @@ pub const WSABUF = extern struct {
225 buf: [*]u8,1093 buf: [*]u8,
226};1094};
2271095
228pub const WSAMSG = extern struct {1096pub const msghdr = WSAMSG;
1097pub const msghdr_const = WSAMSG_const;
1098
1099pub const WSAMSG_const = extern struct {
229 name: *const sockaddr,1100 name: *const sockaddr,
230 namelen: INT,1101 namelen: INT,
231 lpBuffers: [*]WSABUF,1102 lpBuffers: [*]WSABUF,
...@@ -234,26 +1105,108 @@ pub const WSAMSG = extern struct {...@@ -234,26 +1105,108 @@ pub const WSAMSG = extern struct {
234 dwFlags: DWORD,1105 dwFlags: DWORD,
235};1106};
2361107
1108pub const WSAMSG = extern struct {
1109 name: *sockaddr,
1110 namelen: INT,
1111 lpBuffers: [*]WSABUF,
1112 dwBufferCount: DWORD,
1113 Control: WSABUF,
1114 dwFlags: DWORD,
1115};
1116
1117pub const WSAPOLLFD = pollfd;
1118
237pub const pollfd = extern struct {1119pub const pollfd = extern struct {
238 fd: SOCKET,1120 fd: SOCKET,
239 events: SHORT,1121 events: SHORT,
240 revents: SHORT,1122 revents: SHORT,
241};1123};
2421124
243// Event flag definitions for WSAPoll().1125pub const TRANSMIT_FILE_BUFFERS = extern struct {
1126 Head: *c_void,
1127 HeadLength: u32,
1128 Tail: *c_void,
1129 TailLength: u32,
1130};
1131
1132pub const LPFN_TRANSMITFILE = fn (
1133 hSocket: SOCKET,
1134 hFile: HANDLE,
1135 nNumberOfBytesToWrite: u32,
1136 nNumberOfBytesPerSend: u32,
1137 lpOverlapped: ?*OVERLAPPED,
1138 lpTransmitBuffers: ?*TRANSMIT_FILE_BUFFERS,
1139 dwReserved: u32,
1140) callconv(WINAPI) BOOL;
1141
1142pub const LPFN_ACCEPTEX = fn (
1143 sListenSocket: SOCKET,
1144 sAcceptSocket: SOCKET,
1145 lpOutputBuffer: *c_void,
1146 dwReceiveDataLength: u32,
1147 dwLocalAddressLength: u32,
1148 dwRemoteAddressLength: u32,
1149 lpdwBytesReceived: *u32,
1150 lpOverlapped: *OVERLAPPED,
1151) callconv(WINAPI) BOOL;
1152
1153pub const LPFN_GETACCEPTEXSOCKADDRS = fn (
1154 lpOutputBuffer: *c_void,
1155 dwReceiveDataLength: u32,
1156 dwLocalAddressLength: u32,
1157 dwRemoteAddressLength: u32,
1158 LocalSockaddr: **sockaddr,
1159 LocalSockaddrLength: *i32,
1160 RemoteSockaddr: **sockaddr,
1161 RemoteSockaddrLength: *i32,
1162) callconv(WINAPI) void;
1163
1164pub const LPFN_WSASENDMSG = fn (
1165 s: SOCKET,
1166 lpMsg: *const WSAMSG_const,
1167 dwFlags: u32,
1168 lpNumberOfBytesSent: ?*u32,
1169 lpOverlapped: ?*OVERLAPPED,
1170 lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
1171) callconv(WINAPI) i32;
2441172
245pub const POLLRDNORM = 0x0100;1173pub const LPFN_WSARECVMSG = fn (
246pub const POLLRDBAND = 0x0200;1174 s: SOCKET,
247pub const POLLIN = (POLLRDNORM | POLLRDBAND);1175 lpMsg: *WSAMSG,
248pub const POLLPRI = 0x0400;1176 lpdwNumberOfBytesRecv: ?*u32,
1177 lpOverlapped: ?*OVERLAPPED,
1178 lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
1179) callconv(WINAPI) i32;
2491180
250pub const POLLWRNORM = 0x0010;1181pub const LPSERVICE_CALLBACK_PROC = fn (
251pub const POLLOUT = (POLLWRNORM);1182 lParam: LPARAM,
252pub const POLLWRBAND = 0x0020;1183 hAsyncTaskHandle: HANDLE,
1184) callconv(WINAPI) void;
2531185
254pub const POLLERR = 0x0001;1186pub const SERVICE_ASYNC_INFO = extern struct {
255pub const POLLHUP = 0x0002;1187 lpServiceCallbackProc: LPSERVICE_CALLBACK_PROC,
256pub const POLLNVAL = 0x0004;1188 lParam: LPARAM,
1189 hAsyncTaskHandle: HANDLE,
1190};
1191
1192pub const LPLOOKUPSERVICE_COMPLETION_ROUTINE = fn (
1193 dwError: u32,
1194 dwBytes: u32,
1195 lpOverlapped: *OVERLAPPED,
1196) callconv(WINAPI) void;
1197
1198pub const fd_set = extern struct {
1199 fd_count: u32,
1200 fd_array: [64]SOCKET,
1201};
1202
1203pub const hostent = extern struct {
1204 h_name: [*]u8,
1205 h_aliases: **i8,
1206 h_addrtype: i16,
1207 h_length: i16,
1208 h_addr_list: **i8,
1209};
2571210
258// https://docs.microsoft.com/en-au/windows/win32/winsock/windows-sockets-error-codes-21211// https://docs.microsoft.com/en-au/windows/win32/winsock/windows-sockets-error-codes-2
259pub const WinsockError = extern enum(u16) {1212pub const WinsockError = extern enum(u16) {
...@@ -704,180 +1657,649 @@ pub const WinsockError = extern enum(u16) {...@@ -704,180 +1657,649 @@ pub const WinsockError = extern enum(u16) {
704 _,1657 _,
705};1658};
7061659
707/// no parameters1660pub extern "ws2_32" fn accept(
708const IOC_VOID = 0x80000000;1661 s: SOCKET,
1662 addr: ?*sockaddr,
1663 addrlen: ?*i32,
1664) callconv(WINAPI) SOCKET;
7091665
710/// copy out parameters1666pub extern "ws2_32" fn bind(
711const IOC_OUT = 0x40000000;1667 s: SOCKET,
1668 name: *const sockaddr,
1669 namelen: i32,
1670) callconv(WINAPI) i32;
7121671
713/// copy in parameters1672pub extern "ws2_32" fn closesocket(
714const IOC_IN = 0x80000000;1673 s: SOCKET,
1674) callconv(WINAPI) i32;
7151675
716/// The IOCTL is a generic Windows Sockets 2 IOCTL code. New IOCTL codes defined for Windows Sockets 2 will have T == 1.1676pub extern "ws2_32" fn connect(
717const IOC_WS2 = 0x08000000;1677 s: SOCKET,
1678 name: *const sockaddr,
1679 namelen: i32,
1680) callconv(WINAPI) i32;
7181681
719pub const SIO_BASE_HANDLE = IOC_OUT | IOC_WS2 | 34;1682pub extern "ws2_32" fn ioctlsocket(
1683 s: SOCKET,
1684 cmd: i32,
1685 argp: *u32,
1686) callconv(WINAPI) i32;
1687
1688pub extern "ws2_32" fn getpeername(
1689 s: SOCKET,
1690 name: *sockaddr,
1691 namelen: *i32,
1692) callconv(WINAPI) i32;
7201693
721pub const SOL_SOCKET = 0xffff;1694pub extern "ws2_32" fn getsockname(
7221695 s: SOCKET,
723pub const SO_DEBUG = 0x0001;1696 name: *sockaddr,
724pub const SO_ACCEPTCONN = 0x0002;1697 namelen: *i32,
725pub const SO_REUSEADDR = 0x0004;1698) callconv(WINAPI) i32;
726pub const SO_KEEPALIVE = 0x0008;1699
727pub const SO_DONTROUTE = 0x0010;1700pub extern "ws2_32" fn getsockopt(
728pub const SO_BROADCAST = 0x0020;1701 s: SOCKET,
729pub const SO_USELOOPBACK = 0x0040;1702 level: i32,
730pub const SO_LINGER = 0x0080;1703 optname: i32,
731pub const SO_OOBINLINE = 0x0100;1704 optval: [*]u8,
7321705 optlen: *i32,
733pub const SO_DONTLINGER = ~@as(u32, SO_LINGER);1706) callconv(WINAPI) i32;
734pub const SO_EXCLUSIVEADDRUSE = ~@as(u32, SO_REUSEADDR);1707
7351708pub extern "ws2_32" fn htonl(
736pub const SO_SNDBUF = 0x1001;1709 hostlong: u32,
737pub const SO_RCVBUF = 0x1002;1710) callconv(WINAPI) u32;
738pub const SO_SNDLOWAT = 0x1003;1711
739pub const SO_RCVLOWAT = 0x1004;1712pub extern "ws2_32" fn htons(
740pub const SO_SNDTIMEO = 0x1005;1713 hostshort: u16,
741pub const SO_RCVTIMEO = 0x1006;1714) callconv(WINAPI) u16;
742pub const SO_ERROR = 0x1007;1715
743pub const SO_TYPE = 0x1008;1716pub extern "ws2_32" fn inet_addr(
7441717 cp: ?[*]const u8,
745pub const SO_GROUP_ID = 0x2001;1718) callconv(WINAPI) u32;
746pub const SO_GROUP_PRIORITY = 0x2002;1719
747pub const SO_MAX_MSG_SIZE = 0x2003;1720pub extern "ws2_32" fn listen(
748pub const SO_PROTOCOL_INFOA = 0x2004;1721 s: SOCKET,
749pub const SO_PROTOCOL_INFOW = 0x2005;1722 backlog: i32,
7501723) callconv(WINAPI) i32;
751pub const PVD_CONFIG = 0x3001;1724
752pub const SO_CONDITIONAL_ACCEPT = 0x3002;1725pub extern "ws2_32" fn ntohl(
7531726 netlong: u32,
754pub const TCP_NODELAY = 0x0001;1727) callconv(WINAPI) u32;
1728
1729pub extern "ws2_32" fn ntohs(
1730 netshort: u16,
1731) callconv(WINAPI) u16;
1732
1733pub extern "ws2_32" fn recv(
1734 s: SOCKET,
1735 buf: [*]u8,
1736 len: i32,
1737 flags: i32,
1738) callconv(WINAPI) i32;
1739
1740pub extern "ws2_32" fn recvfrom(
1741 s: SOCKET,
1742 buf: [*]u8,
1743 len: i32,
1744 flags: i32,
1745 from: ?*sockaddr,
1746 fromlen: ?*i32,
1747) callconv(WINAPI) i32;
1748
1749pub extern "ws2_32" fn select(
1750 nfds: i32,
1751 readfds: ?*fd_set,
1752 writefds: ?*fd_set,
1753 exceptfds: ?*fd_set,
1754 timeout: ?*const timeval,
1755) callconv(WINAPI) i32;
1756
1757pub extern "ws2_32" fn send(
1758 s: SOCKET,
1759 buf: [*]const u8,
1760 len: i32,
1761 flags: u32,
1762) callconv(WINAPI) i32;
1763
1764pub extern "ws2_32" fn sendto(
1765 s: SOCKET,
1766 buf: [*]const u8,
1767 len: i32,
1768 flags: i32,
1769 to: *const sockaddr,
1770 tolen: i32,
1771) callconv(WINAPI) i32;
1772
1773pub extern "ws2_32" fn setsockopt(
1774 s: SOCKET,
1775 level: i32,
1776 optname: i32,
1777 optval: ?[*]const u8,
1778 optlen: i32,
1779) callconv(WINAPI) i32;
1780
1781pub extern "ws2_32" fn shutdown(
1782 s: SOCKET,
1783 how: i32,
1784) callconv(WINAPI) i32;
1785
1786pub extern "ws2_32" fn socket(
1787 af: i32,
1788 @"type": i32,
1789 protocol: i32,
1790) callconv(WINAPI) SOCKET;
7551791
756pub extern "ws2_32" fn WSAStartup(1792pub extern "ws2_32" fn WSAStartup(
757 wVersionRequired: WORD,1793 wVersionRequired: WORD,
758 lpWSAData: *WSADATA,1794 lpWSAData: *WSADATA,
759) callconv(WINAPI) c_int;1795) callconv(WINAPI) i32;
760pub extern "ws2_32" fn WSACleanup() callconv(WINAPI) c_int;1796
1797pub extern "ws2_32" fn WSACleanup() callconv(WINAPI) i32;
1798
1799pub extern "ws2_32" fn WSASetLastError(iError: i32) callconv(WINAPI) void;
1800
761pub extern "ws2_32" fn WSAGetLastError() callconv(WINAPI) WinsockError;1801pub extern "ws2_32" fn WSAGetLastError() callconv(WINAPI) WinsockError;
762pub extern "ws2_32" fn WSASocketA(1802
763 af: c_int,1803pub extern "ws2_32" fn WSAIsBlocking() callconv(WINAPI) BOOL;
764 type: c_int,1804
765 protocol: c_int,1805pub extern "ws2_32" fn WSAUnhookBlockingHook() callconv(WINAPI) i32;
766 lpProtocolInfo: ?*WSAPROTOCOL_INFOA,1806
767 g: GROUP,1807pub extern "ws2_32" fn WSASetBlockingHook(lpBlockFunc: FARPROC) callconv(WINAPI) FARPROC;
768 dwFlags: DWORD,1808
769) callconv(WINAPI) SOCKET;1809pub extern "ws2_32" fn WSACancelBlockingCall() callconv(WINAPI) i32;
770pub extern "ws2_32" fn WSASocketW(1810
771 af: c_int,1811pub extern "ws2_32" fn WSAAsyncGetServByName(
772 type: c_int,1812 hWnd: HWND,
773 protocol: c_int,1813 wMsg: u32,
774 lpProtocolInfo: ?*WSAPROTOCOL_INFOW,1814 name: [*:0]const u8,
775 g: GROUP,1815 proto: ?[*:0]const u8,
776 dwFlags: DWORD,1816 buf: [*]u8,
777) callconv(WINAPI) SOCKET;1817 buflen: i32,
778pub extern "ws2_32" fn closesocket(s: SOCKET) callconv(WINAPI) c_int;1818) callconv(WINAPI) HANDLE;
779pub extern "ws2_32" fn WSAIoctl(1819
1820pub extern "ws2_32" fn WSAAsyncGetServByPort(
1821 hWnd: HWND,
1822 wMsg: u32,
1823 port: i32,
1824 proto: ?[*:0]const u8,
1825 buf: [*]u8,
1826 buflen: i32,
1827) callconv(WINAPI) HANDLE;
1828
1829pub extern "ws2_32" fn WSAAsyncGetProtoByName(
1830 hWnd: HWND,
1831 wMsg: u32,
1832 name: [*:0]const u8,
1833 buf: [*]u8,
1834 buflen: i32,
1835) callconv(WINAPI) HANDLE;
1836
1837pub extern "ws2_32" fn WSAAsyncGetProtoByNumber(
1838 hWnd: HWND,
1839 wMsg: u32,
1840 number: i32,
1841 buf: [*]u8,
1842 buflen: i32,
1843) callconv(WINAPI) HANDLE;
1844
1845pub extern "ws2_32" fn WSACancelAsyncRequest(hAsyncTaskHandle: HANDLE) callconv(WINAPI) i32;
1846
1847pub extern "ws2_32" fn WSAAsyncSelect(
780 s: SOCKET,1848 s: SOCKET,
781 dwIoControlCode: DWORD,1849 hWnd: HWND,
782 lpvInBuffer: ?*const c_void,1850 wMsg: u32,
783 cbInBuffer: DWORD,1851 lEvent: i32,
784 lpvOutBuffer: ?LPVOID,1852) callconv(WINAPI) i32;
785 cbOutBuffer: DWORD,1853
786 lpcbBytesReturned: LPDWORD,1854pub extern "ws2_32" fn WSAAccept(
787 lpOverlapped: ?*WSAOVERLAPPED,
788 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
789) callconv(WINAPI) c_int;
790pub extern "ws2_32" fn accept(
791 s: SOCKET,1855 s: SOCKET,
792 addr: ?*sockaddr,1856 addr: ?*sockaddr,
793 addrlen: ?*c_int,1857 addrlen: ?*i32,
1858 lpfnCondition: ?LPCONDITIONPROC,
1859 dwCallbackData: usize,
794) callconv(WINAPI) SOCKET;1860) callconv(WINAPI) SOCKET;
795pub extern "ws2_32" fn bind(1861
1862pub extern "ws2_32" fn WSACloseEvent(hEvent: HANDLE) callconv(WINAPI) BOOL;
1863
1864pub extern "ws2_32" fn WSAConnect(
796 s: SOCKET,1865 s: SOCKET,
797 addr: ?*const sockaddr,1866 name: *const sockaddr,
798 addrlen: c_int,1867 namelen: i32,
799) callconv(WINAPI) c_int;1868 lpCallerData: ?*WSABUF,
800pub extern "ws2_32" fn connect(1869 lpCalleeData: ?*WSABUF,
1870 lpSQOS: ?*QOS,
1871 lpGQOS: ?*QOS,
1872) callconv(WINAPI) i32;
1873
1874pub extern "ws2_32" fn WSAConnectByNameW(
1875 s: SOCKET,
1876 nodename: [*:0]const u16,
1877 servicename: [*:0]const u16,
1878 LocalAddressLength: ?*u32,
1879 LocalAddress: ?*sockaddr,
1880 RemoteAddressLength: ?*u32,
1881 RemoteAddress: ?*sockaddr,
1882 timeout: ?*const timeval,
1883 Reserved: *OVERLAPPED,
1884) callconv(WINAPI) BOOL;
1885
1886pub extern "ws2_32" fn WSAConnectByNameA(
1887 s: SOCKET,
1888 nodename: [*:0]const u8,
1889 servicename: [*:0]const u8,
1890 LocalAddressLength: ?*u32,
1891 LocalAddress: ?*sockaddr,
1892 RemoteAddressLength: ?*u32,
1893 RemoteAddress: ?*sockaddr,
1894 timeout: ?*const timeval,
1895 Reserved: *OVERLAPPED,
1896) callconv(WINAPI) BOOL;
1897
1898pub extern "ws2_32" fn WSAConnectByList(
1899 s: SOCKET,
1900 SocketAddress: *SOCKET_ADDRESS_LIST,
1901 LocalAddressLength: ?*u32,
1902 LocalAddress: ?*sockaddr,
1903 RemoteAddressLength: ?*u32,
1904 RemoteAddress: ?*sockaddr,
1905 timeout: ?*const timeval,
1906 Reserved: *OVERLAPPED,
1907) callconv(WINAPI) BOOL;
1908
1909pub extern "ws2_32" fn WSACreateEvent() callconv(WINAPI) HANDLE;
1910
1911pub extern "ws2_32" fn WSADuplicateSocketA(
1912 s: SOCKET,
1913 dwProcessId: u32,
1914 lpProtocolInfo: *WSAPROTOCOL_INFOA,
1915) callconv(WINAPI) i32;
1916
1917pub extern "ws2_32" fn WSADuplicateSocketW(
1918 s: SOCKET,
1919 dwProcessId: u32,
1920 lpProtocolInfo: *WSAPROTOCOL_INFOW,
1921) callconv(WINAPI) i32;
1922
1923pub extern "ws2_32" fn WSAEnumNetworkEvents(
1924 s: SOCKET,
1925 hEventObject: HANDLE,
1926 lpNetworkEvents: *WSANETWORKEVENTS,
1927) callconv(WINAPI) i32;
1928
1929pub extern "ws2_32" fn WSAEnumProtocolsA(
1930 lpiProtocols: ?*i32,
1931 lpProtocolBuffer: ?*WSAPROTOCOL_INFOA,
1932 lpdwBufferLength: *u32,
1933) callconv(WINAPI) i32;
1934
1935pub extern "ws2_32" fn WSAEnumProtocolsW(
1936 lpiProtocols: ?*i32,
1937 lpProtocolBuffer: ?*WSAPROTOCOL_INFOW,
1938 lpdwBufferLength: *u32,
1939) callconv(WINAPI) i32;
1940
1941pub extern "ws2_32" fn WSAEventSelect(
1942 s: SOCKET,
1943 hEventObject: HANDLE,
1944 lNetworkEvents: i32,
1945) callconv(WINAPI) i32;
1946
1947pub extern "ws2_32" fn WSAGetOverlappedResult(
1948 s: SOCKET,
1949 lpOverlapped: *OVERLAPPED,
1950 lpcbTransfer: *u32,
1951 fWait: BOOL,
1952 lpdwFlags: *u32,
1953) callconv(WINAPI) BOOL;
1954
1955pub extern "ws2_32" fn WSAGetQOSByName(
1956 s: SOCKET,
1957 lpQOSName: *WSABUF,
1958 lpQOS: *QOS,
1959) callconv(WINAPI) BOOL;
1960
1961pub extern "ws2_32" fn WSAHtonl(
1962 s: SOCKET,
1963 hostlong: u32,
1964 lpnetlong: *u32,
1965) callconv(WINAPI) i32;
1966
1967pub extern "ws2_32" fn WSAHtons(
1968 s: SOCKET,
1969 hostshort: u16,
1970 lpnetshort: *u16,
1971) callconv(WINAPI) i32;
1972
1973pub extern "ws2_32" fn WSAIoctl(
1974 s: SOCKET,
1975 dwIoControlCode: u32,
1976 lpvInBuffer: ?*const c_void,
1977 cbInBuffer: u32,
1978 lpvOutbuffer: ?*c_void,
1979 cbOutbuffer: u32,
1980 lpcbBytesReturned: *u32,
1981 lpOverlapped: ?*OVERLAPPED,
1982 lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
1983) callconv(WINAPI) i32;
1984
1985pub extern "ws2_32" fn WSAJoinLeaf(
801 s: SOCKET,1986 s: SOCKET,
802 name: *const sockaddr,1987 name: *const sockaddr,
803 namelen: c_int,1988 namelen: i32,
804) callconv(WINAPI) c_int;1989 lpCallerdata: ?*WSABUF,
805pub extern "ws2_32" fn listen(1990 lpCalleeData: ?*WSABUF,
1991 lpSQOS: ?*QOS,
1992 lpGQOS: ?*QOS,
1993 dwFlags: u32,
1994) callconv(WINAPI) SOCKET;
1995
1996pub extern "ws2_32" fn WSANtohl(
1997 s: SOCKET,
1998 netlong: u32,
1999 lphostlong: *u32,
2000) callconv(WINAPI) u32;
2001
2002pub extern "ws2_32" fn WSANtohs(
806 s: SOCKET,2003 s: SOCKET,
807 backlog: c_int,2004 netshort: u16,
808) callconv(WINAPI) c_int;2005 lphostshort: *u16,
2006) callconv(WINAPI) i32;
2007
809pub extern "ws2_32" fn WSARecv(2008pub extern "ws2_32" fn WSARecv(
810 s: SOCKET,2009 s: SOCKET,
811 lpBuffers: [*]const WSABUF,2010 lpBuffers: [*]WSABUF,
812 dwBufferCount: DWORD,2011 dwBufferCouynt: u32,
813 lpNumberOfBytesRecvd: ?*DWORD,2012 lpNumberOfBytesRecv: ?*u32,
814 lpFlags: *DWORD,2013 lpFlags: *u32,
815 lpOverlapped: ?*WSAOVERLAPPED,2014 lpOverlapped: ?*OVERLAPPED,
816 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,2015 lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
817) callconv(WINAPI) c_int;2016) callconv(WINAPI) i32;
2017
2018pub extern "ws2_32" fn WSARecvDisconnect(
2019 s: SOCKET,
2020 lpInboundDisconnectData: ?*WSABUF,
2021) callconv(WINAPI) i32;
2022
818pub extern "ws2_32" fn WSARecvFrom(2023pub extern "ws2_32" fn WSARecvFrom(
819 s: SOCKET,2024 s: SOCKET,
820 lpBuffers: [*]const WSABUF,2025 lpBuffers: [*]WSABUF,
821 dwBufferCount: DWORD,2026 dwBuffercount: u32,
822 lpNumberOfBytesRecvd: ?*DWORD,2027 lpNumberOfBytesRecvd: ?*u32,
823 lpFlags: *DWORD,2028 lpFlags: *u32,
824 lpFrom: ?*sockaddr,2029 lpFrom: ?*sockaddr,
825 lpFromlen: ?*socklen_t,2030 lpFromlen: ?*i32,
826 lpOverlapped: ?*WSAOVERLAPPED,2031 lpOverlapped: ?*OVERLAPPED,
827 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,2032 lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
828) callconv(WINAPI) c_int;2033) callconv(WINAPI) i32;
2034
2035pub extern "ws2_32" fn WSAResetEvent(hEvent: HANDLE) callconv(WINAPI) i32;
2036
829pub extern "ws2_32" fn WSASend(2037pub extern "ws2_32" fn WSASend(
830 s: SOCKET,2038 s: SOCKET,
831 lpBuffers: [*]WSABUF,2039 lpBuffers: [*]WSABUF,
832 dwBufferCount: DWORD,2040 dwBufferCount: u32,
833 lpNumberOfBytesSent: ?*DWORD,2041 lpNumberOfBytesSent: ?*u32,
834 dwFlags: DWORD,2042 dwFlags: u32,
835 lpOverlapped: ?*WSAOVERLAPPED,2043 lpOverlapped: ?*OVERLAPPED,
836 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,2044 lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
837) callconv(WINAPI) c_int;2045) callconv(WINAPI) i32;
2046
2047pub extern "ws2_32" fn WSASendMsg(
2048 s: SOCKET,
2049 lpMsg: *const WSAMSG_const,
2050 dwFlags: u32,
2051 lpNumberOfBytesSent: ?*u32,
2052 lpOverlapped: ?*OVERLAPPED,
2053 lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
2054) callconv(WINAPI) i32;
2055
2056pub extern "ws2_32" fn WSARecvMsg(
2057 s: SOCKET,
2058 lpMsg: *WSAMSG,
2059 lpdwNumberOfBytesRecv: ?*u32,
2060 lpOverlapped: ?*OVERLAPPED,
2061 lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
2062) callconv(WINAPI) i32;
2063
2064pub extern "ws2_32" fn WSASendDisconnect(
2065 s: SOCKET,
2066 lpOutboundDisconnectData: ?*WSABUF,
2067) callconv(WINAPI) i32;
2068
838pub extern "ws2_32" fn WSASendTo(2069pub extern "ws2_32" fn WSASendTo(
839 s: SOCKET,2070 s: SOCKET,
840 lpBuffers: [*]WSABUF,2071 lpBuffers: [*]WSABUF,
841 dwBufferCount: DWORD,2072 dwBufferCount: u32,
842 lpNumberOfBytesSent: ?*DWORD,2073 lpNumberOfBytesSent: ?*u32,
843 dwFlags: DWORD,2074 dwFlags: u32,
844 lpTo: ?*const sockaddr,2075 lpTo: ?*const sockaddr,
845 iTolen: c_int,2076 iToLen: i32,
846 lpOverlapped: ?*WSAOVERLAPPED,2077 lpOverlapped: ?*OVERLAPPED,
847 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,2078 lpCompletionRounte: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
848) callconv(WINAPI) c_int;2079) callconv(WINAPI) i32;
2080
2081pub extern "ws2_32" fn WSASetEvent(
2082 hEvent: HANDLE,
2083) callconv(WINAPI) BOOL;
2084
2085pub extern "ws2_32" fn WSASocketA(
2086 af: i32,
2087 @"type": i32,
2088 protocol: i32,
2089 lpProtocolInfo: ?*WSAPROTOCOL_INFOA,
2090 g: u32,
2091 dwFlags: u32,
2092) callconv(WINAPI) SOCKET;
2093
2094pub extern "ws2_32" fn WSASocketW(
2095 af: i32,
2096 @"type": i32,
2097 protocol: i32,
2098 lpProtocolInfo: ?*WSAPROTOCOL_INFOW,
2099 g: u32,
2100 dwFlags: u32,
2101) callconv(WINAPI) SOCKET;
2102
2103pub extern "ws2_32" fn WSAWaitForMultipleEvents(
2104 cEvents: u32,
2105 lphEvents: [*]const HANDLE,
2106 fWaitAll: BOOL,
2107 dwTimeout: u32,
2108 fAlertable: BOOL,
2109) callconv(WINAPI) u32;
2110
2111pub extern "ws2_32" fn WSAAddressToStringA(
2112 lpsaAddress: *sockaddr,
2113 dwAddressLength: u32,
2114 lpProtocolInfo: ?*WSAPROTOCOL_INFOA,
2115 lpszAddressString: [*]u8,
2116 lpdwAddressStringLength: *u32,
2117) callconv(WINAPI) i32;
2118
2119pub extern "ws2_32" fn WSAAddressToStringW(
2120 lpsaAddress: *sockaddr,
2121 dwAddressLength: u32,
2122 lpProtocolInfo: ?*WSAPROTOCOL_INFOW,
2123 lpszAddressString: [*]u16,
2124 lpdwAddressStringLength: *u32,
2125) callconv(WINAPI) i32;
2126
2127pub extern "ws2_32" fn WSAStringToAddressA(
2128 AddressString: [*:0]const u8,
2129 AddressFamily: i32,
2130 lpProtocolInfo: ?*WSAPROTOCOL_INFOA,
2131 lpAddress: *sockaddr,
2132 lpAddressLength: *i32,
2133) callconv(WINAPI) i32;
2134
2135pub extern "ws2_32" fn WSAStringToAddressW(
2136 AddressString: [*:0]const u16,
2137 AddressFamily: i32,
2138 lpProtocolInfo: ?*WSAPROTOCOL_INFOW,
2139 lpAddrses: *sockaddr,
2140 lpAddressLength: *i32,
2141) callconv(WINAPI) i32;
2142
2143pub extern "ws2_32" fn WSAProviderConfigChange(
2144 lpNotificationHandle: *HANDLE,
2145 lpOverlapped: ?*OVERLAPPED,
2146 lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
2147) callconv(WINAPI) i32;
2148
849pub extern "ws2_32" fn WSAPoll(2149pub extern "ws2_32" fn WSAPoll(
850 fdArray: [*]pollfd,2150 fdArray: [*]WSAPOLLFD,
851 fds: c_ulong,2151 fds: u32,
852 timeout: c_int,2152 timeout: i32,
853) callconv(WINAPI) c_int;2153) callconv(WINAPI) i32;
2154
2155pub extern "mswsock" fn WSARecvEx(
2156 s: SOCKET,
2157 buf: [*]u8,
2158 len: i32,
2159 flags: *i32,
2160) callconv(WINAPI) i32;
2161
2162pub extern "mswsock" fn TransmitFile(
2163 hSocket: SOCKET,
2164 hFile: HANDLE,
2165 nNumberOfBytesToWrite: u32,
2166 nNumberOfBytesPerSend: u32,
2167 lpOverlapped: ?*OVERLAPPED,
2168 lpTransmitBuffers: ?*TRANSMIT_FILE_BUFFERS,
2169 dwReserved: u32,
2170) callconv(WINAPI) BOOL;
2171
2172pub extern "mswsock" fn AcceptEx(
2173 sListenSocket: SOCKET,
2174 sAcceptSocket: SOCKET,
2175 lpOutputBuffer: *c_void,
2176 dwReceiveDataLength: u32,
2177 dwLocalAddressLength: u32,
2178 dwRemoteAddressLength: u32,
2179 lpdwBytesReceived: *u32,
2180 lpOverlapped: *OVERLAPPED,
2181) callconv(WINAPI) BOOL;
2182
2183pub extern "mswsock" fn GetAcceptExSockaddrs(
2184 lpOutputBuffer: *c_void,
2185 dwReceiveDataLength: u32,
2186 dwLocalAddressLength: u32,
2187 dwRemoteAddressLength: u32,
2188 LocalSockaddr: **sockaddr,
2189 LocalSockaddrLength: *i32,
2190 RemoteSockaddr: **sockaddr,
2191 RemoteSockaddrLength: *i32,
2192) callconv(WINAPI) void;
2193
2194pub extern "ws2_32" fn WSAProviderCompleteAsyncCall(
2195 hAsyncCall: HANDLE,
2196 iRetCode: i32,
2197) callconv(WINAPI) i32;
2198
2199pub extern "mswsock" fn EnumProtocolsA(
2200 lpiProtocols: ?*i32,
2201 lpProtocolBuffer: *c_void,
2202 lpdwBufferLength: *u32,
2203) callconv(WINAPI) i32;
2204
2205pub extern "mswsock" fn EnumProtocolsW(
2206 lpiProtocols: ?*i32,
2207 lpProtocolBuffer: *c_void,
2208 lpdwBufferLength: *u32,
2209) callconv(WINAPI) i32;
2210
2211pub extern "mswsock" fn GetAddressByNameA(
2212 dwNameSpace: u32,
2213 lpServiceType: *GUID,
2214 lpServiceName: ?[*:0]u8,
2215 lpiProtocols: ?*i32,
2216 dwResolution: u32,
2217 lpServiceAsyncInfo: ?*SERVICE_ASYNC_INFO,
2218 lpCsaddrBuffer: *c_void,
2219 lpAliasBuffer: ?[*:0]const u8,
2220 lpdwAliasBufferLength: *u32,
2221) callconv(WINAPI) i32;
2222
2223pub extern "mswsock" fn GetAddressByNameW(
2224 dwNameSpace: u32,
2225 lpServiceType: *GUID,
2226 lpServiceName: ?[*:0]u16,
2227 lpiProtocols: ?*i32,
2228 dwResolution: u32,
2229 lpServiceAsyncInfo: ?*SERVICE_ASYNC_INFO,
2230 lpCsaddrBuffer: *c_void,
2231 ldwBufferLEngth: *u32,
2232 lpAliasBuffer: ?[*:0]u16,
2233 lpdwAliasBufferLength: *u32,
2234) callconv(WINAPI) i32;
2235
2236pub extern "mswsock" fn GetTypeByNameA(
2237 lpServiceName: [*:0]u8,
2238 lpServiceType: *GUID,
2239) callconv(WINAPI) i32;
2240
2241pub extern "mswsock" fn GetTypeByNameW(
2242 lpServiceName: [*:0]u16,
2243 lpServiceType: *GUID,
2244) callconv(WINAPI) i32;
2245
2246pub extern "mswsock" fn GetNameByTypeA(
2247 lpServiceType: *GUID,
2248 lpServiceName: [*:0]u8,
2249 dwNameLength: u32,
2250) callconv(WINAPI) i32;
2251
2252pub extern "mswsock" fn GetNameByTypeW(
2253 lpServiceType: *GUID,
2254 lpServiceName: [*:0]u16,
2255 dwNameLength: u32,
2256) callconv(WINAPI) i32;
2257
854pub extern "ws2_32" fn getaddrinfo(2258pub extern "ws2_32" fn getaddrinfo(
855 pNodeName: [*:0]const u8,2259 pNodeName: ?[*:0]const u8,
856 pServiceName: [*:0]const u8,2260 pServiceName: ?[*:0]const u8,
857 pHints: *const addrinfo,2261 pHints: ?*const addrinfoa,
858 ppResult: **addrinfo,2262 ppResult: **addrinfoa,
2263) callconv(WINAPI) i32;
2264
2265pub extern "ws2_32" fn GetAddrInfoExA(
2266 pName: ?[*:0]const u8,
2267 pServiceName: ?[*:0]const u8,
2268 dwNameSapce: u32,
2269 lpNspId: ?*GUID,
2270 hints: ?*const addrinfoexA,
2271 ppResult: **addrinfoexA,
2272 timeout: ?*timeval,
2273 lpOverlapped: ?*OVERLAPPED,
2274 lpCompletionRoutine: ?LPLOOKUPSERVICE_COMPLETION_ROUTINE,
859) callconv(WINAPI) i32;2275) callconv(WINAPI) i32;
2276
2277pub extern "ws2_32" fn GetAddrInfoExCancel(
2278 lpHandle: *HANDLE,
2279) callconv(WINAPI) i32;
2280
2281pub extern "ws2_32" fn GetAddrInfoExOverlappedResult(
2282 lpOverlapped: *OVERLAPPED,
2283) callconv(WINAPI) i32;
2284
860pub extern "ws2_32" fn freeaddrinfo(2285pub extern "ws2_32" fn freeaddrinfo(
861 pAddrInfo: *addrinfo,2286 pAddrInfo: ?*addrinfoa,
862) callconv(WINAPI) void;2287) callconv(WINAPI) void;
863pub extern "ws2_32" fn ioctlsocket(2288
864 s: SOCKET,2289pub extern "ws2_32" fn FreeAddrInfoEx(
865 cmd: c_long,2290 pAddrInfoEx: ?*addrinfoexA,
866 argp: *c_ulong,2291) callconv(WINAPI) void;
867) callconv(WINAPI) c_int;2292
868pub extern "ws2_32" fn getsockname(2293pub extern "ws2_32" fn getnameinfo(
869 s: SOCKET,2294 pSockaddr: *const sockaddr,
870 name: *sockaddr,2295 SockaddrLength: i32,
871 namelen: *c_int,2296 pNodeBuffer: ?[*]u8,
872) callconv(WINAPI) c_int;2297 NodeBufferSize: u32,
873pub extern "ws2_32" fn setsockopt(2298 pServiceBuffer: ?[*]u8,
874 s: SOCKET,2299 ServiceBufferName: u32,
875 level: u32,2300 Flags: i32,
876 optname: u32,2301) callconv(WINAPI) i32;
877 optval: ?*const c_void,2302
878 optlen: socklen_t,2303pub extern "IPHLPAPI" fn if_nametoindex(
879) callconv(WINAPI) c_int;2304 InterfaceName: [*:0]const u8,
880pub extern "ws2_32" fn shutdown(2305) callconv(WINAPI) u32;
881 s: SOCKET,
882 how: c_int,
883) callconv(WINAPI) c_int;
lib/std/x.zig+1-1
...@@ -7,7 +7,7 @@...@@ -7,7 +7,7 @@
7const std = @import("std.zig");7const std = @import("std.zig");
88
9pub const os = struct {9pub const os = struct {
10 pub const Socket = @import("x/os/Socket.zig");10 pub const Socket = @import("x/os/socket.zig").Socket;
11 pub usingnamespace @import("x/os/net.zig");11 pub usingnamespace @import("x/os/net.zig");
12};12};
1313
lib/std/x/net/tcp.zig+82-34
...@@ -6,6 +6,7 @@...@@ -6,6 +6,7 @@
66
7const std = @import("../../std.zig");7const std = @import("../../std.zig");
88
9const io = std.io;
9const os = std.os;10const os = std.os;
10const ip = std.x.net.ip;11const ip = std.x.net.ip;
1112
...@@ -58,6 +59,28 @@ pub const Domain = extern enum(u16) {...@@ -58,6 +59,28 @@ pub const Domain = extern enum(u16) {
58pub const Client = struct {59pub const Client = struct {
59 socket: Socket,60 socket: Socket,
6061
62 /// Implements `std.io.Reader`.
63 pub const Reader = struct {
64 client: Client,
65 flags: u32,
66
67 /// Implements `readFn` for `std.io.Reader`.
68 pub fn read(self: Client.Reader, buffer: []u8) !usize {
69 return self.client.read(buffer, self.flags);
70 }
71 };
72
73 /// Implements `std.io.Writer`.
74 pub const Writer = struct {
75 client: Client,
76 flags: u32,
77
78 /// Implements `writeFn` for `std.io.Writer`.
79 pub fn write(self: Client.Writer, buffer: []const u8) !usize {
80 return self.client.write(buffer, self.flags);
81 }
82 };
83
61 /// Opens a new client.84 /// Opens a new client.
62 pub fn init(domain: tcp.Domain, flags: u32) !Client {85 pub fn init(domain: tcp.Domain, flags: u32) !Client {
63 return Client{86 return Client{
...@@ -89,41 +112,46 @@ pub const Client = struct {...@@ -89,41 +112,46 @@ pub const Client = struct {
89 return self.socket.connect(address.into());112 return self.socket.connect(address.into());
90 }113 }
91114
92 /// Read data from the socket into the buffer provided. It returns the115 /// Extracts the error set of a function.
93 /// number of bytes read into the buffer provided.116 /// TODO: remove after Socket.{read, write} error unions are well-defined across different platforms
94 pub fn read(self: Client, buf: []u8) !usize {117 fn ErrorSetOf(comptime Function: anytype) type {
95 return self.socket.read(buf);118 return @typeInfo(@typeInfo(@TypeOf(Function)).Fn.return_type.?).ErrorUnion.error_set;
96 }119 }
97120
98 /// Read data from the socket into the buffer provided with a set of flags121 /// Wrap `tcp.Client` into `std.io.Reader`.
99 /// specified. It returns the number of bytes read into the buffer provided.122 pub fn reader(self: Client, flags: u32) io.Reader(Client.Reader, ErrorSetOf(Client.Reader.read), Client.Reader.read) {
100 pub fn recv(self: Client, buf: []u8, flags: u32) !usize {123 return .{ .context = .{ .client = self, .flags = flags } };
101 return self.socket.recv(buf, flags);
102 }124 }
103125
104 /// Write a buffer of data provided to the socket. It returns the number126 /// Wrap `tcp.Client` into `std.io.Writer`.
105 /// of bytes that are written to the socket.127 pub fn writer(self: Client, flags: u32) io.Writer(Client.Writer, ErrorSetOf(Client.Writer.write), Client.Writer.write) {
106 pub fn write(self: Client, buf: []const u8) !usize {128 return .{ .context = .{ .client = self, .flags = flags } };
107 return self.socket.write(buf);
108 }129 }
109130
110 /// Writes multiple I/O vectors to the socket. It returns the number131 /// Read data from the socket into the buffer provided with a set of flags
111 /// of bytes that are written to the socket.132 /// specified. It returns the number of bytes read into the buffer provided.
112 pub fn writev(self: Client, buffers: []const os.iovec_const) !usize {133 pub fn read(self: Client, buf: []u8, flags: u32) !usize {
113 return self.socket.writev(buffers);134 return self.socket.read(buf, flags);
114 }135 }
115136
116 /// Write a buffer of data provided to the socket with a set of flags specified.137 /// Write a buffer of data provided to the socket with a set of flags specified.
117 /// It returns the number of bytes that are written to the socket.138 /// It returns the number of bytes that are written to the socket.
118 pub fn send(self: Client, buf: []const u8, flags: u32) !usize {139 pub fn write(self: Client, buf: []const u8, flags: u32) !usize {
119 return self.socket.send(buf, flags);140 return self.socket.write(buf, flags);
120 }141 }
121142
122 /// Writes multiple I/O vectors with a prepended message header to the socket143 /// Writes multiple I/O vectors with a prepended message header to the socket
123 /// with a set of flags specified. It returns the number of bytes that are144 /// with a set of flags specified. It returns the number of bytes that are
124 /// written to the socket.145 /// written to the socket.
125 pub fn sendmsg(self: Client, msg: os.msghdr_const, flags: u32) !usize {146 pub fn writeVectorized(self: Client, msg: os.msghdr_const, flags: u32) !usize {
126 return self.socket.sendmsg(msg, flags);147 return self.socket.writeVectorized(msg, flags);
148 }
149
150 /// Read multiple I/O vectors with a prepended message header from the socket
151 /// with a set of flags specified. It returns the number of bytes that were
152 /// read into the buffer provided.
153 pub fn readVectorized(self: Client, msg: *os.msghdr, flags: u32) !usize {
154 return self.socket.readVectorized(msg, flags);
127 }155 }
128156
129 /// Query and return the latest cached error on the client's underlying socket.157 /// Query and return the latest cached error on the client's underlying socket.
...@@ -146,12 +174,41 @@ pub const Client = struct {...@@ -146,12 +174,41 @@ pub const Client = struct {
146 return ip.Address.from(try self.socket.getLocalAddress());174 return ip.Address.from(try self.socket.getLocalAddress());
147 }175 }
148176
177 /// Query the address that the socket is connected to.
178 pub fn getRemoteAddress(self: Client) !ip.Address {
179 return ip.Address.from(try self.socket.getRemoteAddress());
180 }
181
182 /// Have close() or shutdown() syscalls block until all queued messages in the client have been successfully
183 /// sent, or if the timeout specified in seconds has been reached. It returns `error.UnsupportedSocketOption`
184 /// if the host does not support the option for a socket to linger around up until a timeout specified in
185 /// seconds.
186 pub fn setLinger(self: Client, timeout_seconds: ?u16) !void {
187 return self.socket.setLinger(timeout_seconds);
188 }
189
190 /// Have keep-alive messages be sent periodically. The timing in which keep-alive messages are sent are
191 /// dependant on operating system settings. It returns `error.UnsupportedSocketOption` if the host does
192 /// not support periodically sending keep-alive messages on connection-oriented sockets.
193 pub fn setKeepAlive(self: Client, enabled: bool) !void {
194 return self.socket.setKeepAlive(enabled);
195 }
196
149 /// Disable Nagle's algorithm on a TCP socket. It returns `error.UnsupportedSocketOption` if197 /// Disable Nagle's algorithm on a TCP socket. It returns `error.UnsupportedSocketOption` if
150 /// the host does not support sockets disabling Nagle's algorithm.198 /// the host does not support sockets disabling Nagle's algorithm.
151 pub fn setNoDelay(self: Client, enabled: bool) !void {199 pub fn setNoDelay(self: Client, enabled: bool) !void {
152 if (comptime @hasDecl(os, "TCP_NODELAY")) {200 if (comptime @hasDecl(os, "TCP_NODELAY")) {
153 const bytes = mem.asBytes(&@as(usize, @boolToInt(enabled)));201 const bytes = mem.asBytes(&@as(usize, @boolToInt(enabled)));
154 return os.setsockopt(self.socket.fd, os.IPPROTO_TCP, os.TCP_NODELAY, bytes);202 return self.socket.setOption(os.IPPROTO_TCP, os.TCP_NODELAY, bytes);
203 }
204 return error.UnsupportedSocketOption;
205 }
206
207 /// Enables TCP Quick ACK on a TCP socket to immediately send rather than delay ACKs when necessary. It returns
208 /// `error.UnsupportedSocketOption` if the host does not support TCP Quick ACK.
209 pub fn setQuickACK(self: Client, enabled: bool) !void {
210 if (comptime @hasDecl(os, "TCP_QUICKACK")) {
211 return self.socket.setOption(os.IPPROTO_TCP, os.TCP_QUICKACK, mem.asBytes(&@as(u32, @boolToInt(enabled))));
155 }212 }
156 return error.UnsupportedSocketOption;213 return error.UnsupportedSocketOption;
157 }214 }
...@@ -169,7 +226,7 @@ pub const Client = struct {...@@ -169,7 +226,7 @@ pub const Client = struct {
169 /// Set a timeout on the socket that is to occur if no messages are successfully written226 /// Set a timeout on the socket that is to occur if no messages are successfully written
170 /// to its bound destination after a specified number of milliseconds. A subsequent write227 /// to its bound destination after a specified number of milliseconds. A subsequent write
171 /// to the socket will thereafter return `error.WouldBlock` should the timeout be exceeded.228 /// to the socket will thereafter return `error.WouldBlock` should the timeout be exceeded.
172 pub fn setWriteTimeout(self: Client, milliseconds: usize) !void {229 pub fn setWriteTimeout(self: Client, milliseconds: u32) !void {
173 return self.socket.setWriteTimeout(milliseconds);230 return self.socket.setWriteTimeout(milliseconds);
174 }231 }
175232
...@@ -177,7 +234,7 @@ pub const Client = struct {...@@ -177,7 +234,7 @@ pub const Client = struct {
177 /// from its bound destination after a specified number of milliseconds. A subsequent234 /// from its bound destination after a specified number of milliseconds. A subsequent
178 /// read from the socket will thereafter return `error.WouldBlock` should the timeout be235 /// read from the socket will thereafter return `error.WouldBlock` should the timeout be
179 /// exceeded.236 /// exceeded.
180 pub fn setReadTimeout(self: Client, milliseconds: usize) !void {237 pub fn setReadTimeout(self: Client, milliseconds: u32) !void {
181 return self.socket.setReadTimeout(milliseconds);238 return self.socket.setReadTimeout(milliseconds);
182 }239 }
183};240};
...@@ -251,16 +308,7 @@ pub const Listener = struct {...@@ -251,16 +308,7 @@ pub const Listener = struct {
251 /// support TCP Fast Open.308 /// support TCP Fast Open.
252 pub fn setFastOpen(self: Listener, enabled: bool) !void {309 pub fn setFastOpen(self: Listener, enabled: bool) !void {
253 if (comptime @hasDecl(os, "TCP_FASTOPEN")) {310 if (comptime @hasDecl(os, "TCP_FASTOPEN")) {
254 return os.setsockopt(self.socket.fd, os.IPPROTO_TCP, os.TCP_FASTOPEN, mem.asBytes(&@as(usize, @boolToInt(enabled))));311 return self.socket.setOption(os.IPPROTO_TCP, os.TCP_FASTOPEN, mem.asBytes(&@as(u32, @boolToInt(enabled))));
255 }
256 return error.UnsupportedSocketOption;
257 }
258
259 /// Enables TCP Quick ACK on a TCP socket to immediately send rather than delay ACKs when necessary. It returns
260 /// `error.UnsupportedSocketOption` if the host does not support TCP Quick ACK.
261 pub fn setQuickACK(self: Listener, enabled: bool) !void {
262 if (comptime @hasDecl(os, "TCP_QUICKACK")) {
263 return os.setsockopt(self.socket.fd, os.IPPROTO_TCP, os.TCP_QUICKACK, mem.asBytes(&@as(usize, @boolToInt(enabled))));
264 }312 }
265 return error.UnsupportedSocketOption;313 return error.UnsupportedSocketOption;
266 }314 }
...@@ -322,7 +370,7 @@ test "tcp/client: set read timeout of 1 millisecond on blocking client" {...@@ -322,7 +370,7 @@ test "tcp/client: set read timeout of 1 millisecond on blocking client" {
322 defer conn.deinit();370 defer conn.deinit();
323371
324 var buf: [1]u8 = undefined;372 var buf: [1]u8 = undefined;
325 try testing.expectError(error.WouldBlock, client.read(&buf));373 try testing.expectError(error.WouldBlock, client.reader(0).read(&buf));
326}374}
327375
328test "tcp/listener: bind to unspecified ipv4 address" {376test "tcp/listener: bind to unspecified ipv4 address" {
lib/std/x/os/Socket.zig deleted-295
...@@ -1,295 +0,0 @@
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2015-2021 Zig Contributors
3// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
4// The MIT license requires this copyright notice to be included in all copies
5// and substantial portions of the software.
6
7const std = @import("../../std.zig");
8const net = @import("net.zig");
9
10const os = std.os;
11const fmt = std.fmt;
12const mem = std.mem;
13const time = std.time;
14
15/// A generic socket abstraction.
16const Socket = @This();
17
18/// A socket-address pair.
19pub const Connection = struct {
20 socket: Socket,
21 address: Socket.Address,
22
23 /// Enclose a socket and address into a socket-address pair.
24 pub fn from(socket: Socket, address: Socket.Address) Socket.Connection {
25 return .{ .socket = socket, .address = address };
26 }
27};
28
29/// A generic socket address abstraction. It is safe to directly access and modify
30/// the fields of a `Socket.Address`.
31pub const Address = union(enum) {
32 ipv4: net.IPv4.Address,
33 ipv6: net.IPv6.Address,
34
35 /// Instantiate a new address with a IPv4 host and port.
36 pub fn initIPv4(host: net.IPv4, port: u16) Socket.Address {
37 return .{ .ipv4 = .{ .host = host, .port = port } };
38 }
39
40 /// Instantiate a new address with a IPv6 host and port.
41 pub fn initIPv6(host: net.IPv6, port: u16) Socket.Address {
42 return .{ .ipv6 = .{ .host = host, .port = port } };
43 }
44
45 /// Parses a `sockaddr` into a generic socket address.
46 pub fn fromNative(address: *align(4) const os.sockaddr) Socket.Address {
47 switch (address.family) {
48 os.AF_INET => {
49 const info = @ptrCast(*const os.sockaddr_in, address);
50 const host = net.IPv4{ .octets = @bitCast([4]u8, info.addr) };
51 const port = mem.bigToNative(u16, info.port);
52 return Socket.Address.initIPv4(host, port);
53 },
54 os.AF_INET6 => {
55 const info = @ptrCast(*const os.sockaddr_in6, address);
56 const host = net.IPv6{ .octets = info.addr, .scope_id = info.scope_id };
57 const port = mem.bigToNative(u16, info.port);
58 return Socket.Address.initIPv6(host, port);
59 },
60 else => unreachable,
61 }
62 }
63
64 /// Encodes a generic socket address into an extern union that may be reliably
65 /// casted into a `sockaddr` which may be passed into socket syscalls.
66 pub fn toNative(self: Socket.Address) extern union {
67 ipv4: os.sockaddr_in,
68 ipv6: os.sockaddr_in6,
69 } {
70 return switch (self) {
71 .ipv4 => |address| .{
72 .ipv4 = .{
73 .addr = @bitCast(u32, address.host.octets),
74 .port = mem.nativeToBig(u16, address.port),
75 },
76 },
77 .ipv6 => |address| .{
78 .ipv6 = .{
79 .addr = address.host.octets,
80 .port = mem.nativeToBig(u16, address.port),
81 .scope_id = address.host.scope_id,
82 .flowinfo = 0,
83 },
84 },
85 };
86 }
87
88 /// Returns the number of bytes that make up the `sockaddr` equivalent to the address.
89 pub fn getNativeSize(self: Socket.Address) u32 {
90 return switch (self) {
91 .ipv4 => @sizeOf(os.sockaddr_in),
92 .ipv6 => @sizeOf(os.sockaddr_in6),
93 };
94 }
95
96 /// Implements the `std.fmt.format` API.
97 pub fn format(
98 self: Socket.Address,
99 comptime layout: []const u8,
100 opts: fmt.FormatOptions,
101 writer: anytype,
102 ) !void {
103 switch (self) {
104 .ipv4 => |address| try fmt.format(writer, "{}:{}", .{ address.host, address.port }),
105 .ipv6 => |address| try fmt.format(writer, "{}:{}", .{ address.host, address.port }),
106 }
107 }
108};
109
110/// The underlying handle of a socket.
111fd: os.socket_t,
112
113/// Open a new socket.
114pub fn init(domain: u32, socket_type: u32, protocol: u32) !Socket {
115 return Socket{ .fd = try os.socket(domain, socket_type, protocol) };
116}
117
118/// Enclose a socket abstraction over an existing socket file descriptor.
119pub fn from(fd: os.socket_t) Socket {
120 return Socket{ .fd = fd };
121}
122
123/// Closes the socket.
124pub fn deinit(self: Socket) void {
125 os.closeSocket(self.fd);
126}
127
128/// Shutdown either the read side, write side, or all side of the socket.
129pub fn shutdown(self: Socket, how: os.ShutdownHow) !void {
130 return os.shutdown(self.fd, how);
131}
132
133/// Binds the socket to an address.
134pub fn bind(self: Socket, address: Socket.Address) !void {
135 return os.bind(self.fd, @ptrCast(*const os.sockaddr, &address.toNative()), address.getNativeSize());
136}
137
138/// Start listening for incoming connections on the socket.
139pub fn listen(self: Socket, max_backlog_size: u31) !void {
140 return os.listen(self.fd, max_backlog_size);
141}
142
143/// Have the socket attempt to the connect to an address.
144pub fn connect(self: Socket, address: Socket.Address) !void {
145 return os.connect(self.fd, @ptrCast(*const os.sockaddr, &address.toNative()), address.getNativeSize());
146}
147
148/// Accept a pending incoming connection queued to the kernel backlog
149/// of the socket.
150pub fn accept(self: Socket, flags: u32) !Socket.Connection {
151 var address: os.sockaddr = undefined;
152 var address_len: u32 = @sizeOf(os.sockaddr);
153
154 const socket = Socket{ .fd = try os.accept(self.fd, &address, &address_len, flags) };
155 const socket_address = Socket.Address.fromNative(@alignCast(4, &address));
156
157 return Socket.Connection.from(socket, socket_address);
158}
159
160/// Read data from the socket into the buffer provided. It returns the
161/// number of bytes read into the buffer provided.
162pub fn read(self: Socket, buf: []u8) !usize {
163 return os.read(self.fd, buf);
164}
165
166/// Read data from the socket into the buffer provided with a set of flags
167/// specified. It returns the number of bytes read into the buffer provided.
168pub fn recv(self: Socket, buf: []u8, flags: u32) !usize {
169 return os.recv(self.fd, buf, flags);
170}
171
172/// Write a buffer of data provided to the socket. It returns the number
173/// of bytes that are written to the socket.
174pub fn write(self: Socket, buf: []const u8) !usize {
175 return os.write(self.fd, buf);
176}
177
178/// Writes multiple I/O vectors to the socket. It returns the number
179/// of bytes that are written to the socket.
180pub fn writev(self: Socket, buffers: []const os.iovec_const) !usize {
181 return os.writev(self.fd, buffers);
182}
183
184/// Write a buffer of data provided to the socket with a set of flags specified.
185/// It returns the number of bytes that are written to the socket.
186pub fn send(self: Socket, buf: []const u8, flags: u32) !usize {
187 return os.send(self.fd, buf, flags);
188}
189
190/// Writes multiple I/O vectors with a prepended message header to the socket
191/// with a set of flags specified. It returns the number of bytes that are
192/// written to the socket.
193pub fn sendmsg(self: Socket, msg: os.msghdr_const, flags: u32) !usize {
194 return os.sendmsg(self.fd, msg, flags);
195}
196
197/// Query the address that the socket is locally bounded to.
198pub fn getLocalAddress(self: Socket) !Socket.Address {
199 var address: os.sockaddr = undefined;
200 var address_len: u32 = @sizeOf(os.sockaddr);
201 try os.getsockname(self.fd, &address, &address_len);
202 return Socket.Address.fromNative(@alignCast(4, &address));
203}
204
205/// Query and return the latest cached error on the socket.
206pub fn getError(self: Socket) !void {
207 return os.getsockoptError(self.fd);
208}
209
210/// Query the read buffer size of the socket.
211pub fn getReadBufferSize(self: Socket) !u32 {
212 var value: u32 = undefined;
213 var value_len: u32 = @sizeOf(u32);
214
215 const rc = os.system.getsockopt(self.fd, os.SOL_SOCKET, os.SO_RCVBUF, mem.asBytes(&value), &value_len);
216 return switch (os.errno(rc)) {
217 0 => value,
218 os.EBADF => error.BadFileDescriptor,
219 os.EFAULT => error.InvalidAddressSpace,
220 os.EINVAL => error.InvalidSocketOption,
221 os.ENOPROTOOPT => error.UnknownSocketOption,
222 os.ENOTSOCK => error.NotASocket,
223 else => |err| os.unexpectedErrno(err),
224 };
225}
226
227/// Query the write buffer size of the socket.
228pub fn getWriteBufferSize(self: Socket) !u32 {
229 var value: u32 = undefined;
230 var value_len: u32 = @sizeOf(u32);
231
232 const rc = os.system.getsockopt(self.fd, os.SOL_SOCKET, os.SO_SNDBUF, mem.asBytes(&value), &value_len);
233 return switch (os.errno(rc)) {
234 0 => value,
235 os.EBADF => error.BadFileDescriptor,
236 os.EFAULT => error.InvalidAddressSpace,
237 os.EINVAL => error.InvalidSocketOption,
238 os.ENOPROTOOPT => error.UnknownSocketOption,
239 os.ENOTSOCK => error.NotASocket,
240 else => |err| os.unexpectedErrno(err),
241 };
242}
243
244/// Allow multiple sockets on the same host to listen on the same address. It returns `error.UnsupportedSocketOption` if
245/// the host does not support sockets listening the same address.
246pub fn setReuseAddress(self: Socket, enabled: bool) !void {
247 if (comptime @hasDecl(os, "SO_REUSEADDR")) {
248 return os.setsockopt(self.fd, os.SOL_SOCKET, os.SO_REUSEADDR, mem.asBytes(&@as(usize, @boolToInt(enabled))));
249 }
250 return error.UnsupportedSocketOption;
251}
252
253/// Allow multiple sockets on the same host to listen on the same port. It returns `error.UnsupportedSocketOption` if
254/// the host does not supports sockets listening on the same port.
255pub fn setReusePort(self: Socket, enabled: bool) !void {
256 if (comptime @hasDecl(os, "SO_REUSEPORT")) {
257 return os.setsockopt(self.fd, os.SOL_SOCKET, os.SO_REUSEPORT, mem.asBytes(&@as(usize, @boolToInt(enabled))));
258 }
259 return error.UnsupportedSocketOption;
260}
261
262/// Set the write buffer size of the socket.
263pub fn setWriteBufferSize(self: Socket, size: u32) !void {
264 return os.setsockopt(self.fd, os.SOL_SOCKET, os.SO_SNDBUF, mem.asBytes(&size));
265}
266
267/// Set the read buffer size of the socket.
268pub fn setReadBufferSize(self: Socket, size: u32) !void {
269 return os.setsockopt(self.fd, os.SOL_SOCKET, os.SO_RCVBUF, mem.asBytes(&size));
270}
271
272/// Set a timeout on the socket that is to occur if no messages are successfully written
273/// to its bound destination after a specified number of milliseconds. A subsequent write
274/// to the socket will thereafter return `error.WouldBlock` should the timeout be exceeded.
275pub fn setWriteTimeout(self: Socket, milliseconds: usize) !void {
276 const timeout = os.timeval{
277 .tv_sec = @intCast(i32, milliseconds / time.ms_per_s),
278 .tv_usec = @intCast(i32, (milliseconds % time.ms_per_s) * time.us_per_ms),
279 };
280
281 return os.setsockopt(self.fd, os.SOL_SOCKET, os.SO_SNDTIMEO, mem.asBytes(&timeout));
282}
283
284/// Set a timeout on the socket that is to occur if no messages are successfully read
285/// from its bound destination after a specified number of milliseconds. A subsequent
286/// read from the socket will thereafter return `error.WouldBlock` should the timeout be
287/// exceeded.
288pub fn setReadTimeout(self: Socket, milliseconds: usize) !void {
289 const timeout = os.timeval{
290 .tv_sec = @intCast(i32, milliseconds / time.ms_per_s),
291 .tv_usec = @intCast(i32, (milliseconds % time.ms_per_s) * time.us_per_ms),
292 };
293
294 return os.setsockopt(self.fd, os.SOL_SOCKET, os.SO_RCVTIMEO, mem.asBytes(&timeout));
295}
lib/std/x/os/net.zig+9
...@@ -20,6 +20,14 @@ pub fn resolveScopeID(name: []const u8) !u32 {...@@ -20,6 +20,14 @@ pub fn resolveScopeID(name: []const u8) !u32 {
20 if (comptime @hasDecl(os, "IFNAMESIZE")) {20 if (comptime @hasDecl(os, "IFNAMESIZE")) {
21 if (name.len >= os.IFNAMESIZE - 1) return error.NameTooLong;21 if (name.len >= os.IFNAMESIZE - 1) return error.NameTooLong;
2222
23 if (comptime builtin.os.tag == .windows) {
24 var interface_name: [os.IFNAMESIZE]u8 = undefined;
25 mem.copy(u8, &interface_name, name);
26 interface_name[name.len] = 0;
27
28 return os.windows.ws2_32.if_nametoindex(@ptrCast([*:0]const u8, &interface_name));
29 }
30
23 const fd = try os.socket(os.AF_UNIX, os.SOCK_DGRAM, 0);31 const fd = try os.socket(os.AF_UNIX, os.SOCK_DGRAM, 0);
24 defer os.closeSocket(fd);32 defer os.closeSocket(fd);
2533
...@@ -31,6 +39,7 @@ pub fn resolveScopeID(name: []const u8) !u32 {...@@ -31,6 +39,7 @@ pub fn resolveScopeID(name: []const u8) !u32 {
3139
32 return @bitCast(u32, f.ifru.ivalue);40 return @bitCast(u32, f.ifru.ivalue);
33 }41 }
42
34 return error.Unsupported;43 return error.Unsupported;
35}44}
3645
lib/std/x/os/socket.zig created+123
...@@ -0,0 +1,123 @@
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2015-2021 Zig Contributors
3// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
4// The MIT license requires this copyright notice to be included in all copies
5// and substantial portions of the software.
6
7const std = @import("../../std.zig");
8const net = @import("net.zig");
9
10const os = std.os;
11const fmt = std.fmt;
12const mem = std.mem;
13const time = std.time;
14const builtin = std.builtin;
15
16/// A generic, cross-platform socket abstraction.
17pub const Socket = struct {
18 /// A socket-address pair.
19 pub const Connection = struct {
20 socket: Socket,
21 address: Socket.Address,
22
23 /// Enclose a socket and address into a socket-address pair.
24 pub fn from(socket: Socket, address: Socket.Address) Socket.Connection {
25 return .{ .socket = socket, .address = address };
26 }
27 };
28
29 /// A generic socket address abstraction. It is safe to directly access and modify
30 /// the fields of a `Socket.Address`.
31 pub const Address = union(enum) {
32 ipv4: net.IPv4.Address,
33 ipv6: net.IPv6.Address,
34
35 /// Instantiate a new address with a IPv4 host and port.
36 pub fn initIPv4(host: net.IPv4, port: u16) Socket.Address {
37 return .{ .ipv4 = .{ .host = host, .port = port } };
38 }
39
40 /// Instantiate a new address with a IPv6 host and port.
41 pub fn initIPv6(host: net.IPv6, port: u16) Socket.Address {
42 return .{ .ipv6 = .{ .host = host, .port = port } };
43 }
44
45 /// Parses a `sockaddr` into a generic socket address.
46 pub fn fromNative(address: *align(4) const os.sockaddr) Socket.Address {
47 switch (address.family) {
48 os.AF_INET => {
49 const info = @ptrCast(*const os.sockaddr_in, address);
50 const host = net.IPv4{ .octets = @bitCast([4]u8, info.addr) };
51 const port = mem.bigToNative(u16, info.port);
52 return Socket.Address.initIPv4(host, port);
53 },
54 os.AF_INET6 => {
55 const info = @ptrCast(*const os.sockaddr_in6, address);
56 const host = net.IPv6{ .octets = info.addr, .scope_id = info.scope_id };
57 const port = mem.bigToNative(u16, info.port);
58 return Socket.Address.initIPv6(host, port);
59 },
60 else => unreachable,
61 }
62 }
63
64 /// Encodes a generic socket address into an extern union that may be reliably
65 /// casted into a `sockaddr` which may be passed into socket syscalls.
66 pub fn toNative(self: Socket.Address) extern union {
67 ipv4: os.sockaddr_in,
68 ipv6: os.sockaddr_in6,
69 } {
70 return switch (self) {
71 .ipv4 => |address| .{
72 .ipv4 = .{
73 .addr = @bitCast(u32, address.host.octets),
74 .port = mem.nativeToBig(u16, address.port),
75 },
76 },
77 .ipv6 => |address| .{
78 .ipv6 = .{
79 .addr = address.host.octets,
80 .port = mem.nativeToBig(u16, address.port),
81 .scope_id = address.host.scope_id,
82 .flowinfo = 0,
83 },
84 },
85 };
86 }
87
88 /// Returns the number of bytes that make up the `sockaddr` equivalent to the address.
89 pub fn getNativeSize(self: Socket.Address) u32 {
90 return switch (self) {
91 .ipv4 => @sizeOf(os.sockaddr_in),
92 .ipv6 => @sizeOf(os.sockaddr_in6),
93 };
94 }
95
96 /// Implements the `std.fmt.format` API.
97 pub fn format(
98 self: Socket.Address,
99 comptime layout: []const u8,
100 opts: fmt.FormatOptions,
101 writer: anytype,
102 ) !void {
103 switch (self) {
104 .ipv4 => |address| try fmt.format(writer, "{}:{}", .{ address.host, address.port }),
105 .ipv6 => |address| try fmt.format(writer, "{}:{}", .{ address.host, address.port }),
106 }
107 }
108 };
109
110 /// The underlying handle of a socket.
111 fd: os.socket_t,
112
113 /// Enclose a socket abstraction over an existing socket file descriptor.
114 pub fn from(fd: os.socket_t) Socket {
115 return Socket{ .fd = fd };
116 }
117
118 /// Mix in socket syscalls depending on the platform we are compiling against.
119 pub usingnamespace switch (builtin.os.tag) {
120 .windows => @import("socket_windows.zig"),
121 else => @import("socket_posix.zig"),
122 }.Mixin(Socket);
123};
lib/std/x/os/socket_posix.zig created+251
...@@ -0,0 +1,251 @@
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2015-2021 Zig Contributors
3// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
4// The MIT license requires this copyright notice to be included in all copies
5// and substantial portions of the software.
6
7const std = @import("../../std.zig");
8
9const os = std.os;
10const mem = std.mem;
11const time = std.time;
12
13pub fn Mixin(comptime Socket: type) type {
14 return struct {
15 /// Open a new socket.
16 pub fn init(domain: u32, socket_type: u32, protocol: u32) !Socket {
17 return Socket{ .fd = try os.socket(domain, socket_type, protocol) };
18 }
19
20 /// Closes the socket.
21 pub fn deinit(self: Socket) void {
22 os.closeSocket(self.fd);
23 }
24
25 /// Shutdown either the read side, write side, or all side of the socket.
26 pub fn shutdown(self: Socket, how: os.ShutdownHow) !void {
27 return os.shutdown(self.fd, how);
28 }
29
30 /// Binds the socket to an address.
31 pub fn bind(self: Socket, address: Socket.Address) !void {
32 return os.bind(self.fd, @ptrCast(*const os.sockaddr, &address.toNative()), address.getNativeSize());
33 }
34
35 /// Start listening for incoming connections on the socket.
36 pub fn listen(self: Socket, max_backlog_size: u31) !void {
37 return os.listen(self.fd, max_backlog_size);
38 }
39
40 /// Have the socket attempt to the connect to an address.
41 pub fn connect(self: Socket, address: Socket.Address) !void {
42 return os.connect(self.fd, @ptrCast(*const os.sockaddr, &address.toNative()), address.getNativeSize());
43 }
44
45 /// Accept a pending incoming connection queued to the kernel backlog
46 /// of the socket.
47 pub fn accept(self: Socket, flags: u32) !Socket.Connection {
48 var address: os.sockaddr_storage = undefined;
49 var address_len: u32 = @sizeOf(os.sockaddr_storage);
50
51 const socket = Socket{ .fd = try os.accept(self.fd, @ptrCast(*os.sockaddr, &address), &address_len, flags) };
52 const socket_address = Socket.Address.fromNative(@ptrCast(*os.sockaddr, &address));
53
54 return Socket.Connection.from(socket, socket_address);
55 }
56
57 /// Read data from the socket into the buffer provided with a set of flags
58 /// specified. It returns the number of bytes read into the buffer provided.
59 pub fn read(self: Socket, buf: []u8, flags: u32) !usize {
60 return os.recv(self.fd, buf, flags);
61 }
62
63 /// Write a buffer of data provided to the socket with a set of flags specified.
64 /// It returns the number of bytes that are written to the socket.
65 pub fn write(self: Socket, buf: []const u8, flags: u32) !usize {
66 return os.send(self.fd, buf, flags);
67 }
68
69 /// Writes multiple I/O vectors with a prepended message header to the socket
70 /// with a set of flags specified. It returns the number of bytes that are
71 /// written to the socket.
72 pub fn writeVectorized(self: Socket, msg: os.msghdr_const, flags: u32) !usize {
73 return os.sendmsg(self.fd, msg, flags);
74 }
75
76 /// Read multiple I/O vectors with a prepended message header from the socket
77 /// with a set of flags specified. It returns the number of bytes that were
78 /// read into the buffer provided.
79 pub fn readVectorized(self: Socket, msg: *os.msghdr, flags: u32) !usize {
80 if (comptime @hasDecl(os.system, "recvmsg")) {
81 while (true) {
82 const rc = os.system.recvmsg(self.fd, msg, flags);
83 return switch (os.errno(rc)) {
84 0 => @intCast(usize, rc),
85 os.EBADF => unreachable, // always a race condition
86 os.EFAULT => unreachable,
87 os.EINVAL => unreachable,
88 os.ENOTCONN => unreachable,
89 os.ENOTSOCK => unreachable,
90 os.EINTR => continue,
91 os.EAGAIN => error.WouldBlock,
92 os.ENOMEM => error.SystemResources,
93 os.ECONNREFUSED => error.ConnectionRefused,
94 os.ECONNRESET => error.ConnectionResetByPeer,
95 else => |err| os.unexpectedErrno(err),
96 };
97 }
98 }
99 return error.NotSupported;
100 }
101
102 /// Query the address that the socket is locally bounded to.
103 pub fn getLocalAddress(self: Socket) !Socket.Address {
104 var address: os.sockaddr_storage = undefined;
105 var address_len: u32 = @sizeOf(os.sockaddr_storage);
106 try os.getsockname(self.fd, @ptrCast(*os.sockaddr, &address), &address_len);
107 return Socket.Address.fromNative(@ptrCast(*os.sockaddr, &address));
108 }
109
110 /// Query the address that the socket is connected to.
111 pub fn getRemoteAddress(self: Socket) !Socket.Address {
112 var address: os.sockaddr_storage = undefined;
113 var address_len: u32 = @sizeOf(os.sockaddr_storage);
114 try os.getpeername(self.fd, @ptrCast(*os.sockaddr, &address), &address_len);
115 return Socket.Address.fromNative(@ptrCast(*os.sockaddr, &address));
116 }
117
118 /// Query and return the latest cached error on the socket.
119 pub fn getError(self: Socket) !void {
120 return os.getsockoptError(self.fd);
121 }
122
123 /// Query the read buffer size of the socket.
124 pub fn getReadBufferSize(self: Socket) !u32 {
125 var value: u32 = undefined;
126 var value_len: u32 = @sizeOf(u32);
127
128 const rc = os.system.getsockopt(self.fd, os.SOL_SOCKET, os.SO_RCVBUF, mem.asBytes(&value), &value_len);
129 return switch (os.errno(rc)) {
130 0 => value,
131 os.EBADF => error.BadFileDescriptor,
132 os.EFAULT => error.InvalidAddressSpace,
133 os.EINVAL => error.InvalidSocketOption,
134 os.ENOPROTOOPT => error.UnknownSocketOption,
135 os.ENOTSOCK => error.NotASocket,
136 else => |err| os.unexpectedErrno(err),
137 };
138 }
139
140 /// Query the write buffer size of the socket.
141 pub fn getWriteBufferSize(self: Socket) !u32 {
142 var value: u32 = undefined;
143 var value_len: u32 = @sizeOf(u32);
144
145 const rc = os.system.getsockopt(self.fd, os.SOL_SOCKET, os.SO_SNDBUF, mem.asBytes(&value), &value_len);
146 return switch (os.errno(rc)) {
147 0 => value,
148 os.EBADF => error.BadFileDescriptor,
149 os.EFAULT => error.InvalidAddressSpace,
150 os.EINVAL => error.InvalidSocketOption,
151 os.ENOPROTOOPT => error.UnknownSocketOption,
152 os.ENOTSOCK => error.NotASocket,
153 else => |err| os.unexpectedErrno(err),
154 };
155 }
156
157 /// Set a socket option.
158 pub fn setOption(self: Socket, level: u32, code: u32, value: []const u8) !void {
159 return os.setsockopt(self.fd, level, code, value);
160 }
161
162 /// Have close() or shutdown() syscalls block until all queued messages in the socket have been successfully
163 /// sent, or if the timeout specified in seconds has been reached. It returns `error.UnsupportedSocketOption`
164 /// if the host does not support the option for a socket to linger around up until a timeout specified in
165 /// seconds.
166 pub fn setLinger(self: Socket, timeout_seconds: ?u16) !void {
167 if (comptime @hasDecl(os, "SO_LINGER")) {
168 const settings = extern struct {
169 l_onoff: c_int,
170 l_linger: c_int,
171 }{
172 .l_onoff = @intCast(c_int, @boolToInt(timeout_seconds != null)),
173 .l_linger = if (timeout_seconds) |seconds| @intCast(c_int, seconds) else 0,
174 };
175
176 return self.setOption(os.SOL_SOCKET, os.SO_LINGER, mem.asBytes(&settings));
177 }
178
179 return error.UnsupportedSocketOption;
180 }
181
182 /// On connection-oriented sockets, have keep-alive messages be sent periodically. The timing in which keep-alive
183 /// messages are sent are dependant on operating system settings. It returns `error.UnsupportedSocketOption` if
184 /// the host does not support periodically sending keep-alive messages on connection-oriented sockets.
185 pub fn setKeepAlive(self: Socket, enabled: bool) !void {
186 if (comptime @hasDecl(os, "SO_KEEPALIVE")) {
187 return self.setOption(os.SOL_SOCKET, os.SO_KEEPALIVE, mem.asBytes(&@as(u32, @boolToInt(enabled))));
188 }
189 return error.UnsupportedSocketOption;
190 }
191
192 /// Allow multiple sockets on the same host to listen on the same address. It returns `error.UnsupportedSocketOption` if
193 /// the host does not support sockets listening the same address.
194 pub fn setReuseAddress(self: Socket, enabled: bool) !void {
195 if (comptime @hasDecl(os, "SO_REUSEADDR")) {
196 return self.setOption(os.SOL_SOCKET, os.SO_REUSEADDR, mem.asBytes(&@as(u32, @boolToInt(enabled))));
197 }
198 return error.UnsupportedSocketOption;
199 }
200
201 /// Allow multiple sockets on the same host to listen on the same port. It returns `error.UnsupportedSocketOption` if
202 /// the host does not supports sockets listening on the same port.
203 pub fn setReusePort(self: Socket, enabled: bool) !void {
204 if (comptime @hasDecl(os, "SO_REUSEPORT")) {
205 return self.setOption(os.SOL_SOCKET, os.SO_REUSEPORT, mem.asBytes(&@as(u32, @boolToInt(enabled))));
206 }
207 return error.UnsupportedSocketOption;
208 }
209
210 /// Set the write buffer size of the socket.
211 pub fn setWriteBufferSize(self: Socket, size: u32) !void {
212 return self.setOption(os.SOL_SOCKET, os.SO_SNDBUF, mem.asBytes(&size));
213 }
214
215 /// Set the read buffer size of the socket.
216 pub fn setReadBufferSize(self: Socket, size: u32) !void {
217 return self.setOption(os.SOL_SOCKET, os.SO_RCVBUF, mem.asBytes(&size));
218 }
219
220 /// WARNING: Timeouts only affect blocking sockets. It is undefined behavior if a timeout is
221 /// set on a non-blocking socket.
222 ///
223 /// Set a timeout on the socket that is to occur if no messages are successfully written
224 /// to its bound destination after a specified number of milliseconds. A subsequent write
225 /// to the socket will thereafter return `error.WouldBlock` should the timeout be exceeded.
226 pub fn setWriteTimeout(self: Socket, milliseconds: usize) !void {
227 const timeout = os.timeval{
228 .tv_sec = @intCast(i32, milliseconds / time.ms_per_s),
229 .tv_usec = @intCast(i32, (milliseconds % time.ms_per_s) * time.us_per_ms),
230 };
231
232 return self.setOption(os.SOL_SOCKET, os.SO_SNDTIMEO, mem.asBytes(&timeout));
233 }
234
235 /// WARNING: Timeouts only affect blocking sockets. It is undefined behavior if a timeout is
236 /// set on a non-blocking socket.
237 ///
238 /// Set a timeout on the socket that is to occur if no messages are successfully read
239 /// from its bound destination after a specified number of milliseconds. A subsequent
240 /// read from the socket will thereafter return `error.WouldBlock` should the timeout be
241 /// exceeded.
242 pub fn setReadTimeout(self: Socket, milliseconds: usize) !void {
243 const timeout = os.timeval{
244 .tv_sec = @intCast(i32, milliseconds / time.ms_per_s),
245 .tv_usec = @intCast(i32, (milliseconds % time.ms_per_s) * time.us_per_ms),
246 };
247
248 return self.setOption(os.SOL_SOCKET, os.SO_RCVTIMEO, mem.asBytes(&timeout));
249 }
250 };
251}
lib/std/x/os/socket_windows.zig created+448
...@@ -0,0 +1,448 @@
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2015-2021 Zig Contributors
3// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
4// The MIT license requires this copyright notice to be included in all copies
5// and substantial portions of the software.
6
7const std = @import("../../std.zig");
8const net = @import("net.zig");
9
10const os = std.os;
11const mem = std.mem;
12
13const windows = std.os.windows;
14const ws2_32 = windows.ws2_32;
15
16pub fn Mixin(comptime Socket: type) type {
17 return struct {
18 /// Open a new socket.
19 pub fn init(domain: u32, socket_type: u32, protocol: u32) !Socket {
20 var filtered_socket_type = socket_type & ~@as(u32, os.SOCK_CLOEXEC);
21
22 var filtered_flags: u32 = ws2_32.WSA_FLAG_OVERLAPPED;
23 if (socket_type & os.SOCK_CLOEXEC != 0) {
24 filtered_flags |= ws2_32.WSA_FLAG_NO_HANDLE_INHERIT;
25 }
26
27 const fd = ws2_32.WSASocketW(
28 @intCast(i32, domain),
29 @intCast(i32, filtered_socket_type),
30 @intCast(i32, protocol),
31 null,
32 0,
33 filtered_flags,
34 );
35 if (fd == ws2_32.INVALID_SOCKET) {
36 return switch (ws2_32.WSAGetLastError()) {
37 .WSANOTINITIALISED => {
38 _ = try windows.WSAStartup(2, 2);
39 return Socket.init(domain, socket_type, protocol);
40 },
41 .WSAEAFNOSUPPORT => error.AddressFamilyNotSupported,
42 .WSAEMFILE => error.ProcessFdQuotaExceeded,
43 .WSAENOBUFS => error.SystemResources,
44 .WSAEPROTONOSUPPORT => error.ProtocolNotSupported,
45 else => |err| windows.unexpectedWSAError(err),
46 };
47 }
48
49 return Socket{ .fd = fd };
50 }
51
52 /// Closes the socket.
53 pub fn deinit(self: Socket) void {
54 _ = ws2_32.closesocket(self.fd);
55 }
56
57 /// Shutdown either the read side, write side, or all side of the socket.
58 pub fn shutdown(self: Socket, how: os.ShutdownHow) !void {
59 const rc = ws2_32.shutdown(self.fd, switch (how) {
60 .recv => ws2_32.SD_RECEIVE,
61 .send => ws2_32.SD_SEND,
62 .both => ws2_32.SD_BOTH,
63 });
64 if (rc == ws2_32.SOCKET_ERROR) {
65 return switch (ws2_32.WSAGetLastError()) {
66 .WSAECONNABORTED => return error.ConnectionAborted,
67 .WSAECONNRESET => return error.ConnectionResetByPeer,
68 .WSAEINPROGRESS => return error.BlockingOperationInProgress,
69 .WSAEINVAL => unreachable,
70 .WSAENETDOWN => return error.NetworkSubsystemFailed,
71 .WSAENOTCONN => return error.SocketNotConnected,
72 .WSAENOTSOCK => unreachable,
73 .WSANOTINITIALISED => unreachable,
74 else => |err| return windows.unexpectedWSAError(err),
75 };
76 }
77 }
78
79 /// Binds the socket to an address.
80 pub fn bind(self: Socket, address: Socket.Address) !void {
81 const rc = ws2_32.bind(self.fd, @ptrCast(*const ws2_32.sockaddr, &address.toNative()), @intCast(c_int, address.getNativeSize()));
82 if (rc == ws2_32.SOCKET_ERROR) {
83 return switch (ws2_32.WSAGetLastError()) {
84 .WSAENETDOWN => error.NetworkSubsystemFailed,
85 .WSAEACCES => error.AccessDenied,
86 .WSAEADDRINUSE => error.AddressInUse,
87 .WSAEADDRNOTAVAIL => error.AddressNotAvailable,
88 .WSAEFAULT => error.BadAddress,
89 .WSAEINPROGRESS => error.WouldBlock,
90 .WSAEINVAL => error.AlreadyBound,
91 .WSAENOBUFS => error.NoEphemeralPortsAvailable,
92 .WSAENOTSOCK => error.NotASocket,
93 else => |err| windows.unexpectedWSAError(err),
94 };
95 }
96 }
97
98 /// Start listening for incoming connections on the socket.
99 pub fn listen(self: Socket, max_backlog_size: u31) !void {
100 const rc = ws2_32.listen(self.fd, max_backlog_size);
101 if (rc == ws2_32.SOCKET_ERROR) {
102 return switch (ws2_32.WSAGetLastError()) {
103 .WSAENETDOWN => error.NetworkSubsystemFailed,
104 .WSAEADDRINUSE => error.AddressInUse,
105 .WSAEISCONN => error.AlreadyConnected,
106 .WSAEINVAL => error.SocketNotBound,
107 .WSAEMFILE, .WSAENOBUFS => error.SystemResources,
108 .WSAENOTSOCK => error.FileDescriptorNotASocket,
109 .WSAEOPNOTSUPP => error.OperationNotSupported,
110 .WSAEINPROGRESS => error.WouldBlock,
111 else => |err| windows.unexpectedWSAError(err),
112 };
113 }
114 }
115
116 /// Have the socket attempt to the connect to an address.
117 pub fn connect(self: Socket, address: Socket.Address) !void {
118 const rc = ws2_32.connect(self.fd, @ptrCast(*const ws2_32.sockaddr, &address.toNative()), @intCast(c_int, address.getNativeSize()));
119 if (rc == ws2_32.SOCKET_ERROR) {
120 return switch (ws2_32.WSAGetLastError()) {
121 .WSAEADDRINUSE => error.AddressInUse,
122 .WSAEADDRNOTAVAIL => error.AddressNotAvailable,
123 .WSAECONNREFUSED => error.ConnectionRefused,
124 .WSAETIMEDOUT => error.ConnectionTimedOut,
125 .WSAEFAULT => error.BadAddress,
126 .WSAEINVAL => error.ListeningSocket,
127 .WSAEISCONN => error.AlreadyConnected,
128 .WSAENOTSOCK => error.NotASocket,
129 .WSAEACCES => error.BroadcastNotEnabled,
130 .WSAENOBUFS => error.SystemResources,
131 .WSAEAFNOSUPPORT => error.AddressFamilyNotSupported,
132 .WSAEINPROGRESS, .WSAEWOULDBLOCK => error.WouldBlock,
133 .WSAEHOSTUNREACH, .WSAENETUNREACH => error.NetworkUnreachable,
134 else => |err| windows.unexpectedWSAError(err),
135 };
136 }
137 }
138
139 /// Accept a pending incoming connection queued to the kernel backlog
140 /// of the socket.
141 pub fn accept(self: Socket, flags: u32) !Socket.Connection {
142 var address: ws2_32.sockaddr_storage = undefined;
143 var address_len: c_int = @sizeOf(ws2_32.sockaddr_storage);
144
145 const rc = ws2_32.accept(self.fd, @ptrCast(*ws2_32.sockaddr, &address), &address_len);
146 if (rc == ws2_32.INVALID_SOCKET) {
147 return switch (ws2_32.WSAGetLastError()) {
148 .WSANOTINITIALISED => unreachable,
149 .WSAECONNRESET => error.ConnectionResetByPeer,
150 .WSAEFAULT => unreachable,
151 .WSAEINVAL => error.SocketNotListening,
152 .WSAEMFILE => error.ProcessFdQuotaExceeded,
153 .WSAENETDOWN => error.NetworkSubsystemFailed,
154 .WSAENOBUFS => error.FileDescriptorNotASocket,
155 .WSAEOPNOTSUPP => error.OperationNotSupported,
156 .WSAEWOULDBLOCK => error.WouldBlock,
157 else => |err| windows.unexpectedWSAError(err),
158 };
159 }
160
161 const socket = Socket.from(rc);
162 const socket_address = Socket.Address.fromNative(@ptrCast(*ws2_32.sockaddr, &address));
163
164 return Socket.Connection.from(socket, socket_address);
165 }
166
167 /// Read data from the socket into the buffer provided with a set of flags
168 /// specified. It returns the number of bytes read into the buffer provided.
169 pub fn read(self: Socket, buf: []u8, flags: u32) !usize {
170 var bufs = &[_]ws2_32.WSABUF{.{ .len = @intCast(u32, buf.len), .buf = buf.ptr }};
171 var num_bytes: u32 = undefined;
172 var flags_ = flags;
173
174 const rc = ws2_32.WSARecv(self.fd, bufs, 1, &num_bytes, &flags_, null, null);
175 if (rc == ws2_32.SOCKET_ERROR) {
176 return switch (ws2_32.WSAGetLastError()) {
177 .WSAECONNABORTED => error.ConnectionAborted,
178 .WSAECONNRESET => error.ConnectionResetByPeer,
179 .WSAEDISCON => error.ConnectionClosedByPeer,
180 .WSAEFAULT => error.BadBuffer,
181 .WSAEINPROGRESS,
182 .WSAEWOULDBLOCK,
183 .WSA_IO_PENDING,
184 .WSAETIMEDOUT,
185 => error.WouldBlock,
186 .WSAEINTR => error.Cancelled,
187 .WSAEINVAL => error.SocketNotBound,
188 .WSAEMSGSIZE => error.MessageTooLarge,
189 .WSAENETDOWN => error.NetworkSubsystemFailed,
190 .WSAENETRESET => error.NetworkReset,
191 .WSAENOTCONN => error.SocketNotConnected,
192 .WSAENOTSOCK => error.FileDescriptorNotASocket,
193 .WSAEOPNOTSUPP => error.OperationNotSupported,
194 .WSAESHUTDOWN => error.AlreadyShutdown,
195 .WSA_OPERATION_ABORTED => error.OperationAborted,
196 else => |err| windows.unexpectedWSAError(err),
197 };
198 }
199
200 return @intCast(usize, num_bytes);
201 }
202
203 /// Write a buffer of data provided to the socket with a set of flags specified.
204 /// It returns the number of bytes that are written to the socket.
205 pub fn write(self: Socket, buf: []const u8, flags: u32) !usize {
206 var bufs = &[_]ws2_32.WSABUF{.{ .len = @intCast(u32, buf.len), .buf = @intToPtr([*]u8, @ptrToInt(buf.ptr)) }};
207 var num_bytes: u32 = undefined;
208
209 const rc = ws2_32.WSASend(self.fd, bufs, 1, &num_bytes, flags, null, null);
210 if (rc == ws2_32.SOCKET_ERROR) {
211 return switch (ws2_32.WSAGetLastError()) {
212 .WSAECONNABORTED => error.ConnectionAborted,
213 .WSAECONNRESET => error.ConnectionResetByPeer,
214 .WSAEFAULT => error.BadBuffer,
215 .WSAEINPROGRESS,
216 .WSAEWOULDBLOCK,
217 .WSA_IO_PENDING,
218 .WSAETIMEDOUT,
219 => error.WouldBlock,
220 .WSAEINTR => error.Cancelled,
221 .WSAEINVAL => error.SocketNotBound,
222 .WSAEMSGSIZE => error.MessageTooLarge,
223 .WSAENETDOWN => error.NetworkSubsystemFailed,
224 .WSAENETRESET => error.NetworkReset,
225 .WSAENOBUFS => error.BufferDeadlock,
226 .WSAENOTCONN => error.SocketNotConnected,
227 .WSAENOTSOCK => error.FileDescriptorNotASocket,
228 .WSAEOPNOTSUPP => error.OperationNotSupported,
229 .WSAESHUTDOWN => error.AlreadyShutdown,
230 .WSA_OPERATION_ABORTED => error.OperationAborted,
231 else => |err| windows.unexpectedWSAError(err),
232 };
233 }
234
235 return @intCast(usize, num_bytes);
236 }
237
238 /// Writes multiple I/O vectors with a prepended message header to the socket
239 /// with a set of flags specified. It returns the number of bytes that are
240 /// written to the socket.
241 pub fn writeVectorized(self: Socket, msg: ws2_32.msghdr_const, flags: u32) !usize {
242 const call = try windows.loadWinsockExtensionFunction(ws2_32.LPFN_WSASENDMSG, self.fd, ws2_32.WSAID_WSASENDMSG);
243
244 var num_bytes: u32 = undefined;
245
246 const rc = call(self.fd, &msg, flags, &num_bytes, null, null);
247 if (rc == ws2_32.SOCKET_ERROR) {
248 return switch (ws2_32.WSAGetLastError()) {
249 .WSAECONNABORTED => error.ConnectionAborted,
250 .WSAECONNRESET => error.ConnectionResetByPeer,
251 .WSAEFAULT => error.BadBuffer,
252 .WSAEINPROGRESS,
253 .WSAEWOULDBLOCK,
254 .WSA_IO_PENDING,
255 .WSAETIMEDOUT,
256 => error.WouldBlock,
257 .WSAEINTR => error.Cancelled,
258 .WSAEINVAL => error.SocketNotBound,
259 .WSAEMSGSIZE => error.MessageTooLarge,
260 .WSAENETDOWN => error.NetworkSubsystemFailed,
261 .WSAENETRESET => error.NetworkReset,
262 .WSAENOBUFS => error.BufferDeadlock,
263 .WSAENOTCONN => error.SocketNotConnected,
264 .WSAENOTSOCK => error.FileDescriptorNotASocket,
265 .WSAEOPNOTSUPP => error.OperationNotSupported,
266 .WSAESHUTDOWN => error.AlreadyShutdown,
267 .WSA_OPERATION_ABORTED => error.OperationAborted,
268 else => |err| windows.unexpectedWSAError(err),
269 };
270 }
271
272 return @intCast(usize, num_bytes);
273 }
274
275 /// Read multiple I/O vectors with a prepended message header from the socket
276 /// with a set of flags specified. It returns the number of bytes that were
277 /// read into the buffer provided.
278 pub fn readVectorized(self: Socket, msg: *ws2_32.msghdr, flags: u32) !usize {
279 const call = try windows.loadWinsockExtensionFunction(ws2_32.LPFN_WSARECVMSG, self.fd, ws2_32.WSAID_WSARECVMSG);
280
281 var num_bytes: u32 = undefined;
282
283 const rc = call(self.fd, msg, &num_bytes, null, null);
284 if (rc == ws2_32.SOCKET_ERROR) {
285 return switch (ws2_32.WSAGetLastError()) {
286 .WSAECONNABORTED => error.ConnectionAborted,
287 .WSAECONNRESET => error.ConnectionResetByPeer,
288 .WSAEDISCON => error.ConnectionClosedByPeer,
289 .WSAEFAULT => error.BadBuffer,
290 .WSAEINPROGRESS,
291 .WSAEWOULDBLOCK,
292 .WSA_IO_PENDING,
293 .WSAETIMEDOUT,
294 => error.WouldBlock,
295 .WSAEINTR => error.Cancelled,
296 .WSAEINVAL => error.SocketNotBound,
297 .WSAEMSGSIZE => error.MessageTooLarge,
298 .WSAENETDOWN => error.NetworkSubsystemFailed,
299 .WSAENETRESET => error.NetworkReset,
300 .WSAENOTCONN => error.SocketNotConnected,
301 .WSAENOTSOCK => error.FileDescriptorNotASocket,
302 .WSAEOPNOTSUPP => error.OperationNotSupported,
303 .WSAESHUTDOWN => error.AlreadyShutdown,
304 .WSA_OPERATION_ABORTED => error.OperationAborted,
305 else => |err| windows.unexpectedWSAError(err),
306 };
307 }
308
309 return @intCast(usize, num_bytes);
310 }
311
312 /// Query the address that the socket is locally bounded to.
313 pub fn getLocalAddress(self: Socket) !Socket.Address {
314 var address: ws2_32.sockaddr_storage = undefined;
315 var address_len: c_int = @sizeOf(ws2_32.sockaddr_storage);
316
317 const rc = ws2_32.getsockname(self.fd, @ptrCast(*ws2_32.sockaddr, &address), &address_len);
318 if (rc == ws2_32.SOCKET_ERROR) {
319 return switch (ws2_32.WSAGetLastError()) {
320 .WSANOTINITIALISED => unreachable,
321 .WSAEFAULT => unreachable,
322 .WSAENETDOWN => error.NetworkSubsystemFailed,
323 .WSAENOTSOCK => error.FileDescriptorNotASocket,
324 .WSAEINVAL => error.SocketNotBound,
325 else => |err| windows.unexpectedWSAError(err),
326 };
327 }
328
329 return Socket.Address.fromNative(@ptrCast(*ws2_32.sockaddr, &address));
330 }
331
332 /// Query the address that the socket is connected to.
333 pub fn getRemoteAddress(self: Socket) !Socket.Address {
334 var address: ws2_32.sockaddr_storage = undefined;
335 var address_len: c_int = @sizeOf(ws2_32.sockaddr_storage);
336
337 const rc = ws2_32.getpeername(self.fd, @ptrCast(*ws2_32.sockaddr, &address), &address_len);
338 if (rc == ws2_32.SOCKET_ERROR) {
339 return switch (ws2_32.WSAGetLastError()) {
340 .WSANOTINITIALISED => unreachable,
341 .WSAEFAULT => unreachable,
342 .WSAENETDOWN => error.NetworkSubsystemFailed,
343 .WSAENOTSOCK => error.FileDescriptorNotASocket,
344 .WSAEINVAL => error.SocketNotBound,
345 else => |err| windows.unexpectedWSAError(err),
346 };
347 }
348
349 return Socket.Address.fromNative(@ptrCast(*ws2_32.sockaddr, &address));
350 }
351
352 /// Query and return the latest cached error on the socket.
353 pub fn getError(self: Socket) !void {
354 return {};
355 }
356
357 /// Query the read buffer size of the socket.
358 pub fn getReadBufferSize(self: Socket) !u32 {
359 return 0;
360 }
361
362 /// Query the write buffer size of the socket.
363 pub fn getWriteBufferSize(self: Socket) !u32 {
364 return 0;
365 }
366
367 /// Set a socket option.
368 pub fn setOption(self: Socket, level: u32, code: u32, value: []const u8) !void {
369 const rc = ws2_32.setsockopt(self.fd, @intCast(i32, level), @intCast(i32, code), value.ptr, @intCast(i32, value.len));
370 if (rc == ws2_32.SOCKET_ERROR) {
371 return switch (ws2_32.WSAGetLastError()) {
372 .WSANOTINITIALISED => unreachable,
373 .WSAENETDOWN => return error.NetworkSubsystemFailed,
374 .WSAEFAULT => unreachable,
375 .WSAENOTSOCK => return error.FileDescriptorNotASocket,
376 .WSAEINVAL => return error.SocketNotBound,
377 else => |err| windows.unexpectedWSAError(err),
378 };
379 }
380 }
381
382 /// Have close() or shutdown() syscalls block until all queued messages in the socket have been successfully
383 /// sent, or if the timeout specified in seconds has been reached. It returns `error.UnsupportedSocketOption`
384 /// if the host does not support the option for a socket to linger around up until a timeout specified in
385 /// seconds.
386 pub fn setLinger(self: Socket, timeout_seconds: ?u16) !void {
387 const settings = ws2_32.linger{
388 .l_onoff = @as(u16, @boolToInt(timeout_seconds != null)),
389 .l_linger = if (timeout_seconds) |seconds| seconds else 0,
390 };
391
392 return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_LINGER, mem.asBytes(&settings));
393 }
394
395 /// On connection-oriented sockets, have keep-alive messages be sent periodically. The timing in which keep-alive
396 /// messages are sent are dependant on operating system settings. It returns `error.UnsupportedSocketOption` if
397 /// the host does not support periodically sending keep-alive messages on connection-oriented sockets.
398 pub fn setKeepAlive(self: Socket, enabled: bool) !void {
399 return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_KEEPALIVE, mem.asBytes(&@as(u32, @boolToInt(enabled))));
400 }
401
402 /// Allow multiple sockets on the same host to listen on the same address. It returns `error.UnsupportedSocketOption` if
403 /// the host does not support sockets listening the same address.
404 pub fn setReuseAddress(self: Socket, enabled: bool) !void {
405 return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_REUSEADDR, mem.asBytes(&@as(u32, @boolToInt(enabled))));
406 }
407
408 /// Allow multiple sockets on the same host to listen on the same port. It returns `error.UnsupportedSocketOption` if
409 /// the host does not supports sockets listening on the same port.
410 ///
411 /// TODO: verify if this truly mimicks SO_REUSEPORT behavior, or if SO_REUSE_UNICASTPORT provides the correct behavior
412 pub fn setReusePort(self: Socket, enabled: bool) !void {
413 try self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_BROADCAST, mem.asBytes(&@as(u32, @boolToInt(enabled))));
414 try self.setReuseAddress(enabled);
415 }
416
417 /// Set the write buffer size of the socket.
418 pub fn setWriteBufferSize(self: Socket, size: u32) !void {
419 return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_SNDBUF, mem.asBytes(&size));
420 }
421
422 /// Set the read buffer size of the socket.
423 pub fn setReadBufferSize(self: Socket, size: u32) !void {
424 return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_RCVBUF, mem.asBytes(&size));
425 }
426
427 /// WARNING: Timeouts only affect blocking sockets. It is undefined behavior if a timeout is
428 /// set on a non-blocking socket.
429 ///
430 /// Set a timeout on the socket that is to occur if no messages are successfully written
431 /// to its bound destination after a specified number of milliseconds. A subsequent write
432 /// to the socket will thereafter return `error.WouldBlock` should the timeout be exceeded.
433 pub fn setWriteTimeout(self: Socket, milliseconds: u32) !void {
434 return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_SNDTIMEO, mem.asBytes(&milliseconds));
435 }
436
437 /// WARNING: Timeouts only affect blocking sockets. It is undefined behavior if a timeout is
438 /// set on a non-blocking socket.
439 ///
440 /// Set a timeout on the socket that is to occur if no messages are successfully read
441 /// from its bound destination after a specified number of milliseconds. A subsequent
442 /// read from the socket will thereafter return `error.WouldBlock` should the timeout be
443 /// exceeded.
444 pub fn setReadTimeout(self: Socket, milliseconds: u32) !void {
445 return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_RCVTIMEO, mem.asBytes(&milliseconds));
446 }
447 };
448}