Commit d7b601b35e

lithdew <kenta@lithdew.net>
2021-05-08 15:44:39
std/os, x/os/socket: windows support, socket helpers, getpeername()
Socket I/O methods such as read, readv, write, writev, send, recv, sendmsg, recvmsg have been generalized to read(buf, flags), write(buf, flags), readVectorized(vectors, flags), and writeVectorized(vectors, flags). There is still some work left to be done abstracting both readVectorized and writeVectorized properly across platforms, which is work to be done in a future PR. Support for setting the linger timeout of a socket, querying the remote address of a socket, setting whether or not keep-alive messages are to be sent through a connection-oriented socket periodically depending on host operating system settings has been added. `std.io.Reader` and `std.io.Writer` wrappers around `Socket` has been implemented, which wrap around Socket.read(buf, flags) and Socket.write(buf, flags). Both wrappers may be provided flags which are passed to Socket.read / Socket.write accordingly. Cross-platform support for `getpeername()` has been implemented. Windows support for the new `std.x.os.Socket` has been implemented. To accomplish this, a full refactor of `std.os.windows.ws2_32` has been done to supply any missing definitions and constants based on auto-generated Windows syscall bindings by @marler8997. `std.x.net.TCP.Listener.setQuickACK` has been moved to `std.x.net.TCP.Client.setQuickACK`. Windows support for resolving the scope ID of an interface name specified in an IPv6 address has been provided. `sockaddr_storage` definitions have been provided for Windows, Linux, and Darwin. `sockaddr_storage` is used to allocate space before any socket addresses are queried via. calls such as accept(), getsockname(), and getpeername(). Zig-friendly wrappers for GetQueuedCompletionStatusEx(), getpeername(), SetConsoleCtrlHandler(), SetFileCompletionNotificationModes() syscalls on Windows have been provided. Socket.setOption() was provided to set the value of a socket option in place of os.setsockopt. Socket.getOption() will be provided in a future PR. There is still further work to be done regarding querying socket option values on Windows, which is to be done in a subsequent PR.
1 parent 9c03b39
lib/std/os/bits/darwin.zig
@@ -23,6 +23,13 @@ pub const sockaddr = extern struct {
     family: sa_family_t,
     data: [14]u8,
 };
+pub const sockaddr_storage = extern struct {
+    len: u8,
+    family: sa_family_t,
+    __pad1: [6]u8,
+    __align: i64,
+    __pad2: [112]u8,
+};
 pub const sockaddr_in = extern struct {
     len: u8 = @sizeOf(sockaddr_in),
     family: sa_family_t = AF_INET,
lib/std/os/bits/linux.zig
@@ -1149,6 +1149,13 @@ pub const sockaddr = extern struct {
     data: [14]u8,
 };
 
+pub const sockaddr_storage = extern struct {
+    family: sa_family_t,
+    __pad1: [6]u8,
+    __align: i64,
+    __pad2: [112]u8,
+};
+
 /// IPv4 socket address
 pub const sockaddr_in = extern struct {
     family: sa_family_t = AF_INET,
lib/std/os/bits/windows.zig
@@ -321,3 +321,5 @@ pub const O_NOATIME = 0o1000000;
 pub const O_PATH = 0o10000000;
 pub const O_TMPFILE = 0o20200000;
 pub const O_NDELAY = O_NONBLOCK;
+
+pub const IFNAMESIZE = 30;
lib/std/os/windows/bits.zig
@@ -1619,10 +1619,6 @@ pub const MOUNTMGR_MOUNT_POINTS = extern struct {
 };
 pub const IOCTL_MOUNTMGR_QUERY_POINTS: ULONG = 0x6d0008;
 
-pub const SD_RECEIVE = 0;
-pub const SD_SEND = 1;
-pub const SD_BOTH = 2;
-
 pub const OBJECT_INFORMATION_CLASS = extern enum {
     ObjectBasicInformation = 0,
     ObjectNameInformation = 1,
@@ -1642,3 +1638,14 @@ pub const SRWLOCK = usize;
 pub const SRWLOCK_INIT: SRWLOCK = 0;
 pub const CONDITION_VARIABLE = usize;
 pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = 0;
+
+pub const FILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 0x1;
+pub const FILE_SKIP_SET_EVENT_ON_HANDLE = 0x2;
+
+pub const CTRL_C_EVENT: DWORD = 0;
+pub const CTRL_BREAK_EVENT: DWORD = 1;
+pub const CTRL_CLOSE_EVENT: DWORD = 2;
+pub const CTRL_LOGOFF_EVENT: DWORD = 5;
+pub const CTRL_SHUTDOWN_EVENT: DWORD = 6;
+
+pub const HANDLER_ROUTINE = fn (dwCtrlType: DWORD) callconv(.C) BOOL;
lib/std/os/windows/kernel32.zig
@@ -140,6 +140,14 @@ pub extern "kernel32" fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERL
 
 pub extern "kernel32" fn GetProcessHeap() callconv(WINAPI) ?HANDLE;
 pub extern "kernel32" fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) callconv(WINAPI) BOOL;
+pub extern "kernel32" fn GetQueuedCompletionStatusEx(
+    CompletionPort: HANDLE,
+    lpCompletionPortEntries: [*]OVERLAPPED_ENTRY,
+    ulCount: ULONG,
+    ulNumEntriesRemoved: *ULONG,
+    dwMilliseconds: DWORD,
+    fAlertable: BOOL,
+) callconv(WINAPI) BOOL;
 
 pub extern "kernel32" fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) callconv(WINAPI) void;
 pub extern "kernel32" fn GetSystemTimeAsFileTime(*FILETIME) callconv(WINAPI) void;
@@ -197,6 +205,16 @@ pub extern "kernel32" fn RemoveDirectoryW(lpPathName: [*:0]const u16) callconv(W
 
 pub extern "kernel32" fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) callconv(WINAPI) BOOL;
 
+pub extern "kernel32" fn SetConsoleCtrlHandler(
+    HandlerRoutine: ?HANDLER_ROUTINE,
+    Add: BOOL,
+) callconv(WINAPI) BOOL;
+
+pub extern "kernel32" fn SetFileCompletionNotificationModes(
+    FileHandle: HANDLE,
+    Flags: UCHAR,
+) callconv(WINAPI) BOOL;
+
 pub extern "kernel32" fn SetFilePointerEx(
     in_fFile: HANDLE,
     in_liDistanceToMove: LARGE_INTEGER,
lib/std/os/windows/ws2_32.zig
@@ -7,10 +7,879 @@ usingnamespace @import("bits.zig");
 
 pub const SOCKET = *opaque {};
 pub const INVALID_SOCKET = @intToPtr(SOCKET, ~@as(usize, 0));
-pub const SOCKET_ERROR = -1;
 
-pub const WSADESCRIPTION_LEN = 256;
-pub const WSASYS_STATUS_LEN = 128;
+pub const GROUP = u32;
+pub const ADDRESS_FAMILY = u16;
+pub const WSAEVENT = HANDLE;
+
+// Microsoft use the signed c_int for this, but it should never be negative
+pub const socklen_t = u32;
+
+pub const LM_HB_Extension = @as(i32, 128);
+pub const LM_HB1_PnP = @as(i32, 1);
+pub const LM_HB1_PDA_Palmtop = @as(i32, 2);
+pub const LM_HB1_Computer = @as(i32, 4);
+pub const LM_HB1_Printer = @as(i32, 8);
+pub const LM_HB1_Modem = @as(i32, 16);
+pub const LM_HB1_Fax = @as(i32, 32);
+pub const LM_HB1_LANAccess = @as(i32, 64);
+pub const LM_HB2_Telephony = @as(i32, 1);
+pub const LM_HB2_FileServer = @as(i32, 2);
+pub const ATMPROTO_AALUSER = @as(u32, 0);
+pub const ATMPROTO_AAL1 = @as(u32, 1);
+pub const ATMPROTO_AAL2 = @as(u32, 2);
+pub const ATMPROTO_AAL34 = @as(u32, 3);
+pub const ATMPROTO_AAL5 = @as(u32, 5);
+pub const SAP_FIELD_ABSENT = @as(u32, 4294967294);
+pub const SAP_FIELD_ANY = @as(u32, 4294967295);
+pub const SAP_FIELD_ANY_AESA_SEL = @as(u32, 4294967290);
+pub const SAP_FIELD_ANY_AESA_REST = @as(u32, 4294967291);
+pub const ATM_E164 = @as(u32, 1);
+pub const ATM_NSAP = @as(u32, 2);
+pub const ATM_AESA = @as(u32, 2);
+pub const ATM_ADDR_SIZE = @as(u32, 20);
+pub const BLLI_L2_ISO_1745 = @as(u32, 1);
+pub const BLLI_L2_Q921 = @as(u32, 2);
+pub const BLLI_L2_X25L = @as(u32, 6);
+pub const BLLI_L2_X25M = @as(u32, 7);
+pub const BLLI_L2_ELAPB = @as(u32, 8);
+pub const BLLI_L2_HDLC_ARM = @as(u32, 9);
+pub const BLLI_L2_HDLC_NRM = @as(u32, 10);
+pub const BLLI_L2_HDLC_ABM = @as(u32, 11);
+pub const BLLI_L2_LLC = @as(u32, 12);
+pub const BLLI_L2_X75 = @as(u32, 13);
+pub const BLLI_L2_Q922 = @as(u32, 14);
+pub const BLLI_L2_USER_SPECIFIED = @as(u32, 16);
+pub const BLLI_L2_ISO_7776 = @as(u32, 17);
+pub const BLLI_L3_X25 = @as(u32, 6);
+pub const BLLI_L3_ISO_8208 = @as(u32, 7);
+pub const BLLI_L3_X223 = @as(u32, 8);
+pub const BLLI_L3_SIO_8473 = @as(u32, 9);
+pub const BLLI_L3_T70 = @as(u32, 10);
+pub const BLLI_L3_ISO_TR9577 = @as(u32, 11);
+pub const BLLI_L3_USER_SPECIFIED = @as(u32, 16);
+pub const BLLI_L3_IPI_SNAP = @as(u32, 128);
+pub const BLLI_L3_IPI_IP = @as(u32, 204);
+pub const BHLI_ISO = @as(u32, 0);
+pub const BHLI_UserSpecific = @as(u32, 1);
+pub const BHLI_HighLayerProfile = @as(u32, 2);
+pub const BHLI_VendorSpecificAppId = @as(u32, 3);
+pub const AAL5_MODE_MESSAGE = @as(u32, 1);
+pub const AAL5_MODE_STREAMING = @as(u32, 2);
+pub const AAL5_SSCS_NULL = @as(u32, 0);
+pub const AAL5_SSCS_SSCOP_ASSURED = @as(u32, 1);
+pub const AAL5_SSCS_SSCOP_NON_ASSURED = @as(u32, 2);
+pub const AAL5_SSCS_FRAME_RELAY = @as(u32, 4);
+pub const BCOB_A = @as(u32, 1);
+pub const BCOB_C = @as(u32, 3);
+pub const BCOB_X = @as(u32, 16);
+pub const TT_NOIND = @as(u32, 0);
+pub const TT_CBR = @as(u32, 4);
+pub const TT_VBR = @as(u32, 8);
+pub const TR_NOIND = @as(u32, 0);
+pub const TR_END_TO_END = @as(u32, 1);
+pub const TR_NO_END_TO_END = @as(u32, 2);
+pub const CLIP_NOT = @as(u32, 0);
+pub const CLIP_SUS = @as(u32, 32);
+pub const UP_P2P = @as(u32, 0);
+pub const UP_P2MP = @as(u32, 1);
+pub const BLLI_L2_MODE_NORMAL = @as(u32, 64);
+pub const BLLI_L2_MODE_EXT = @as(u32, 128);
+pub const BLLI_L3_MODE_NORMAL = @as(u32, 64);
+pub const BLLI_L3_MODE_EXT = @as(u32, 128);
+pub const BLLI_L3_PACKET_16 = @as(u32, 4);
+pub const BLLI_L3_PACKET_32 = @as(u32, 5);
+pub const BLLI_L3_PACKET_64 = @as(u32, 6);
+pub const BLLI_L3_PACKET_128 = @as(u32, 7);
+pub const BLLI_L3_PACKET_256 = @as(u32, 8);
+pub const BLLI_L3_PACKET_512 = @as(u32, 9);
+pub const BLLI_L3_PACKET_1024 = @as(u32, 10);
+pub const BLLI_L3_PACKET_2048 = @as(u32, 11);
+pub const BLLI_L3_PACKET_4096 = @as(u32, 12);
+pub const PI_ALLOWED = @as(u32, 0);
+pub const PI_RESTRICTED = @as(u32, 64);
+pub const PI_NUMBER_NOT_AVAILABLE = @as(u32, 128);
+pub const SI_USER_NOT_SCREENED = @as(u32, 0);
+pub const SI_USER_PASSED = @as(u32, 1);
+pub const SI_USER_FAILED = @as(u32, 2);
+pub const SI_NETWORK = @as(u32, 3);
+pub const CAUSE_LOC_USER = @as(u32, 0);
+pub const CAUSE_LOC_PRIVATE_LOCAL = @as(u32, 1);
+pub const CAUSE_LOC_PUBLIC_LOCAL = @as(u32, 2);
+pub const CAUSE_LOC_TRANSIT_NETWORK = @as(u32, 3);
+pub const CAUSE_LOC_PUBLIC_REMOTE = @as(u32, 4);
+pub const CAUSE_LOC_PRIVATE_REMOTE = @as(u32, 5);
+pub const CAUSE_LOC_INTERNATIONAL_NETWORK = @as(u32, 7);
+pub const CAUSE_LOC_BEYOND_INTERWORKING = @as(u32, 10);
+pub const CAUSE_UNALLOCATED_NUMBER = @as(u32, 1);
+pub const CAUSE_NO_ROUTE_TO_TRANSIT_NETWORK = @as(u32, 2);
+pub const CAUSE_NO_ROUTE_TO_DESTINATION = @as(u32, 3);
+pub const CAUSE_VPI_VCI_UNACCEPTABLE = @as(u32, 10);
+pub const CAUSE_NORMAL_CALL_CLEARING = @as(u32, 16);
+pub const CAUSE_USER_BUSY = @as(u32, 17);
+pub const CAUSE_NO_USER_RESPONDING = @as(u32, 18);
+pub const CAUSE_CALL_REJECTED = @as(u32, 21);
+pub const CAUSE_NUMBER_CHANGED = @as(u32, 22);
+pub const CAUSE_USER_REJECTS_CLIR = @as(u32, 23);
+pub const CAUSE_DESTINATION_OUT_OF_ORDER = @as(u32, 27);
+pub const CAUSE_INVALID_NUMBER_FORMAT = @as(u32, 28);
+pub const CAUSE_STATUS_ENQUIRY_RESPONSE = @as(u32, 30);
+pub const CAUSE_NORMAL_UNSPECIFIED = @as(u32, 31);
+pub const CAUSE_VPI_VCI_UNAVAILABLE = @as(u32, 35);
+pub const CAUSE_NETWORK_OUT_OF_ORDER = @as(u32, 38);
+pub const CAUSE_TEMPORARY_FAILURE = @as(u32, 41);
+pub const CAUSE_ACCESS_INFORMAION_DISCARDED = @as(u32, 43);
+pub const CAUSE_NO_VPI_VCI_AVAILABLE = @as(u32, 45);
+pub const CAUSE_RESOURCE_UNAVAILABLE = @as(u32, 47);
+pub const CAUSE_QOS_UNAVAILABLE = @as(u32, 49);
+pub const CAUSE_USER_CELL_RATE_UNAVAILABLE = @as(u32, 51);
+pub const CAUSE_BEARER_CAPABILITY_UNAUTHORIZED = @as(u32, 57);
+pub const CAUSE_BEARER_CAPABILITY_UNAVAILABLE = @as(u32, 58);
+pub const CAUSE_OPTION_UNAVAILABLE = @as(u32, 63);
+pub const CAUSE_BEARER_CAPABILITY_UNIMPLEMENTED = @as(u32, 65);
+pub const CAUSE_UNSUPPORTED_TRAFFIC_PARAMETERS = @as(u32, 73);
+pub const CAUSE_INVALID_CALL_REFERENCE = @as(u32, 81);
+pub const CAUSE_CHANNEL_NONEXISTENT = @as(u32, 82);
+pub const CAUSE_INCOMPATIBLE_DESTINATION = @as(u32, 88);
+pub const CAUSE_INVALID_ENDPOINT_REFERENCE = @as(u32, 89);
+pub const CAUSE_INVALID_TRANSIT_NETWORK_SELECTION = @as(u32, 91);
+pub const CAUSE_TOO_MANY_PENDING_ADD_PARTY = @as(u32, 92);
+pub const CAUSE_AAL_PARAMETERS_UNSUPPORTED = @as(u32, 93);
+pub const CAUSE_MANDATORY_IE_MISSING = @as(u32, 96);
+pub const CAUSE_UNIMPLEMENTED_MESSAGE_TYPE = @as(u32, 97);
+pub const CAUSE_UNIMPLEMENTED_IE = @as(u32, 99);
+pub const CAUSE_INVALID_IE_CONTENTS = @as(u32, 100);
+pub const CAUSE_INVALID_STATE_FOR_MESSAGE = @as(u32, 101);
+pub const CAUSE_RECOVERY_ON_TIMEOUT = @as(u32, 102);
+pub const CAUSE_INCORRECT_MESSAGE_LENGTH = @as(u32, 104);
+pub const CAUSE_PROTOCOL_ERROR = @as(u32, 111);
+pub const CAUSE_COND_UNKNOWN = @as(u32, 0);
+pub const CAUSE_COND_PERMANENT = @as(u32, 1);
+pub const CAUSE_COND_TRANSIENT = @as(u32, 2);
+pub const CAUSE_REASON_USER = @as(u32, 0);
+pub const CAUSE_REASON_IE_MISSING = @as(u32, 4);
+pub const CAUSE_REASON_IE_INSUFFICIENT = @as(u32, 8);
+pub const CAUSE_PU_PROVIDER = @as(u32, 0);
+pub const CAUSE_PU_USER = @as(u32, 8);
+pub const CAUSE_NA_NORMAL = @as(u32, 0);
+pub const CAUSE_NA_ABNORMAL = @as(u32, 4);
+pub const QOS_CLASS0 = @as(u32, 0);
+pub const QOS_CLASS1 = @as(u32, 1);
+pub const QOS_CLASS2 = @as(u32, 2);
+pub const QOS_CLASS3 = @as(u32, 3);
+pub const QOS_CLASS4 = @as(u32, 4);
+pub const TNS_TYPE_NATIONAL = @as(u32, 64);
+pub const TNS_PLAN_CARRIER_ID_CODE = @as(u32, 1);
+pub const SIO_GET_NUMBER_OF_ATM_DEVICES = @as(u32, 1343619073);
+pub const SIO_GET_ATM_ADDRESS = @as(u32, 3491102722);
+pub const SIO_ASSOCIATE_PVC = @as(u32, 2417360899);
+pub const SIO_GET_ATM_CONNECTION_ID = @as(u32, 1343619076);
+pub const RIO_MSG_DONT_NOTIFY = @as(u32, 1);
+pub const RIO_MSG_DEFER = @as(u32, 2);
+pub const RIO_MSG_WAITALL = @as(u32, 4);
+pub const RIO_MSG_COMMIT_ONLY = @as(u32, 8);
+pub const RIO_MAX_CQ_SIZE = @as(u32, 134217728);
+pub const RIO_CORRUPT_CQ = @as(u32, 4294967295);
+pub const WINDOWS_AF_IRDA = @as(u32, 26);
+pub const WCE_AF_IRDA = @as(u32, 22);
+pub const IRDA_PROTO_SOCK_STREAM = @as(u32, 1);
+pub const SOL_IRLMP = @as(u32, 255);
+pub const IRLMP_ENUMDEVICES = @as(u32, 16);
+pub const IRLMP_IAS_SET = @as(u32, 17);
+pub const IRLMP_IAS_QUERY = @as(u32, 18);
+pub const IRLMP_SEND_PDU_LEN = @as(u32, 19);
+pub const IRLMP_EXCLUSIVE_MODE = @as(u32, 20);
+pub const IRLMP_IRLPT_MODE = @as(u32, 21);
+pub const IRLMP_9WIRE_MODE = @as(u32, 22);
+pub const IRLMP_TINYTP_MODE = @as(u32, 23);
+pub const IRLMP_PARAMETERS = @as(u32, 24);
+pub const IRLMP_DISCOVERY_MODE = @as(u32, 25);
+pub const IRLMP_SHARP_MODE = @as(u32, 32);
+pub const IAS_ATTRIB_NO_CLASS = @as(u32, 16);
+pub const IAS_ATTRIB_NO_ATTRIB = @as(u32, 0);
+pub const IAS_ATTRIB_INT = @as(u32, 1);
+pub const IAS_ATTRIB_OCTETSEQ = @as(u32, 2);
+pub const IAS_ATTRIB_STR = @as(u32, 3);
+pub const IAS_MAX_USER_STRING = @as(u32, 256);
+pub const IAS_MAX_OCTET_STRING = @as(u32, 1024);
+pub const IAS_MAX_CLASSNAME = @as(u32, 64);
+pub const IAS_MAX_ATTRIBNAME = @as(u32, 256);
+pub const LmCharSetASCII = @as(u32, 0);
+pub const LmCharSetISO_8859_1 = @as(u32, 1);
+pub const LmCharSetISO_8859_2 = @as(u32, 2);
+pub const LmCharSetISO_8859_3 = @as(u32, 3);
+pub const LmCharSetISO_8859_4 = @as(u32, 4);
+pub const LmCharSetISO_8859_5 = @as(u32, 5);
+pub const LmCharSetISO_8859_6 = @as(u32, 6);
+pub const LmCharSetISO_8859_7 = @as(u32, 7);
+pub const LmCharSetISO_8859_8 = @as(u32, 8);
+pub const LmCharSetISO_8859_9 = @as(u32, 9);
+pub const LmCharSetUNICODE = @as(u32, 255);
+pub const LM_BAUD_1200 = @as(u32, 1200);
+pub const LM_BAUD_2400 = @as(u32, 2400);
+pub const LM_BAUD_9600 = @as(u32, 9600);
+pub const LM_BAUD_19200 = @as(u32, 19200);
+pub const LM_BAUD_38400 = @as(u32, 38400);
+pub const LM_BAUD_57600 = @as(u32, 57600);
+pub const LM_BAUD_115200 = @as(u32, 115200);
+pub const LM_BAUD_576K = @as(u32, 576000);
+pub const LM_BAUD_1152K = @as(u32, 1152000);
+pub const LM_BAUD_4M = @as(u32, 4000000);
+pub const LM_BAUD_16M = @as(u32, 16000000);
+pub const IPX_PTYPE = @as(u32, 16384);
+pub const IPX_FILTERPTYPE = @as(u32, 16385);
+pub const IPX_STOPFILTERPTYPE = @as(u32, 16387);
+pub const IPX_DSTYPE = @as(u32, 16386);
+pub const IPX_EXTENDED_ADDRESS = @as(u32, 16388);
+pub const IPX_RECVHDR = @as(u32, 16389);
+pub const IPX_MAXSIZE = @as(u32, 16390);
+pub const IPX_ADDRESS = @as(u32, 16391);
+pub const IPX_GETNETINFO = @as(u32, 16392);
+pub const IPX_GETNETINFO_NORIP = @as(u32, 16393);
+pub const IPX_SPXGETCONNECTIONSTATUS = @as(u32, 16395);
+pub const IPX_ADDRESS_NOTIFY = @as(u32, 16396);
+pub const IPX_MAX_ADAPTER_NUM = @as(u32, 16397);
+pub const IPX_RERIPNETNUMBER = @as(u32, 16398);
+pub const IPX_RECEIVE_BROADCAST = @as(u32, 16399);
+pub const IPX_IMMEDIATESPXACK = @as(u32, 16400);
+pub const IPPROTO_RM = @as(u32, 113);
+pub const MAX_MCAST_TTL = @as(u32, 255);
+pub const RM_OPTIONSBASE = @as(u32, 1000);
+pub const RM_RATE_WINDOW_SIZE = @as(u32, 1001);
+pub const RM_SET_MESSAGE_BOUNDARY = @as(u32, 1002);
+pub const RM_FLUSHCACHE = @as(u32, 1003);
+pub const RM_SENDER_WINDOW_ADVANCE_METHOD = @as(u32, 1004);
+pub const RM_SENDER_STATISTICS = @as(u32, 1005);
+pub const RM_LATEJOIN = @as(u32, 1006);
+pub const RM_SET_SEND_IF = @as(u32, 1007);
+pub const RM_ADD_RECEIVE_IF = @as(u32, 1008);
+pub const RM_DEL_RECEIVE_IF = @as(u32, 1009);
+pub const RM_SEND_WINDOW_ADV_RATE = @as(u32, 1010);
+pub const RM_USE_FEC = @as(u32, 1011);
+pub const RM_SET_MCAST_TTL = @as(u32, 1012);
+pub const RM_RECEIVER_STATISTICS = @as(u32, 1013);
+pub const RM_HIGH_SPEED_INTRANET_OPT = @as(u32, 1014);
+pub const SENDER_DEFAULT_RATE_KBITS_PER_SEC = @as(u32, 56);
+pub const SENDER_DEFAULT_WINDOW_ADV_PERCENTAGE = @as(u32, 15);
+pub const MAX_WINDOW_INCREMENT_PERCENTAGE = @as(u32, 25);
+pub const SENDER_DEFAULT_LATE_JOINER_PERCENTAGE = @as(u32, 0);
+pub const SENDER_MAX_LATE_JOINER_PERCENTAGE = @as(u32, 75);
+pub const BITS_PER_BYTE = @as(u32, 8);
+pub const LOG2_BITS_PER_BYTE = @as(u32, 3);
+pub const SOCKET_DEFAULT2_QM_POLICY = Guid.initString("aec2ef9c-3a4d-4d3e-8842-239942e39a47");
+pub const REAL_TIME_NOTIFICATION_CAPABILITY = Guid.initString("6b59819a-5cae-492d-a901-2a3c2c50164f");
+pub const REAL_TIME_NOTIFICATION_CAPABILITY_EX = Guid.initString("6843da03-154a-4616-a508-44371295f96b");
+pub const ASSOCIATE_NAMERES_CONTEXT = Guid.initString("59a38b67-d4fe-46e1-ba3c-87ea74ca3049");
+pub const TCP_INITIAL_RTO_DEFAULT_RTT = @as(u32, 0);
+pub const TCP_INITIAL_RTO_DEFAULT_MAX_SYN_RETRANSMISSIONS = @as(u32, 0);
+pub const SOCKET_SETTINGS_GUARANTEE_ENCRYPTION = @as(u32, 1);
+pub const SOCKET_SETTINGS_ALLOW_INSECURE = @as(u32, 2);
+pub const SOCKET_SETTINGS_IPSEC_SKIP_FILTER_INSTANTIATION = @as(u32, 1);
+pub const SOCKET_SETTINGS_IPSEC_OPTIONAL_PEER_NAME_VERIFICATION = @as(u32, 2);
+pub const SOCKET_SETTINGS_IPSEC_ALLOW_FIRST_INBOUND_PKT_UNENCRYPTED = @as(u32, 4);
+pub const SOCKET_SETTINGS_IPSEC_PEER_NAME_IS_RAW_FORMAT = @as(u32, 8);
+pub const SOCKET_QUERY_IPSEC2_ABORT_CONNECTION_ON_FIELD_CHANGE = @as(u32, 1);
+pub const SOCKET_QUERY_IPSEC2_FIELD_MASK_MM_SA_ID = @as(u32, 1);
+pub const SOCKET_QUERY_IPSEC2_FIELD_MASK_QM_SA_ID = @as(u32, 2);
+pub const SOCKET_INFO_CONNECTION_SECURED = @as(u32, 1);
+pub const SOCKET_INFO_CONNECTION_ENCRYPTED = @as(u32, 2);
+pub const SOCKET_INFO_CONNECTION_IMPERSONATED = @as(u32, 4);
+pub const IN4ADDR_LOOPBACK = @as(u32, 16777343);
+pub const IN4ADDR_LOOPBACKPREFIX_LENGTH = @as(u32, 8);
+pub const IN4ADDR_LINKLOCALPREFIX_LENGTH = @as(u32, 16);
+pub const IN4ADDR_MULTICASTPREFIX_LENGTH = @as(u32, 4);
+pub const IFF_UP = @as(u32, 1);
+pub const IFF_BROADCAST = @as(u32, 2);
+pub const IFF_LOOPBACK = @as(u32, 4);
+pub const IFF_POINTTOPOINT = @as(u32, 8);
+pub const IFF_MULTICAST = @as(u32, 16);
+pub const IP_OPTIONS = @as(u32, 1);
+pub const IP_HDRINCL = @as(u32, 2);
+pub const IP_TOS = @as(u32, 3);
+pub const IP_TTL = @as(u32, 4);
+pub const IP_MULTICAST_IF = @as(u32, 9);
+pub const IP_MULTICAST_TTL = @as(u32, 10);
+pub const IP_MULTICAST_LOOP = @as(u32, 11);
+pub const IP_ADD_MEMBERSHIP = @as(u32, 12);
+pub const IP_DROP_MEMBERSHIP = @as(u32, 13);
+pub const IP_DONTFRAGMENT = @as(u32, 14);
+pub const IP_ADD_SOURCE_MEMBERSHIP = @as(u32, 15);
+pub const IP_DROP_SOURCE_MEMBERSHIP = @as(u32, 16);
+pub const IP_BLOCK_SOURCE = @as(u32, 17);
+pub const IP_UNBLOCK_SOURCE = @as(u32, 18);
+pub const IP_PKTINFO = @as(u32, 19);
+pub const IP_HOPLIMIT = @as(u32, 21);
+pub const IP_RECVTTL = @as(u32, 21);
+pub const IP_RECEIVE_BROADCAST = @as(u32, 22);
+pub const IP_RECVIF = @as(u32, 24);
+pub const IP_RECVDSTADDR = @as(u32, 25);
+pub const IP_IFLIST = @as(u32, 28);
+pub const IP_ADD_IFLIST = @as(u32, 29);
+pub const IP_DEL_IFLIST = @as(u32, 30);
+pub const IP_UNICAST_IF = @as(u32, 31);
+pub const IP_RTHDR = @as(u32, 32);
+pub const IP_GET_IFLIST = @as(u32, 33);
+pub const IP_RECVRTHDR = @as(u32, 38);
+pub const IP_TCLASS = @as(u32, 39);
+pub const IP_RECVTCLASS = @as(u32, 40);
+pub const IP_RECVTOS = @as(u32, 40);
+pub const IP_ORIGINAL_ARRIVAL_IF = @as(u32, 47);
+pub const IP_ECN = @as(u32, 50);
+pub const IP_PKTINFO_EX = @as(u32, 51);
+pub const IP_WFP_REDIRECT_RECORDS = @as(u32, 60);
+pub const IP_WFP_REDIRECT_CONTEXT = @as(u32, 70);
+pub const IP_MTU_DISCOVER = @as(u32, 71);
+pub const IP_MTU = @as(u32, 73);
+pub const IP_NRT_INTERFACE = @as(u32, 74);
+pub const IP_RECVERR = @as(u32, 75);
+pub const IP_USER_MTU = @as(u32, 76);
+pub const IP_UNSPECIFIED_TYPE_OF_SERVICE = @as(i32, -1);
+pub const IN6ADDR_LINKLOCALPREFIX_LENGTH = @as(u32, 64);
+pub const IN6ADDR_MULTICASTPREFIX_LENGTH = @as(u32, 8);
+pub const IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_LENGTH = @as(u32, 104);
+pub const IN6ADDR_V4MAPPEDPREFIX_LENGTH = @as(u32, 96);
+pub const IN6ADDR_6TO4PREFIX_LENGTH = @as(u32, 16);
+pub const IN6ADDR_TEREDOPREFIX_LENGTH = @as(u32, 32);
+pub const MCAST_JOIN_GROUP = @as(u32, 41);
+pub const MCAST_LEAVE_GROUP = @as(u32, 42);
+pub const MCAST_BLOCK_SOURCE = @as(u32, 43);
+pub const MCAST_UNBLOCK_SOURCE = @as(u32, 44);
+pub const MCAST_JOIN_SOURCE_GROUP = @as(u32, 45);
+pub const MCAST_LEAVE_SOURCE_GROUP = @as(u32, 46);
+pub const IPV6_HOPOPTS = @as(u32, 1);
+pub const IPV6_HDRINCL = @as(u32, 2);
+pub const IPV6_UNICAST_HOPS = @as(u32, 4);
+pub const IPV6_MULTICAST_IF = @as(u32, 9);
+pub const IPV6_MULTICAST_HOPS = @as(u32, 10);
+pub const IPV6_MULTICAST_LOOP = @as(u32, 11);
+pub const IPV6_ADD_MEMBERSHIP = @as(u32, 12);
+pub const IPV6_DROP_MEMBERSHIP = @as(u32, 13);
+pub const IPV6_DONTFRAG = @as(u32, 14);
+pub const IPV6_PKTINFO = @as(u32, 19);
+pub const IPV6_HOPLIMIT = @as(u32, 21);
+pub const IPV6_PROTECTION_LEVEL = @as(u32, 23);
+pub const IPV6_RECVIF = @as(u32, 24);
+pub const IPV6_RECVDSTADDR = @as(u32, 25);
+pub const IPV6_CHECKSUM = @as(u32, 26);
+pub const IPV6_V6ONLY = @as(u32, 27);
+pub const IPV6_IFLIST = @as(u32, 28);
+pub const IPV6_ADD_IFLIST = @as(u32, 29);
+pub const IPV6_DEL_IFLIST = @as(u32, 30);
+pub const IPV6_UNICAST_IF = @as(u32, 31);
+pub const IPV6_RTHDR = @as(u32, 32);
+pub const IPV6_GET_IFLIST = @as(u32, 33);
+pub const IPV6_RECVRTHDR = @as(u32, 38);
+pub const IPV6_TCLASS = @as(u32, 39);
+pub const IPV6_RECVTCLASS = @as(u32, 40);
+pub const IPV6_ECN = @as(u32, 50);
+pub const IPV6_PKTINFO_EX = @as(u32, 51);
+pub const IPV6_WFP_REDIRECT_RECORDS = @as(u32, 60);
+pub const IPV6_WFP_REDIRECT_CONTEXT = @as(u32, 70);
+pub const IPV6_MTU_DISCOVER = @as(u32, 71);
+pub const IPV6_MTU = @as(u32, 72);
+pub const IPV6_NRT_INTERFACE = @as(u32, 74);
+pub const IPV6_RECVERR = @as(u32, 75);
+pub const IPV6_USER_MTU = @as(u32, 76);
+pub const IP_UNSPECIFIED_HOP_LIMIT = @as(i32, -1);
+pub const PROTECTION_LEVEL_UNRESTRICTED = @as(u32, 10);
+pub const PROTECTION_LEVEL_EDGERESTRICTED = @as(u32, 20);
+pub const PROTECTION_LEVEL_RESTRICTED = @as(u32, 30);
+pub const INET_ADDRSTRLEN = @as(u32, 22);
+pub const INET6_ADDRSTRLEN = @as(u32, 65);
+pub const TCP_OFFLOAD_NO_PREFERENCE = @as(u32, 0);
+pub const TCP_OFFLOAD_NOT_PREFERRED = @as(u32, 1);
+pub const TCP_OFFLOAD_PREFERRED = @as(u32, 2);
+pub const TCP_EXPEDITED_1122 = @as(u32, 2);
+pub const TCP_KEEPALIVE = @as(u32, 3);
+pub const TCP_MAXSEG = @as(u32, 4);
+pub const TCP_MAXRT = @as(u32, 5);
+pub const TCP_STDURG = @as(u32, 6);
+pub const TCP_NOURG = @as(u32, 7);
+pub const TCP_ATMARK = @as(u32, 8);
+pub const TCP_NOSYNRETRIES = @as(u32, 9);
+pub const TCP_TIMESTAMPS = @as(u32, 10);
+pub const TCP_OFFLOAD_PREFERENCE = @as(u32, 11);
+pub const TCP_CONGESTION_ALGORITHM = @as(u32, 12);
+pub const TCP_DELAY_FIN_ACK = @as(u32, 13);
+pub const TCP_MAXRTMS = @as(u32, 14);
+pub const TCP_FASTOPEN = @as(u32, 15);
+pub const TCP_KEEPCNT = @as(u32, 16);
+pub const TCP_KEEPINTVL = @as(u32, 17);
+pub const TCP_FAIL_CONNECT_ON_ICMP_ERROR = @as(u32, 18);
+pub const TCP_ICMP_ERROR_INFO = @as(u32, 19);
+pub const UDP_SEND_MSG_SIZE = @as(u32, 2);
+pub const UDP_RECV_MAX_COALESCED_SIZE = @as(u32, 3);
+pub const UDP_COALESCED_INFO = @as(u32, 3);
+pub const AF_UNSPEC = @as(u32, 0);
+pub const AF_UNIX = @as(u32, 1);
+pub const AF_INET = @as(u32, 2);
+pub const AF_IMPLINK = @as(u32, 3);
+pub const AF_PUP = @as(u32, 4);
+pub const AF_CHAOS = @as(u32, 5);
+pub const AF_NS = @as(u32, 6);
+pub const AF_ISO = @as(u32, 7);
+pub const AF_ECMA = @as(u32, 8);
+pub const AF_DATAKIT = @as(u32, 9);
+pub const AF_CCITT = @as(u32, 10);
+pub const AF_SNA = @as(u32, 11);
+pub const AF_DECnet = @as(u32, 12);
+pub const AF_DLI = @as(u32, 13);
+pub const AF_LAT = @as(u32, 14);
+pub const AF_HYLINK = @as(u32, 15);
+pub const AF_APPLETALK = @as(u32, 16);
+pub const AF_NETBIOS = @as(u32, 17);
+pub const AF_VOICEVIEW = @as(u32, 18);
+pub const AF_FIREFOX = @as(u32, 19);
+pub const AF_UNKNOWN1 = @as(u32, 20);
+pub const AF_BAN = @as(u32, 21);
+pub const AF_ATM = @as(u32, 22);
+pub const AF_INET6 = @as(u32, 23);
+pub const AF_CLUSTER = @as(u32, 24);
+pub const AF_12844 = @as(u32, 25);
+pub const AF_IRDA = @as(u32, 26);
+pub const AF_NETDES = @as(u32, 28);
+pub const AF_MAX = @as(u32, 29);
+pub const AF_TCNPROCESS = @as(u32, 29);
+pub const AF_TCNMESSAGE = @as(u32, 30);
+pub const AF_ICLFXBM = @as(u32, 31);
+pub const AF_LINK = @as(u32, 33);
+pub const AF_HYPERV = @as(u32, 34);
+pub const SOCK_STREAM = @as(u32, 1);
+pub const SOCK_DGRAM = @as(u32, 2);
+pub const SOCK_RAW = @as(u32, 3);
+pub const SOCK_RDM = @as(u32, 4);
+pub const SOCK_SEQPACKET = @as(u32, 5);
+pub const SOL_SOCKET = @as(u32, 65535);
+pub const SO_DEBUG = @as(u32, 1);
+pub const SO_ACCEPTCONN = @as(u32, 2);
+pub const SO_REUSEADDR = @as(u32, 4);
+pub const SO_KEEPALIVE = @as(u32, 8);
+pub const SO_DONTROUTE = @as(u32, 16);
+pub const SO_BROADCAST = @as(u32, 32);
+pub const SO_USELOOPBACK = @as(u32, 64);
+pub const SO_LINGER = @as(u32, 128);
+pub const SO_OOBINLINE = @as(u32, 256);
+pub const SO_SNDBUF = @as(u32, 4097);
+pub const SO_RCVBUF = @as(u32, 4098);
+pub const SO_SNDLOWAT = @as(u32, 4099);
+pub const SO_RCVLOWAT = @as(u32, 4100);
+pub const SO_SNDTIMEO = @as(u32, 4101);
+pub const SO_RCVTIMEO = @as(u32, 4102);
+pub const SO_ERROR = @as(u32, 4103);
+pub const SO_TYPE = @as(u32, 4104);
+pub const SO_BSP_STATE = @as(u32, 4105);
+pub const SO_GROUP_ID = @as(u32, 8193);
+pub const SO_GROUP_PRIORITY = @as(u32, 8194);
+pub const SO_MAX_MSG_SIZE = @as(u32, 8195);
+pub const SO_CONDITIONAL_ACCEPT = @as(u32, 12290);
+pub const SO_PAUSE_ACCEPT = @as(u32, 12291);
+pub const SO_COMPARTMENT_ID = @as(u32, 12292);
+pub const SO_RANDOMIZE_PORT = @as(u32, 12293);
+pub const SO_PORT_SCALABILITY = @as(u32, 12294);
+pub const SO_REUSE_UNICASTPORT = @as(u32, 12295);
+pub const SO_REUSE_MULTICASTPORT = @as(u32, 12296);
+pub const SO_ORIGINAL_DST = @as(u32, 12303);
+pub const WSK_SO_BASE = @as(u32, 16384);
+pub const TCP_NODELAY = @as(u32, 1);
+pub const IOC_UNIX = @as(u32, 0);
+pub const IOC_WS2 = @as(u32, 134217728);
+pub const IOC_PROTOCOL = @as(u32, 268435456);
+pub const IOC_VENDOR = @as(u32, 402653184);
+pub const IPPROTO_IP = @as(u32, 0);
+pub const IPPORT_TCPMUX = @as(u32, 1);
+pub const IPPORT_ECHO = @as(u32, 7);
+pub const IPPORT_DISCARD = @as(u32, 9);
+pub const IPPORT_SYSTAT = @as(u32, 11);
+pub const IPPORT_DAYTIME = @as(u32, 13);
+pub const IPPORT_NETSTAT = @as(u32, 15);
+pub const IPPORT_QOTD = @as(u32, 17);
+pub const IPPORT_MSP = @as(u32, 18);
+pub const IPPORT_CHARGEN = @as(u32, 19);
+pub const IPPORT_FTP_DATA = @as(u32, 20);
+pub const IPPORT_FTP = @as(u32, 21);
+pub const IPPORT_TELNET = @as(u32, 23);
+pub const IPPORT_SMTP = @as(u32, 25);
+pub const IPPORT_TIMESERVER = @as(u32, 37);
+pub const IPPORT_NAMESERVER = @as(u32, 42);
+pub const IPPORT_WHOIS = @as(u32, 43);
+pub const IPPORT_MTP = @as(u32, 57);
+pub const IPPORT_TFTP = @as(u32, 69);
+pub const IPPORT_RJE = @as(u32, 77);
+pub const IPPORT_FINGER = @as(u32, 79);
+pub const IPPORT_TTYLINK = @as(u32, 87);
+pub const IPPORT_SUPDUP = @as(u32, 95);
+pub const IPPORT_POP3 = @as(u32, 110);
+pub const IPPORT_NTP = @as(u32, 123);
+pub const IPPORT_EPMAP = @as(u32, 135);
+pub const IPPORT_NETBIOS_NS = @as(u32, 137);
+pub const IPPORT_NETBIOS_DGM = @as(u32, 138);
+pub const IPPORT_NETBIOS_SSN = @as(u32, 139);
+pub const IPPORT_IMAP = @as(u32, 143);
+pub const IPPORT_SNMP = @as(u32, 161);
+pub const IPPORT_SNMP_TRAP = @as(u32, 162);
+pub const IPPORT_IMAP3 = @as(u32, 220);
+pub const IPPORT_LDAP = @as(u32, 389);
+pub const IPPORT_HTTPS = @as(u32, 443);
+pub const IPPORT_MICROSOFT_DS = @as(u32, 445);
+pub const IPPORT_EXECSERVER = @as(u32, 512);
+pub const IPPORT_LOGINSERVER = @as(u32, 513);
+pub const IPPORT_CMDSERVER = @as(u32, 514);
+pub const IPPORT_EFSSERVER = @as(u32, 520);
+pub const IPPORT_BIFFUDP = @as(u32, 512);
+pub const IPPORT_WHOSERVER = @as(u32, 513);
+pub const IPPORT_ROUTESERVER = @as(u32, 520);
+pub const IPPORT_RESERVED = @as(u32, 1024);
+pub const IPPORT_REGISTERED_MAX = @as(u32, 49151);
+pub const IPPORT_DYNAMIC_MIN = @as(u32, 49152);
+pub const IPPORT_DYNAMIC_MAX = @as(u32, 65535);
+pub const IN_CLASSA_NET = @as(u32, 4278190080);
+pub const IN_CLASSA_NSHIFT = @as(u32, 24);
+pub const IN_CLASSA_HOST = @as(u32, 16777215);
+pub const IN_CLASSA_MAX = @as(u32, 128);
+pub const IN_CLASSB_NET = @as(u32, 4294901760);
+pub const IN_CLASSB_NSHIFT = @as(u32, 16);
+pub const IN_CLASSB_HOST = @as(u32, 65535);
+pub const IN_CLASSB_MAX = @as(u32, 65536);
+pub const IN_CLASSC_NET = @as(u32, 4294967040);
+pub const IN_CLASSC_NSHIFT = @as(u32, 8);
+pub const IN_CLASSC_HOST = @as(u32, 255);
+pub const IN_CLASSD_NET = @as(u32, 4026531840);
+pub const IN_CLASSD_NSHIFT = @as(u32, 28);
+pub const IN_CLASSD_HOST = @as(u32, 268435455);
+pub const INADDR_LOOPBACK = @as(u32, 2130706433);
+pub const INADDR_NONE = @as(u32, 4294967295);
+pub const IOCPARM_MASK = @as(u32, 127);
+pub const IOC_VOID = @as(u32, 536870912);
+pub const IOC_OUT = @as(u32, 1073741824);
+pub const IOC_IN = @as(u32, 2147483648);
+pub const MSG_TRUNC = @as(u32, 256);
+pub const MSG_CTRUNC = @as(u32, 512);
+pub const MSG_BCAST = @as(u32, 1024);
+pub const MSG_MCAST = @as(u32, 2048);
+pub const MSG_ERRQUEUE = @as(u32, 4096);
+pub const AI_PASSIVE = @as(u32, 1);
+pub const AI_CANONNAME = @as(u32, 2);
+pub const AI_NUMERICHOST = @as(u32, 4);
+pub const AI_NUMERICSERV = @as(u32, 8);
+pub const AI_DNS_ONLY = @as(u32, 16);
+pub const AI_ALL = @as(u32, 256);
+pub const AI_ADDRCONFIG = @as(u32, 1024);
+pub const AI_V4MAPPED = @as(u32, 2048);
+pub const AI_NON_AUTHORITATIVE = @as(u32, 16384);
+pub const AI_SECURE = @as(u32, 32768);
+pub const AI_RETURN_PREFERRED_NAMES = @as(u32, 65536);
+pub const AI_FQDN = @as(u32, 131072);
+pub const AI_FILESERVER = @as(u32, 262144);
+pub const AI_DISABLE_IDN_ENCODING = @as(u32, 524288);
+pub const AI_EXTENDED = @as(u32, 2147483648);
+pub const AI_RESOLUTION_HANDLE = @as(u32, 1073741824);
+pub const ADDRINFOEX_VERSION_2 = @as(u32, 2);
+pub const ADDRINFOEX_VERSION_3 = @as(u32, 3);
+pub const ADDRINFOEX_VERSION_4 = @as(u32, 4);
+pub const NS_ALL = @as(u32, 0);
+pub const NS_SAP = @as(u32, 1);
+pub const NS_NDS = @as(u32, 2);
+pub const NS_PEER_BROWSE = @as(u32, 3);
+pub const NS_SLP = @as(u32, 5);
+pub const NS_DHCP = @as(u32, 6);
+pub const NS_TCPIP_LOCAL = @as(u32, 10);
+pub const NS_TCPIP_HOSTS = @as(u32, 11);
+pub const NS_DNS = @as(u32, 12);
+pub const NS_NETBT = @as(u32, 13);
+pub const NS_WINS = @as(u32, 14);
+pub const NS_NLA = @as(u32, 15);
+pub const NS_NBP = @as(u32, 20);
+pub const NS_MS = @as(u32, 30);
+pub const NS_STDA = @as(u32, 31);
+pub const NS_NTDS = @as(u32, 32);
+pub const NS_EMAIL = @as(u32, 37);
+pub const NS_X500 = @as(u32, 40);
+pub const NS_NIS = @as(u32, 41);
+pub const NS_NISPLUS = @as(u32, 42);
+pub const NS_WRQ = @as(u32, 50);
+pub const NS_NETDES = @as(u32, 60);
+pub const NI_NOFQDN = @as(u32, 1);
+pub const NI_NUMERICHOST = @as(u32, 2);
+pub const NI_NAMEREQD = @as(u32, 4);
+pub const NI_NUMERICSERV = @as(u32, 8);
+pub const NI_DGRAM = @as(u32, 16);
+pub const NI_MAXHOST = @as(u32, 1025);
+pub const NI_MAXSERV = @as(u32, 32);
+pub const INCL_WINSOCK_API_PROTOTYPES = @as(u32, 1);
+pub const INCL_WINSOCK_API_TYPEDEFS = @as(u32, 0);
+pub const FD_SETSIZE = @as(u32, 64);
+pub const IMPLINK_IP = @as(u32, 155);
+pub const IMPLINK_LOWEXPER = @as(u32, 156);
+pub const IMPLINK_HIGHEXPER = @as(u32, 158);
+pub const WSADESCRIPTION_LEN = @as(u32, 256);
+pub const WSASYS_STATUS_LEN = @as(u32, 128);
+pub const SOCKET_ERROR = @as(i32, -1);
+pub const FROM_PROTOCOL_INFO = @as(i32, -1);
+pub const SO_PROTOCOL_INFOA = @as(u32, 8196);
+pub const SO_PROTOCOL_INFOW = @as(u32, 8197);
+pub const PVD_CONFIG = @as(u32, 12289);
+pub const SOMAXCONN = @as(u32, 2147483647);
+pub const MSG_PEEK = @as(u32, 2);
+pub const MSG_WAITALL = @as(u32, 8);
+pub const MSG_PUSH_IMMEDIATE = @as(u32, 32);
+pub const MSG_PARTIAL = @as(u32, 32768);
+pub const MSG_INTERRUPT = @as(u32, 16);
+pub const MSG_MAXIOVLEN = @as(u32, 16);
+pub const MAXGETHOSTSTRUCT = @as(u32, 1024);
+pub const FD_READ_BIT = @as(u32, 0);
+pub const FD_WRITE_BIT = @as(u32, 1);
+pub const FD_OOB_BIT = @as(u32, 2);
+pub const FD_ACCEPT_BIT = @as(u32, 3);
+pub const FD_CONNECT_BIT = @as(u32, 4);
+pub const FD_CLOSE_BIT = @as(u32, 5);
+pub const FD_QOS_BIT = @as(u32, 6);
+pub const FD_GROUP_QOS_BIT = @as(u32, 7);
+pub const FD_ROUTING_INTERFACE_CHANGE_BIT = @as(u32, 8);
+pub const FD_ADDRESS_LIST_CHANGE_BIT = @as(u32, 9);
+pub const FD_MAX_EVENTS = @as(u32, 10);
+pub const CF_ACCEPT = @as(u32, 0);
+pub const CF_REJECT = @as(u32, 1);
+pub const CF_DEFER = @as(u32, 2);
+pub const SD_RECEIVE = @as(u32, 0);
+pub const SD_SEND = @as(u32, 1);
+pub const SD_BOTH = @as(u32, 2);
+pub const SG_UNCONSTRAINED_GROUP = @as(u32, 1);
+pub const SG_CONSTRAINED_GROUP = @as(u32, 2);
+pub const MAX_PROTOCOL_CHAIN = @as(u32, 7);
+pub const BASE_PROTOCOL = @as(u32, 1);
+pub const LAYERED_PROTOCOL = @as(u32, 0);
+pub const WSAPROTOCOL_LEN = @as(u32, 255);
+pub const PFL_MULTIPLE_PROTO_ENTRIES = @as(u32, 1);
+pub const PFL_RECOMMENDED_PROTO_ENTRY = @as(u32, 2);
+pub const PFL_HIDDEN = @as(u32, 4);
+pub const PFL_MATCHES_PROTOCOL_ZERO = @as(u32, 8);
+pub const PFL_NETWORKDIRECT_PROVIDER = @as(u32, 16);
+pub const XP1_CONNECTIONLESS = @as(u32, 1);
+pub const XP1_GUARANTEED_DELIVERY = @as(u32, 2);
+pub const XP1_GUARANTEED_ORDER = @as(u32, 4);
+pub const XP1_MESSAGE_ORIENTED = @as(u32, 8);
+pub const XP1_PSEUDO_STREAM = @as(u32, 16);
+pub const XP1_GRACEFUL_CLOSE = @as(u32, 32);
+pub const XP1_EXPEDITED_DATA = @as(u32, 64);
+pub const XP1_CONNECT_DATA = @as(u32, 128);
+pub const XP1_DISCONNECT_DATA = @as(u32, 256);
+pub const XP1_SUPPORT_BROADCAST = @as(u32, 512);
+pub const XP1_SUPPORT_MULTIPOINT = @as(u32, 1024);
+pub const XP1_MULTIPOINT_CONTROL_PLANE = @as(u32, 2048);
+pub const XP1_MULTIPOINT_DATA_PLANE = @as(u32, 4096);
+pub const XP1_QOS_SUPPORTED = @as(u32, 8192);
+pub const XP1_INTERRUPT = @as(u32, 16384);
+pub const XP1_UNI_SEND = @as(u32, 32768);
+pub const XP1_UNI_RECV = @as(u32, 65536);
+pub const XP1_IFS_HANDLES = @as(u32, 131072);
+pub const XP1_PARTIAL_MESSAGE = @as(u32, 262144);
+pub const XP1_SAN_SUPPORT_SDP = @as(u32, 524288);
+pub const BIGENDIAN = @as(u32, 0);
+pub const LITTLEENDIAN = @as(u32, 1);
+pub const SECURITY_PROTOCOL_NONE = @as(u32, 0);
+pub const JL_SENDER_ONLY = @as(u32, 1);
+pub const JL_RECEIVER_ONLY = @as(u32, 2);
+pub const JL_BOTH = @as(u32, 4);
+pub const WSA_FLAG_OVERLAPPED = @as(u32, 1);
+pub const WSA_FLAG_MULTIPOINT_C_ROOT = @as(u32, 2);
+pub const WSA_FLAG_MULTIPOINT_C_LEAF = @as(u32, 4);
+pub const WSA_FLAG_MULTIPOINT_D_ROOT = @as(u32, 8);
+pub const WSA_FLAG_MULTIPOINT_D_LEAF = @as(u32, 16);
+pub const WSA_FLAG_ACCESS_SYSTEM_SECURITY = @as(u32, 64);
+pub const WSA_FLAG_NO_HANDLE_INHERIT = @as(u32, 128);
+pub const WSA_FLAG_REGISTERED_IO = @as(u32, 256);
+pub const TH_NETDEV = @as(u32, 1);
+pub const TH_TAPI = @as(u32, 2);
+pub const SERVICE_MULTIPLE = @as(u32, 1);
+pub const NS_LOCALNAME = @as(u32, 19);
+pub const RES_UNUSED_1 = @as(u32, 1);
+pub const RES_FLUSH_CACHE = @as(u32, 2);
+pub const RES_SERVICE = @as(u32, 4);
+pub const LUP_DEEP = @as(u32, 1);
+pub const LUP_CONTAINERS = @as(u32, 2);
+pub const LUP_NOCONTAINERS = @as(u32, 4);
+pub const LUP_NEAREST = @as(u32, 8);
+pub const LUP_RETURN_NAME = @as(u32, 16);
+pub const LUP_RETURN_TYPE = @as(u32, 32);
+pub const LUP_RETURN_VERSION = @as(u32, 64);
+pub const LUP_RETURN_COMMENT = @as(u32, 128);
+pub const LUP_RETURN_ADDR = @as(u32, 256);
+pub const LUP_RETURN_BLOB = @as(u32, 512);
+pub const LUP_RETURN_ALIASES = @as(u32, 1024);
+pub const LUP_RETURN_QUERY_STRING = @as(u32, 2048);
+pub const LUP_RETURN_ALL = @as(u32, 4080);
+pub const LUP_RES_SERVICE = @as(u32, 32768);
+pub const LUP_FLUSHCACHE = @as(u32, 4096);
+pub const LUP_FLUSHPREVIOUS = @as(u32, 8192);
+pub const LUP_NON_AUTHORITATIVE = @as(u32, 16384);
+pub const LUP_SECURE = @as(u32, 32768);
+pub const LUP_RETURN_PREFERRED_NAMES = @as(u32, 65536);
+pub const LUP_DNS_ONLY = @as(u32, 131072);
+pub const LUP_ADDRCONFIG = @as(u32, 1048576);
+pub const LUP_DUAL_ADDR = @as(u32, 2097152);
+pub const LUP_FILESERVER = @as(u32, 4194304);
+pub const LUP_DISABLE_IDN_ENCODING = @as(u32, 8388608);
+pub const LUP_API_ANSI = @as(u32, 16777216);
+pub const LUP_RESOLUTION_HANDLE = @as(u32, 2147483648);
+pub const RESULT_IS_ALIAS = @as(u32, 1);
+pub const RESULT_IS_ADDED = @as(u32, 16);
+pub const RESULT_IS_CHANGED = @as(u32, 32);
+pub const RESULT_IS_DELETED = @as(u32, 64);
+pub const POLLRDNORM = @as(u32, 256);
+pub const POLLRDBAND = @as(u32, 512);
+pub const POLLPRI = @as(u32, 1024);
+pub const POLLWRNORM = @as(u32, 16);
+pub const POLLWRBAND = @as(u32, 32);
+pub const POLLERR = @as(u32, 1);
+pub const POLLHUP = @as(u32, 2);
+pub const POLLNVAL = @as(u32, 4);
+pub const SO_CONNDATA = @as(u32, 28672);
+pub const SO_CONNOPT = @as(u32, 28673);
+pub const SO_DISCDATA = @as(u32, 28674);
+pub const SO_DISCOPT = @as(u32, 28675);
+pub const SO_CONNDATALEN = @as(u32, 28676);
+pub const SO_CONNOPTLEN = @as(u32, 28677);
+pub const SO_DISCDATALEN = @as(u32, 28678);
+pub const SO_DISCOPTLEN = @as(u32, 28679);
+pub const SO_OPENTYPE = @as(u32, 28680);
+pub const SO_SYNCHRONOUS_ALERT = @as(u32, 16);
+pub const SO_SYNCHRONOUS_NONALERT = @as(u32, 32);
+pub const SO_MAXDG = @as(u32, 28681);
+pub const SO_MAXPATHDG = @as(u32, 28682);
+pub const SO_UPDATE_ACCEPT_CONTEXT = @as(u32, 28683);
+pub const SO_CONNECT_TIME = @as(u32, 28684);
+pub const SO_UPDATE_CONNECT_CONTEXT = @as(u32, 28688);
+pub const TCP_BSDURGENT = @as(u32, 28672);
+pub const TF_DISCONNECT = @as(u32, 1);
+pub const TF_REUSE_SOCKET = @as(u32, 2);
+pub const TF_WRITE_BEHIND = @as(u32, 4);
+pub const TF_USE_DEFAULT_WORKER = @as(u32, 0);
+pub const TF_USE_SYSTEM_THREAD = @as(u32, 16);
+pub const TF_USE_KERNEL_APC = @as(u32, 32);
+pub const TP_ELEMENT_MEMORY = @as(u32, 1);
+pub const TP_ELEMENT_FILE = @as(u32, 2);
+pub const TP_ELEMENT_EOP = @as(u32, 4);
+pub const NLA_ALLUSERS_NETWORK = @as(u32, 1);
+pub const NLA_FRIENDLY_NAME = @as(u32, 2);
+pub const WSPDESCRIPTION_LEN = @as(u32, 255);
+pub const WSS_OPERATION_IN_PROGRESS = @as(i32, 259);
+pub const LSP_SYSTEM = @as(u32, 2147483648);
+pub const LSP_INSPECTOR = @as(u32, 1);
+pub const LSP_REDIRECTOR = @as(u32, 2);
+pub const LSP_PROXY = @as(u32, 4);
+pub const LSP_FIREWALL = @as(u32, 8);
+pub const LSP_INBOUND_MODIFY = @as(u32, 16);
+pub const LSP_OUTBOUND_MODIFY = @as(u32, 32);
+pub const LSP_CRYPTO_COMPRESS = @as(u32, 64);
+pub const LSP_LOCAL_CACHE = @as(u32, 128);
+pub const IPPROTO_ICMP = @as(u32, 1);
+pub const IPPROTO_IGMP = @as(u32, 2);
+pub const IPPROTO_GGP = @as(u32, 3);
+pub const IPPROTO_TCP = @as(u32, 6);
+pub const IPPROTO_PUP = @as(u32, 12);
+pub const IPPROTO_UDP = @as(u32, 17);
+pub const IPPROTO_IDP = @as(u32, 22);
+pub const IPPROTO_ND = @as(u32, 77);
+pub const IPPROTO_RAW = @as(u32, 255);
+pub const IPPROTO_MAX = @as(u32, 256);
+pub const IP_DEFAULT_MULTICAST_TTL = @as(u32, 1);
+pub const IP_DEFAULT_MULTICAST_LOOP = @as(u32, 1);
+pub const IP_MAX_MEMBERSHIPS = @as(u32, 20);
+pub const AF_IPX = @as(u32, 6);
+pub const FD_READ = @as(u32, 1);
+pub const FD_WRITE = @as(u32, 2);
+pub const FD_OOB = @as(u32, 4);
+pub const FD_ACCEPT = @as(u32, 8);
+pub const FD_CONNECT = @as(u32, 16);
+pub const FD_CLOSE = @as(u32, 32);
+pub const SERVICE_RESOURCE = @as(u32, 1);
+pub const SERVICE_SERVICE = @as(u32, 2);
+pub const SERVICE_LOCAL = @as(u32, 4);
+pub const SERVICE_FLAG_DEFER = @as(u32, 1);
+pub const SERVICE_FLAG_HARD = @as(u32, 2);
+pub const PROP_COMMENT = @as(u32, 1);
+pub const PROP_LOCALE = @as(u32, 2);
+pub const PROP_DISPLAY_HINT = @as(u32, 4);
+pub const PROP_VERSION = @as(u32, 8);
+pub const PROP_START_TIME = @as(u32, 16);
+pub const PROP_MACHINE = @as(u32, 32);
+pub const PROP_ADDRESSES = @as(u32, 256);
+pub const PROP_SD = @as(u32, 512);
+pub const PROP_ALL = @as(u32, 2147483648);
+pub const SERVICE_ADDRESS_FLAG_RPC_CN = @as(u32, 1);
+pub const SERVICE_ADDRESS_FLAG_RPC_DG = @as(u32, 2);
+pub const SERVICE_ADDRESS_FLAG_RPC_NB = @as(u32, 4);
+pub const NS_DEFAULT = @as(u32, 0);
+pub const NS_VNS = @as(u32, 50);
+pub const NSTYPE_HIERARCHICAL = @as(u32, 1);
+pub const NSTYPE_DYNAMIC = @as(u32, 2);
+pub const NSTYPE_ENUMERABLE = @as(u32, 4);
+pub const NSTYPE_WORKGROUP = @as(u32, 8);
+pub const XP_CONNECTIONLESS = @as(u32, 1);
+pub const XP_GUARANTEED_DELIVERY = @as(u32, 2);
+pub const XP_GUARANTEED_ORDER = @as(u32, 4);
+pub const XP_MESSAGE_ORIENTED = @as(u32, 8);
+pub const XP_PSEUDO_STREAM = @as(u32, 16);
+pub const XP_GRACEFUL_CLOSE = @as(u32, 32);
+pub const XP_EXPEDITED_DATA = @as(u32, 64);
+pub const XP_CONNECT_DATA = @as(u32, 128);
+pub const XP_DISCONNECT_DATA = @as(u32, 256);
+pub const XP_SUPPORTS_BROADCAST = @as(u32, 512);
+pub const XP_SUPPORTS_MULTICAST = @as(u32, 1024);
+pub const XP_BANDWIDTH_ALLOCATION = @as(u32, 2048);
+pub const XP_FRAGMENTATION = @as(u32, 4096);
+pub const XP_ENCRYPTS = @as(u32, 8192);
+pub const RES_SOFT_SEARCH = @as(u32, 1);
+pub const RES_FIND_MULTIPLE = @as(u32, 2);
+pub const SET_SERVICE_PARTIAL_SUCCESS = @as(u32, 1);
+pub const UDP_NOCHECKSUM = @as(u32, 1);
+pub const UDP_CHECKSUM_COVERAGE = @as(u32, 20);
+pub const GAI_STRERROR_BUFFER_SIZE = @as(u32, 1024);
+
+pub const LPCONDITIONPROC = fn (
+    lpCallerId: *WSABUF,
+    lpCallerData: *WSABUF,
+    lpSQOS: *QOS,
+    lpGQOS: *QOS,
+    lpCalleeId: *WSABUF,
+    lpCalleeData: *WSABUF,
+    g: *u32,
+    dwCallbackData: usize,
+) callconv(WINAPI) i32;
+
+pub const LPWSAOVERLAPPED_COMPLETION_ROUTINE = fn (
+    dwError: u32,
+    cbTransferred: u32,
+    lpOverlapped: *OVERLAPPED,
+    dwFlags: u32,
+) callconv(WINAPI) void;
+
+pub const FLOWSPEC = extern struct {
+    TokenRate: u32,
+    TokenBucketSize: u32,
+    PeakBandwidth: u32,
+    Latency: u32,
+    DelayVariation: u32,
+    ServiceType: u32,
+    MaxSduSize: u32,
+    MinimumPolicedSize: u32,
+};
+
+pub const QOS = extern struct {
+    SendingFlowspec: FLOWSPEC,
+    ReceivingFlowspec: FLOWSPEC,
+    ProviderSpecific: WSABUF,
+};
+
+pub const SOCKET_ADDRESS = extern struct {
+    lpSockaddr: *sockaddr,
+    iSockaddrLength: i32,
+};
+
+pub const SOCKET_ADDRESS_LIST = extern struct {
+    iAddressCount: i32,
+    Address: [1]SOCKET_ADDRESS,
+};
 
 pub const WSADATA = if (@sizeOf(usize) == @sizeOf(u64))
     extern struct {
@@ -33,15 +902,11 @@ else
         lpVendorInfo: *u8,
     };
 
-pub const MAX_PROTOCOL_CHAIN = 7;
-
 pub const WSAPROTOCOLCHAIN = extern struct {
     ChainLen: c_int,
     ChainEntries: [MAX_PROTOCOL_CHAIN]DWORD,
 };
 
-pub const WSAPROTOCOL_LEN = 255;
-
 pub const WSAPROTOCOL_INFOA = extern struct {
     dwServiceFlags1: DWORD,
     dwServiceFlags2: DWORD,
@@ -88,20 +953,20 @@ pub const WSAPROTOCOL_INFOW = extern struct {
     szProtocol: [WSAPROTOCOL_LEN + 1]WCHAR,
 };
 
-pub const GROUP = u32;
-
-pub const SG_UNCONSTRAINED_GROUP = 0x1;
-pub const SG_CONSTRAINED_GROUP = 0x2;
+pub const sockproto = extern struct {
+    sp_family: u16,
+    sp_protocol: u16,
+};
 
-pub const WSA_FLAG_OVERLAPPED = 0x01;
-pub const WSA_FLAG_MULTIPOINT_C_ROOT = 0x02;
-pub const WSA_FLAG_MULTIPOINT_C_LEAF = 0x04;
-pub const WSA_FLAG_MULTIPOINT_D_ROOT = 0x08;
-pub const WSA_FLAG_MULTIPOINT_D_LEAF = 0x10;
-pub const WSA_FLAG_ACCESS_SYSTEM_SECURITY = 0x40;
-pub const WSA_FLAG_NO_HANDLE_INHERIT = 0x80;
+pub const linger = extern struct {
+    l_onoff: u16,
+    l_linger: u16,
+};
 
-pub const WSAEVENT = HANDLE;
+pub const WSANETWORKEVENTS = extern struct {
+    lNetworkEvents: i32,
+    iErrorCode: [10]i32,
+};
 
 pub const WSAOVERLAPPED = extern struct {
     Internal: DWORD,
@@ -111,82 +976,9 @@ pub const WSAOVERLAPPED = extern struct {
     hEvent: ?WSAEVENT,
 };
 
-pub const WSAOVERLAPPED_COMPLETION_ROUTINE = fn (dwError: DWORD, cbTransferred: DWORD, lpOverlapped: *WSAOVERLAPPED, dwFlags: DWORD) callconv(.C) void;
-
-pub const ADDRESS_FAMILY = u16;
+pub const addrinfo = addrinfoa;
 
-// Microsoft use the signed c_int for this, but it should never be negative
-pub const socklen_t = u32;
-
-pub const AF_UNSPEC = 0;
-pub const AF_UNIX = 1;
-pub const AF_INET = 2;
-pub const AF_IMPLINK = 3;
-pub const AF_PUP = 4;
-pub const AF_CHAOS = 5;
-pub const AF_NS = 6;
-pub const AF_IPX = AF_NS;
-pub const AF_ISO = 7;
-pub const AF_OSI = AF_ISO;
-pub const AF_ECMA = 8;
-pub const AF_DATAKIT = 9;
-pub const AF_CCITT = 10;
-pub const AF_SNA = 11;
-pub const AF_DECnet = 12;
-pub const AF_DLI = 13;
-pub const AF_LAT = 14;
-pub const AF_HYLINK = 15;
-pub const AF_APPLETALK = 16;
-pub const AF_NETBIOS = 17;
-pub const AF_VOICEVIEW = 18;
-pub const AF_FIREFOX = 19;
-pub const AF_UNKNOWN1 = 20;
-pub const AF_BAN = 21;
-pub const AF_ATM = 22;
-pub const AF_INET6 = 23;
-pub const AF_CLUSTER = 24;
-pub const AF_12844 = 25;
-pub const AF_IRDA = 26;
-pub const AF_NETDES = 28;
-pub const AF_TCNPROCESS = 29;
-pub const AF_TCNMESSAGE = 30;
-pub const AF_ICLFXBM = 31;
-pub const AF_BTH = 32;
-pub const AF_MAX = 33;
-
-pub const SOCK_STREAM = 1;
-pub const SOCK_DGRAM = 2;
-pub const SOCK_RAW = 3;
-pub const SOCK_RDM = 4;
-pub const SOCK_SEQPACKET = 5;
-
-pub const IPPROTO_ICMP = 1;
-pub const IPPROTO_IGMP = 2;
-pub const BTHPROTO_RFCOMM = 3;
-pub const IPPROTO_TCP = 6;
-pub const IPPROTO_UDP = 17;
-pub const IPPROTO_ICMPV6 = 58;
-pub const IPPROTO_RM = 113;
-
-pub const AI_PASSIVE = 0x00001;
-pub const AI_CANONNAME = 0x00002;
-pub const AI_NUMERICHOST = 0x00004;
-pub const AI_NUMERICSERV = 0x00008;
-pub const AI_ADDRCONFIG = 0x00400;
-pub const AI_V4MAPPED = 0x00800;
-pub const AI_NON_AUTHORITATIVE = 0x04000;
-pub const AI_SECURE = 0x08000;
-pub const AI_RETURN_PREFERRED_NAMES = 0x10000;
-pub const AI_DISABLE_IDN_ENCODING = 0x80000;
-
-pub const FIONBIO = -2147195266;
-
-pub const sockaddr = extern struct {
-    family: ADDRESS_FAMILY,
-    data: [14]u8,
-};
-
-pub const addrinfo = extern struct {
+pub const addrinfoa = extern struct {
     flags: i32,
     family: i32,
     socktype: i32,
@@ -197,6 +989,32 @@ pub const addrinfo = extern struct {
     next: ?*addrinfo,
 };
 
+pub const addrinfoexA = extern struct {
+    ai_flags: i32,
+    ai_family: i32,
+    ai_socktype: i32,
+    ai_protocol: i32,
+    ai_addrlen: usize,
+    ai_canonname: [*:0]u8,
+    ai_addr: *sockaddr,
+    ai_blob: *c_void,
+    ai_bloblen: usize,
+    ai_provider: *Guid,
+    ai_next: *addrinfoexA,
+};
+
+pub const sockaddr = extern struct {
+    family: ADDRESS_FAMILY,
+    data: [14]u8,
+};
+
+pub const sockaddr_storage = extern struct {
+    family: ADDRESS_FAMILY,
+    __pad1: [6]u8,
+    __align: i64,
+    __pad2: [112]u8,
+};
+
 /// IPv4 socket address
 pub const sockaddr_in = extern struct {
     family: ADDRESS_FAMILY = AF_INET,
@@ -225,7 +1043,10 @@ pub const WSABUF = extern struct {
     buf: [*]u8,
 };
 
-pub const WSAMSG = extern struct {
+pub const msghdr = WSAMSG;
+pub const msghdr_const = WSAMSG_const;
+
+pub const WSAMSG_const = extern struct {
     name: *const sockaddr,
     namelen: INT,
     lpBuffers: [*]WSABUF,
@@ -234,26 +1055,108 @@ pub const WSAMSG = extern struct {
     dwFlags: DWORD,
 };
 
+pub const WSAMSG = extern struct {
+    name: *sockaddr,
+    namelen: INT,
+    lpBuffers: [*]WSABUF,
+    dwBufferCount: DWORD,
+    Control: WSABUF,
+    dwFlags: DWORD,
+};
+
+pub const WSAPOLLFD = pollfd;
+
 pub const pollfd = extern struct {
     fd: SOCKET,
     events: SHORT,
     revents: SHORT,
 };
 
-// Event flag definitions for WSAPoll().
+pub const TRANSMIT_FILE_BUFFERS = extern struct {
+    Head: *c_void,
+    HeadLength: u32,
+    Tail: *c_void,
+    TailLength: u32,
+};
+
+pub const LPFN_TRANSMITFILE = fn (
+    hSocket: SOCKET,
+    hFile: HANDLE,
+    nNumberOfBytesToWrite: u32,
+    nNumberOfBytesPerSend: u32,
+    lpOverlapped: ?*OVERLAPPED,
+    lpTransmitBuffers: ?*TRANSMIT_FILE_BUFFERS,
+    dwReserved: u32,
+) callconv(WINAPI) BOOL;
+
+pub const LPFN_ACCEPTEX = fn (
+    sListenSocket: SOCKET,
+    sAcceptSocket: SOCKET,
+    lpOutputBuffer: *c_void,
+    dwReceiveDataLength: u32,
+    dwLocalAddressLength: u32,
+    dwRemoteAddressLength: u32,
+    lpdwBytesReceived: *u32,
+    lpOverlapped: *OVERLAPPED,
+) callconv(WINAPI) BOOL;
+
+pub const LPFN_GETACCEPTEXSOCKADDRS = fn (
+    lpOutputBuffer: *c_void,
+    dwReceiveDataLength: u32,
+    dwLocalAddressLength: u32,
+    dwRemoteAddressLength: u32,
+    LocalSockaddr: **sockaddr,
+    LocalSockaddrLength: *i32,
+    RemoteSockaddr: **sockaddr,
+    RemoteSockaddrLength: *i32,
+) callconv(WINAPI) void;
+
+pub const LFN_WSASENDMSG = fn (
+    s: SOCKET,
+    lpMsg: *WSAMSG_const,
+    dwFlags: u32,
+    lpNumberOfBytesSent: ?*u32,
+    lpOverlapped: ?*OVERLAPPED,
+    lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+) callconv(WINAPI) i32;
 
-pub const POLLRDNORM = 0x0100;
-pub const POLLRDBAND = 0x0200;
-pub const POLLIN = (POLLRDNORM | POLLRDBAND);
-pub const POLLPRI = 0x0400;
+pub const LPFN_WSARECVMSG = fn (
+    s: SOCKET,
+    lpMsg: *WSAMSG,
+    lpdwNumberOfBytesRecv: ?*u32,
+    lpOverlapped: ?*OVERLAPPED,
+    lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+) callconv(WINAPI) i32;
 
-pub const POLLWRNORM = 0x0010;
-pub const POLLOUT = (POLLWRNORM);
-pub const POLLWRBAND = 0x0020;
+pub const LPSERVICE_CALLBACK_PROC = fn (
+    lParam: LPARAM,
+    hAsyncTaskHandle: HANDLE,
+) callconv(WINAPI) void;
 
-pub const POLLERR = 0x0001;
-pub const POLLHUP = 0x0002;
-pub const POLLNVAL = 0x0004;
+pub const SERVICE_ASYNC_INFO = extern struct {
+    lpServiceCallbackProc: LPSERVICE_CALLBACK_PROC,
+    lParam: LPARAM,
+    hAsyncTaskHandle: HANDLE,
+};
+
+pub const LPLOOKUPSERVICE_COMPLETION_ROUTINE = fn (
+    dwError: u32,
+    dwBytes: u32,
+    lpOverlapped: *OVERLAPPED,
+) callconv(WINAPI) void;
+
+pub const fd_set = extern struct {
+    fd_count: u32,
+    fd_array: [64]SOCKET,
+};
+
+pub const hostent = extern struct {
+    h_name: [*]u8,
+    h_aliases: **i8,
+    h_addrtype: i16,
+    h_length: i16,
+    h_addr_list: **i8,
+};
 
 // https://docs.microsoft.com/en-au/windows/win32/winsock/windows-sockets-error-codes-2
 pub const WinsockError = extern enum(u16) {
@@ -704,180 +1607,649 @@ pub const WinsockError = extern enum(u16) {
     _,
 };
 
-/// no parameters
-const IOC_VOID = 0x80000000;
+pub extern "ws2_32" fn accept(
+    s: SOCKET,
+    addr: ?*sockaddr,
+    addrlen: ?*i32,
+) callconv(WINAPI) SOCKET;
+
+pub extern "ws2_32" fn bind(
+    s: SOCKET,
+    name: *const sockaddr,
+    namelen: i32,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn closesocket(
+    s: SOCKET,
+) callconv(WINAPI) i32;
 
-/// copy out parameters
-const IOC_OUT = 0x40000000;
+pub extern "ws2_32" fn connect(
+    s: SOCKET,
+    name: *const sockaddr,
+    namelen: i32,
+) callconv(WINAPI) i32;
 
-/// copy in parameters
-const IOC_IN = 0x80000000;
+pub extern "ws2_32" fn ioctlsocket(
+    s: SOCKET,
+    cmd: i32,
+    argp: *u32,
+) callconv(WINAPI) i32;
 
-/// The IOCTL is a generic Windows Sockets 2 IOCTL code. New IOCTL codes defined for Windows Sockets 2 will have T == 1.
-const IOC_WS2 = 0x08000000;
+pub extern "ws2_32" fn getpeername(
+    s: SOCKET,
+    name: *sockaddr,
+    namelen: *i32,
+) callconv(WINAPI) i32;
 
-pub const SIO_BASE_HANDLE = IOC_OUT | IOC_WS2 | 34;
+pub extern "ws2_32" fn getsockname(
+    s: SOCKET,
+    name: *sockaddr,
+    namelen: *i32,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn getsockopt(
+    s: SOCKET,
+    level: i32,
+    optname: i32,
+    optval: [*]u8,
+    optlen: *i32,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn htonl(
+    hostlong: u32,
+) callconv(WINAPI) u32;
+
+pub extern "ws2_32" fn htons(
+    hostshort: u16,
+) callconv(WINAPI) u16;
+
+pub extern "ws2_32" fn inet_addr(
+    cp: [*]const u8,
+) callconv(WINAPI) u32;
+
+pub extern "ws2_32" fn listen(
+    s: SOCKET,
+    backlog: i32,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn ntohl(
+    netlong: u32,
+) callconv(WINAPI) u32;
+
+pub extern "ws2_32" fn ntohs(
+    netshort: u16,
+) callconv(WINAPI) u16;
+
+pub extern "ws2_32" fn recv(
+    s: SOCKET,
+    buf: [*]u8,
+    len: i32,
+    flags: i32,
+) callconv(WINAPI) i32;
 
-pub const SOL_SOCKET = 0xffff;
+pub extern "ws2_32" fn recvfrom(
+    s: SOCKET,
+    buf: [*]u8,
+    len: i32,
+    flags: i32,
+    from: ?*sockaddr,
+    fromlen: ?*i32,
+) callconv(WINAPI) i32;
 
-pub const SO_DEBUG = 0x0001;
-pub const SO_ACCEPTCONN = 0x0002;
-pub const SO_REUSEADDR = 0x0004;
-pub const SO_KEEPALIVE = 0x0008;
-pub const SO_DONTROUTE = 0x0010;
-pub const SO_BROADCAST = 0x0020;
-pub const SO_USELOOPBACK = 0x0040;
-pub const SO_LINGER = 0x0080;
-pub const SO_OOBINLINE = 0x0100;
+pub extern "ws2_32" fn select(
+    nfds: i32,
+    readfds: ?*fd_set,
+    writefds: ?*fd_set,
+    exceptfds: ?*fd_set,
+    timeout: ?*const timeval,
+) callconv(WINAPI) i32;
 
-pub const SO_DONTLINGER = ~@as(u32, SO_LINGER);
-pub const SO_EXCLUSIVEADDRUSE = ~@as(u32, SO_REUSEADDR);
+pub extern "ws2_32" fn send(
+    s: SOCKEt,
+    buf: [*]const u8,
+    len: i32,
+    flags: u32,
+) callconv(WINAPI) i32;
 
-pub const SO_SNDBUF = 0x1001;
-pub const SO_RCVBUF = 0x1002;
-pub const SO_SNDLOWAT = 0x1003;
-pub const SO_RCVLOWAT = 0x1004;
-pub const SO_SNDTIMEO = 0x1005;
-pub const SO_RCVTIMEO = 0x1006;
-pub const SO_ERROR = 0x1007;
-pub const SO_TYPE = 0x1008;
+pub extern "ws2_32" fn sendto(
+    s: SOCKET,
+    buf: [*]const u8,
+    len: i32,
+    flags: i32,
+    to: *const sockaddr,
+    tolen: i32,
+) callconv(WINAPI) i32;
 
-pub const SO_GROUP_ID = 0x2001;
-pub const SO_GROUP_PRIORITY = 0x2002;
-pub const SO_MAX_MSG_SIZE = 0x2003;
-pub const SO_PROTOCOL_INFOA = 0x2004;
-pub const SO_PROTOCOL_INFOW = 0x2005;
+pub extern "ws2_32" fn setsockopt(
+    s: SOCKET,
+    level: i32,
+    optname: i32,
+    optval: ?[*]const u8,
+    optlen: i32,
+) callconv(WINAPI) i32;
 
-pub const PVD_CONFIG = 0x3001;
-pub const SO_CONDITIONAL_ACCEPT = 0x3002;
+pub extern "ws2_32" fn shutdown(
+    s: SOCKET,
+    how: i32,
+) callconv(WINAPI) i32;
 
-pub const TCP_NODELAY = 0x0001;
+pub extern "ws2_32" fn socket(
+    af: i32,
+    @"type": i32,
+    protocol: i32,
+) callconv(WINAPI) SOCKET;
 
 pub extern "ws2_32" fn WSAStartup(
     wVersionRequired: WORD,
     lpWSAData: *WSADATA,
-) callconv(WINAPI) c_int;
-pub extern "ws2_32" fn WSACleanup() callconv(WINAPI) c_int;
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSACleanup() callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSASetLastError(iError: i32) callconv(WINAPI) void;
+
 pub extern "ws2_32" fn WSAGetLastError() callconv(WINAPI) WinsockError;
-pub extern "ws2_32" fn WSASocketA(
-    af: c_int,
-    type: c_int,
-    protocol: c_int,
-    lpProtocolInfo: ?*WSAPROTOCOL_INFOA,
-    g: GROUP,
-    dwFlags: DWORD,
-) callconv(WINAPI) SOCKET;
-pub extern "ws2_32" fn WSASocketW(
-    af: c_int,
-    type: c_int,
-    protocol: c_int,
-    lpProtocolInfo: ?*WSAPROTOCOL_INFOW,
-    g: GROUP,
-    dwFlags: DWORD,
-) callconv(WINAPI) SOCKET;
-pub extern "ws2_32" fn closesocket(s: SOCKET) callconv(WINAPI) c_int;
-pub extern "ws2_32" fn WSAIoctl(
+
+pub extern "ws2_32" fn WSAIsBlocking(WINAPI) BOOL;
+
+pub extern "ws2_32" fn WSAUnhookBlockingHook() callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSASetBlockingHook(lpBlockFunc: FARPROC) FARPROC;
+
+pub extern "ws2_32" fn WSACancelBlockingCall() callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSAAsyncGetServByName(
+    hWnd: HWND,
+    wMsg: u32,
+    name: [*:0]const u8,
+    proto: ?[*:0]const u8,
+    buf: [*]u8,
+    buflen: i32,
+) callconv(WINAPI) HANDLE;
+
+pub extern "ws2_32" fn WSAAsyncGetServByPort(
+    hWnd: HWND,
+    wMsg: u32,
+    port: i32,
+    proto: ?[*:0]const u8,
+    buf: [*]u8,
+    buflen: i32,
+) callconv(WINAPI) HANDLE;
+
+pub extern "ws2_32" fn WSAAsyncGetProtoByName(
+    hWnd: HWND,
+    wMsg: u32,
+    name: [*:0]const u8,
+    buf: [*]u8,
+    buflen: i32,
+) callconv(WINAPI) HANDLE;
+
+pub extern "ws2_32" fn WSAAsyncGetProtoByNumber(
+    hWnd: HWND,
+    wMsg: u32,
+    number: i32,
+    buf: [*]u8,
+    buflen: i32,
+) callconv(WINAPI) HANDLE;
+
+pub extern "ws2_32" fn WSACancelAsyncRequest(hAsyncTaskHandle: HANDLE) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSAAsyncSelect(
     s: SOCKET,
-    dwIoControlCode: DWORD,
-    lpvInBuffer: ?*const c_void,
-    cbInBuffer: DWORD,
-    lpvOutBuffer: ?LPVOID,
-    cbOutBuffer: DWORD,
-    lpcbBytesReturned: LPDWORD,
-    lpOverlapped: ?*WSAOVERLAPPED,
-    lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
-) callconv(WINAPI) c_int;
-pub extern "ws2_32" fn accept(
+    hWnd: HWND,
+    wMsg: u32,
+    lEvent: i32,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSAAccept(
     s: SOCKET,
     addr: ?*sockaddr,
-    addrlen: ?*c_int,
+    addrlen: ?*i32,
+    lpfnCondition: ?LPCONDITIONPROC,
+    dwCallbackData: usize,
 ) callconv(WINAPI) SOCKET;
-pub extern "ws2_32" fn bind(
+
+pub extern "ws2_32" fn WSACloseEvent(hEvent: HANDLE) callconv(WINAPI) BOOL;
+
+pub extern "ws2_32" fn WSAConnect(
     s: SOCKET,
-    addr: ?*const sockaddr,
-    addrlen: c_int,
-) callconv(WINAPI) c_int;
-pub extern "ws2_32" fn connect(
+    name: *const sockaddr,
+    namelen: i32,
+    lpCallerData: ?*WSABUF,
+    lpCalleeData: ?*WSABUF,
+    lpSQOS: ?*QOS,
+    lpGQOS: ?*QOS,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSAConnectByNameW(
+    s: SOCKET,
+    nodename: [*:0]const u16,
+    servicename: [*:0]const u16,
+    LocalAddressLength: ?*u32,
+    LocalAddress: ?*sockaddr,
+    RemoteAddressLength: ?*u32,
+    RemoteAddress: ?*sockaddr,
+    timeout: ?*const timeval,
+    Reserved: *OVERLAPPED,
+) callconv(WINAPI) BOOL;
+
+pub extern "ws2_32" fn WSAConnectByNameA(
+    s: SOCKET,
+    nodename: [*:0]const u8,
+    servicename: [*:0]const u8,
+    LocalAddressLength: ?*u32,
+    LocalAddress: ?*sockaddr,
+    RemoteAddressLength: ?*u32,
+    RemoteAddress: ?*sockaddr,
+    timeout: ?*const timeval,
+    Reserved: *OVERLAPPED,
+) callconv(WINAPI) BOOL;
+
+pub extern "ws2_32" fn WSAConnectByList(
+    s: SOCKET,
+    SocketAddress: *SOCKET_ADDRESS_LIST,
+    LocalAddressLength: ?*u32,
+    LocalAddress: ?*sockaddr,
+    RemoteAddressLength: ?*u32,
+    RemoteAddress: ?*sockaddr,
+    timeout: ?*const timeval,
+    Reserved: *OVERLAPPED,
+) callconv(WINAPI) BOOL;
+
+pub extern "ws2_32" fn WSACreateEvent() callconv(WINAPI) HANDLE;
+
+pub extern "ws2_32" fn WSADuplicateSocketA(
+    s: SOCKET,
+    dwProcessId: u32,
+    lpProtocolInfo: *WSAPROTOCOL_INFOA,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSADuplicateSocketW(
+    s: SOCKET,
+    dwProcessId: u32,
+    lpProtocolInfo: *WSAPROTOCOL_INFOW,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSAEnumNetworkEvents(
+    s: SOCKET,
+    hEventObject: HANDLE,
+    lpNetworkEvents: *WSANETWORKEVENTS,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSAEnumProtocolsA(
+    lpiProtocols: ?*i32,
+    lpProtocolBuffer: ?*WSAPROTOCOL_INFOA,
+    lpdwBufferLength: *u32,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSAEnumProtocolsW(
+    lpiProtocols: ?*i32,
+    lpProtocolBuffer: ?*WSAPROTOCOL_INFOW,
+    lpdwBufferLength: *u32,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSAEventSelect(
+    s: SOCKET,
+    hEventObject: HANDLE,
+    lNetworkEvents: i32,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSAGetOverlappedResult(
+    s: SOCKET,
+    lpOverlapped: *OVERLAPPED,
+    lpcbTransfer: *u32,
+    fWait: BOOL,
+    lpdwFlags: *u32,
+) callconv(WINAPI) BOOL;
+
+pub extern "ws2_32" fn WSAGetQOSByName(
+    s: SOCKET,
+    lpQOSName: *WSABUF,
+    lpQOS: *QOS,
+) callconv(WINAPI) BOOL;
+
+pub extern "ws2_32" fn WSAHtonl(
+    s: SOCKET,
+    hostlong: u32,
+    lpnetlong: *u32,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSAHtons(
+    s: SOCKET,
+    hostshort: u16,
+    lpnetshort: *u16,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSAIoctl(
+    s: SOCKET,
+    dwIoControlCode: u32,
+    lpvInBuffer: ?*c_void,
+    cbInBuffer: u32,
+    lpvOutbuffer: ?*c_void,
+    cbOutbuffer: u32,
+    lpcbBytesReturned: *u32,
+    lpOverlapped: ?*OVERLAPPED,
+    lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSAJoinLeaf(
     s: SOCKET,
     name: *const sockaddr,
-    namelen: c_int,
-) callconv(WINAPI) c_int;
-pub extern "ws2_32" fn listen(
+    namelen: i32,
+    lpCallerdata: ?*WSABUF,
+    lpCalleeData: ?*WSABUF,
+    lpSQOS: ?*QOS,
+    lpGQOS: ?*QOS,
+    dwFlags: u32,
+) callconv(WINAPI) SOCKET;
+
+pub extern "ws2_32" fn WSANtohl(
     s: SOCKET,
-    backlog: c_int,
-) callconv(WINAPI) c_int;
+    netlong: u32,
+    lphostlong: *u32,
+) callconv(WINAPI) u32;
+
+pub extern "ws2_32" fn WSANtohs(
+    s: SOCKET,
+    netshort: u16,
+    lphostshort: *u16,
+) callconv(WINAPI) i32;
+
 pub extern "ws2_32" fn WSARecv(
     s: SOCKET,
-    lpBuffers: [*]const WSABUF,
-    dwBufferCount: DWORD,
-    lpNumberOfBytesRecvd: ?*DWORD,
-    lpFlags: *DWORD,
-    lpOverlapped: ?*WSAOVERLAPPED,
-    lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
-) callconv(WINAPI) c_int;
+    lpBuffers: [*]WSABUF,
+    dwBufferCouynt: u32,
+    lpNumberOfBytesRecv: ?*u32,
+    lpFlags: *u32,
+    lpOverlapped: ?*OVERLAPPED,
+    lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSARecvDisconnect(
+    s: SOCKET,
+    lpInboundDisconnectData: ?*WSABUF,
+) callconv(WINAPI) i32;
+
 pub extern "ws2_32" fn WSARecvFrom(
     s: SOCKET,
-    lpBuffers: [*]const WSABUF,
-    dwBufferCount: DWORD,
-    lpNumberOfBytesRecvd: ?*DWORD,
-    lpFlags: *DWORD,
+    lpBuffers: [*]WSABUF,
+    dwBuffercount: u32,
+    lpNumberOfBytesRecvd: ?*u32,
+    lpFlags: *u32,
     lpFrom: ?*sockaddr,
-    lpFromlen: ?*socklen_t,
-    lpOverlapped: ?*WSAOVERLAPPED,
-    lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
-) callconv(WINAPI) c_int;
+    lpFromlen: ?*i32,
+    lpOverlapped: ?*OVERLAPPED,
+    lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSAResetEvent(hEvent: HANDLE) callconv(WINAPI) i32;
+
 pub extern "ws2_32" fn WSASend(
     s: SOCKET,
     lpBuffers: [*]WSABUF,
-    dwBufferCount: DWORD,
-    lpNumberOfBytesSent: ?*DWORD,
-    dwFlags: DWORD,
-    lpOverlapped: ?*WSAOVERLAPPED,
-    lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
-) callconv(WINAPI) c_int;
+    dwBufferCount: u32,
+    lpNumberOfBytesSent: ?*U32,
+    dwFlags: u32,
+    lpOverlapped: ?*OVERLAPPED,
+    lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSASendMsg(
+    s: SOCKET,
+    lpMsg: *WSAMSG_const,
+    dwFlags: u32,
+    lpNumberOfBytesSent: ?*u32,
+    lpOverlapped: ?*OVERLAPPED,
+    lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSARecvMsg(
+    s: SOCKET,
+    lpMsg: *WSAMSG,
+    lpdwNumberOfBytesRecv: ?*u32,
+    lpOverlapped: ?*OVERLAPPED,
+    lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSASendDisconnect(
+    s: SOCKET,
+    lpOutboundDisconnectData: ?*WSABUF,
+) callconv(WINAPI) i32;
+
 pub extern "ws2_32" fn WSASendTo(
     s: SOCKET,
     lpBuffers: [*]WSABUF,
-    dwBufferCount: DWORD,
-    lpNumberOfBytesSent: ?*DWORD,
-    dwFlags: DWORD,
+    dwBufferCount: u32,
+    lpNumberOfBytesSent: ?*u32,
+    dwFlags: u32,
     lpTo: ?*const sockaddr,
-    iTolen: c_int,
-    lpOverlapped: ?*WSAOVERLAPPED,
-    lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
-) callconv(WINAPI) c_int;
+    iToLen: i32,
+    lpOverlapped: ?*OVERLAPPED,
+    lpCompletionRounte: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSASetEvent(
+    hEvent: HANDLE,
+) callconv(WINAPI) BOOL;
+
+pub extern "ws2_32" fn WSASocketA(
+    af: i32,
+    @"type": i32,
+    protocol: i32,
+    lpProtocolInfo: ?*WSAPROTOCOL_INFOA,
+    g: u32,
+    dwFlags: u32,
+) callconv(WINAPI) SOCKET;
+
+pub extern "ws2_32" fn WSASocketW(
+    af: i32,
+    @"type": i32,
+    protocol: i32,
+    lpProtocolInfo: ?*WSAPROTOCOL_INFOW,
+    g: u32,
+    dwFlags: u32,
+) callconv(WINAPI) SOCKET;
+
+pub extern "ws2_32" fn WSAWaitForMultipleEvents(
+    cEvents: u32,
+    lphEvents: [*]const HANDLE,
+    fWaitAll: BOOL,
+    dwTimeout: u32,
+    fAlertable: BOOL,
+) callconv(WINAPI) u32;
+
+pub extern "ws2_32" fn WSAAddressToStringA(
+    lpsaAddress: *sockaddr,
+    dwAddressLength: u32,
+    lpProtocolInfo: ?*WSAPROTOCOL_INFOA,
+    lpszAddressString: [*]u8,
+    lpdwAddressStringLength: *u32,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSAAddressToStringW(
+    lpsaAddress: *sockaddr,
+    dwAddressLength: u32,
+    lpProtocolInfo: ?*WSAPROTOCOL_INFOW,
+    lpszAddressString: [*]u16,
+    lpdwAddressStringLength: *u32,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSAStringToAddressA(
+    AddressString: [*:0]const u8,
+    AddressFamily: i32,
+    lpProtocolInfo: ?*WSAPROTOCOL_INFOA,
+    lpAddress: *sockaddr,
+    lpAddressLength: *i32,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSAStringToAddressW(
+    AddressString: [*:0]const u16,
+    AddressFamily: i32,
+    lpProtocolInfo: ?*WSAPROTOCOL_INFOW,
+    lpAddrses: *sockaddr,
+    lpAddressLength: *i32,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn WSAProviderConfigChange(
+    lpNotificationHandle: *HANDLE,
+    lpOverlapped: ?*OVERLAPPED,
+    lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+) callconv(WINAPI) i32;
+
 pub extern "ws2_32" fn WSAPoll(
-    fdArray: [*]pollfd,
-    fds: c_ulong,
-    timeout: c_int,
-) callconv(WINAPI) c_int;
+    fdArray: [*]WSAPOLLFD,
+    fds: u32,
+    timeout: i32,
+) callconv(WINAPI) i32;
+
+pub extern "mswsock" fn WSARecvEx(
+    s: SOCKET,
+    buf: [*]u8,
+    len: i32,
+    flags: *i32,
+) callconv(WINAPI) i32;
+
+pub extern "mswsock" fn TransmitFile(
+    hSocket: SOCKET,
+    hFile: HANDLE,
+    nNumberOfBytesToWrite: u32,
+    nNumberOfBytesPerSend: u32,
+    lpOverlapped: ?*OVERLAPPED,
+    lpTransmitBuffers: ?*TRANSMIT_FILE_BUFFERS,
+    dwReserved: u32,
+) callconv(WINAPI) BOOL;
+
+pub extern "mswsock" fn AcceptEx(
+    sListenSocket: SOCKET,
+    sAcceptSocket: SOCKET,
+    lpOutputBuffer: *c_void,
+    dwReceiveDataLength: u32,
+    dwLocalAddressLength: u32,
+    dwRemoteAddressLength: u32,
+    lpdwBytesReceived: *u32,
+    lpOverlapped: *OVERLAPPED,
+) callconv(WINAPI) BOOL;
+
+pub extern "mswsock" fn GetAcceptExSockaddrs(
+    lpOutputBuffer: *c_void,
+    dwReceiveDataLength: u32,
+    dwLocalAddressLength: u32,
+    dwRemoteAddressLength: u32,
+    LocalSockaddr: **sockaddr,
+    LocalSockaddrLength: *i32,
+    RemoteSockaddr: **sockaddr,
+    RemoteSockaddrLength: *i32,
+) callconv(WINAPI) void;
+
+pub extern "ws2_32" fn WSAProviderCompleteAsyncCall(
+    hAsyncCall: HANDLE,
+    iRetCode: i32,
+) callconv(WINAPI) i32;
+
+pub extern "mswsock" fn EnumProtocolsA(
+    lpiProtocols: ?*i32,
+    lpProtocolBuffer: *c_void,
+    lpdwBufferLength: *u32,
+) callconv(WINAPI) i32;
+
+pub extern "mswsock" fn EnumProtocolsW(
+    lpiProtocols: ?*i32,
+    lpProtocolBuffer: *c_void,
+    lpdwBufferLength: *u32,
+) callconv(WINAPI) i32;
+
+pub extern "mswsock" fn GetAddressByNameA(
+    dwNameSpace: u32,
+    lpServiceType: *GUID,
+    lpServiceName: ?[*:0]u8,
+    lpiProtocols: ?*i32,
+    dwResolution: u32,
+    lpServiceAsyncInfo: ?*SERVICE_ASYNC_INFO,
+    lpCsaddrBuffer: *c_void,
+    lpAliasBuffer: ?[*:0]const u8,
+    lpdwAliasBufferLength: *u32,
+) callconv(WINAPI) i32;
+
+pub extern "mswsock" fn GetAddressByNameW(
+    dwNameSpace: u32,
+    lpServiceType: *GUID,
+    lpServiceName: ?[*:0]u16,
+    lpiProtocols: ?*i32,
+    dwResolution: u32,
+    lpServiceAsyncInfo: ?*SERVICE_ASYNC_INFO,
+    lpCsaddrBuffer: *c_void,
+    ldwBufferLEngth: *u32,
+    lpAliasBuffer: ?[*:0]u16,
+    lpdwAliasBufferLength: *u32,
+) callconv(WINAPI) i32;
+
+pub extern "mswsock" fn GetTypeByNameA(
+    lpServiceName: [*:0]u8,
+    lpServiceType: *GUID,
+) callconv(WINAPI) i32;
+
+pub extern "mswsock" fn GetTypeByNameW(
+    lpServiceName: [*:0]u16,
+    lpServiceType: *GUID,
+) callconv(WINAPI) i32;
+
+pub extern "mswsock" fn GetNameByTypeA(
+    lpServiceType: *GUID,
+    lpServiceName: [*:0]u8,
+    dwNameLength: u32,
+) callconv(WINAPI) i32;
+
+pub extern "mswsock" fn GetNameByTypeW(
+    lpServiceType: *GUID,
+    lpServiceName: [*:0]u16,
+    dwNameLength: u32,
+) callconv(WINAPI) i32;
+
 pub extern "ws2_32" fn getaddrinfo(
-    pNodeName: [*:0]const u8,
-    pServiceName: [*:0]const u8,
-    pHints: *const addrinfo,
-    ppResult: **addrinfo,
+    pNodeName: ?[*:0]const u8,
+    pServiceName: ?[*:0]const u8,
+    pHints: ?*const addrinfoa,
+    ppResult: **addrinfoa,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn GetAddrInfoExA(
+    pName: ?[*:0]const u8,
+    pServiceName: ?[*:0]const u8,
+    dwNameSapce: u32,
+    lpNspId: ?*GUID,
+    hints: ?*const addrinfoexA,
+    ppResult: **addrinfoexA,
+    timeout: ?*timeval,
+    lpOverlapped: ?*OVERLAPPED,
+    lpCompletionRoutine: ?LPLOOKUPSERVICE_COMPLETION_ROUTINE,
 ) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn GetAddrInfoExCancel(
+    lpHandle: *HANDLE,
+) callconv(WINAPI) i32;
+
+pub extern "ws2_32" fn GetAddrInfoExOverlappedResult(
+    lpOverlapped: *OVERLAPPED,
+) callconv(WINAPI) i32;
+
 pub extern "ws2_32" fn freeaddrinfo(
-    pAddrInfo: *addrinfo,
+    pAddrInfo: ?*addrinfoa,
 ) callconv(WINAPI) void;
-pub extern "ws2_32" fn ioctlsocket(
-    s: SOCKET,
-    cmd: c_long,
-    argp: *c_ulong,
-) callconv(WINAPI) c_int;
-pub extern "ws2_32" fn getsockname(
-    s: SOCKET,
-    name: *sockaddr,
-    namelen: *c_int,
-) callconv(WINAPI) c_int;
-pub extern "ws2_32" fn setsockopt(
-    s: SOCKET,
-    level: u32,
-    optname: u32,
-    optval: ?*const c_void,
-    optlen: socklen_t,
-) callconv(WINAPI) c_int;
-pub extern "ws2_32" fn shutdown(
-    s: SOCKET,
-    how: c_int,
-) callconv(WINAPI) c_int;
+
+pub extern "ws2_32" fn FreeAddrInfoEx(
+    pAddrInfoEx: ?*addrinfoexA,
+) callconv(WINAPI) void;
+
+pub extern "ws2_32" fn getnameinfo(
+    pSockaddr: *const sockaddr,
+    SockaddrLength: i32,
+    pNodeBuffer: ?[*]u8,
+    NodeBufferSize: u32,
+    pServiceBuffer: ?[*]u8,
+    ServiceBufferName: u32,
+    Flags: i32,
+) callconv(WINAPI) i32;
+
+pub extern "IPHLPAPI" fn if_nametoindex(
+    InterfaceName: [*:0]const u8,
+) callconv(WINAPI) u32;
lib/std/os/windows.zig
@@ -389,6 +389,43 @@ pub fn GetQueuedCompletionStatus(
     return GetQueuedCompletionStatusResult.Normal;
 }
 
+pub const GetQueuedCompletionStatusError = error{
+    Aborted,
+    Cancelled,
+    EOF,
+    Timeout,
+} || std.os.UnexpectedError;
+
+pub fn GetQueuedCompletionStatusEx(
+    completion_port: HANDLE,
+    completion_port_entries: []OVERLAPPED_ENTRY,
+    timeout_ms: ?DWORD,
+    alertable: bool,
+) GetQueuedCompletionStatusError!u32 {
+    var num_entries_removed: u32 = 0;
+
+    const success = kernel32.GetQueuedCompletionStatusEx(
+        completion_port,
+        completion_port_entries.ptr,
+        @intCast(ULONG, completion_port_entries.len),
+        &num_entries_removed,
+        timeout_ms orelse INFINITE,
+        @boolToInt(alertable),
+    );
+
+    if (success == FALSE) {
+        return switch (kernel32.GetLastError()) {
+            .ABANDONED_WAIT_0 => error.Aborted,
+            .OPERATION_ABORTED => error.Cancelled,
+            .HANDLE_EOF => error.EOF,
+            .IMEOUT => error.Timeout,
+            else => |err| unexpectedError(err),
+        };
+    }
+
+    return num_entries_removed;
+}
+
 pub fn CloseHandle(hObject: HANDLE) void {
     assert(ntdll.NtClose(hObject) == .SUCCESS);
 }
@@ -1291,6 +1328,10 @@ pub fn getsockname(s: ws2_32.SOCKET, name: *ws2_32.sockaddr, namelen: *ws2_32.so
     return ws2_32.getsockname(s, name, @ptrCast(*i32, namelen));
 }
 
+pub fn getpeername(s: ws2_32.SOCKET, name: *ws2_32.sockaddr, namelen: *ws2_32.socklen_t) i32 {
+    return ws2_32.getpeername(s, name, @ptrCast(*i32, namelen));
+}
+
 pub fn sendmsg(
     s: ws2_32.SOCKET,
     msg: *const ws2_32.WSAMSG,
@@ -1404,6 +1445,28 @@ pub fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) SetCon
     }
 }
 
+pub fn SetConsoleCtrlHandler(handler_routine: ?HANDLER_ROUTINE, add: bool) !void {
+    const success = kernel32.SetConsoleCtrlHandler(
+        handler_routine,
+        if (add) TRUE else FALSE,
+    );
+
+    if (success == FALSE) {
+        return switch (kernel32.GetLastError()) {
+            else => |err| unexpectedError(err),
+        };
+    }
+}
+
+pub fn SetFileCompletionNotificationModes(handle: HANDLE, flags: UCHAR) !void {
+    const success = kernel32.SetFileCompletionNotificationModes(handle, flags);
+    if (success == FALSE) {
+        return switch (kernel32.GetLastError()) {
+            else => |err| unexpectedError(err),
+        };
+    }
+}
+
 pub const GetEnvironmentStringsError = error{OutOfMemory};
 
 pub fn GetEnvironmentStringsW() GetEnvironmentStringsError![*:0]u16 {
lib/std/x/net/tcp.zig
@@ -89,41 +89,30 @@ pub const Client = struct {
         return self.socket.connect(address.into());
     }
 
-    /// Read data from the socket into the buffer provided. It returns the
-    /// number of bytes read into the buffer provided.
-    pub fn read(self: Client, buf: []u8) !usize {
-        return self.socket.read(buf);
-    }
-
     /// Read data from the socket into the buffer provided with a set of flags
     /// specified. It returns the number of bytes read into the buffer provided.
-    pub fn recv(self: Client, buf: []u8, flags: u32) !usize {
-        return self.socket.recv(buf, flags);
-    }
-
-    /// Write a buffer of data provided to the socket. It returns the number
-    /// of bytes that are written to the socket.
-    pub fn write(self: Client, buf: []const u8) !usize {
-        return self.socket.write(buf);
-    }
-
-    /// Writes multiple I/O vectors to the socket. It returns the number
-    /// of bytes that are written to the socket.
-    pub fn writev(self: Client, buffers: []const os.iovec_const) !usize {
-        return self.socket.writev(buffers);
+    pub fn read(self: Client, buf: []u8, flags: u32) !usize {
+        return self.socket.read(buf, flags);
     }
 
     /// Write a buffer of data provided to the socket with a set of flags specified.
     /// It returns the number of bytes that are written to the socket.
-    pub fn send(self: Client, buf: []const u8, flags: u32) !usize {
-        return self.socket.send(buf, flags);
+    pub fn write(self: Client, buf: []const u8, flags: u32) !usize {
+        return self.socket.write(buf, flags);
     }
 
     /// Writes multiple I/O vectors with a prepended message header to the socket
     /// with a set of flags specified. It returns the number of bytes that are
     /// written to the socket.
-    pub fn sendmsg(self: Client, msg: os.msghdr_const, flags: u32) !usize {
-        return self.socket.sendmsg(msg, flags);
+    pub fn writeVectorized(self: Client, msg: os.msghdr_const, flags: u32) !usize {
+        return self.socket.writeVectorized(msg, flags);
+    }
+
+    /// Read multiple I/O vectors with a prepended message header from the socket
+    /// with a set of flags specified. It returns the number of bytes that were
+    /// read into the buffer provided.
+    pub fn readVectorized(self: cLIENT, msg: *os.msghdr, flags: u32) !usize {
+        return self.socket.readVectorized(msg, flags);
     }
 
     /// Query and return the latest cached error on the client's underlying socket.
@@ -146,12 +135,41 @@ pub const Client = struct {
         return ip.Address.from(try self.socket.getLocalAddress());
     }
 
+    /// Query the address that the socket is connected to.
+    pub fn getRemoteAddress(self: Client) !ip.Address {
+        return ip.Address.from(try self.socket.getRemoteAddress());
+    }
+
+    /// Have close() or shutdown() syscalls block until all queued messages in the client have been successfully
+    /// sent, or if the timeout specified in seconds has been reached. It returns `error.UnsupportedSocketOption`
+    /// if the host does not support the option for a socket to linger around up until a timeout specified in
+    /// seconds.
+    pub fn setLinger(self: Client, timeout_seconds: ?u16) !void {
+        return self.socket.setLinger(timeout_seconds);
+    }
+
+    /// Have keep-alive messages be sent periodically. The timing in which keep-alive messages are sent are
+    /// dependant on operating system settings. It returns `error.UnsupportedSocketOption` if the host does
+    /// not support periodically sending keep-alive messages on connection-oriented sockets. 
+    pub fn setKeepAlive(self: Client, enabled: bool) !void {
+        return self.socket.setKeepAlive(enabled);
+    }
+
     /// Disable Nagle's algorithm on a TCP socket. It returns `error.UnsupportedSocketOption` if
     /// the host does not support sockets disabling Nagle's algorithm.
     pub fn setNoDelay(self: Client, enabled: bool) !void {
         if (comptime @hasDecl(os, "TCP_NODELAY")) {
             const bytes = mem.asBytes(&@as(usize, @boolToInt(enabled)));
-            return os.setsockopt(self.socket.fd, os.IPPROTO_TCP, os.TCP_NODELAY, bytes);
+            return self.socket.setOption(os.IPPROTO_TCP, os.TCP_NODELAY, bytes);
+        }
+        return error.UnsupportedSocketOption;
+    }
+
+    /// Enables TCP Quick ACK on a TCP socket to immediately send rather than delay ACKs when necessary. It returns
+    /// `error.UnsupportedSocketOption` if the host does not support TCP Quick ACK.
+    pub fn setQuickACK(self: Client, enabled: bool) !void {
+        if (comptime @hasDecl(os, "TCP_QUICKACK")) {
+            return self.socket.setOption(os.IPPROTO_TCP, os.TCP_QUICKACK, mem.asBytes(&@as(u32, @boolToInt(enabled))));
         }
         return error.UnsupportedSocketOption;
     }
@@ -169,7 +187,7 @@ pub const Client = struct {
     /// Set a timeout on the socket that is to occur if no messages are successfully written
     /// to its bound destination after a specified number of milliseconds. A subsequent write
     /// to the socket will thereafter return `error.WouldBlock` should the timeout be exceeded.
-    pub fn setWriteTimeout(self: Client, milliseconds: usize) !void {
+    pub fn setWriteTimeout(self: Client, milliseconds: u32) !void {
         return self.socket.setWriteTimeout(milliseconds);
     }
 
@@ -177,7 +195,7 @@ pub const Client = struct {
     /// from its bound destination after a specified number of milliseconds. A subsequent
     /// read from the socket will thereafter return `error.WouldBlock` should the timeout be
     /// exceeded.
-    pub fn setReadTimeout(self: Client, milliseconds: usize) !void {
+    pub fn setReadTimeout(self: Client, milliseconds: u32) !void {
         return self.socket.setReadTimeout(milliseconds);
     }
 };
@@ -251,16 +269,7 @@ pub const Listener = struct {
     /// support TCP Fast Open.
     pub fn setFastOpen(self: Listener, enabled: bool) !void {
         if (comptime @hasDecl(os, "TCP_FASTOPEN")) {
-            return os.setsockopt(self.socket.fd, os.IPPROTO_TCP, os.TCP_FASTOPEN, mem.asBytes(&@as(usize, @boolToInt(enabled))));
-        }
-        return error.UnsupportedSocketOption;
-    }
-
-    /// Enables TCP Quick ACK on a TCP socket to immediately send rather than delay ACKs when necessary. It returns
-    /// `error.UnsupportedSocketOption` if the host does not support TCP Quick ACK.
-    pub fn setQuickACK(self: Listener, enabled: bool) !void {
-        if (comptime @hasDecl(os, "TCP_QUICKACK")) {
-            return os.setsockopt(self.socket.fd, os.IPPROTO_TCP, os.TCP_QUICKACK, mem.asBytes(&@as(usize, @boolToInt(enabled))));
+            return self.socket.setOption(os.IPPROTO_TCP, os.TCP_FASTOPEN, mem.asBytes(&@as(u32, @boolToInt(enabled))));
         }
         return error.UnsupportedSocketOption;
     }
@@ -322,7 +331,7 @@ test "tcp/client: set read timeout of 1 millisecond on blocking client" {
     defer conn.deinit();
 
     var buf: [1]u8 = undefined;
-    try testing.expectError(error.WouldBlock, client.read(&buf));
+    try testing.expectError(error.WouldBlock, client.reader(0).read(&buf));
 }
 
 test "tcp/listener: bind to unspecified ipv4 address" {
lib/std/x/os/net.zig
@@ -20,6 +20,14 @@ pub fn resolveScopeID(name: []const u8) !u32 {
     if (comptime @hasDecl(os, "IFNAMESIZE")) {
         if (name.len >= os.IFNAMESIZE - 1) return error.NameTooLong;
 
+        if (comptime builtin.os.tag == .windows) {
+            var interface_name: [os.IFNAMESIZE]u8 = undefined;
+            mem.copy(u8, &interface_name, name);
+            interface_name[name.len] = 0;
+
+            return os.windows.ws2_32.if_nametoindex(@ptrCast([*:0]const u8, &interface_name));
+        }
+
         const fd = try os.socket(os.AF_UNIX, os.SOCK_DGRAM, 0);
         defer os.closeSocket(fd);
 
@@ -31,6 +39,7 @@ pub fn resolveScopeID(name: []const u8) !u32 {
 
         return @bitCast(u32, f.ifru.ivalue);
     }
+
     return error.Unsupported;
 }
 
lib/std/x/os/Socket.zig
@@ -1,295 +0,0 @@
-// SPDX-License-Identifier: MIT
-// Copyright (c) 2015-2021 Zig Contributors
-// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
-// The MIT license requires this copyright notice to be included in all copies
-// and substantial portions of the software.
-
-const std = @import("../../std.zig");
-const net = @import("net.zig");
-
-const os = std.os;
-const fmt = std.fmt;
-const mem = std.mem;
-const time = std.time;
-
-/// A generic socket abstraction.
-const Socket = @This();
-
-/// A socket-address pair.
-pub const Connection = struct {
-    socket: Socket,
-    address: Socket.Address,
-
-    /// Enclose a socket and address into a socket-address pair.
-    pub fn from(socket: Socket, address: Socket.Address) Socket.Connection {
-        return .{ .socket = socket, .address = address };
-    }
-};
-
-/// A generic socket address abstraction. It is safe to directly access and modify
-/// the fields of a `Socket.Address`.
-pub const Address = union(enum) {
-    ipv4: net.IPv4.Address,
-    ipv6: net.IPv6.Address,
-
-    /// Instantiate a new address with a IPv4 host and port.
-    pub fn initIPv4(host: net.IPv4, port: u16) Socket.Address {
-        return .{ .ipv4 = .{ .host = host, .port = port } };
-    }
-
-    /// Instantiate a new address with a IPv6 host and port.
-    pub fn initIPv6(host: net.IPv6, port: u16) Socket.Address {
-        return .{ .ipv6 = .{ .host = host, .port = port } };
-    }
-
-    /// Parses a `sockaddr` into a generic socket address.
-    pub fn fromNative(address: *align(4) const os.sockaddr) Socket.Address {
-        switch (address.family) {
-            os.AF_INET => {
-                const info = @ptrCast(*const os.sockaddr_in, address);
-                const host = net.IPv4{ .octets = @bitCast([4]u8, info.addr) };
-                const port = mem.bigToNative(u16, info.port);
-                return Socket.Address.initIPv4(host, port);
-            },
-            os.AF_INET6 => {
-                const info = @ptrCast(*const os.sockaddr_in6, address);
-                const host = net.IPv6{ .octets = info.addr, .scope_id = info.scope_id };
-                const port = mem.bigToNative(u16, info.port);
-                return Socket.Address.initIPv6(host, port);
-            },
-            else => unreachable,
-        }
-    }
-
-    /// Encodes a generic socket address into an extern union that may be reliably
-    /// casted into a `sockaddr` which may be passed into socket syscalls.
-    pub fn toNative(self: Socket.Address) extern union {
-        ipv4: os.sockaddr_in,
-        ipv6: os.sockaddr_in6,
-    } {
-        return switch (self) {
-            .ipv4 => |address| .{
-                .ipv4 = .{
-                    .addr = @bitCast(u32, address.host.octets),
-                    .port = mem.nativeToBig(u16, address.port),
-                },
-            },
-            .ipv6 => |address| .{
-                .ipv6 = .{
-                    .addr = address.host.octets,
-                    .port = mem.nativeToBig(u16, address.port),
-                    .scope_id = address.host.scope_id,
-                    .flowinfo = 0,
-                },
-            },
-        };
-    }
-
-    /// Returns the number of bytes that make up the `sockaddr` equivalent to the address. 
-    pub fn getNativeSize(self: Socket.Address) u32 {
-        return switch (self) {
-            .ipv4 => @sizeOf(os.sockaddr_in),
-            .ipv6 => @sizeOf(os.sockaddr_in6),
-        };
-    }
-
-    /// Implements the `std.fmt.format` API.
-    pub fn format(
-        self: Socket.Address,
-        comptime layout: []const u8,
-        opts: fmt.FormatOptions,
-        writer: anytype,
-    ) !void {
-        switch (self) {
-            .ipv4 => |address| try fmt.format(writer, "{}:{}", .{ address.host, address.port }),
-            .ipv6 => |address| try fmt.format(writer, "{}:{}", .{ address.host, address.port }),
-        }
-    }
-};
-
-/// The underlying handle of a socket.
-fd: os.socket_t,
-
-/// Open a new socket.
-pub fn init(domain: u32, socket_type: u32, protocol: u32) !Socket {
-    return Socket{ .fd = try os.socket(domain, socket_type, protocol) };
-}
-
-/// Enclose a socket abstraction over an existing socket file descriptor.
-pub fn from(fd: os.socket_t) Socket {
-    return Socket{ .fd = fd };
-}
-
-/// Closes the socket.
-pub fn deinit(self: Socket) void {
-    os.closeSocket(self.fd);
-}
-
-/// Shutdown either the read side, write side, or all side of the socket.
-pub fn shutdown(self: Socket, how: os.ShutdownHow) !void {
-    return os.shutdown(self.fd, how);
-}
-
-/// Binds the socket to an address.
-pub fn bind(self: Socket, address: Socket.Address) !void {
-    return os.bind(self.fd, @ptrCast(*const os.sockaddr, &address.toNative()), address.getNativeSize());
-}
-
-/// Start listening for incoming connections on the socket.
-pub fn listen(self: Socket, max_backlog_size: u31) !void {
-    return os.listen(self.fd, max_backlog_size);
-}
-
-/// Have the socket attempt to the connect to an address.
-pub fn connect(self: Socket, address: Socket.Address) !void {
-    return os.connect(self.fd, @ptrCast(*const os.sockaddr, &address.toNative()), address.getNativeSize());
-}
-
-/// Accept a pending incoming connection queued to the kernel backlog
-/// of the socket.
-pub fn accept(self: Socket, flags: u32) !Socket.Connection {
-    var address: os.sockaddr = undefined;
-    var address_len: u32 = @sizeOf(os.sockaddr);
-
-    const socket = Socket{ .fd = try os.accept(self.fd, &address, &address_len, flags) };
-    const socket_address = Socket.Address.fromNative(@alignCast(4, &address));
-
-    return Socket.Connection.from(socket, socket_address);
-}
-
-/// Read data from the socket into the buffer provided. It returns the
-/// number of bytes read into the buffer provided.
-pub fn read(self: Socket, buf: []u8) !usize {
-    return os.read(self.fd, buf);
-}
-
-/// Read data from the socket into the buffer provided with a set of flags
-/// specified. It returns the number of bytes read into the buffer provided.
-pub fn recv(self: Socket, buf: []u8, flags: u32) !usize {
-    return os.recv(self.fd, buf, flags);
-}
-
-/// Write a buffer of data provided to the socket. It returns the number
-/// of bytes that are written to the socket.
-pub fn write(self: Socket, buf: []const u8) !usize {
-    return os.write(self.fd, buf);
-}
-
-/// Writes multiple I/O vectors to the socket. It returns the number
-/// of bytes that are written to the socket.
-pub fn writev(self: Socket, buffers: []const os.iovec_const) !usize {
-    return os.writev(self.fd, buffers);
-}
-
-/// Write a buffer of data provided to the socket with a set of flags specified.
-/// It returns the number of bytes that are written to the socket.
-pub fn send(self: Socket, buf: []const u8, flags: u32) !usize {
-    return os.send(self.fd, buf, flags);
-}
-
-/// Writes multiple I/O vectors with a prepended message header to the socket
-/// with a set of flags specified. It returns the number of bytes that are
-/// written to the socket.
-pub fn sendmsg(self: Socket, msg: os.msghdr_const, flags: u32) !usize {
-    return os.sendmsg(self.fd, msg, flags);
-}
-
-/// Query the address that the socket is locally bounded to.
-pub fn getLocalAddress(self: Socket) !Socket.Address {
-    var address: os.sockaddr = undefined;
-    var address_len: u32 = @sizeOf(os.sockaddr);
-    try os.getsockname(self.fd, &address, &address_len);
-    return Socket.Address.fromNative(@alignCast(4, &address));
-}
-
-/// Query and return the latest cached error on the socket.
-pub fn getError(self: Socket) !void {
-    return os.getsockoptError(self.fd);
-}
-
-/// Query the read buffer size of the socket.
-pub fn getReadBufferSize(self: Socket) !u32 {
-    var value: u32 = undefined;
-    var value_len: u32 = @sizeOf(u32);
-
-    const rc = os.system.getsockopt(self.fd, os.SOL_SOCKET, os.SO_RCVBUF, mem.asBytes(&value), &value_len);
-    return switch (os.errno(rc)) {
-        0 => value,
-        os.EBADF => error.BadFileDescriptor,
-        os.EFAULT => error.InvalidAddressSpace,
-        os.EINVAL => error.InvalidSocketOption,
-        os.ENOPROTOOPT => error.UnknownSocketOption,
-        os.ENOTSOCK => error.NotASocket,
-        else => |err| os.unexpectedErrno(err),
-    };
-}
-
-/// Query the write buffer size of the socket.
-pub fn getWriteBufferSize(self: Socket) !u32 {
-    var value: u32 = undefined;
-    var value_len: u32 = @sizeOf(u32);
-
-    const rc = os.system.getsockopt(self.fd, os.SOL_SOCKET, os.SO_SNDBUF, mem.asBytes(&value), &value_len);
-    return switch (os.errno(rc)) {
-        0 => value,
-        os.EBADF => error.BadFileDescriptor,
-        os.EFAULT => error.InvalidAddressSpace,
-        os.EINVAL => error.InvalidSocketOption,
-        os.ENOPROTOOPT => error.UnknownSocketOption,
-        os.ENOTSOCK => error.NotASocket,
-        else => |err| os.unexpectedErrno(err),
-    };
-}
-
-/// Allow multiple sockets on the same host to listen on the same address. It returns `error.UnsupportedSocketOption` if
-/// the host does not support sockets listening the same address.
-pub fn setReuseAddress(self: Socket, enabled: bool) !void {
-    if (comptime @hasDecl(os, "SO_REUSEADDR")) {
-        return os.setsockopt(self.fd, os.SOL_SOCKET, os.SO_REUSEADDR, mem.asBytes(&@as(usize, @boolToInt(enabled))));
-    }
-    return error.UnsupportedSocketOption;
-}
-
-/// Allow multiple sockets on the same host to listen on the same port. It returns `error.UnsupportedSocketOption` if
-/// the host does not supports sockets listening on the same port.
-pub fn setReusePort(self: Socket, enabled: bool) !void {
-    if (comptime @hasDecl(os, "SO_REUSEPORT")) {
-        return os.setsockopt(self.fd, os.SOL_SOCKET, os.SO_REUSEPORT, mem.asBytes(&@as(usize, @boolToInt(enabled))));
-    }
-    return error.UnsupportedSocketOption;
-}
-
-/// Set the write buffer size of the socket.
-pub fn setWriteBufferSize(self: Socket, size: u32) !void {
-    return os.setsockopt(self.fd, os.SOL_SOCKET, os.SO_SNDBUF, mem.asBytes(&size));
-}
-
-/// Set the read buffer size of the socket.
-pub fn setReadBufferSize(self: Socket, size: u32) !void {
-    return os.setsockopt(self.fd, os.SOL_SOCKET, os.SO_RCVBUF, mem.asBytes(&size));
-}
-
-/// Set a timeout on the socket that is to occur if no messages are successfully written
-/// to its bound destination after a specified number of milliseconds. A subsequent write
-/// to the socket will thereafter return `error.WouldBlock` should the timeout be exceeded.
-pub fn setWriteTimeout(self: Socket, milliseconds: usize) !void {
-    const timeout = os.timeval{
-        .tv_sec = @intCast(i32, milliseconds / time.ms_per_s),
-        .tv_usec = @intCast(i32, (milliseconds % time.ms_per_s) * time.us_per_ms),
-    };
-
-    return os.setsockopt(self.fd, os.SOL_SOCKET, os.SO_SNDTIMEO, mem.asBytes(&timeout));
-}
-
-/// Set a timeout on the socket that is to occur if no messages are successfully read
-/// from its bound destination after a specified number of milliseconds. A subsequent
-/// read from the socket will thereafter return `error.WouldBlock` should the timeout be
-/// exceeded.
-pub fn setReadTimeout(self: Socket, milliseconds: usize) !void {
-    const timeout = os.timeval{
-        .tv_sec = @intCast(i32, milliseconds / time.ms_per_s),
-        .tv_usec = @intCast(i32, (milliseconds % time.ms_per_s) * time.us_per_ms),
-    };
-
-    return os.setsockopt(self.fd, os.SOL_SOCKET, os.SO_RCVTIMEO, mem.asBytes(&timeout));
-}
lib/std/x/os/socket.zig
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2015-2021 Zig Contributors
+// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
+// The MIT license requires this copyright notice to be included in all copies
+// and substantial portions of the software.
+
+const std = @import("../../std.zig");
+const net = @import("net.zig");
+
+const io = std.io;
+const os = std.os;
+const fmt = std.fmt;
+const mem = std.mem;
+const time = std.time;
+const builtin = std.builtin;
+
+/// Import in a `Socket` abstraction depending on the platform we are compiling against.
+pub usingnamespace switch (builtin.os.tag) {
+    .windows => @import("socket_windows.zig"),
+    else => @import("socket_posix.zig"),
+};
+
+/// A common subset of shared structs across cross-platform abstractions over socket syscalls.
+pub fn Mixin(comptime Self: type) type {
+    return struct {
+        /// A socket-address pair.
+        pub const Connection = struct {
+            socket: Self,
+            address: Self.Address,
+
+            /// Enclose a socket and address into a socket-address pair.
+            pub fn from(socket: Self, address: Self.Address) Self.Connection {
+                return .{ .socket = socket, .address = address };
+            }
+        };
+
+        /// A generic socket address abstraction. It is safe to directly access and modify
+        /// the fields of a `Self.Address`.
+        pub const Address = union(enum) {
+            ipv4: net.IPv4.Address,
+            ipv6: net.IPv6.Address,
+
+            /// Instantiate a new address with a IPv4 host and port.
+            pub fn initIPv4(host: net.IPv4, port: u16) Self.Address {
+                return .{ .ipv4 = .{ .host = host, .port = port } };
+            }
+
+            /// Instantiate a new address with a IPv6 host and port.
+            pub fn initIPv6(host: net.IPv6, port: u16) Self.Address {
+                return .{ .ipv6 = .{ .host = host, .port = port } };
+            }
+
+            /// Parses a `sockaddr` into a generic socket address.
+            pub fn fromNative(address: *align(4) const os.sockaddr) Self.Address {
+                switch (address.family) {
+                    os.AF_INET => {
+                        const info = @ptrCast(*const os.sockaddr_in, address);
+                        const host = net.IPv4{ .octets = @bitCast([4]u8, info.addr) };
+                        const port = mem.bigToNative(u16, info.port);
+                        return Self.Address.initIPv4(host, port);
+                    },
+                    os.AF_INET6 => {
+                        const info = @ptrCast(*const os.sockaddr_in6, address);
+                        const host = net.IPv6{ .octets = info.addr, .scope_id = info.scope_id };
+                        const port = mem.bigToNative(u16, info.port);
+                        return Self.Address.initIPv6(host, port);
+                    },
+                    else => unreachable,
+                }
+            }
+
+            /// Encodes a generic socket address into an extern union that may be reliably
+            /// casted into a `sockaddr` which may be passed into socket syscalls.
+            pub fn toNative(self: Self.Address) extern union {
+                ipv4: os.sockaddr_in,
+                ipv6: os.sockaddr_in6,
+            } {
+                return switch (self) {
+                    .ipv4 => |address| .{
+                        .ipv4 = .{
+                            .addr = @bitCast(u32, address.host.octets),
+                            .port = mem.nativeToBig(u16, address.port),
+                        },
+                    },
+                    .ipv6 => |address| .{
+                        .ipv6 = .{
+                            .addr = address.host.octets,
+                            .port = mem.nativeToBig(u16, address.port),
+                            .scope_id = address.host.scope_id,
+                            .flowinfo = 0,
+                        },
+                    },
+                };
+            }
+
+            /// Returns the number of bytes that make up the `sockaddr` equivalent to the address. 
+            pub fn getNativeSize(self: Self.Address) u32 {
+                return switch (self) {
+                    .ipv4 => @sizeOf(os.sockaddr_in),
+                    .ipv6 => @sizeOf(os.sockaddr_in6),
+                };
+            }
+
+            /// Implements the `std.fmt.format` API.
+            pub fn format(
+                self: Self.Address,
+                comptime layout: []const u8,
+                opts: fmt.FormatOptions,
+                writer: anytype,
+            ) !void {
+                switch (self) {
+                    .ipv4 => |address| try fmt.format(writer, "{}:{}", .{ address.host, address.port }),
+                    .ipv6 => |address| try fmt.format(writer, "{}:{}", .{ address.host, address.port }),
+                }
+            }
+        };
+
+        /// Implements `std.io.Reader`.
+        pub const Reader = struct {
+            socket: Self,
+            flags: u32,
+
+            /// Implements `readFn` for `std.io.Reader`.
+            pub fn read(self: Self.Reader, buffer: []u8) !usize {
+                return self.socket.read(buffer, self.flags);
+            }
+        };
+
+        /// Implements `std.io.Writer`.
+        pub const Writer = struct {
+            socket: Self,
+            flags: u32,
+
+            /// Implements `writeFn` for `std.io.Writer`.
+            pub fn write(self: Self.Writer, buffer: []const u8) !usize {
+                return self.socket.write(buffer, self.flags);
+            }
+        };
+
+        /// Extracts the error set of a function.
+        /// TODO: remove after Socket.{read, write} error unions are well-defined across different platforms
+        fn ErrorSetOf(comptime Function: anytype) type {
+            return @typeInfo(@typeInfo(@TypeOf(Function)).Fn.return_type.?).ErrorUnion.error_set;
+        }
+
+        /// Wrap `Socket` into `std.io.Reader`.
+        pub fn reader(self: Self, flags: u32) io.Reader(Self.Reader, ErrorSetOf(Self.Reader.read), Self.Reader.read) {
+            return .{ .context = .{ .socket = self, .flags = flags } };
+        }
+
+        /// Wrap `Socket` into `std.io.Writer`.
+        pub fn writer(self: Self, flags: u32) io.Writer(Self.Writer, ErrorSetOf(Self.Writer.write), Self.Writer.write) {
+            return .{ .context = .{ .socket = self, .flags = flags } };
+        }
+    };
+}
lib/std/x/os/socket_posix.zig
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2015-2021 Zig Contributors
+// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
+// The MIT license requires this copyright notice to be included in all copies
+// and substantial portions of the software.
+
+const std = @import("../../std.zig");
+
+const os = std.os;
+const mem = std.mem;
+const time = std.time;
+
+pub const Socket = struct {
+    /// Import in `Socket.Address` and `Socket.Connection`.
+    pub usingnamespace @import("socket.zig").Mixin(Socket);
+
+    /// The underlying handle of a socket.
+    fd: os.socket_t,
+
+    /// Open a new socket.
+    pub fn init(domain: u32, socket_type: u32, protocol: u32) !Socket {
+        return Socket{ .fd = try os.socket(domain, socket_type, protocol) };
+    }
+
+    /// Enclose a socket abstraction over an existing socket file descriptor.
+    pub fn from(fd: os.socket_t) Socket {
+        return Socket{ .fd = fd };
+    }
+
+    /// Closes the socket.
+    pub fn deinit(self: Socket) void {
+        os.closeSocket(self.fd);
+    }
+
+    /// Shutdown either the read side, write side, or all side of the socket.
+    pub fn shutdown(self: Socket, how: os.ShutdownHow) !void {
+        return os.shutdown(self.fd, how);
+    }
+
+    /// Binds the socket to an address.
+    pub fn bind(self: Socket, address: Socket.Address) !void {
+        return os.bind(self.fd, @ptrCast(*const os.sockaddr, &address.toNative()), address.getNativeSize());
+    }
+
+    /// Start listening for incoming connections on the socket.
+    pub fn listen(self: Socket, max_backlog_size: u31) !void {
+        return os.listen(self.fd, max_backlog_size);
+    }
+
+    /// Have the socket attempt to the connect to an address.
+    pub fn connect(self: Socket, address: Socket.Address) !void {
+        return os.connect(self.fd, @ptrCast(*const os.sockaddr, &address.toNative()), address.getNativeSize());
+    }
+
+    /// Accept a pending incoming connection queued to the kernel backlog
+    /// of the socket.
+    pub fn accept(self: Socket, flags: u32) !Socket.Connection {
+        var address: os.sockaddr = undefined;
+        var address_len: u32 = @sizeOf(os.sockaddr);
+
+        const socket = Socket{ .fd = try os.accept(self.fd, &address, &address_len, flags) };
+        const socket_address = Socket.Address.fromNative(@alignCast(4, &address));
+
+        return Socket.Connection.from(socket, socket_address);
+    }
+
+    /// Read data from the socket into the buffer provided with a set of flags
+    /// specified. It returns the number of bytes read into the buffer provided.
+    pub fn read(self: Socket, buf: []u8, flags: u32) !usize {
+        return os.recv(self.fd, buf, flags);
+    }
+
+    /// Write a buffer of data provided to the socket with a set of flags specified.
+    /// It returns the number of bytes that are written to the socket.
+    pub fn write(self: Socket, buf: []const u8, flags: u32) !usize {
+        return os.send(self.fd, buf, flags);
+    }
+
+    /// Writes multiple I/O vectors with a prepended message header to the socket
+    /// with a set of flags specified. It returns the number of bytes that are
+    /// written to the socket.
+    pub fn writeVectorized(self: Socket, msg: os.msghdr_const, flags: u32) !usize {
+        return os.sendmsg(self.fd, msg, flags);
+    }
+
+    /// Read multiple I/O vectors with a prepended message header from the socket
+    /// with a set of flags specified. It returns the number of bytes that were
+    /// read into the buffer provided.
+    pub fn readVectorized(self: Socket, msg: *os.msghdr, flags: u32) !usize {
+        return error.NotImplemented;
+    }
+
+    /// Query the address that the socket is locally bounded to.
+    pub fn getLocalAddress(self: Socket) !Socket.Address {
+        var address: os.sockaddr_storage = undefined;
+        var address_len: u32 = @sizeOf(os.sockaddr_storage);
+        try os.getsockname(self.fd, @ptrCast(*os.sockaddr, &address), &address_len);
+        return Socket.Address.fromNative(@alignCast(4, @ptrCast(*os.sockaddr, &address)));
+    }
+
+    /// Query the address that the socket is connected to.
+    pub fn getRemoteAddress(self: Socket) !Socket.Address {
+        var address: os.sockaddr_storage = undefined;
+        var address_len: u32 = @sizeOf(os.sockaddr_storage);
+        try os.getpeername(self.fd, @ptrCast(*os.sockaddr, &address), &address_len);
+        return Socket.Address.fromNative(@alignCast(4, @ptrCast(*os.sockaddr, &address)));
+    }
+
+    /// Query and return the latest cached error on the socket.
+    pub fn getError(self: Socket) !void {
+        return os.getsockoptError(self.fd);
+    }
+
+    /// Query the read buffer size of the socket.
+    pub fn getReadBufferSize(self: Socket) !u32 {
+        var value: u32 = undefined;
+        var value_len: u32 = @sizeOf(u32);
+
+        const rc = os.system.getsockopt(self.fd, os.SOL_SOCKET, os.SO_RCVBUF, mem.asBytes(&value), &value_len);
+        return switch (os.errno(rc)) {
+            0 => value,
+            os.EBADF => error.BadFileDescriptor,
+            os.EFAULT => error.InvalidAddressSpace,
+            os.EINVAL => error.InvalidSocketOption,
+            os.ENOPROTOOPT => error.UnknownSocketOption,
+            os.ENOTSOCK => error.NotASocket,
+            else => |err| os.unexpectedErrno(err),
+        };
+    }
+
+    /// Query the write buffer size of the socket.
+    pub fn getWriteBufferSize(self: Socket) !u32 {
+        var value: u32 = undefined;
+        var value_len: u32 = @sizeOf(u32);
+
+        const rc = os.system.getsockopt(self.fd, os.SOL_SOCKET, os.SO_SNDBUF, mem.asBytes(&value), &value_len);
+        return switch (os.errno(rc)) {
+            0 => value,
+            os.EBADF => error.BadFileDescriptor,
+            os.EFAULT => error.InvalidAddressSpace,
+            os.EINVAL => error.InvalidSocketOption,
+            os.ENOPROTOOPT => error.UnknownSocketOption,
+            os.ENOTSOCK => error.NotASocket,
+            else => |err| os.unexpectedErrno(err),
+        };
+    }
+
+    /// Set a socket option.
+    pub fn setOption(self: Socket, level: u32, name: u32, value: []const u8) !void {
+        return os.setsockopt(self.fd, level, name, value);
+    }
+
+    /// Have close() or shutdown() syscalls block until all queued messages in the socket have been successfully
+    /// sent, or if the timeout specified in seconds has been reached. It returns `error.UnsupportedSocketOption`
+    /// if the host does not support the option for a socket to linger around up until a timeout specified in
+    /// seconds.
+    pub fn setLinger(self: Socket, timeout_seconds: ?u16) !void {
+        if (comptime @hasDecl(os, "SO_LINGER")) {
+            const settings = struct {
+                l_onoff: c_int,
+                l_linger: c_int,
+            }{
+                .l_onoff = @intCast(c_int, @boolToInt(timeout_seconds != null)),
+                .l_linger = if (timeout_seconds) |seconds| @intCast(c_int, seconds) else 0,
+            };
+
+            return self.setOption(os.SOL_SOCKET, os.SO_LINGER, mem.asBytes(&settings));
+        }
+
+        return error.UnsupportedSocketOption;
+    }
+
+    /// On connection-oriented sockets, have keep-alive messages be sent periodically. The timing in which keep-alive
+    /// messages are sent are dependant on operating system settings. It returns `error.UnsupportedSocketOption` if
+    /// the host does not support periodically sending keep-alive messages on connection-oriented sockets. 
+    pub fn setKeepAlive(self: Socket, enabled: bool) !void {
+        if (comptime @hasDecl(os, "SO_KEEPALIVE")) {
+            return self.setOption(os.SOL_SOCKET, os.SO_KEEPALIVE, mem.asBytes(&@as(u32, @boolToInt(enabled))));
+        }
+        return error.UnsupportedSocketOption;
+    }
+
+    /// Allow multiple sockets on the same host to listen on the same address. It returns `error.UnsupportedSocketOption` if
+    /// the host does not support sockets listening the same address.
+    pub fn setReuseAddress(self: Socket, enabled: bool) !void {
+        if (comptime @hasDecl(os, "SO_REUSEADDR")) {
+            return self.setOption(os.SOL_SOCKET, os.SO_REUSEADDR, mem.asBytes(&@as(u32, @boolToInt(enabled))));
+        }
+        return error.UnsupportedSocketOption;
+    }
+
+    /// Allow multiple sockets on the same host to listen on the same port. It returns `error.UnsupportedSocketOption` if
+    /// the host does not supports sockets listening on the same port.
+    pub fn setReusePort(self: Socket, enabled: bool) !void {
+        if (comptime @hasDecl(os, "SO_REUSEPORT")) {
+            return self.setOption(os.SOL_SOCKET, os.SO_REUSEPORT, mem.asBytes(&@as(u32, @boolToInt(enabled))));
+        }
+        return error.UnsupportedSocketOption;
+    }
+
+    /// Set the write buffer size of the socket.
+    pub fn setWriteBufferSize(self: Socket, size: u32) !void {
+        return self.setOption(os.SOL_SOCKET, os.SO_SNDBUF, mem.asBytes(&size));
+    }
+
+    /// Set the read buffer size of the socket.
+    pub fn setReadBufferSize(self: Socket, size: u32) !void {
+        return self.setOption(os.SOL_SOCKET, os.SO_RCVBUF, mem.asBytes(&size));
+    }
+
+    /// Set a timeout on the socket that is to occur if no messages are successfully written
+    /// to its bound destination after a specified number of milliseconds. A subsequent write
+    /// to the socket will thereafter return `error.WouldBlock` should the timeout be exceeded.
+    pub fn setWriteTimeout(self: Socket, milliseconds: usize) !void {
+        const timeout = os.timeval{
+            .tv_sec = @intCast(i32, milliseconds / time.ms_per_s),
+            .tv_usec = @intCast(i32, (milliseconds % time.ms_per_s) * time.us_per_ms),
+        };
+
+        return self.setOption(os.SOL_SOCKET, os.SO_SNDTIMEO, mem.asBytes(&timeout));
+    }
+
+    /// Set a timeout on the socket that is to occur if no messages are successfully read
+    /// from its bound destination after a specified number of milliseconds. A subsequent
+    /// read from the socket will thereafter return `error.WouldBlock` should the timeout be
+    /// exceeded.
+    pub fn setReadTimeout(self: Socket, milliseconds: usize) !void {
+        const timeout = os.timeval{
+            .tv_sec = @intCast(i32, milliseconds / time.ms_per_s),
+            .tv_usec = @intCast(i32, (milliseconds % time.ms_per_s) * time.us_per_ms),
+        };
+
+        return self.setOption(os.SOL_SOCKET, os.SO_RCVTIMEO, mem.asBytes(&timeout));
+    }
+};
lib/std/x/os/socket_windows.zig
@@ -0,0 +1,392 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2015-2021 Zig Contributors
+// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
+// The MIT license requires this copyright notice to be included in all copies
+// and substantial portions of the software.
+
+const std = @import("../../std.zig");
+const net = @import("net.zig");
+
+const os = std.os;
+const mem = std.mem;
+
+const windows = std.os.windows;
+const ws2_32 = windows.ws2_32;
+
+pub const Socket = struct {
+    /// Import in `Socket.Address` and `Socket.Connection`.
+    pub usingnamespace @import("socket.zig").Mixin(Socket);
+
+    /// The underlying handle of a socket.
+    fd: os.socket_t,
+
+    /// Open a new socket.
+    pub fn init(domain: u32, socket_type: u32, protocol: u32) !Socket {
+        var filtered_socket_type = socket_type & ~@as(u32, os.SOCK_CLOEXEC);
+
+        var filtered_flags = ws2_32.WSA_FLAG_OVERLAPPED;
+        if (socket_type & os.SOCK_CLOEXEC != 0) {
+            filtered_flags |= ws2_32.WSA_FLAG_NO_HANDLE_INHERIT;
+        }
+
+        const fd = ws2_32.WSASocketW(
+            @intCast(i32, domain),
+            @intCast(i32, filtered_socket_type),
+            @intCast(i32, protocol),
+            null,
+            0,
+            filtered_flags,
+        );
+        if (fd == ws2_32.INVALID_SOCKET) {
+            return switch (ws2_32.WSAGetLastError()) {
+                .WSANOTINITIALISED => {
+                    _ = try windows.WSAStartup(2, 2);
+                    return Socket.init(domain, socket_type, protocol);
+                },
+                .WSAEAFNOSUPPORT => error.AddressFamilyNotSupported,
+                .WSAEMFILE => error.ProcessFdQuotaExceeded,
+                .WSAENOBUFS => error.SystemResources,
+                .WSAEPROTONOSUPPORT => error.ProtocolNotSupported,
+                else => |err| windows.unexpectedWSAError(err),
+            };
+        }
+
+        return Socket{ .fd = fd };
+    }
+
+    /// Enclose a socket abstraction over an existing socket file descriptor.
+    pub fn from(fd: os.socket_t) Socket {
+        return Socket{ .fd = fd };
+    }
+
+    /// Closes the socket.
+    pub fn deinit(self: Socket) void {
+        _ = ws2_32.closesocket(self.fd);
+    }
+
+    /// Shutdown either the read side, write side, or all side of the socket.
+    pub fn shutdown(self: Socket, how: os.ShutdownHow) !void {
+        const rc = ws2_32.shutdown(self.fd, switch (how) {
+            .recv => ws2_32.SD_RECEIVE,
+            .send => ws2_32.SD_SEND,
+            .both => ws2_32.SD_BOTH,
+        });
+        if (rc == ws2_32.SOCKET_ERROR) {
+            return switch (ws2_32.WSAGetLastError()) {
+                .WSAECONNABORTED => return error.ConnectionAborted,
+                .WSAECONNRESET => return error.ConnectionResetByPeer,
+                .WSAEINPROGRESS => return error.BlockingOperationInProgress,
+                .WSAEINVAL => unreachable,
+                .WSAENETDOWN => return error.NetworkSubsystemFailed,
+                .WSAENOTCONN => return error.SocketNotConnected,
+                .WSAENOTSOCK => unreachable,
+                .WSANOTINITIALISED => unreachable,
+                else => |err| return windows.unexpectedWSAError(err),
+            };
+        }
+    }
+
+    /// Binds the socket to an address.
+    pub fn bind(self: Socket, address: Socket.Address) !void {
+        const rc = ws2_32.bind(self.fd, @ptrCast(*const ws2_32.sockaddr, &address.toNative()), @intCast(c_int, address.getNativeSize()));
+        if (rc == ws2_32.SOCKET_ERROR) {
+            return switch (ws2_32.WSAGetLastError()) {
+                .WSAENETDOWN => error.NetworkSubsystemFailed,
+                .WSAEACCES => error.AccessDenied,
+                .WSAEADDRINUSE => error.AddressInUse,
+                .WSAEADDRNOTAVAIL => error.AddressNotAvailable,
+                .WSAEFAULT => error.BadAddress,
+                .WSAEINPROGRESS => error.WouldBlock,
+                .WSAEINVAL => error.AlreadyBound,
+                .WSAENOBUFS => error.NoEphemeralPortsAvailable,
+                .WSAENOTSOCK => error.NotASocket,
+                else => |err| windows.unexpectedWSAError(err),
+            };
+        }
+    }
+
+    /// Start listening for incoming connections on the socket.
+    pub fn listen(self: Socket, max_backlog_size: u31) !void {
+        const rc = ws2_32.listen(self.fd, max_backlog_size);
+        if (rc == ws2_32.SOCKET_ERROR) {
+            return switch (ws2_32.WSAGetLastError()) {
+                .WSAENETDOWN => error.NetworkSubsystemFailed,
+                .WSAEADDRINUSE => error.AddressInUse,
+                .WSAEISCONN => error.AlreadyConnected,
+                .WSAEINVAL => error.SocketNotBound,
+                .WSAEMFILE, .WSAENOBUFS => error.SystemResources,
+                .WSAENOTSOCK => error.FileDescriptorNotASocket,
+                .WSAEOPNOTSUPP => error.OperationNotSupported,
+                .WSAEINPROGRESS => error.WouldBlock,
+                else => |err| windows.unexpectedWSAError(err),
+            };
+        }
+    }
+
+    /// Have the socket attempt to the connect to an address.
+    pub fn connect(self: Socket, address: Socket.Address) !void {
+        const rc = ws2_32.connect(self.fd, @ptrCast(*const ws2_32.sockaddr, &address.toNative()), @intCast(c_int, address.getNativeSize()));
+        if (rc == ws2_32.SOCKET_ERROR) {
+            return switch (ws2_32.WSAGetLastError()) {
+                .WSAEADDRINUSE => error.AddressInUse,
+                .WSAEADDRNOTAVAIL => error.AddressNotAvailable,
+                .WSAECONNREFUSED => error.ConnectionRefused,
+                .WSAETIMEDOUT => error.ConnectionTimedOut,
+                .WSAEFAULT => error.BadAddress,
+                .WSAEINVAL => error.ListeningSocket,
+                .WSAEISCONN => error.AlreadyConnected,
+                .WSAENOTSOCK => error.NotASocket,
+                .WSAEACCES => error.BroadcastNotEnabled,
+                .WSAENOBUFS => error.SystemResources,
+                .WSAEAFNOSUPPORT => error.AddressFamilyNotSupported,
+                .WSAEINPROGRESS, .WSAEWOULDBLOCK => error.WouldBlock,
+                .WSAEHOSTUNREACH, .WSAENETUNREACH => error.NetworkUnreachable,
+                else => |err| windows.unexpectedWSAError(err),
+            };
+        }
+    }
+
+    /// Accept a pending incoming connection queued to the kernel backlog
+    /// of the socket.
+    pub fn accept(self: Socket, flags: u32) !Socket.Connection {
+        var address: ws2_32.sockaddr = undefined;
+        var address_len: c_int = @sizeOf(ws2_32.sockaddr);
+
+        const rc = ws2_32.accept(self.fd, &address, &address_len);
+        if (rc == ws2_32.INVALID_SOCKET) {
+            return switch (ws2_32.WSAGetLastError()) {
+                .WSANOTINITIALISED => unreachable,
+                .WSAECONNRESET => error.ConnectionResetByPeer,
+                .WSAEFAULT => unreachable,
+                .WSAEINVAL => error.SocketNotListening,
+                .WSAEMFILE => error.ProcessFdQuotaExceeded,
+                .WSAENETDOWN => error.NetworkSubsystemFailed,
+                .WSAENOBUFS => error.FileDescriptorNotASocket,
+                .WSAEOPNOTSUPP => error.OperationNotSupported,
+                .WSAEWOULDBLOCK => error.WouldBlock,
+                else => |err| windows.unexpectedWSAError(err),
+            };
+        }
+
+        const socket = Socket.from(rc);
+        const socket_address = Socket.Address.fromNative(@alignCast(4, &address));
+
+        return Socket.Connection.from(socket, socket_address);
+    }
+
+    /// Read data from the socket into the buffer provided with a set of flags
+    /// specified. It returns the number of bytes read into the buffer provided.
+    pub fn read(self: Socket, buf: []u8, flags: u32) !usize {
+        var bufs = &[_]ws2_32.WSABUF{.{ .len = @intCast(u32, buf.len), .buf = buf.ptr }};
+        var flags_ = flags;
+
+        const rc = ws2_32.WSARecv(self.fd, bufs, 1, null, &flags_, null, null);
+        if (rc == ws2_32.SOCKET_ERROR) {
+            return switch (ws2_32.WSAGetLastError()) {
+                .WSAECONNABORTED => error.ConnectionAborted,
+                .WSAECONNRESET => error.ConnectionResetByPeer,
+                .WSAEDISCON => error.ConnectionClosedByPeer,
+                .WSAEFAULT => error.BadBuffer,
+                .WSAEINPROGRESS,
+                .WSAEWOULDBLOCK,
+                .WSA_IO_PENDING,
+                .WSAETIMEDOUT,
+                => error.WouldBlock,
+                .WSAEINTR => error.Cancelled,
+                .WSAEINVAL => error.SocketNotBound,
+                .WSAEMSGSIZE => error.MessageTooLarge,
+                .WSAENETDOWN => error.NetworkSubsystemFailed,
+                .WSAENETRESET => error.NetworkReset,
+                .WSAENOTCONN => error.SocketNotConnected,
+                .WSAENOTSOCK => error.FileDescriptorNotASocket,
+                .WSAEOPNOTSUPP => error.OperationNotSupported,
+                .WSAESHUTDOWN => error.AlreadyShutdown,
+                .WSA_OPERATION_ABORTED => error.OperationAborted,
+                else => |err| windows.unexpectedWSAError(err),
+            };
+        }
+
+        return @intCast(usize, rc);
+    }
+
+    /// Write a buffer of data provided to the socket with a set of flags specified.
+    /// It returns the number of bytes that are written to the socket.
+    pub fn write(self: Socket, buf: []const u8, flags: u32) !usize {
+        var bufs = &[_]ws2_32.WSABUF{.{ .len = @intCast(u32, buf.len), .buf = buf.ptr }};
+        var flags_ = flags;
+
+        const rc = ws2_32.WSASend(self.fd, bufs, 1, null, &flags_, null, null);
+        if (rc == ws2_32.SOCKET_ERROR) {
+            return switch (ws2_32.WSAGetLastError()) {
+                .WSAECONNABORTED => error.ConnectionAborted,
+                .WSAECONNRESET => error.ConnectionResetByPeer,
+                .WSAEFAULT => error.BadBuffer,
+                .WSAEINPROGRESS,
+                .WSAEWOULDBLOCK,
+                .WSA_IO_PENDING,
+                .WSAETIMEDOUT,
+                => error.WouldBlock,
+                .WSAEINTR => error.Cancelled,
+                .WSAEINVAL => error.SocketNotBound,
+                .WSAEMSGSIZE => error.MessageTooLarge,
+                .WSAENETDOWN => error.NetworkSubsystemFailed,
+                .WSAENETRESET => error.NetworkReset,
+                .WSAENOBUFS => error.BufferDeadlock,
+                .WSAENOTCONN => error.SocketNotConnected,
+                .WSAENOTSOCK => error.FileDescriptorNotASocket,
+                .WSAEOPNOTSUPP => error.OperationNotSupported,
+                .WSAESHUTDOWN => error.AlreadyShutdown,
+                .WSA_OPERATION_ABORTED => error.OperationAborted,
+                else => |err| windows.unexpectedWSAError(err),
+            };
+        }
+
+        return @intCast(usize, rc);
+    }
+
+    /// Writes multiple I/O vectors with a prepended message header to the socket
+    /// with a set of flags specified. It returns the number of bytes that are
+    /// written to the socket.
+    pub fn writeVectorized(self: Socket, msg: os.msghdr_const, flags: u32) !usize {
+        return error.NotImplemented;
+    }
+
+    /// Read multiple I/O vectors with a prepended message header from the socket
+    /// with a set of flags specified. It returns the number of bytes that were
+    /// read into the buffer provided.
+    pub fn readVectorized(self: Socket, msg: *os.msghdr, flags: u32) !usize {
+        return error.NotImplemented;
+    }
+
+    /// Query the address that the socket is locally bounded to.
+    pub fn getLocalAddress(self: Socket) !Socket.Address {
+        var address: ws2_32.sockaddr_storage = undefined;
+        var address_len: c_int = @sizeOf(ws2_32.sockaddr_storage);
+
+        const rc = ws2_32.getsockname(self.fd, @ptrCast(*ws2_32.sockaddr, &address), &address_len);
+        if (rc == ws2_32.SOCKET_ERROR) {
+            return switch (ws2_32.WSAGetLastError()) {
+                .WSANOTINITIALISED => unreachable,
+                .WSAEFAULT => unreachable,
+                .WSAENETDOWN => error.NetworkSubsystemFailed,
+                .WSAENOTSOCK => error.FileDescriptorNotASocket,
+                .WSAEINVAL => error.SocketNotBound,
+                else => |err| windows.unexpectedWSAError(err),
+            };
+        }
+
+        return Socket.Address.fromNative(@alignCast(4, @ptrCast(*os.sockaddr, &address)));
+    }
+
+    /// Query the address that the socket is connected to.
+    pub fn getRemoteAddress(self: Socket) !Socket.Address {
+        var address: ws2_32.sockaddr_storage = undefined;
+        var address_len: c_int = @sizeOf(ws2_32.sockaddr_storage);
+
+        const rc = ws2_32.getpeername(self.fd, @ptrCast(*ws2_32.sockaddr, &address), &address_len);
+        if (rc == ws2_32.SOCKET_ERROR) {
+            return switch (ws2_32.WSAGetLastError()) {
+                .WSANOTINITIALISED => unreachable,
+                .WSAEFAULT => unreachable,
+                .WSAENETDOWN => error.NetworkSubsystemFailed,
+                .WSAENOTSOCK => error.FileDescriptorNotASocket,
+                .WSAEINVAL => error.SocketNotBound,
+                else => |err| windows.unexpectedWSAError(err),
+            };
+        }
+
+        return Socket.Address.fromNative(@alignCast(4, @ptrCast(*os.sockaddr, &address)));
+    }
+
+    /// Query and return the latest cached error on the socket.
+    pub fn getError(self: Socket) !void {
+        return {};
+    }
+
+    /// Query the read buffer size of the socket.
+    pub fn getReadBufferSize(self: Socket) !u32 {
+        return 0;
+    }
+
+    /// Query the write buffer size of the socket.
+    pub fn getWriteBufferSize(self: Socket) !u32 {
+        return 0;
+    }
+
+    /// Set a socket option.
+    pub fn setOption(self: Socket, level: u32, name: u32, value: []const u8) !void {
+        const rc = ws2_32.setsockopt(self.fd, @intCast(i32, level), @intCast(i32, name), value.ptr, @intCast(i32, value.len));
+        if (rc == ws2_32.SOCKET_ERROR) {
+            return switch (ws2_32.WSAGetLastError()) {
+                .WSANOTINITIALISED => unreachable,
+                .WSAENETDOWN => return error.NetworkSubsystemFailed,
+                .WSAEFAULT => unreachable,
+                .WSAENOTSOCK => return error.FileDescriptorNotASocket,
+                .WSAEINVAL => return error.SocketNotBound,
+                .WSAENOTCONN => return error.SocketNotConnected,
+                .WSAESHUTDOWN => return error.AlreadyShutdown,
+                else => |err| windows.unexpectedWSAError(err),
+            };
+        }
+    }
+
+    /// Have close() or shutdown() syscalls block until all queued messages in the socket have been successfully
+    /// sent, or if the timeout specified in seconds has been reached. It returns `error.UnsupportedSocketOption`
+    /// if the host does not support the option for a socket to linger around up until a timeout specified in
+    /// seconds.
+    pub fn setLinger(self: Socket, timeout_seconds: ?u16) !void {
+        const settings = ws2_32.linger{
+            .l_onoff = @as(u16, @boolToInt(timeout_seconds != null)),
+            .l_linger = if (timeout_seconds) |seconds| seconds else 0,
+        };
+
+        return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_LINGER, mem.asBytes(&settings));
+    }
+
+    /// On connection-oriented sockets, have keep-alive messages be sent periodically. The timing in which keep-alive
+    /// messages are sent are dependant on operating system settings. It returns `error.UnsupportedSocketOption` if
+    /// the host does not support periodically sending keep-alive messages on connection-oriented sockets. 
+    pub fn setKeepAlive(self: Socket, enabled: bool) !void {
+        return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_KEEPALIVE, mem.asBytes(&@as(u32, @boolToInt(enabled))));
+    }
+
+    /// Allow multiple sockets on the same host to listen on the same address. It returns `error.UnsupportedSocketOption` if
+    /// the host does not support sockets listening the same address.
+    pub fn setReuseAddress(self: Socket, enabled: bool) !void {
+        return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_REUSEADDR, mem.asBytes(&@as(u32, @boolToInt(enabled))));
+    }
+
+    /// Allow multiple sockets on the same host to listen on the same port. It returns `error.UnsupportedSocketOption` if
+    /// the host does not supports sockets listening on the same port.
+    ///
+    /// TODO: verify if this truly mimicks SO_REUSEPORT behavior, or if SO_REUSE_UNICASTPORT provides the correct behavior
+    pub fn setReusePort(self: Socket, enabled: bool) !void {
+        try self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_BROADCAST, mem.asBytes(&@as(u32, @boolToInt(enabled))));
+        try self.setReuseAddress(enabled);
+    }
+
+    /// Set the write buffer size of the socket.
+    pub fn setWriteBufferSize(self: Socket, size: u32) !void {
+        return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_SNDBUF, mem.asBytes(&size));
+    }
+
+    /// Set the read buffer size of the socket.
+    pub fn setReadBufferSize(self: Socket, size: u32) !void {
+        return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_RCVBUF, mem.asBytes(&size));
+    }
+
+    /// Set a timeout on the socket that is to occur if no messages are successfully written
+    /// to its bound destination after a specified number of milliseconds. A subsequent write
+    /// to the socket will thereafter return `error.WouldBlock` should the timeout be exceeded.
+    pub fn setWriteTimeout(self: Socket, milliseconds: u32) !void {
+        return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_SNDTIMEO, mem.asBytes(&milliseconds));
+    }
+
+    /// Set a timeout on the socket that is to occur if no messages are successfully read
+    /// from its bound destination after a specified number of milliseconds. A subsequent
+    /// read from the socket will thereafter return `error.WouldBlock` should the timeout be
+    /// exceeded.
+    pub fn setReadTimeout(self: Socket, milliseconds: u32) !void {
+        return self.setOption(ws2_32.SOL_SOCKET, ws2_32.SO_RCVTIMEO, mem.asBytes(&milliseconds));
+    }
+};
lib/std/c.zig
@@ -151,6 +151,7 @@ pub extern "c" fn bind(socket: fd_t, address: ?*const sockaddr, address_len: soc
 pub extern "c" fn socketpair(domain: c_uint, sock_type: c_uint, protocol: c_uint, sv: *[2]fd_t) c_int;
 pub extern "c" fn listen(sockfd: fd_t, backlog: c_uint) c_int;
 pub extern "c" fn getsockname(sockfd: fd_t, noalias addr: *sockaddr, noalias addrlen: *socklen_t) c_int;
+pub extern "c" fn getpeername(sockfd: fd_t, noalias addr: *sockaddr, noalias addrlen: *socklen_t) c_int;
 pub extern "c" fn connect(sockfd: fd_t, sock_addr: *const sockaddr, addrlen: socklen_t) c_int;
 pub extern "c" fn accept(sockfd: fd_t, noalias addr: ?*sockaddr, noalias addrlen: ?*socklen_t) c_int;
 pub extern "c" fn accept4(sockfd: fd_t, noalias addr: ?*sockaddr, noalias addrlen: ?*socklen_t, flags: c_uint) c_int;
lib/std/os.zig
@@ -3217,6 +3217,35 @@ pub fn getsockname(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSock
     }
 }
 
+pub fn getpeername(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSockNameError!void {
+    if (builtin.os.tag == .windows) {
+        const rc = windows.getpeername(sock, addr, addrlen);
+        if (rc == windows.ws2_32.SOCKET_ERROR) {
+            switch (windows.ws2_32.WSAGetLastError()) {
+                .WSANOTINITIALISED => unreachable,
+                .WSAENETDOWN => return error.NetworkSubsystemFailed,
+                .WSAEFAULT => unreachable, // addr or addrlen have invalid pointers or addrlen points to an incorrect value
+                .WSAENOTSOCK => return error.FileDescriptorNotASocket,
+                .WSAEINVAL => return error.SocketNotBound,
+                else => |err| return windows.unexpectedWSAError(err),
+            }
+        }
+        return;
+    } else {
+        const rc = system.getpeername(sock, addr, addrlen);
+        switch (errno(rc)) {
+            0 => return,
+            else => |err| return unexpectedErrno(err),
+
+            EBADF => unreachable, // always a race condition
+            EFAULT => unreachable,
+            EINVAL => unreachable, // invalid parameters
+            ENOTSOCK => return error.FileDescriptorNotASocket,
+            ENOBUFS => return error.SystemResources,
+        }
+    }
+}
+
 pub const ConnectError = error{
     /// For UNIX domain sockets, which are identified by pathname: Write permission is denied on  the  socket
     /// file,  or  search  permission  is  denied  for  one of the directories in the path prefix.
lib/std/x.zig
@@ -7,7 +7,7 @@
 const std = @import("std.zig");
 
 pub const os = struct {
-    pub const Socket = @import("x/os/Socket.zig");
+    pub const Socket = @import("x/os/socket.zig").Socket;
     pub usingnamespace @import("x/os/net.zig");
 };