source: trunk/Packages/synapse/source/lib/sswin32.inc

Last change on this file was 2, checked in by chronos, 12 years ago
  • Přidáno: Základní kostra projektu.
  • Přidáno: Knihovna synapse.
File size: 54.7 KB
Line 
1{==============================================================================|
2| Project : Ararat Synapse | 002.003.000 |
3|==============================================================================|
4| Content: Socket Independent Platform Layer - Win32/64 definition include |
5|==============================================================================|
6| Copyright (c)1999-2011, Lukas Gebauer |
7| All rights reserved. |
8| |
9| Redistribution and use in source and binary forms, with or without |
10| modification, are permitted provided that the following conditions are met: |
11| |
12| Redistributions of source code must retain the above copyright notice, this |
13| list of conditions and the following disclaimer. |
14| |
15| Redistributions in binary form must reproduce the above copyright notice, |
16| this list of conditions and the following disclaimer in the documentation |
17| and/or other materials provided with the distribution. |
18| |
19| Neither the name of Lukas Gebauer nor the names of its contributors may |
20| be used to endorse or promote products derived from this software without |
21| specific prior written permission. |
22| |
23| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
24| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
25| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
26| ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR |
27| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
28| DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
29| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
30| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
31| LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
32| OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
33| DAMAGE. |
34|==============================================================================|
35| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
36| Portions created by Lukas Gebauer are Copyright (c)2003-2011. |
37| All Rights Reserved. |
38|==============================================================================|
39| Contributor(s): |
40|==============================================================================|
41| History: see HISTORY.HTM from distribution package |
42| (Found at URL: http://www.ararat.cz/synapse/) |
43|==============================================================================}
44
45{:@exclude}
46
47//{$DEFINE WINSOCK1}
48{Note about define WINSOCK1:
49If you activate this compiler directive, then socket interface level 1.1 is
50used instead default level 2.2. Level 2.2 is not available on old W95, however
51you can install update.
52}
53
54//{$DEFINE FORCEOLDAPI}
55{Note about define FORCEOLDAPI:
56If you activate this compiler directive, then is allways used old socket API
57for name resolution. If you leave this directive inactive, then the new API
58is used, when running system allows it.
59
60For IPv6 support you must have new API!
61}
62
63{$IFDEF FPC}
64 {$MODE DELPHI}
65{$ENDIF}
66{$H+}
67{$IFDEF VER125}
68 {$DEFINE BCB}
69{$ENDIF}
70{$IFDEF BCB}
71 {$ObjExportAll On}
72 (*$HPPEMIT '/* EDE 2003-02-19 */' *)
73 (*$HPPEMIT 'namespace Synsock { using System::Shortint; }' *)
74 (*$HPPEMIT '#undef h_addr' *)
75 (*$HPPEMIT '#undef IOCPARM_MASK' *)
76 (*$HPPEMIT '#undef FD_SETSIZE' *)
77 (*$HPPEMIT '#undef IOC_VOID' *)
78 (*$HPPEMIT '#undef IOC_OUT' *)
79 (*$HPPEMIT '#undef IOC_IN' *)
80 (*$HPPEMIT '#undef IOC_INOUT' *)
81 (*$HPPEMIT '#undef FIONREAD' *)
82 (*$HPPEMIT '#undef FIONBIO' *)
83 (*$HPPEMIT '#undef FIOASYNC' *)
84 (*$HPPEMIT '#undef IPPROTO_IP' *)
85 (*$HPPEMIT '#undef IPPROTO_ICMP' *)
86 (*$HPPEMIT '#undef IPPROTO_IGMP' *)
87 (*$HPPEMIT '#undef IPPROTO_TCP' *)
88 (*$HPPEMIT '#undef IPPROTO_UDP' *)
89 (*$HPPEMIT '#undef IPPROTO_RAW' *)
90 (*$HPPEMIT '#undef IPPROTO_MAX' *)
91 (*$HPPEMIT '#undef INADDR_ANY' *)
92 (*$HPPEMIT '#undef INADDR_LOOPBACK' *)
93 (*$HPPEMIT '#undef INADDR_BROADCAST' *)
94 (*$HPPEMIT '#undef INADDR_NONE' *)
95 (*$HPPEMIT '#undef INVALID_SOCKET' *)
96 (*$HPPEMIT '#undef SOCKET_ERROR' *)
97 (*$HPPEMIT '#undef WSADESCRIPTION_LEN' *)
98 (*$HPPEMIT '#undef WSASYS_STATUS_LEN' *)
99 (*$HPPEMIT '#undef IP_OPTIONS' *)
100 (*$HPPEMIT '#undef IP_TOS' *)
101 (*$HPPEMIT '#undef IP_TTL' *)
102 (*$HPPEMIT '#undef IP_MULTICAST_IF' *)
103 (*$HPPEMIT '#undef IP_MULTICAST_TTL' *)
104 (*$HPPEMIT '#undef IP_MULTICAST_LOOP' *)
105 (*$HPPEMIT '#undef IP_ADD_MEMBERSHIP' *)
106 (*$HPPEMIT '#undef IP_DROP_MEMBERSHIP' *)
107 (*$HPPEMIT '#undef IP_DONTFRAGMENT' *)
108 (*$HPPEMIT '#undef IP_DEFAULT_MULTICAST_TTL' *)
109 (*$HPPEMIT '#undef IP_DEFAULT_MULTICAST_LOOP' *)
110 (*$HPPEMIT '#undef IP_MAX_MEMBERSHIPS' *)
111 (*$HPPEMIT '#undef SOL_SOCKET' *)
112 (*$HPPEMIT '#undef SO_DEBUG' *)
113 (*$HPPEMIT '#undef SO_ACCEPTCONN' *)
114 (*$HPPEMIT '#undef SO_REUSEADDR' *)
115 (*$HPPEMIT '#undef SO_KEEPALIVE' *)
116 (*$HPPEMIT '#undef SO_DONTROUTE' *)
117 (*$HPPEMIT '#undef SO_BROADCAST' *)
118 (*$HPPEMIT '#undef SO_USELOOPBACK' *)
119 (*$HPPEMIT '#undef SO_LINGER' *)
120 (*$HPPEMIT '#undef SO_OOBINLINE' *)
121 (*$HPPEMIT '#undef SO_DONTLINGER' *)
122 (*$HPPEMIT '#undef SO_SNDBUF' *)
123 (*$HPPEMIT '#undef SO_RCVBUF' *)
124 (*$HPPEMIT '#undef SO_SNDLOWAT' *)
125 (*$HPPEMIT '#undef SO_RCVLOWAT' *)
126 (*$HPPEMIT '#undef SO_SNDTIMEO' *)
127 (*$HPPEMIT '#undef SO_RCVTIMEO' *)
128 (*$HPPEMIT '#undef SO_ERROR' *)
129 (*$HPPEMIT '#undef SO_OPENTYPE' *)
130 (*$HPPEMIT '#undef SO_SYNCHRONOUS_ALERT' *)
131 (*$HPPEMIT '#undef SO_SYNCHRONOUS_NONALERT' *)
132 (*$HPPEMIT '#undef SO_MAXDG' *)
133 (*$HPPEMIT '#undef SO_MAXPATHDG' *)
134 (*$HPPEMIT '#undef SO_UPDATE_ACCEPT_CONTEXT' *)
135 (*$HPPEMIT '#undef SO_CONNECT_TIME' *)
136 (*$HPPEMIT '#undef SO_TYPE' *)
137 (*$HPPEMIT '#undef SOCK_STREAM' *)
138 (*$HPPEMIT '#undef SOCK_DGRAM' *)
139 (*$HPPEMIT '#undef SOCK_RAW' *)
140 (*$HPPEMIT '#undef SOCK_RDM' *)
141 (*$HPPEMIT '#undef SOCK_SEQPACKET' *)
142 (*$HPPEMIT '#undef TCP_NODELAY' *)
143 (*$HPPEMIT '#undef AF_UNSPEC' *)
144 (*$HPPEMIT '#undef SOMAXCONN' *)
145 (*$HPPEMIT '#undef AF_INET' *)
146 (*$HPPEMIT '#undef AF_MAX' *)
147 (*$HPPEMIT '#undef PF_UNSPEC' *)
148 (*$HPPEMIT '#undef PF_INET' *)
149 (*$HPPEMIT '#undef PF_MAX' *)
150 (*$HPPEMIT '#undef MSG_OOB' *)
151 (*$HPPEMIT '#undef MSG_PEEK' *)
152 (*$HPPEMIT '#undef WSABASEERR' *)
153 (*$HPPEMIT '#undef WSAEINTR' *)
154 (*$HPPEMIT '#undef WSAEBADF' *)
155 (*$HPPEMIT '#undef WSAEACCES' *)
156 (*$HPPEMIT '#undef WSAEFAULT' *)
157 (*$HPPEMIT '#undef WSAEINVAL' *)
158 (*$HPPEMIT '#undef WSAEMFILE' *)
159 (*$HPPEMIT '#undef WSAEWOULDBLOCK' *)
160 (*$HPPEMIT '#undef WSAEINPROGRESS' *)
161 (*$HPPEMIT '#undef WSAEALREADY' *)
162 (*$HPPEMIT '#undef WSAENOTSOCK' *)
163 (*$HPPEMIT '#undef WSAEDESTADDRREQ' *)
164 (*$HPPEMIT '#undef WSAEMSGSIZE' *)
165 (*$HPPEMIT '#undef WSAEPROTOTYPE' *)
166 (*$HPPEMIT '#undef WSAENOPROTOOPT' *)
167 (*$HPPEMIT '#undef WSAEPROTONOSUPPORT' *)
168 (*$HPPEMIT '#undef WSAESOCKTNOSUPPORT' *)
169 (*$HPPEMIT '#undef WSAEOPNOTSUPP' *)
170 (*$HPPEMIT '#undef WSAEPFNOSUPPORT' *)
171 (*$HPPEMIT '#undef WSAEAFNOSUPPORT' *)
172 (*$HPPEMIT '#undef WSAEADDRINUSE' *)
173 (*$HPPEMIT '#undef WSAEADDRNOTAVAIL' *)
174 (*$HPPEMIT '#undef WSAENETDOWN' *)
175 (*$HPPEMIT '#undef WSAENETUNREACH' *)
176 (*$HPPEMIT '#undef WSAENETRESET' *)
177 (*$HPPEMIT '#undef WSAECONNABORTED' *)
178 (*$HPPEMIT '#undef WSAECONNRESET' *)
179 (*$HPPEMIT '#undef WSAENOBUFS' *)
180 (*$HPPEMIT '#undef WSAEISCONN' *)
181 (*$HPPEMIT '#undef WSAENOTCONN' *)
182 (*$HPPEMIT '#undef WSAESHUTDOWN' *)
183 (*$HPPEMIT '#undef WSAETOOMANYREFS' *)
184 (*$HPPEMIT '#undef WSAETIMEDOUT' *)
185 (*$HPPEMIT '#undef WSAECONNREFUSED' *)
186 (*$HPPEMIT '#undef WSAELOOP' *)
187 (*$HPPEMIT '#undef WSAENAMETOOLONG' *)
188 (*$HPPEMIT '#undef WSAEHOSTDOWN' *)
189 (*$HPPEMIT '#undef WSAEHOSTUNREACH' *)
190 (*$HPPEMIT '#undef WSAENOTEMPTY' *)
191 (*$HPPEMIT '#undef WSAEPROCLIM' *)
192 (*$HPPEMIT '#undef WSAEUSERS' *)
193 (*$HPPEMIT '#undef WSAEDQUOT' *)
194 (*$HPPEMIT '#undef WSAESTALE' *)
195 (*$HPPEMIT '#undef WSAEREMOTE' *)
196 (*$HPPEMIT '#undef WSASYSNOTREADY' *)
197 (*$HPPEMIT '#undef WSAVERNOTSUPPORTED' *)
198 (*$HPPEMIT '#undef WSANOTINITIALISED' *)
199 (*$HPPEMIT '#undef WSAEDISCON' *)
200 (*$HPPEMIT '#undef WSAENOMORE' *)
201 (*$HPPEMIT '#undef WSAECANCELLED' *)
202 (*$HPPEMIT '#undef WSAEEINVALIDPROCTABLE' *)
203 (*$HPPEMIT '#undef WSAEINVALIDPROVIDER' *)
204 (*$HPPEMIT '#undef WSAEPROVIDERFAILEDINIT' *)
205 (*$HPPEMIT '#undef WSASYSCALLFAILURE' *)
206 (*$HPPEMIT '#undef WSASERVICE_NOT_FOUND' *)
207 (*$HPPEMIT '#undef WSATYPE_NOT_FOUND' *)
208 (*$HPPEMIT '#undef WSA_E_NO_MORE' *)
209 (*$HPPEMIT '#undef WSA_E_CANCELLED' *)
210 (*$HPPEMIT '#undef WSAEREFUSED' *)
211 (*$HPPEMIT '#undef WSAHOST_NOT_FOUND' *)
212 (*$HPPEMIT '#undef HOST_NOT_FOUND' *)
213 (*$HPPEMIT '#undef WSATRY_AGAIN' *)
214 (*$HPPEMIT '#undef TRY_AGAIN' *)
215 (*$HPPEMIT '#undef WSANO_RECOVERY' *)
216 (*$HPPEMIT '#undef NO_RECOVERY' *)
217 (*$HPPEMIT '#undef WSANO_DATA' *)
218 (*$HPPEMIT '#undef NO_DATA' *)
219 (*$HPPEMIT '#undef WSANO_ADDRESS' *)
220 (*$HPPEMIT '#undef ENAMETOOLONG' *)
221 (*$HPPEMIT '#undef ENOTEMPTY' *)
222 (*$HPPEMIT '#undef FD_CLR' *)
223 (*$HPPEMIT '#undef FD_ISSET' *)
224 (*$HPPEMIT '#undef FD_SET' *)
225 (*$HPPEMIT '#undef FD_ZERO' *)
226 (*$HPPEMIT '#undef NO_ADDRESS' *)
227 (*$HPPEMIT '#undef ADDR_ANY' *)
228 (*$HPPEMIT '#undef SO_GROUP_ID' *)
229 (*$HPPEMIT '#undef SO_GROUP_PRIORITY' *)
230 (*$HPPEMIT '#undef SO_MAX_MSG_SIZE' *)
231 (*$HPPEMIT '#undef SO_PROTOCOL_INFOA' *)
232 (*$HPPEMIT '#undef SO_PROTOCOL_INFOW' *)
233 (*$HPPEMIT '#undef SO_PROTOCOL_INFO' *)
234 (*$HPPEMIT '#undef PVD_CONFIG' *)
235 (*$HPPEMIT '#undef AF_INET6' *)
236 (*$HPPEMIT '#undef PF_INET6' *)
237{$ENDIF}
238
239{$IFDEF FPC}
240 {$IFDEF WIN32}
241 {$ALIGN OFF}
242 {$ELSE}
243 {$PACKRECORDS C}
244 {$ENDIF}
245{$ENDIF}
246
247interface
248
249uses
250 SyncObjs, SysUtils, Classes,
251 Windows;
252
253function InitSocketInterface(stack: String): Boolean;
254function DestroySocketInterface: Boolean;
255
256const
257{$IFDEF WINSOCK1}
258 WinsockLevel = $0101;
259{$ELSE}
260 WinsockLevel = $0202;
261{$ENDIF}
262
263type
264 u_short = Word;
265 u_int = Integer;
266 u_long = Longint;
267 pu_long = ^u_long;
268 pu_short = ^u_short;
269{$IFDEF FPC}
270 TSocket = ptruint;
271{$ELSE}
272 {$IFDEF WIN64}
273 TSocket = UINT_PTR;
274 {$ELSE}
275 TSocket = u_int;
276 {$ENDIF}
277{$ENDIF}
278 TAddrFamily = integer;
279
280 TMemory = pointer;
281
282const
283 {$IFDEF WINCE}
284 DLLStackName = 'ws2.dll';
285 {$ELSE}
286 {$IFDEF WINSOCK1}
287 DLLStackName = 'wsock32.dll';
288 {$ELSE}
289 DLLStackName = 'ws2_32.dll';
290 {$ENDIF}
291 {$ENDIF}
292 DLLwship6 = 'wship6.dll';
293
294 cLocalhost = '127.0.0.1';
295 cAnyHost = '0.0.0.0';
296 cBroadcast = '255.255.255.255';
297 c6Localhost = '::1';
298 c6AnyHost = '::0';
299 c6Broadcast = 'ffff::1';
300 cAnyPort = '0';
301
302
303const
304 FD_SETSIZE = 64;
305type
306 PFDSet = ^TFDSet;
307 TFDSet = record
308 fd_count: u_int;
309 fd_array: array[0..FD_SETSIZE-1] of TSocket;
310 end;
311
312const
313 FIONREAD = $4004667f;
314 FIONBIO = $8004667e;
315 FIOASYNC = $8004667d;
316
317type
318 PTimeVal = ^TTimeVal;
319 TTimeVal = record
320 tv_sec: Longint;
321 tv_usec: Longint;
322 end;
323
324const
325 IPPROTO_IP = 0; { Dummy }
326 IPPROTO_ICMP = 1; { Internet Control Message Protocol }
327 IPPROTO_IGMP = 2; { Internet Group Management Protocol}
328 IPPROTO_TCP = 6; { TCP }
329 IPPROTO_UDP = 17; { User Datagram Protocol }
330 IPPROTO_IPV6 = 41;
331 IPPROTO_ICMPV6 = 58;
332 IPPROTO_RM = 113;
333
334 IPPROTO_RAW = 255;
335 IPPROTO_MAX = 256;
336
337type
338
339 PInAddr = ^TInAddr;
340 TInAddr = record
341 case integer of
342 0: (S_bytes: packed array [0..3] of byte);
343 1: (S_addr: u_long);
344 end;
345
346 PSockAddrIn = ^TSockAddrIn;
347 TSockAddrIn = record
348 case Integer of
349 0: (sin_family: u_short;
350 sin_port: u_short;
351 sin_addr: TInAddr;
352 sin_zero: array[0..7] of byte);
353 1: (sa_family: u_short;
354 sa_data: array[0..13] of byte)
355 end;
356
357 TIP_mreq = record
358 imr_multiaddr: TInAddr; { IP multicast address of group }
359 imr_interface: TInAddr; { local IP address of interface }
360 end;
361
362 PInAddr6 = ^TInAddr6;
363 TInAddr6 = record
364 case integer of
365 0: (S6_addr: packed array [0..15] of byte);
366 1: (u6_addr8: packed array [0..15] of byte);
367 2: (u6_addr16: packed array [0..7] of word);
368 3: (u6_addr32: packed array [0..3] of integer);
369 end;
370
371 PSockAddrIn6 = ^TSockAddrIn6;
372 TSockAddrIn6 = record
373 sin6_family: u_short; // AF_INET6
374 sin6_port: u_short; // Transport level port number
375 sin6_flowinfo: u_long; // IPv6 flow information
376 sin6_addr: TInAddr6; // IPv6 address
377 sin6_scope_id: u_long; // Scope Id: IF number for link-local
378 // SITE id for site-local
379 end;
380
381 TIPv6_mreq = record
382 ipv6mr_multiaddr: TInAddr6; // IPv6 multicast address.
383 ipv6mr_interface: integer; // Interface index.
384 padding: integer;
385 end;
386
387 PHostEnt = ^THostEnt;
388 THostEnt = record
389 h_name: PAnsiChar;
390 h_aliases: ^PAnsiChar;
391 h_addrtype: Smallint;
392 h_length: Smallint;
393 case integer of
394 0: (h_addr_list: ^PAnsiChar);
395 1: (h_addr: ^PInAddr);
396 end;
397
398 PNetEnt = ^TNetEnt;
399 TNetEnt = record
400 n_name: PAnsiChar;
401 n_aliases: ^PAnsiChar;
402 n_addrtype: Smallint;
403 n_net: u_long;
404 end;
405
406 PServEnt = ^TServEnt;
407 TServEnt = record
408 s_name: PAnsiChar;
409 s_aliases: ^PAnsiChar;
410{$ifdef WIN64}
411 s_proto: PAnsiChar;
412 s_port: Smallint;
413{$else}
414 s_port: Smallint;
415 s_proto: PAnsiChar;
416{$endif}
417 end;
418
419 PProtoEnt = ^TProtoEnt;
420 TProtoEnt = record
421 p_name: PAnsiChar;
422 p_aliases: ^PAnsichar;
423 p_proto: Smallint;
424 end;
425
426const
427 INADDR_ANY = $00000000;
428 INADDR_LOOPBACK = $7F000001;
429 INADDR_BROADCAST = $FFFFFFFF;
430 INADDR_NONE = $FFFFFFFF;
431 ADDR_ANY = INADDR_ANY;
432 INVALID_SOCKET = TSocket(NOT(0));
433 SOCKET_ERROR = -1;
434
435Const
436 {$IFDEF WINSOCK1}
437 IP_OPTIONS = 1;
438 IP_MULTICAST_IF = 2; { set/get IP multicast interface }
439 IP_MULTICAST_TTL = 3; { set/get IP multicast timetolive }
440 IP_MULTICAST_LOOP = 4; { set/get IP multicast loopback }
441 IP_ADD_MEMBERSHIP = 5; { add an IP group membership }
442 IP_DROP_MEMBERSHIP = 6; { drop an IP group membership }
443 IP_TTL = 7; { set/get IP Time To Live }
444 IP_TOS = 8; { set/get IP Type Of Service }
445 IP_DONTFRAGMENT = 9; { set/get IP Don't Fragment flag }
446 {$ELSE}
447 IP_OPTIONS = 1;
448 IP_HDRINCL = 2;
449 IP_TOS = 3; { set/get IP Type Of Service }
450 IP_TTL = 4; { set/get IP Time To Live }
451 IP_MULTICAST_IF = 9; { set/get IP multicast interface }
452 IP_MULTICAST_TTL = 10; { set/get IP multicast timetolive }
453 IP_MULTICAST_LOOP = 11; { set/get IP multicast loopback }
454 IP_ADD_MEMBERSHIP = 12; { add an IP group membership }
455 IP_DROP_MEMBERSHIP = 13; { drop an IP group membership }
456 IP_DONTFRAGMENT = 14; { set/get IP Don't Fragment flag }
457 {$ENDIF}
458
459 IP_DEFAULT_MULTICAST_TTL = 1; { normally limit m'casts to 1 hop }
460 IP_DEFAULT_MULTICAST_LOOP = 1; { normally hear sends if a member }
461 IP_MAX_MEMBERSHIPS = 20; { per socket; must fit in one mbuf }
462
463 SOL_SOCKET = $ffff; {options for socket level }
464{ Option flags per-socket. }
465 SO_DEBUG = $0001; { turn on debugging info recording }
466 SO_ACCEPTCONN = $0002; { socket has had listen() }
467 SO_REUSEADDR = $0004; { allow local address reuse }
468 SO_KEEPALIVE = $0008; { keep connections alive }
469 SO_DONTROUTE = $0010; { just use interface addresses }
470 SO_BROADCAST = $0020; { permit sending of broadcast msgs }
471 SO_USELOOPBACK = $0040; { bypass hardware when possible }
472 SO_LINGER = $0080; { linger on close if data present }
473 SO_OOBINLINE = $0100; { leave received OOB data in line }
474 SO_DONTLINGER = $ff7f;
475{ Additional options. }
476 SO_SNDBUF = $1001; { send buffer size }
477 SO_RCVBUF = $1002; { receive buffer size }
478 SO_SNDLOWAT = $1003; { send low-water mark }
479 SO_RCVLOWAT = $1004; { receive low-water mark }
480 SO_SNDTIMEO = $1005; { send timeout }
481 SO_RCVTIMEO = $1006; { receive timeout }
482 SO_ERROR = $1007; { get error status and clear }
483 SO_TYPE = $1008; { get socket type }
484{ WinSock 2 extension -- new options }
485 SO_GROUP_ID = $2001; { ID of a socket group}
486 SO_GROUP_PRIORITY = $2002; { the relative priority within a group}
487 SO_MAX_MSG_SIZE = $2003; { maximum message size }
488 SO_PROTOCOL_INFOA = $2004; { WSAPROTOCOL_INFOA structure }
489 SO_PROTOCOL_INFOW = $2005; { WSAPROTOCOL_INFOW structure }
490 SO_PROTOCOL_INFO = SO_PROTOCOL_INFOA;
491 PVD_CONFIG = $3001; {configuration info for service provider }
492{ Option for opening sockets for synchronous access. }
493 SO_OPENTYPE = $7008;
494 SO_SYNCHRONOUS_ALERT = $10;
495 SO_SYNCHRONOUS_NONALERT = $20;
496{ Other NT-specific options. }
497 SO_MAXDG = $7009;
498 SO_MAXPATHDG = $700A;
499 SO_UPDATE_ACCEPT_CONTEXT = $700B;
500 SO_CONNECT_TIME = $700C;
501
502 SOMAXCONN = $7fffffff;
503
504 IPV6_UNICAST_HOPS = 8; // ???
505 IPV6_MULTICAST_IF = 9; // set/get IP multicast i/f
506 IPV6_MULTICAST_HOPS = 10; // set/get IP multicast ttl
507 IPV6_MULTICAST_LOOP = 11; // set/get IP multicast loopback
508 IPV6_JOIN_GROUP = 12; // add an IP group membership
509 IPV6_LEAVE_GROUP = 13; // drop an IP group membership
510
511 MSG_NOSIGNAL = 0;
512
513 // getnameinfo constants
514 NI_MAXHOST = 1025;
515 NI_MAXSERV = 32;
516 NI_NOFQDN = $1;
517 NI_NUMERICHOST = $2;
518 NI_NAMEREQD = $4;
519 NI_NUMERICSERV = $8;
520 NI_DGRAM = $10;
521
522
523const
524 SOCK_STREAM = 1; { stream socket }
525 SOCK_DGRAM = 2; { datagram socket }
526 SOCK_RAW = 3; { raw-protocol interface }
527 SOCK_RDM = 4; { reliably-delivered message }
528 SOCK_SEQPACKET = 5; { sequenced packet stream }
529
530{ TCP options. }
531 TCP_NODELAY = $0001;
532
533{ Address families. }
534
535 AF_UNSPEC = 0; { unspecified }
536 AF_INET = 2; { internetwork: UDP, TCP, etc. }
537 AF_INET6 = 23; { Internetwork Version 6 }
538 AF_MAX = 24;
539
540{ Protocol families, same as address families for now. }
541 PF_UNSPEC = AF_UNSPEC;
542 PF_INET = AF_INET;
543 PF_INET6 = AF_INET6;
544 PF_MAX = AF_MAX;
545
546type
547 { Structure used by kernel to store most addresses. }
548 PSockAddr = ^TSockAddr;
549 TSockAddr = TSockAddrIn;
550
551 { Structure used by kernel to pass protocol information in raw sockets. }
552 PSockProto = ^TSockProto;
553 TSockProto = record
554 sp_family: u_short;
555 sp_protocol: u_short;
556 end;
557
558type
559 PAddrInfo = ^TAddrInfo;
560 TAddrInfo = record
561 ai_flags: integer; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST.
562 ai_family: integer; // PF_xxx.
563 ai_socktype: integer; // SOCK_xxx.
564 ai_protocol: integer; // 0 or IPPROTO_xxx for IPv4 and IPv6.
565 ai_addrlen: u_int; // Length of ai_addr.
566 ai_canonname: PAnsiChar; // Canonical name for nodename.
567 ai_addr: PSockAddr; // Binary address.
568 ai_next: PAddrInfo; // Next structure in linked list.
569 end;
570
571const
572 // Flags used in "hints" argument to getaddrinfo().
573 AI_PASSIVE = $1; // Socket address will be used in bind() call.
574 AI_CANONNAME = $2; // Return canonical name in first ai_canonname.
575 AI_NUMERICHOST = $4; // Nodename must be a numeric address string.
576
577type
578{ Structure used for manipulating linger option. }
579 PLinger = ^TLinger;
580 TLinger = record
581 l_onoff: u_short;
582 l_linger: u_short;
583 end;
584
585const
586
587 MSG_OOB = $01; // Process out-of-band data.
588 MSG_PEEK = $02; // Peek at incoming messages.
589
590const
591
592{ All Windows Sockets error constants are biased by WSABASEERR from the "normal" }
593 WSABASEERR = 10000;
594
595{ Windows Sockets definitions of regular Microsoft C error constants }
596
597 WSAEINTR = (WSABASEERR+4);
598 WSAEBADF = (WSABASEERR+9);
599 WSAEACCES = (WSABASEERR+13);
600 WSAEFAULT = (WSABASEERR+14);
601 WSAEINVAL = (WSABASEERR+22);
602 WSAEMFILE = (WSABASEERR+24);
603
604{ Windows Sockets definitions of regular Berkeley error constants }
605
606 WSAEWOULDBLOCK = (WSABASEERR+35);
607 WSAEINPROGRESS = (WSABASEERR+36);
608 WSAEALREADY = (WSABASEERR+37);
609 WSAENOTSOCK = (WSABASEERR+38);
610 WSAEDESTADDRREQ = (WSABASEERR+39);
611 WSAEMSGSIZE = (WSABASEERR+40);
612 WSAEPROTOTYPE = (WSABASEERR+41);
613 WSAENOPROTOOPT = (WSABASEERR+42);
614 WSAEPROTONOSUPPORT = (WSABASEERR+43);
615 WSAESOCKTNOSUPPORT = (WSABASEERR+44);
616 WSAEOPNOTSUPP = (WSABASEERR+45);
617 WSAEPFNOSUPPORT = (WSABASEERR+46);
618 WSAEAFNOSUPPORT = (WSABASEERR+47);
619 WSAEADDRINUSE = (WSABASEERR+48);
620 WSAEADDRNOTAVAIL = (WSABASEERR+49);
621 WSAENETDOWN = (WSABASEERR+50);
622 WSAENETUNREACH = (WSABASEERR+51);
623 WSAENETRESET = (WSABASEERR+52);
624 WSAECONNABORTED = (WSABASEERR+53);
625 WSAECONNRESET = (WSABASEERR+54);
626 WSAENOBUFS = (WSABASEERR+55);
627 WSAEISCONN = (WSABASEERR+56);
628 WSAENOTCONN = (WSABASEERR+57);
629 WSAESHUTDOWN = (WSABASEERR+58);
630 WSAETOOMANYREFS = (WSABASEERR+59);
631 WSAETIMEDOUT = (WSABASEERR+60);
632 WSAECONNREFUSED = (WSABASEERR+61);
633 WSAELOOP = (WSABASEERR+62);
634 WSAENAMETOOLONG = (WSABASEERR+63);
635 WSAEHOSTDOWN = (WSABASEERR+64);
636 WSAEHOSTUNREACH = (WSABASEERR+65);
637 WSAENOTEMPTY = (WSABASEERR+66);
638 WSAEPROCLIM = (WSABASEERR+67);
639 WSAEUSERS = (WSABASEERR+68);
640 WSAEDQUOT = (WSABASEERR+69);
641 WSAESTALE = (WSABASEERR+70);
642 WSAEREMOTE = (WSABASEERR+71);
643
644{ Extended Windows Sockets error constant definitions }
645
646 WSASYSNOTREADY = (WSABASEERR+91);
647 WSAVERNOTSUPPORTED = (WSABASEERR+92);
648 WSANOTINITIALISED = (WSABASEERR+93);
649 WSAEDISCON = (WSABASEERR+101);
650 WSAENOMORE = (WSABASEERR+102);
651 WSAECANCELLED = (WSABASEERR+103);
652 WSAEEINVALIDPROCTABLE = (WSABASEERR+104);
653 WSAEINVALIDPROVIDER = (WSABASEERR+105);
654 WSAEPROVIDERFAILEDINIT = (WSABASEERR+106);
655 WSASYSCALLFAILURE = (WSABASEERR+107);
656 WSASERVICE_NOT_FOUND = (WSABASEERR+108);
657 WSATYPE_NOT_FOUND = (WSABASEERR+109);
658 WSA_E_NO_MORE = (WSABASEERR+110);
659 WSA_E_CANCELLED = (WSABASEERR+111);
660 WSAEREFUSED = (WSABASEERR+112);
661
662{ Error return codes from gethostbyname() and gethostbyaddr()
663 (when using the resolver). Note that these errors are
664 retrieved via WSAGetLastError() and must therefore follow
665 the rules for avoiding clashes with error numbers from
666 specific implementations or language run-time systems.
667 For this reason the codes are based at WSABASEERR+1001.
668 Note also that [WSA]NO_ADDRESS is defined only for
669 compatibility purposes. }
670
671{ Authoritative Answer: Host not found }
672 WSAHOST_NOT_FOUND = (WSABASEERR+1001);
673 HOST_NOT_FOUND = WSAHOST_NOT_FOUND;
674{ Non-Authoritative: Host not found, or SERVERFAIL }
675 WSATRY_AGAIN = (WSABASEERR+1002);
676 TRY_AGAIN = WSATRY_AGAIN;
677{ Non recoverable errors, FORMERR, REFUSED, NOTIMP }
678 WSANO_RECOVERY = (WSABASEERR+1003);
679 NO_RECOVERY = WSANO_RECOVERY;
680{ Valid name, no data record of requested type }
681 WSANO_DATA = (WSABASEERR+1004);
682 NO_DATA = WSANO_DATA;
683{ no address, look for MX record }
684 WSANO_ADDRESS = WSANO_DATA;
685 NO_ADDRESS = WSANO_ADDRESS;
686
687 EWOULDBLOCK = WSAEWOULDBLOCK;
688 EINPROGRESS = WSAEINPROGRESS;
689 EALREADY = WSAEALREADY;
690 ENOTSOCK = WSAENOTSOCK;
691 EDESTADDRREQ = WSAEDESTADDRREQ;
692 EMSGSIZE = WSAEMSGSIZE;
693 EPROTOTYPE = WSAEPROTOTYPE;
694 ENOPROTOOPT = WSAENOPROTOOPT;
695 EPROTONOSUPPORT = WSAEPROTONOSUPPORT;
696 ESOCKTNOSUPPORT = WSAESOCKTNOSUPPORT;
697 EOPNOTSUPP = WSAEOPNOTSUPP;
698 EPFNOSUPPORT = WSAEPFNOSUPPORT;
699 EAFNOSUPPORT = WSAEAFNOSUPPORT;
700 EADDRINUSE = WSAEADDRINUSE;
701 EADDRNOTAVAIL = WSAEADDRNOTAVAIL;
702 ENETDOWN = WSAENETDOWN;
703 ENETUNREACH = WSAENETUNREACH;
704 ENETRESET = WSAENETRESET;
705 ECONNABORTED = WSAECONNABORTED;
706 ECONNRESET = WSAECONNRESET;
707 ENOBUFS = WSAENOBUFS;
708 EISCONN = WSAEISCONN;
709 ENOTCONN = WSAENOTCONN;
710 ESHUTDOWN = WSAESHUTDOWN;
711 ETOOMANYREFS = WSAETOOMANYREFS;
712 ETIMEDOUT = WSAETIMEDOUT;
713 ECONNREFUSED = WSAECONNREFUSED;
714 ELOOP = WSAELOOP;
715 ENAMETOOLONG = WSAENAMETOOLONG;
716 EHOSTDOWN = WSAEHOSTDOWN;
717 EHOSTUNREACH = WSAEHOSTUNREACH;
718 ENOTEMPTY = WSAENOTEMPTY;
719 EPROCLIM = WSAEPROCLIM;
720 EUSERS = WSAEUSERS;
721 EDQUOT = WSAEDQUOT;
722 ESTALE = WSAESTALE;
723 EREMOTE = WSAEREMOTE;
724
725 EAI_ADDRFAMILY = 1; // Address family for nodename not supported.
726 EAI_AGAIN = 2; // Temporary failure in name resolution.
727 EAI_BADFLAGS = 3; // Invalid value for ai_flags.
728 EAI_FAIL = 4; // Non-recoverable failure in name resolution.
729 EAI_FAMILY = 5; // Address family ai_family not supported.
730 EAI_MEMORY = 6; // Memory allocation failure.
731 EAI_NODATA = 7; // No address associated with nodename.
732 EAI_NONAME = 8; // Nodename nor servname provided, or not known.
733 EAI_SERVICE = 9; // Servname not supported for ai_socktype.
734 EAI_SOCKTYPE = 10; // Socket type ai_socktype not supported.
735 EAI_SYSTEM = 11; // System error returned in errno.
736
737const
738 WSADESCRIPTION_LEN = 256;
739 WSASYS_STATUS_LEN = 128;
740type
741 PWSAData = ^TWSAData;
742 TWSAData = record
743 wVersion: Word;
744 wHighVersion: Word;
745{$ifdef win64}
746 iMaxSockets : Word;
747 iMaxUdpDg : Word;
748 lpVendorInfo : PAnsiChar;
749 szDescription : array[0..WSADESCRIPTION_LEN] of AnsiChar;
750 szSystemStatus : array[0..WSASYS_STATUS_LEN] of AnsiChar;
751{$else}
752 szDescription: array[0..WSADESCRIPTION_LEN] of AnsiChar;
753 szSystemStatus: array[0..WSASYS_STATUS_LEN] of AnsiChar;
754 iMaxSockets: Word;
755 iMaxUdpDg: Word;
756 lpVendorInfo: PAnsiChar;
757{$endif}
758 end;
759
760 function IN6_IS_ADDR_UNSPECIFIED(const a: PInAddr6): boolean;
761 function IN6_IS_ADDR_LOOPBACK(const a: PInAddr6): boolean;
762 function IN6_IS_ADDR_LINKLOCAL(const a: PInAddr6): boolean;
763 function IN6_IS_ADDR_SITELOCAL(const a: PInAddr6): boolean;
764 function IN6_IS_ADDR_MULTICAST(const a: PInAddr6): boolean;
765 function IN6_ADDR_EQUAL(const a: PInAddr6; const b: PInAddr6):boolean;
766 procedure SET_IN6_IF_ADDR_ANY (const a: PInAddr6);
767 procedure SET_LOOPBACK_ADDR6 (const a: PInAddr6);
768var
769 in6addr_any, in6addr_loopback : TInAddr6;
770
771procedure FD_CLR(Socket: TSocket; var FDSet: TFDSet);
772function FD_ISSET(Socket: TSocket; var FDSet: TFDSet): Boolean;
773procedure FD_SET(Socket: TSocket; var FDSet: TFDSet);
774procedure FD_ZERO(var FDSet: TFDSet);
775
776{=============================================================================}
777
778type
779 TWSAStartup = function(wVersionRequired: Word; var WSData: TWSAData): Integer;
780 stdcall;
781 TWSACleanup = function: Integer;
782 stdcall;
783 TWSAGetLastError = function: Integer;
784 stdcall;
785 TGetServByName = function(name, proto: PAnsiChar): PServEnt;
786 stdcall;
787 TGetServByPort = function(port: Integer; proto: PAnsiChar): PServEnt;
788 stdcall;
789 TGetProtoByName = function(name: PAnsiChar): PProtoEnt;
790 stdcall;
791 TGetProtoByNumber = function(proto: Integer): PProtoEnt;
792 stdcall;
793 TGetHostByName = function(name: PAnsiChar): PHostEnt;
794 stdcall;
795 TGetHostByAddr = function(addr: Pointer; len, Struc: Integer): PHostEnt;
796 stdcall;
797 TGetHostName = function(name: PAnsiChar; len: Integer): Integer;
798 stdcall;
799 TShutdown = function(s: TSocket; how: Integer): Integer;
800 stdcall;
801 TSetSockOpt = function(s: TSocket; level, optname: Integer; optval: PAnsiChar;
802 optlen: Integer): Integer;
803 stdcall;
804 TGetSockOpt = function(s: TSocket; level, optname: Integer; optval: PAnsiChar;
805 var optlen: Integer): Integer;
806 stdcall;
807 TSendTo = function(s: TSocket; const Buf; len, flags: Integer; addrto: PSockAddr;
808 tolen: Integer): Integer;
809 stdcall;
810 TSend = function(s: TSocket; const Buf; len, flags: Integer): Integer;
811 stdcall;
812 TRecv = function(s: TSocket; var Buf; len, flags: Integer): Integer;
813 stdcall;
814 TRecvFrom = function(s: TSocket; var Buf; len, flags: Integer; from: PSockAddr;
815 var fromlen: Integer): Integer;
816 stdcall;
817 Tntohs = function(netshort: u_short): u_short;
818 stdcall;
819 Tntohl = function(netlong: u_long): u_long;
820 stdcall;
821 TListen = function(s: TSocket; backlog: Integer): Integer;
822 stdcall;
823 TIoctlSocket = function(s: TSocket; cmd: DWORD; var arg: Integer): Integer;
824 stdcall;
825 TInet_ntoa = function(inaddr: TInAddr): PAnsiChar;
826 stdcall;
827 TInet_addr = function(cp: PAnsiChar): u_long;
828 stdcall;
829 Thtons = function(hostshort: u_short): u_short;
830 stdcall;
831 Thtonl = function(hostlong: u_long): u_long;
832 stdcall;
833 TGetSockName = function(s: TSocket; name: PSockAddr; var namelen: Integer): Integer;
834 stdcall;
835 TGetPeerName = function(s: TSocket; name: PSockAddr; var namelen: Integer): Integer;
836 stdcall;
837 TConnect = function(s: TSocket; name: PSockAddr; namelen: Integer): Integer;
838 stdcall;
839 TCloseSocket = function(s: TSocket): Integer;
840 stdcall;
841 TBind = function(s: TSocket; addr: PSockAddr; namelen: Integer): Integer;
842 stdcall;
843 TAccept = function(s: TSocket; addr: PSockAddr; var addrlen: Integer): TSocket;
844 stdcall;
845 TTSocket = function(af, Struc, Protocol: Integer): TSocket;
846 stdcall;
847 TSelect = function(nfds: Integer; readfds, writefds, exceptfds: PFDSet;
848 timeout: PTimeVal): Longint;
849 stdcall;
850
851 TGetAddrInfo = function(NodeName: PAnsiChar; ServName: PAnsiChar; Hints: PAddrInfo;
852 var Addrinfo: PAddrInfo): integer;
853 stdcall;
854 TFreeAddrInfo = procedure(ai: PAddrInfo);
855 stdcall;
856 TGetNameInfo = function( addr: PSockAddr; namelen: Integer; host: PAnsiChar;
857 hostlen: DWORD; serv: PAnsiChar; servlen: DWORD; flags: integer): integer;
858 stdcall;
859
860 T__WSAFDIsSet = function (s: TSocket; var FDSet: TFDSet): Bool;
861 stdcall;
862
863 TWSAIoctl = function (s: TSocket; dwIoControlCode: DWORD; lpvInBuffer: Pointer;
864 cbInBuffer: DWORD; lpvOutBuffer: Pointer; cbOutBuffer: DWORD;
865 lpcbBytesReturned: PDWORD; lpOverlapped: Pointer;
866 lpCompletionRoutine: pointer): u_int;
867 stdcall;
868
869var
870 WSAStartup: TWSAStartup = nil;
871 WSACleanup: TWSACleanup = nil;
872 WSAGetLastError: TWSAGetLastError = nil;
873 GetServByName: TGetServByName = nil;
874 GetServByPort: TGetServByPort = nil;
875 GetProtoByName: TGetProtoByName = nil;
876 GetProtoByNumber: TGetProtoByNumber = nil;
877 GetHostByName: TGetHostByName = nil;
878 GetHostByAddr: TGetHostByAddr = nil;
879 ssGetHostName: TGetHostName = nil;
880 Shutdown: TShutdown = nil;
881 SetSockOpt: TSetSockOpt = nil;
882 GetSockOpt: TGetSockOpt = nil;
883 ssSendTo: TSendTo = nil;
884 ssSend: TSend = nil;
885 ssRecv: TRecv = nil;
886 ssRecvFrom: TRecvFrom = nil;
887 ntohs: Tntohs = nil;
888 ntohl: Tntohl = nil;
889 Listen: TListen = nil;
890 IoctlSocket: TIoctlSocket = nil;
891 Inet_ntoa: TInet_ntoa = nil;
892 Inet_addr: TInet_addr = nil;
893 htons: Thtons = nil;
894 htonl: Thtonl = nil;
895 ssGetSockName: TGetSockName = nil;
896 ssGetPeerName: TGetPeerName = nil;
897 ssConnect: TConnect = nil;
898 CloseSocket: TCloseSocket = nil;
899 ssBind: TBind = nil;
900 ssAccept: TAccept = nil;
901 Socket: TTSocket = nil;
902 Select: TSelect = nil;
903
904 GetAddrInfo: TGetAddrInfo = nil;
905 FreeAddrInfo: TFreeAddrInfo = nil;
906 GetNameInfo: TGetNameInfo = nil;
907
908 __WSAFDIsSet: T__WSAFDIsSet = nil;
909
910 WSAIoctl: TWSAIoctl = nil;
911
912var
913 SynSockCS: SyncObjs.TCriticalSection;
914 SockEnhancedApi: Boolean;
915 SockWship6Api: Boolean;
916
917type
918 TVarSin = packed record
919 case integer of
920 0: (AddressFamily: u_short);
921 1: (
922 case sin_family: u_short of
923 AF_INET: (sin_port: u_short;
924 sin_addr: TInAddr;
925 sin_zero: array[0..7] of byte);
926 AF_INET6: (sin6_port: u_short;
927 sin6_flowinfo: u_long;
928 sin6_addr: TInAddr6;
929 sin6_scope_id: u_long);
930 );
931 end;
932
933function SizeOfVarSin(sin: TVarSin): integer;
934
935function Bind(s: TSocket; const addr: TVarSin): Integer;
936function Connect(s: TSocket; const name: TVarSin): Integer;
937function GetSockName(s: TSocket; var name: TVarSin): Integer;
938function GetPeerName(s: TSocket; var name: TVarSin): Integer;
939function GetHostName: AnsiString;
940function Send(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
941function Recv(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
942function SendTo(s: TSocket; Buf: TMemory; len, flags: Integer; addrto: TVarSin): Integer;
943function RecvFrom(s: TSocket; Buf: TMemory; len, flags: Integer; var from: TVarSin): Integer;
944function Accept(s: TSocket; var addr: TVarSin): TSocket;
945
946function IsNewApi(Family: integer): Boolean;
947function SetVarSin(var Sin: TVarSin; IP, Port: AnsiString; Family, SockProtocol, SockType: integer; PreferIP4: Boolean): integer;
948function GetSinIP(Sin: TVarSin): AnsiString;
949function GetSinPort(Sin: TVarSin): Integer;
950procedure ResolveNameToIP(Name: AnsiString; Family, SockProtocol, SockType: integer; const IPList: TStrings);
951function ResolveIPToName(IP: AnsiString; Family, SockProtocol, SockType: integer): AnsiString;
952function ResolvePort(Port: AnsiString; Family, SockProtocol, SockType: integer): Word;
953
954{==============================================================================}
955implementation
956
957var
958 SynSockCount: Integer = 0;
959 LibHandle: THandle = 0;
960 Libwship6Handle: THandle = 0;
961
962function IN6_IS_ADDR_UNSPECIFIED(const a: PInAddr6): boolean;
963begin
964 Result := ((a^.u6_addr32[0] = 0) and (a^.u6_addr32[1] = 0) and
965 (a^.u6_addr32[2] = 0) and (a^.u6_addr32[3] = 0));
966end;
967
968function IN6_IS_ADDR_LOOPBACK(const a: PInAddr6): boolean;
969begin
970 Result := ((a^.u6_addr32[0] = 0) and (a^.u6_addr32[1] = 0) and
971 (a^.u6_addr32[2] = 0) and
972 (a^.u6_addr8[12] = 0) and (a^.u6_addr8[13] = 0) and
973 (a^.u6_addr8[14] = 0) and (a^.u6_addr8[15] = 1));
974end;
975
976function IN6_IS_ADDR_LINKLOCAL(const a: PInAddr6): boolean;
977begin
978 Result := ((a^.u6_addr8[0] = $FE) and (a^.u6_addr8[1] = $80));
979end;
980
981function IN6_IS_ADDR_SITELOCAL(const a: PInAddr6): boolean;
982begin
983 Result := ((a^.u6_addr8[0] = $FE) and (a^.u6_addr8[1] = $C0));
984end;
985
986function IN6_IS_ADDR_MULTICAST(const a: PInAddr6): boolean;
987begin
988 Result := (a^.u6_addr8[0] = $FF);
989end;
990
991function IN6_ADDR_EQUAL(const a: PInAddr6; const b: PInAddr6): boolean;
992begin
993 Result := (CompareMem( a, b, sizeof(TInAddr6)));
994end;
995
996procedure SET_IN6_IF_ADDR_ANY (const a: PInAddr6);
997begin
998 FillChar(a^, sizeof(TInAddr6), 0);
999end;
1000
1001procedure SET_LOOPBACK_ADDR6 (const a: PInAddr6);
1002begin
1003 FillChar(a^, sizeof(TInAddr6), 0);
1004 a^.u6_addr8[15] := 1;
1005end;
1006
1007{=============================================================================}
1008procedure FD_CLR(Socket: TSocket; var FDSet: TFDSet);
1009var
1010 I: Integer;
1011begin
1012 I := 0;
1013 while I < FDSet.fd_count do
1014 begin
1015 if FDSet.fd_array[I] = Socket then
1016 begin
1017 while I < FDSet.fd_count - 1 do
1018 begin
1019 FDSet.fd_array[I] := FDSet.fd_array[I + 1];
1020 Inc(I);
1021 end;
1022 Dec(FDSet.fd_count);
1023 Break;
1024 end;
1025 Inc(I);
1026 end;
1027end;
1028
1029function FD_ISSET(Socket: TSocket; var FDSet: TFDSet): Boolean;
1030begin
1031 Result := __WSAFDIsSet(Socket, FDSet);
1032end;
1033
1034procedure FD_SET(Socket: TSocket; var FDSet: TFDSet);
1035begin
1036 if FDSet.fd_count < FD_SETSIZE then
1037 begin
1038 FDSet.fd_array[FDSet.fd_count] := Socket;
1039 Inc(FDSet.fd_count);
1040 end;
1041end;
1042
1043procedure FD_ZERO(var FDSet: TFDSet);
1044begin
1045 FDSet.fd_count := 0;
1046end;
1047
1048{=============================================================================}
1049
1050function SizeOfVarSin(sin: TVarSin): integer;
1051begin
1052 case sin.sin_family of
1053 AF_INET:
1054 Result := SizeOf(TSockAddrIn);
1055 AF_INET6:
1056 Result := SizeOf(TSockAddrIn6);
1057 else
1058 Result := 0;
1059 end;
1060end;
1061
1062{=============================================================================}
1063
1064function Bind(s: TSocket; const addr: TVarSin): Integer;
1065begin
1066 Result := ssBind(s, @addr, SizeOfVarSin(addr));
1067end;
1068
1069function Connect(s: TSocket; const name: TVarSin): Integer;
1070begin
1071 Result := ssConnect(s, @name, SizeOfVarSin(name));
1072end;
1073
1074function GetSockName(s: TSocket; var name: TVarSin): Integer;
1075var
1076 len: integer;
1077begin
1078 len := SizeOf(name);
1079 FillChar(name, len, 0);
1080 Result := ssGetSockName(s, @name, Len);
1081end;
1082
1083function GetPeerName(s: TSocket; var name: TVarSin): Integer;
1084var
1085 len: integer;
1086begin
1087 len := SizeOf(name);
1088 FillChar(name, len, 0);
1089 Result := ssGetPeerName(s, @name, Len);
1090end;
1091
1092function GetHostName: AnsiString;
1093var
1094 s: AnsiString;
1095begin
1096 Result := '';
1097 setlength(s, 255);
1098 ssGetHostName(pAnsichar(s), Length(s) - 1);
1099 Result := PAnsichar(s);
1100end;
1101
1102function Send(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
1103begin
1104 Result := ssSend(s, Buf^, len, flags);
1105end;
1106
1107function Recv(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
1108begin
1109 Result := ssRecv(s, Buf^, len, flags);
1110end;
1111
1112function SendTo(s: TSocket; Buf: TMemory; len, flags: Integer; addrto: TVarSin): Integer;
1113begin
1114 Result := ssSendTo(s, Buf^, len, flags, @addrto, SizeOfVarSin(addrto));
1115end;
1116
1117function RecvFrom(s: TSocket; Buf: TMemory; len, flags: Integer; var from: TVarSin): Integer;
1118var
1119 x: integer;
1120begin
1121 x := SizeOf(from);
1122 Result := ssRecvFrom(s, Buf^, len, flags, @from, x);
1123end;
1124
1125function Accept(s: TSocket; var addr: TVarSin): TSocket;
1126var
1127 x: integer;
1128begin
1129 x := SizeOf(addr);
1130 Result := ssAccept(s, @addr, x);
1131end;
1132
1133{=============================================================================}
1134function IsNewApi(Family: integer): Boolean;
1135begin
1136 Result := SockEnhancedApi;
1137 if not Result then
1138 Result := (Family = AF_INET6) and SockWship6Api;
1139end;
1140
1141function SetVarSin(var Sin: TVarSin; IP, Port: AnsiString; Family, SockProtocol, SockType: integer; PreferIP4: Boolean): integer;
1142type
1143 pu_long = ^u_long;
1144var
1145 ProtoEnt: PProtoEnt;
1146 ServEnt: PServEnt;
1147 HostEnt: PHostEnt;
1148 r: integer;
1149 Hints1, Hints2: TAddrInfo;
1150 Sin1, Sin2: TVarSin;
1151 TwoPass: boolean;
1152
1153 function GetAddr(const IP, port: AnsiString; Hints: TAddrInfo; var Sin: TVarSin): integer;
1154 var
1155 Addr: PAddrInfo;
1156 begin
1157 Addr := nil;
1158 try
1159 FillChar(Sin, Sizeof(Sin), 0);
1160 if Hints.ai_socktype = SOCK_RAW then
1161 begin
1162 Hints.ai_socktype := 0;
1163 Hints.ai_protocol := 0;
1164 Result := synsock.GetAddrInfo(PAnsiChar(IP), nil, @Hints, Addr);
1165 end
1166 else
1167 begin
1168 if (IP = cAnyHost) or (IP = c6AnyHost) then
1169 begin
1170 Hints.ai_flags := AI_PASSIVE;
1171 Result := synsock.GetAddrInfo(nil, PAnsiChar(Port), @Hints, Addr);
1172 end
1173 else
1174 if (IP = cLocalhost) or (IP = c6Localhost) then
1175 begin
1176 Result := synsock.GetAddrInfo(nil, PAnsiChar(Port), @Hints, Addr);
1177 end
1178 else
1179 begin
1180 Result := synsock.GetAddrInfo(PAnsiChar(IP), PAnsiChar(Port), @Hints, Addr);
1181 end;
1182 end;
1183 if Result = 0 then
1184 if (Addr <> nil) then
1185 Move(Addr^.ai_addr^, Sin, Addr^.ai_addrlen);
1186 finally
1187 if Assigned(Addr) then
1188 synsock.FreeAddrInfo(Addr);
1189 end;
1190 end;
1191
1192begin
1193 Result := 0;
1194 FillChar(Sin, Sizeof(Sin), 0);
1195 if not IsNewApi(family) then
1196 begin
1197 SynSockCS.Enter;
1198 try
1199 Sin.sin_family := AF_INET;
1200 ProtoEnt := synsock.GetProtoByNumber(SockProtocol);
1201 ServEnt := nil;
1202 if (ProtoEnt <> nil) and (StrToIntDef(string(Port),-1) =-1) then
1203 ServEnt := synsock.GetServByName(PAnsiChar(Port), ProtoEnt^.p_name);
1204 if ServEnt = nil then
1205 Sin.sin_port := synsock.htons(StrToIntDef(string(Port), 0))
1206 else
1207 Sin.sin_port := ServEnt^.s_port;
1208 if IP = cBroadcast then
1209 Sin.sin_addr.s_addr := u_long(INADDR_BROADCAST)
1210 else
1211 begin
1212 Sin.sin_addr.s_addr := synsock.inet_addr(PAnsiChar(IP));
1213 if Sin.sin_addr.s_addr = u_long(INADDR_NONE) then
1214 begin
1215 HostEnt := synsock.GetHostByName(PAnsiChar(IP));
1216 Result := synsock.WSAGetLastError;
1217 if HostEnt <> nil then
1218 Sin.sin_addr.S_addr := u_long(Pu_long(HostEnt^.h_addr_list^)^);
1219 end;
1220 end;
1221 finally
1222 SynSockCS.Leave;
1223 end;
1224 end
1225 else
1226 begin
1227 FillChar(Hints1, Sizeof(Hints1), 0);
1228 FillChar(Hints2, Sizeof(Hints2), 0);
1229 TwoPass := False;
1230 if Family = AF_UNSPEC then
1231 begin
1232 if PreferIP4 then
1233 begin
1234 Hints1.ai_family := AF_INET;
1235 Hints2.ai_family := AF_INET6;
1236 TwoPass := True;
1237 end
1238 else
1239 begin
1240 Hints2.ai_family := AF_INET;
1241 Hints1.ai_family := AF_INET6;
1242 TwoPass := True;
1243 end;
1244 end
1245 else
1246 Hints1.ai_family := Family;
1247
1248 Hints1.ai_socktype := SockType;
1249 Hints1.ai_protocol := SockProtocol;
1250 Hints2.ai_socktype := Hints1.ai_socktype;
1251 Hints2.ai_protocol := Hints1.ai_protocol;
1252
1253 r := GetAddr(IP, Port, Hints1, Sin1);
1254 Result := r;
1255 sin := sin1;
1256 if r <> 0 then
1257 if TwoPass then
1258 begin
1259 r := GetAddr(IP, Port, Hints2, Sin2);
1260 Result := r;
1261 if r = 0 then
1262 sin := sin2;
1263 end;
1264 end;
1265end;
1266
1267function GetSinIP(Sin: TVarSin): AnsiString;
1268var
1269 p: PAnsiChar;
1270 host, serv: AnsiString;
1271 hostlen, servlen: integer;
1272 r: integer;
1273begin
1274 Result := '';
1275 if not IsNewApi(Sin.AddressFamily) then
1276 begin
1277 p := synsock.inet_ntoa(Sin.sin_addr);
1278 if p <> nil then
1279 Result := p;
1280 end
1281 else
1282 begin
1283 hostlen := NI_MAXHOST;
1284 servlen := NI_MAXSERV;
1285 setlength(host, hostlen);
1286 setlength(serv, servlen);
1287 r := getnameinfo(@sin, SizeOfVarSin(sin), PAnsiChar(host), hostlen,
1288 PAnsiChar(serv), servlen, NI_NUMERICHOST + NI_NUMERICSERV);
1289 if r = 0 then
1290 Result := PAnsiChar(host);
1291 end;
1292end;
1293
1294function GetSinPort(Sin: TVarSin): Integer;
1295begin
1296 if (Sin.sin_family = AF_INET6) then
1297 Result := synsock.ntohs(Sin.sin6_port)
1298 else
1299 Result := synsock.ntohs(Sin.sin_port);
1300end;
1301
1302procedure ResolveNameToIP(Name: AnsiString; Family, SockProtocol, SockType: integer; const IPList: TStrings);
1303type
1304 TaPInAddr = array[0..250] of PInAddr;
1305 PaPInAddr = ^TaPInAddr;
1306var
1307 Hints: TAddrInfo;
1308 Addr: PAddrInfo;
1309 AddrNext: PAddrInfo;
1310 r: integer;
1311 host, serv: AnsiString;
1312 hostlen, servlen: integer;
1313 RemoteHost: PHostEnt;
1314 IP: u_long;
1315 PAdrPtr: PaPInAddr;
1316 i: Integer;
1317 s: String;
1318 InAddr: TInAddr;
1319begin
1320 IPList.Clear;
1321 if not IsNewApi(Family) then
1322 begin
1323 IP := synsock.inet_addr(PAnsiChar(Name));
1324 if IP = u_long(INADDR_NONE) then
1325 begin
1326 SynSockCS.Enter;
1327 try
1328 RemoteHost := synsock.GetHostByName(PAnsiChar(Name));
1329 if RemoteHost <> nil then
1330 begin
1331 PAdrPtr := PAPInAddr(RemoteHost^.h_addr_list);
1332 i := 0;
1333 while PAdrPtr^[i] <> nil do
1334 begin
1335 InAddr := PAdrPtr^[i]^;
1336 s := Format('%d.%d.%d.%d', [InAddr.S_bytes[0], InAddr.S_bytes[1],
1337 InAddr.S_bytes[2], InAddr.S_bytes[3]]);
1338 IPList.Add(s);
1339 Inc(i);
1340 end;
1341 end;
1342 finally
1343 SynSockCS.Leave;
1344 end;
1345 end
1346 else
1347 IPList.Add(string(Name));
1348 end
1349 else
1350 begin
1351 Addr := nil;
1352 try
1353 FillChar(Hints, Sizeof(Hints), 0);
1354 Hints.ai_family := AF_UNSPEC;
1355 Hints.ai_socktype := SockType;
1356 Hints.ai_protocol := SockProtocol;
1357 Hints.ai_flags := 0;
1358 r := synsock.GetAddrInfo(PAnsiChar(Name), nil, @Hints, Addr);
1359 if r = 0 then
1360 begin
1361 AddrNext := Addr;
1362 while not(AddrNext = nil) do
1363 begin
1364 if not(((Family = AF_INET6) and (AddrNext^.ai_family = AF_INET))
1365 or ((Family = AF_INET) and (AddrNext^.ai_family = AF_INET6))) then
1366 begin
1367 hostlen := NI_MAXHOST;
1368 servlen := NI_MAXSERV;
1369 setlength(host, hostlen);
1370 setlength(serv, servlen);
1371 r := getnameinfo(AddrNext^.ai_addr, AddrNext^.ai_addrlen,
1372 PAnsiChar(host), hostlen, PAnsiChar(serv), servlen,
1373 NI_NUMERICHOST + NI_NUMERICSERV);
1374 if r = 0 then
1375 begin
1376 host := PAnsiChar(host);
1377 IPList.Add(string(host));
1378 end;
1379 end;
1380 AddrNext := AddrNext^.ai_next;
1381 end;
1382 end;
1383 finally
1384 if Assigned(Addr) then
1385 synsock.FreeAddrInfo(Addr);
1386 end;
1387 end;
1388 if IPList.Count = 0 then
1389 IPList.Add(cAnyHost);
1390end;
1391
1392function ResolvePort(Port: AnsiString; Family, SockProtocol, SockType: integer): Word;
1393var
1394 ProtoEnt: PProtoEnt;
1395 ServEnt: PServEnt;
1396 Hints: TAddrInfo;
1397 Addr: PAddrInfo;
1398 r: integer;
1399begin
1400 Result := 0;
1401 if not IsNewApi(Family) then
1402 begin
1403 SynSockCS.Enter;
1404 try
1405 ProtoEnt := synsock.GetProtoByNumber(SockProtocol);
1406 ServEnt := nil;
1407 if ProtoEnt <> nil then
1408 ServEnt := synsock.GetServByName(PAnsiChar(Port), ProtoEnt^.p_name);
1409 if ServEnt = nil then
1410 Result := StrToIntDef(string(Port), 0)
1411 else
1412 Result := synsock.htons(ServEnt^.s_port);
1413 finally
1414 SynSockCS.Leave;
1415 end;
1416 end
1417 else
1418 begin
1419 Addr := nil;
1420 try
1421 FillChar(Hints, Sizeof(Hints), 0);
1422 Hints.ai_family := AF_UNSPEC;
1423 Hints.ai_socktype := SockType;
1424 Hints.ai_protocol := Sockprotocol;
1425 Hints.ai_flags := AI_PASSIVE;
1426 r := synsock.GetAddrInfo(nil, PAnsiChar(Port), @Hints, Addr);
1427 if (r = 0) and Assigned(Addr) then
1428 begin
1429 if Addr^.ai_family = AF_INET then
1430 Result := synsock.htons(Addr^.ai_addr^.sin_port);
1431 if Addr^.ai_family = AF_INET6 then
1432 Result := synsock.htons(PSockAddrIn6(Addr^.ai_addr)^.sin6_port);
1433 end;
1434 finally
1435 if Assigned(Addr) then
1436 synsock.FreeAddrInfo(Addr);
1437 end;
1438 end;
1439end;
1440
1441function ResolveIPToName(IP: AnsiString; Family, SockProtocol, SockType: integer): AnsiString;
1442var
1443 Hints: TAddrInfo;
1444 Addr: PAddrInfo;
1445 r: integer;
1446 host, serv: AnsiString;
1447 hostlen, servlen: integer;
1448 RemoteHost: PHostEnt;
1449 IPn: u_long;
1450begin
1451 Result := IP;
1452 if not IsNewApi(Family) then
1453 begin
1454 IPn := synsock.inet_addr(PAnsiChar(IP));
1455 if IPn <> u_long(INADDR_NONE) then
1456 begin
1457 SynSockCS.Enter;
1458 try
1459 RemoteHost := GetHostByAddr(@IPn, SizeOf(IPn), AF_INET);
1460 if RemoteHost <> nil then
1461 Result := RemoteHost^.h_name;
1462 finally
1463 SynSockCS.Leave;
1464 end;
1465 end;
1466 end
1467 else
1468 begin
1469 Addr := nil;
1470 try
1471 FillChar(Hints, Sizeof(Hints), 0);
1472 Hints.ai_family := AF_UNSPEC;
1473 Hints.ai_socktype := SockType;
1474 Hints.ai_protocol := SockProtocol;
1475 Hints.ai_flags := 0;
1476 r := synsock.GetAddrInfo(PAnsiChar(IP), nil, @Hints, Addr);
1477 if (r = 0) and Assigned(Addr)then
1478 begin
1479 hostlen := NI_MAXHOST;
1480 servlen := NI_MAXSERV;
1481 setlength(host, hostlen);
1482 setlength(serv, servlen);
1483 r := getnameinfo(Addr^.ai_addr, Addr^.ai_addrlen,
1484 PAnsiChar(host), hostlen, PAnsiChar(serv), servlen,
1485 NI_NUMERICSERV);
1486 if r = 0 then
1487 Result := PAnsiChar(host);
1488 end;
1489 finally
1490 if Assigned(Addr) then
1491 synsock.FreeAddrInfo(Addr);
1492 end;
1493 end;
1494end;
1495
1496{=============================================================================}
1497
1498function InitSocketInterface(stack: String): Boolean;
1499begin
1500 Result := False;
1501 SockEnhancedApi := False;
1502 if stack = '' then
1503 stack := DLLStackName;
1504 SynSockCS.Enter;
1505 try
1506 if SynSockCount = 0 then
1507 begin
1508 SockEnhancedApi := False;
1509 SockWship6Api := False;
1510 LibHandle := LoadLibrary(PChar(Stack));
1511 if LibHandle <> 0 then
1512 begin
1513 WSAIoctl := GetProcAddress(LibHandle, PAnsiChar(AnsiString('WSAIoctl')));
1514 __WSAFDIsSet := GetProcAddress(LibHandle, PAnsiChar(AnsiString('__WSAFDIsSet')));
1515 CloseSocket := GetProcAddress(LibHandle, PAnsiChar(AnsiString('closesocket')));
1516 IoctlSocket := GetProcAddress(LibHandle, PAnsiChar(AnsiString('ioctlsocket')));
1517 WSAGetLastError := GetProcAddress(LibHandle, PAnsiChar(AnsiString('WSAGetLastError')));
1518 WSAStartup := GetProcAddress(LibHandle, PAnsiChar(AnsiString('WSAStartup')));
1519 WSACleanup := GetProcAddress(LibHandle, PAnsiChar(AnsiString('WSACleanup')));
1520 ssAccept := GetProcAddress(LibHandle, PAnsiChar(AnsiString('accept')));
1521 ssBind := GetProcAddress(LibHandle, PAnsiChar(AnsiString('bind')));
1522 ssConnect := GetProcAddress(LibHandle, PAnsiChar(AnsiString('connect')));
1523 ssGetPeerName := GetProcAddress(LibHandle, PAnsiChar(AnsiString('getpeername')));
1524 ssGetSockName := GetProcAddress(LibHandle, PAnsiChar(AnsiString('getsockname')));
1525 GetSockOpt := GetProcAddress(LibHandle, PAnsiChar(AnsiString('getsockopt')));
1526 Htonl := GetProcAddress(LibHandle, PAnsiChar(AnsiString('htonl')));
1527 Htons := GetProcAddress(LibHandle, PAnsiChar(AnsiString('htons')));
1528 Inet_Addr := GetProcAddress(LibHandle, PAnsiChar(AnsiString('inet_addr')));
1529 Inet_Ntoa := GetProcAddress(LibHandle, PAnsiChar(AnsiString('inet_ntoa')));
1530 Listen := GetProcAddress(LibHandle, PAnsiChar(AnsiString('listen')));
1531 Ntohl := GetProcAddress(LibHandle, PAnsiChar(AnsiString('ntohl')));
1532 Ntohs := GetProcAddress(LibHandle, PAnsiChar(AnsiString('ntohs')));
1533 ssRecv := GetProcAddress(LibHandle, PAnsiChar(AnsiString('recv')));
1534 ssRecvFrom := GetProcAddress(LibHandle, PAnsiChar(AnsiString('recvfrom')));
1535 Select := GetProcAddress(LibHandle, PAnsiChar(AnsiString('select')));
1536 ssSend := GetProcAddress(LibHandle, PAnsiChar(AnsiString('send')));
1537 ssSendTo := GetProcAddress(LibHandle, PAnsiChar(AnsiString('sendto')));
1538 SetSockOpt := GetProcAddress(LibHandle, PAnsiChar(AnsiString('setsockopt')));
1539 ShutDown := GetProcAddress(LibHandle, PAnsiChar(AnsiString('shutdown')));
1540 Socket := GetProcAddress(LibHandle, PAnsiChar(AnsiString('socket')));
1541 GetHostByAddr := GetProcAddress(LibHandle, PAnsiChar(AnsiString('gethostbyaddr')));
1542 GetHostByName := GetProcAddress(LibHandle, PAnsiChar(AnsiString('gethostbyname')));
1543 GetProtoByName := GetProcAddress(LibHandle, PAnsiChar(AnsiString('getprotobyname')));
1544 GetProtoByNumber := GetProcAddress(LibHandle, PAnsiChar(AnsiString('getprotobynumber')));
1545 GetServByName := GetProcAddress(LibHandle, PAnsiChar(AnsiString('getservbyname')));
1546 GetServByPort := GetProcAddress(LibHandle, PAnsiChar(AnsiString('getservbyport')));
1547 ssGetHostName := GetProcAddress(LibHandle, PAnsiChar(AnsiString('gethostname')));
1548
1549{$IFNDEF FORCEOLDAPI}
1550 GetAddrInfo := GetProcAddress(LibHandle, PAnsiChar(AnsiString('getaddrinfo')));
1551 FreeAddrInfo := GetProcAddress(LibHandle, PAnsiChar(AnsiString('freeaddrinfo')));
1552 GetNameInfo := GetProcAddress(LibHandle, PAnsiChar(AnsiString('getnameinfo')));
1553 SockEnhancedApi := Assigned(GetAddrInfo) and Assigned(FreeAddrInfo)
1554 and Assigned(GetNameInfo);
1555 if not SockEnhancedApi then
1556 begin
1557 LibWship6Handle := LoadLibrary(PChar(DLLWship6));
1558 if LibWship6Handle <> 0 then
1559 begin
1560 GetAddrInfo := GetProcAddress(LibWship6Handle, PAnsiChar(AnsiString('getaddrinfo')));
1561 FreeAddrInfo := GetProcAddress(LibWship6Handle, PAnsiChar(AnsiString('freeaddrinfo')));
1562 GetNameInfo := GetProcAddress(LibWship6Handle, PAnsiChar(AnsiString('getnameinfo')));
1563 SockWship6Api := Assigned(GetAddrInfo) and Assigned(FreeAddrInfo)
1564 and Assigned(GetNameInfo);
1565 end;
1566 end;
1567{$ENDIF}
1568 Result := True;
1569 end;
1570 end
1571 else Result := True;
1572 if Result then
1573 Inc(SynSockCount);
1574 finally
1575 SynSockCS.Leave;
1576 end;
1577end;
1578
1579function DestroySocketInterface: Boolean;
1580begin
1581 SynSockCS.Enter;
1582 try
1583 Dec(SynSockCount);
1584 if SynSockCount < 0 then
1585 SynSockCount := 0;
1586 if SynSockCount = 0 then
1587 begin
1588 if LibHandle <> 0 then
1589 begin
1590 FreeLibrary(libHandle);
1591 LibHandle := 0;
1592 end;
1593 if LibWship6Handle <> 0 then
1594 begin
1595 FreeLibrary(LibWship6Handle);
1596 LibWship6Handle := 0;
1597 end;
1598 end;
1599 finally
1600 SynSockCS.Leave;
1601 end;
1602 Result := True;
1603end;
1604
1605initialization
1606begin
1607 SynSockCS := SyncObjs.TCriticalSection.Create;
1608 SET_IN6_IF_ADDR_ANY (@in6addr_any);
1609 SET_LOOPBACK_ADDR6 (@in6addr_loopback);
1610end;
1611
1612finalization
1613begin
1614 SynSockCS.Free;
1615end;
Note: See TracBrowser for help on using the repository browser.