1 /*
2 Written by Christopher E. Miller
3 $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 */
5
6
7 module core.sys.windows.winsock2;
8 version (Windows):
9
10 pragma(lib, "ws2_32");
11
12 extern(Windows):
13 nothrow:
14
15 alias SOCKET = size_t;
16 alias socklen_t = int;
17
18 enum SOCKET INVALID_SOCKET = cast(SOCKET)~0;
19 enum int SOCKET_ERROR = -1;
20
21 enum WSADESCRIPTION_LEN = 256;
22 enum WSASYS_STATUS_LEN = 128;
23
24 struct WSADATA
25 {
26 ushort wVersion;
27 ushort wHighVersion;
28 char[WSADESCRIPTION_LEN + 1] szDescription = 0;
29 char[WSASYS_STATUS_LEN + 1] szSystemStatus = 0;
30 ushort iMaxSockets;
31 ushort iMaxUdpDg;
32 char* lpVendorInfo;
33 }
34 alias LPWSADATA = WSADATA*;
35
36
37 enum int IOCPARM_MASK = 0x7F;
38 enum int IOC_IN = cast(int)0x80000000;
39 enum int FIONBIO = cast(int)(IOC_IN | ((uint.sizeof & IOCPARM_MASK) << 16) | (102 << 8) | 126);
40
41 enum NI_MAXHOST = 1025;
42 enum NI_MAXSERV = 32;
43
44 @nogc
45 {
46 int WSAStartup(ushort wVersionRequested, LPWSADATA lpWSAData);
47 int WSACleanup();
48 SOCKET socket(int af, int type, int protocol);
49 int ioctlsocket(SOCKET s, int cmd, uint* argp);
50 int bind(SOCKET s, const(sockaddr)* name, socklen_t namelen);
51 int connect(SOCKET s, const(sockaddr)* name, socklen_t namelen);
52 int listen(SOCKET s, int backlog);
53 SOCKET accept(SOCKET s, sockaddr* addr, socklen_t* addrlen);
54 int closesocket(SOCKET s);
55 int shutdown(SOCKET s, int how);
56 int getpeername(SOCKET s, sockaddr* name, socklen_t* namelen);
57 int getsockname(SOCKET s, sockaddr* name, socklen_t* namelen);
58 int send(SOCKET s, const(void)* buf, int len, int flags);
59 int sendto(SOCKET s, const(void)* buf, int len, int flags, const(sockaddr)* to, socklen_t tolen);
60 int recv(SOCKET s, void* buf, int len, int flags);
61 int recvfrom(SOCKET s, void* buf, int len, int flags, sockaddr* from, socklen_t* fromlen);
62 int getsockopt(SOCKET s, int level, int optname, void* optval, socklen_t* optlen);
63 int setsockopt(SOCKET s, int level, int optname, const(void)* optval, socklen_t optlen);
64 uint inet_addr(const char* cp);
65 int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, const(timeval)* timeout);
66 char* inet_ntoa(in_addr ina);
67 hostent* gethostbyname(const char* name);
68 hostent* gethostbyaddr(const(void)* addr, int len, int type);
69 protoent* getprotobyname(const char* name);
70 protoent* getprotobynumber(int number);
71 servent* getservbyname(const char* name, const char* proto);
72 servent* getservbyport(int port, const char* proto);
73 }
74
75 enum: int
76 {
77 NI_NOFQDN = 0x01,
78 NI_NUMERICHOST = 0x02,
79 NI_NAMEREQD = 0x04,
80 NI_NUMERICSERV = 0x08,
81 NI_DGRAM = 0x10,
82 }
83
84 @nogc
85 {
86 int gethostname(const char* name, int namelen);
87 int getaddrinfo(const(char)* nodename, const(char)* servname, const(addrinfo)* hints, addrinfo** res);
88 void freeaddrinfo(addrinfo* ai);
89 int getnameinfo(const(sockaddr)* sa, socklen_t salen, char* host, uint hostlen, char* serv, uint servlen, int flags);
90 }
91
92 enum WSABASEERR = 10000;
93
94 enum: int
95 {
96 /*
97 * Windows Sockets definitions of regular Microsoft C error constants
98 */
99 WSAEINTR = (WSABASEERR+4),
100 WSAEBADF = (WSABASEERR+9),
101 WSAEACCES = (WSABASEERR+13),
102 WSAEFAULT = (WSABASEERR+14),
103 WSAEINVAL = (WSABASEERR+22),
104 WSAEMFILE = (WSABASEERR+24),
105
106 /*
107 * Windows Sockets definitions of regular Berkeley error constants
108 */
109 WSAEWOULDBLOCK = (WSABASEERR+35),
110 WSAEINPROGRESS = (WSABASEERR+36),
111 WSAEALREADY = (WSABASEERR+37),
112 WSAENOTSOCK = (WSABASEERR+38),
113 WSAEDESTADDRREQ = (WSABASEERR+39),
114 WSAEMSGSIZE = (WSABASEERR+40),
115 WSAEPROTOTYPE = (WSABASEERR+41),
116 WSAENOPROTOOPT = (WSABASEERR+42),
117 WSAEPROTONOSUPPORT = (WSABASEERR+43),
118 WSAESOCKTNOSUPPORT = (WSABASEERR+44),
119 WSAEOPNOTSUPP = (WSABASEERR+45),
120 WSAEPFNOSUPPORT = (WSABASEERR+46),
121 WSAEAFNOSUPPORT = (WSABASEERR+47),
122 WSAEADDRINUSE = (WSABASEERR+48),
123 WSAEADDRNOTAVAIL = (WSABASEERR+49),
124 WSAENETDOWN = (WSABASEERR+50),
125 WSAENETUNREACH = (WSABASEERR+51),
126 WSAENETRESET = (WSABASEERR+52),
127 WSAECONNABORTED = (WSABASEERR+53),
128 WSAECONNRESET = (WSABASEERR+54),
129 WSAENOBUFS = (WSABASEERR+55),
130 WSAEISCONN = (WSABASEERR+56),
131 WSAENOTCONN = (WSABASEERR+57),
132 WSAESHUTDOWN = (WSABASEERR+58),
133 WSAETOOMANYREFS = (WSABASEERR+59),
134 WSAETIMEDOUT = (WSABASEERR+60),
135 WSAECONNREFUSED = (WSABASEERR+61),
136 WSAELOOP = (WSABASEERR+62),
137 WSAENAMETOOLONG = (WSABASEERR+63),
138 WSAEHOSTDOWN = (WSABASEERR+64),
139 WSAEHOSTUNREACH = (WSABASEERR+65),
140 WSAENOTEMPTY = (WSABASEERR+66),
141 WSAEPROCLIM = (WSABASEERR+67),
142 WSAEUSERS = (WSABASEERR+68),
143 WSAEDQUOT = (WSABASEERR+69),
144 WSAESTALE = (WSABASEERR+70),
145 WSAEREMOTE = (WSABASEERR+71),
146
147 /*
148 * Extended Windows Sockets error constant definitions
149 */
150 WSASYSNOTREADY = (WSABASEERR+91),
151 WSAVERNOTSUPPORTED = (WSABASEERR+92),
152 WSANOTINITIALISED = (WSABASEERR+93),
153
154 /* Authoritative Answer: Host not found */
155 WSAHOST_NOT_FOUND = (WSABASEERR+1001),
156 HOST_NOT_FOUND = WSAHOST_NOT_FOUND,
157
158 /* Non-Authoritative: Host not found, or SERVERFAIL */
159 WSATRY_AGAIN = (WSABASEERR+1002),
160 TRY_AGAIN = WSATRY_AGAIN,
161
162 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
163 WSANO_RECOVERY = (WSABASEERR+1003),
164 NO_RECOVERY = WSANO_RECOVERY,
165
166 /* Valid name, no data record of requested type */
167 WSANO_DATA = (WSABASEERR+1004),
168 NO_DATA = WSANO_DATA,
169
170 /* no address, look for MX record */
171 WSANO_ADDRESS = WSANO_DATA,
172 NO_ADDRESS = WSANO_ADDRESS
173 }
174
175 /*
176 * Windows Sockets errors redefined as regular Berkeley error constants
177 */
178 enum: int
179 {
180 EWOULDBLOCK = WSAEWOULDBLOCK,
181 EINPROGRESS = WSAEINPROGRESS,
182 EALREADY = WSAEALREADY,
183 ENOTSOCK = WSAENOTSOCK,
184 EDESTADDRREQ = WSAEDESTADDRREQ,
185 EMSGSIZE = WSAEMSGSIZE,
186 EPROTOTYPE = WSAEPROTOTYPE,
187 ENOPROTOOPT = WSAENOPROTOOPT,
188 EPROTONOSUPPORT = WSAEPROTONOSUPPORT,
189 ESOCKTNOSUPPORT = WSAESOCKTNOSUPPORT,
190 EOPNOTSUPP = WSAEOPNOTSUPP,
191 EPFNOSUPPORT = WSAEPFNOSUPPORT,
192 EAFNOSUPPORT = WSAEAFNOSUPPORT,
193 EADDRINUSE = WSAEADDRINUSE,
194 EADDRNOTAVAIL = WSAEADDRNOTAVAIL,
195 ENETDOWN = WSAENETDOWN,
196 ENETUNREACH = WSAENETUNREACH,
197 ENETRESET = WSAENETRESET,
198 ECONNABORTED = WSAECONNABORTED,
199 ECONNRESET = WSAECONNRESET,
200 ENOBUFS = WSAENOBUFS,
201 EISCONN = WSAEISCONN,
202 ENOTCONN = WSAENOTCONN,
203 ESHUTDOWN = WSAESHUTDOWN,
204 ETOOMANYREFS = WSAETOOMANYREFS,
205 ETIMEDOUT = WSAETIMEDOUT,
206 ECONNREFUSED = WSAECONNREFUSED,
207 ELOOP = WSAELOOP,
208 ENAMETOOLONG = WSAENAMETOOLONG,
209 EHOSTDOWN = WSAEHOSTDOWN,
210 EHOSTUNREACH = WSAEHOSTUNREACH,
211 ENOTEMPTY = WSAENOTEMPTY,
212 EPROCLIM = WSAEPROCLIM,
213 EUSERS = WSAEUSERS,
214 EDQUOT = WSAEDQUOT,
215 ESTALE = WSAESTALE,
216 EREMOTE = WSAEREMOTE
217 }
218
219 enum: int
220 {
221 EAI_NONAME = WSAHOST_NOT_FOUND,
222 }
223
224 int WSAGetLastError() @trusted @nogc;
225
226
227 enum: int
228 {
229 AF_UNSPEC = 0,
230
231 AF_UNIX = 1,
232 AF_INET = 2,
233 AF_IMPLINK = 3,
234 AF_PUP = 4,
235 AF_CHAOS = 5,
236 AF_NS = 6,
237 AF_IPX = AF_NS,
238 AF_ISO = 7,
239 AF_OSI = AF_ISO,
240 AF_ECMA = 8,
241 AF_DATAKIT = 9,
242 AF_CCITT = 10,
243 AF_SNA = 11,
244 AF_DECnet = 12,
245 AF_DLI = 13,
246 AF_LAT = 14,
247 AF_HYLINK = 15,
248 AF_APPLETALK = 16,
249 AF_NETBIOS = 17,
250 AF_VOICEVIEW = 18,
251 AF_FIREFOX = 19,
252 AF_UNKNOWN1 = 20,
253 AF_BAN = 21,
254 AF_ATM = 22,
255 AF_INET6 = 23,
256 AF_CLUSTER = 24,
257 AF_12844 = 25,
258 AF_IRDA = 26,
259 AF_NETDES = 28,
260
261 AF_MAX = 29,
262
263
264 PF_UNSPEC = AF_UNSPEC,
265
266 PF_UNIX = AF_UNIX,
267 PF_INET = AF_INET,
268 PF_IMPLINK = AF_IMPLINK,
269 PF_PUP = AF_PUP,
270 PF_CHAOS = AF_CHAOS,
271 PF_NS = AF_NS,
272 PF_IPX = AF_IPX,
273 PF_ISO = AF_ISO,
274 PF_OSI = AF_OSI,
275 PF_ECMA = AF_ECMA,
276 PF_DATAKIT = AF_DATAKIT,
277 PF_CCITT = AF_CCITT,
278 PF_SNA = AF_SNA,
279 PF_DECnet = AF_DECnet,
280 PF_DLI = AF_DLI,
281 PF_LAT = AF_LAT,
282 PF_HYLINK = AF_HYLINK,
283 PF_APPLETALK = AF_APPLETALK,
284 PF_VOICEVIEW = AF_VOICEVIEW,
285 PF_FIREFOX = AF_FIREFOX,
286 PF_UNKNOWN1 = AF_UNKNOWN1,
287 PF_BAN = AF_BAN,
288 PF_INET6 = AF_INET6,
289
290 PF_MAX = AF_MAX,
291 }
292
293
294 enum: int
295 {
296 SOL_SOCKET = 0xFFFF,
297 }
298
299
300 enum: int
301 {
302 SO_DEBUG = 0x0001,
303 SO_ACCEPTCONN = 0x0002,
304 SO_REUSEADDR = 0x0004,
305 SO_KEEPALIVE = 0x0008,
306 SO_DONTROUTE = 0x0010,
307 SO_BROADCAST = 0x0020,
308 SO_USELOOPBACK = 0x0040,
309 SO_LINGER = 0x0080,
310 SO_DONTLINGER = ~SO_LINGER,
311 SO_OOBINLINE = 0x0100,
312 SO_SNDBUF = 0x1001,
313 SO_RCVBUF = 0x1002,
314 SO_SNDLOWAT = 0x1003,
315 SO_RCVLOWAT = 0x1004,
316 SO_SNDTIMEO = 0x1005,
317 SO_RCVTIMEO = 0x1006,
318 SO_ERROR = 0x1007,
319 SO_TYPE = 0x1008,
320 SO_EXCLUSIVEADDRUSE = ~SO_REUSEADDR,
321
322 TCP_NODELAY = 1,
323
324 IP_OPTIONS = 1,
325
326 IP_HDRINCL = 2,
327 IP_TOS = 3,
328 IP_TTL = 4,
329 IP_MULTICAST_IF = 9,
330 IP_MULTICAST_TTL = 10,
331 IP_MULTICAST_LOOP = 11,
332 IP_ADD_MEMBERSHIP = 12,
333 IP_DROP_MEMBERSHIP = 13,
334 IP_DONTFRAGMENT = 14,
335 IP_ADD_SOURCE_MEMBERSHIP = 15,
336 IP_DROP_SOURCE_MEMBERSHIP = 16,
337 IP_BLOCK_SOURCE = 17,
338 IP_UNBLOCK_SOURCE = 18,
339 IP_PKTINFO = 19,
340
341 IPV6_UNICAST_HOPS = 4,
342 IPV6_MULTICAST_IF = 9,
343 IPV6_MULTICAST_HOPS = 10,
344 IPV6_MULTICAST_LOOP = 11,
345 IPV6_ADD_MEMBERSHIP = 12,
346 IPV6_DROP_MEMBERSHIP = 13,
347 IPV6_JOIN_GROUP = IPV6_ADD_MEMBERSHIP,
348 IPV6_LEAVE_GROUP = IPV6_DROP_MEMBERSHIP,
349 IPV6_V6ONLY = 27,
350 }
351
352
353 /// Default FD_SETSIZE value.
354 /// In C/C++, it is redefinable by #define-ing the macro before #include-ing
355 /// winsock.h. In D, use the $(D FD_CREATE) function to allocate a $(D fd_set)
356 /// of an arbitrary size.
357 enum int FD_SETSIZE = 64;
358
359
fd_set_custom(uint SETSIZE)360 struct fd_set_custom(uint SETSIZE)
361 {
362 uint fd_count;
363 SOCKET[SETSIZE] fd_array;
364 }
365
366 alias fd_set = fd_set_custom!FD_SETSIZE;
367
368 // Removes.
FD_CLR(SOCKET fd,fd_set * set)369 void FD_CLR(SOCKET fd, fd_set* set) pure @nogc
370 {
371 uint c = set.fd_count;
372 SOCKET* start = set.fd_array.ptr;
373 SOCKET* stop = start + c;
374
375 for (; start != stop; start++)
376 {
377 if (*start == fd)
378 goto found;
379 }
380 return; //not found
381
382 found:
383 for (++start; start != stop; start++)
384 {
385 *(start - 1) = *start;
386 }
387
388 set.fd_count = c - 1;
389 }
390
391
392 // Tests.
FD_ISSET(SOCKET fd,const (fd_set)* set)393 int FD_ISSET(SOCKET fd, const(fd_set)* set) pure @nogc
394 {
395 const(SOCKET)* start = set.fd_array.ptr;
396 const(SOCKET)* stop = start + set.fd_count;
397
398 for (; start != stop; start++)
399 {
400 if (*start == fd)
401 return true;
402 }
403 return false;
404 }
405
406
407 // Adds.
FD_SET(SOCKET fd,fd_set * set)408 void FD_SET(SOCKET fd, fd_set* set) pure @nogc
409 {
410 uint c = set.fd_count;
411 set.fd_array.ptr[c] = fd;
412 set.fd_count = c + 1;
413 }
414
415
416 // Resets to zero.
FD_ZERO(fd_set * set)417 void FD_ZERO(fd_set* set) pure @nogc
418 {
419 set.fd_count = 0;
420 }
421
422
423 /// Creates a new $(D fd_set) with the specified capacity.
FD_CREATE(uint capacity)424 fd_set* FD_CREATE(uint capacity) pure
425 {
426 // Take into account alignment (SOCKET may be 64-bit and require 64-bit alignment on 64-bit systems)
427 size_t size = (fd_set_custom!1).sizeof - SOCKET.sizeof + (SOCKET.sizeof * capacity);
428 auto data = new ubyte[size];
429 auto set = cast(fd_set*)data.ptr;
430 FD_ZERO(set);
431 return set;
432 }
433
434 struct linger
435 {
436 ushort l_onoff;
437 ushort l_linger;
438 }
439
440
441 struct protoent
442 {
443 char* p_name;
444 char** p_aliases;
445 short p_proto;
446 }
447
448
449 struct servent
450 {
451 char* s_name;
452 char** s_aliases;
453
versionservent454 version (Win64)
455 {
456 char* s_proto;
457 short s_port;
458 }
versionservent459 else version (Win32)
460 {
461 short s_port;
462 char* s_proto;
463 }
464 }
465
466
467 /+
468 union in6_addr
469 {
470 private union _u_t
471 {
472 ubyte[16] Byte;
473 ushort[8] Word;
474 }
475 _u_t u;
476 }
477
478
479 struct in_addr6
480 {
481 ubyte[16] s6_addr;
482 }
483 +/
484
485 @safe pure @nogc
486 {
487 ushort htons(ushort x);
488 uint htonl(uint x);
489 ushort ntohs(ushort x);
490 uint ntohl(uint x);
491 }
492
493
494 enum: int
495 {
496 SOCK_STREAM = 1,
497 SOCK_DGRAM = 2,
498 SOCK_RAW = 3,
499 SOCK_RDM = 4,
500 SOCK_SEQPACKET = 5,
501 }
502
503
504 enum: int
505 {
506 IPPROTO_IP = 0,
507 IPPROTO_ICMP = 1,
508 IPPROTO_IGMP = 2,
509 IPPROTO_GGP = 3,
510 IPPROTO_TCP = 6,
511 IPPROTO_PUP = 12,
512 IPPROTO_UDP = 17,
513 IPPROTO_IDP = 22,
514 IPPROTO_IPV6 = 41,
515 IPPROTO_ND = 77,
516 IPPROTO_RAW = 255,
517
518 IPPROTO_MAX = 256,
519 }
520
521
522 enum: int
523 {
524 MSG_OOB = 0x1,
525 MSG_PEEK = 0x2,
526 MSG_DONTROUTE = 0x4
527 }
528
529
530 enum: int
531 {
532 SD_RECEIVE = 0,
533 SD_SEND = 1,
534 SD_BOTH = 2,
535 }
536
537
538 enum: uint
539 {
540 INADDR_ANY = 0,
541 INADDR_LOOPBACK = 0x7F000001,
542 INADDR_BROADCAST = 0xFFFFFFFF,
543 INADDR_NONE = 0xFFFFFFFF,
544 ADDR_ANY = INADDR_ANY,
545 }
546
547
548 enum: int
549 {
550 AI_PASSIVE = 0x1,
551 AI_CANONNAME = 0x2,
552 AI_NUMERICHOST = 0x4,
553 AI_ADDRCONFIG = 0x0400,
554 AI_NON_AUTHORITATIVE = 0x04000,
555 AI_SECURE = 0x08000,
556 AI_RETURN_PREFERRED_NAMES = 0x010000,
557 }
558
559
560 struct timeval
561 {
562 int tv_sec;
563 int tv_usec;
564 }
565
566
567 union in_addr
568 {
569 private union _S_un_t
570 {
571 private struct _S_un_b_t
572 {
573 ubyte s_b1, s_b2, s_b3, s_b4;
574 }
575 _S_un_b_t S_un_b;
576
577 private struct _S_un_w_t
578 {
579 ushort s_w1, s_w2;
580 }
581 _S_un_w_t S_un_w;
582
583 uint S_addr;
584 }
585 _S_un_t S_un;
586
587 uint s_addr;
588
589 struct
590 {
591 ubyte s_net, s_host;
592
593 union
594 {
595 ushort s_imp;
596
597 struct
598 {
599 ubyte s_lh, s_impno;
600 }
601 }
602 }
603 }
604
605
606 union in6_addr
607 {
608 private union _in6_u_t
609 {
610 ubyte[16] u6_addr8;
611 ushort[8] u6_addr16;
612 uint[4] u6_addr32;
613 }
614 _in6_u_t in6_u;
615
616 ubyte[16] s6_addr8;
617 ushort[8] s6_addr16;
618 uint[4] s6_addr32;
619
620 alias s6_addr = s6_addr8;
621 }
622
623
624 enum in6_addr IN6ADDR_ANY = { s6_addr8: [0] };
625 enum in6_addr IN6ADDR_LOOPBACK = { s6_addr8: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] };
626 //alias IN6ADDR_ANY_INIT = IN6ADDR_ANY;
627 //alias IN6ADDR_LOOPBACK_INIT = IN6ADDR_LOOPBACK;
628
629 enum int INET_ADDRSTRLEN = 16;
630 enum int INET6_ADDRSTRLEN = 46;
631
632
633
634
635 struct sockaddr
636 {
637 short sa_family;
638 ubyte[14] sa_data;
639 }
640 alias sockaddr SOCKADDR;
641 alias SOCKADDR* PSOCKADDR, LPSOCKADDR;
642
643 struct sockaddr_storage
644 {
645 short ss_family;
646 char[6] __ss_pad1 = void;
647 long __ss_align;
648 char[112] __ss_pad2 = void;
649 }
650 alias sockaddr_storage SOCKADDR_STORAGE;
651 alias SOCKADDR_STORAGE* PSOCKADDR_STORAGE;
652
653 struct sockaddr_in
654 {
655 short sin_family = AF_INET;
656 ushort sin_port;
657 in_addr sin_addr;
658 ubyte[8] sin_zero;
659 }
660 alias sockaddr_in SOCKADDR_IN;
661 alias SOCKADDR_IN* PSOCKADDR_IN, LPSOCKADDR_IN;
662
663
664 struct sockaddr_in6
665 {
666 short sin6_family = AF_INET6;
667 ushort sin6_port;
668 uint sin6_flowinfo;
669 in6_addr sin6_addr;
670 uint sin6_scope_id;
671 }
672
673
674 struct addrinfo
675 {
676 int ai_flags;
677 int ai_family;
678 int ai_socktype;
679 int ai_protocol;
680 size_t ai_addrlen;
681 char* ai_canonname;
682 sockaddr* ai_addr;
683 addrinfo* ai_next;
684 }
685
686
687 struct hostent
688 {
689 char* h_name;
690 char** h_aliases;
691 short h_addrtype;
692 short h_length;
693 char** h_addr_list;
694
695
696 char* h_addr() @safe pure nothrow @nogc
697 {
698 return h_addr_list[0];
699 }
700 }
701
702 // Note: These are Winsock2!!
703 struct WSAOVERLAPPED;
704 alias LPWSAOVERLAPPED = WSAOVERLAPPED*;
705 alias LPWSAOVERLAPPED_COMPLETION_ROUTINE = void function(uint, uint, LPWSAOVERLAPPED, uint);
706 int WSAIoctl(SOCKET s, uint dwIoControlCode,
707 void* lpvInBuffer, uint cbInBuffer,
708 void* lpvOutBuffer, uint cbOutBuffer,
709 uint* lpcbBytesReturned,
710 LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
711
712
713 enum IOC_VENDOR = 0x18000000;
714 enum SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4;
715
716 /* Argument structure for SIO_KEEPALIVE_VALS */
717 struct tcp_keepalive
718 {
719 uint onoff;
720 uint keepalivetime;
721 uint keepaliveinterval;
722 }
723