source: trunk/Packages/synapse/sslinux.pas

Last change on this file was 5, checked in by chronos, 12 years ago
  • Added: Required packages.
File size: 40.3 KB
Line 
1{==============================================================================|
2| Project : Ararat Synapse | 002.000.008 |
3|==============================================================================|
4| Content: Socket Independent Platform Layer - Linux definition include |
5|==============================================================================|
6| Copyright (c)1999-2003, 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. |
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{$IFDEF LINUX}
48
49//{$DEFINE FORCEOLDAPI}
50{Note about define FORCEOLDAPI:
51If you activate this compiler directive, then is allways used old socket API
52for name resolution. If you leave this directive inactive, then the new API
53is used, when running system allows it.
54
55For IPv6 support you must have new API!
56}
57
58{$IFDEF FPC}
59 {$MODE DELPHI}
60{$ENDIF}
61{$H+}
62interface
63
64uses
65 SyncObjs, SysUtils, Classes,
66 synafpc,
67 Libc;
68
69function InitSocketInterface(stack: string): Boolean;
70function DestroySocketInterface: Boolean;
71
72const
73 WinsockLevel = $0202;
74
75type
76 u_char = Char;
77 u_short = Word;
78 u_int = Integer;
79 u_long = Longint;
80 pu_long = ^u_long;
81 pu_short = ^u_short;
82 TSocket = u_int;
83 TAddrFamily = integer;
84
85 TMemory = pointer;
86
87
88const
89 DLLStackName = 'libc.so.6';
90
91 cLocalhost = '127.0.0.1';
92 cAnyHost = '0.0.0.0';
93 cBroadcast = '255.255.255.255';
94 c6Localhost = '::1';
95 c6AnyHost = '::0';
96 c6Broadcast = 'ffff::1';
97 cAnyPort = '0';
98
99type
100 DWORD = Integer;
101 __fd_mask = LongWord;
102const
103 __FD_SETSIZE = 1024;
104 __NFDBITS = 8 * sizeof(__fd_mask);
105type
106 __fd_set = {packed} record
107 fds_bits: packed array[0..(__FD_SETSIZE div __NFDBITS)-1] of __fd_mask;
108 end;
109 TFDSet = __fd_set;
110 PFDSet = ^TFDSet;
111
112const
113 FIONREAD = $541B;
114 FIONBIO = $5421;
115 FIOASYNC = $5452;
116
117type
118 PTimeVal = ^TTimeVal;
119 TTimeVal = packed record
120 tv_sec: Longint;
121 tv_usec: Longint;
122 end;
123
124const
125 IPPROTO_IP = 0; { Dummy }
126 IPPROTO_ICMP = 1; { Internet Control Message Protocol }
127 IPPROTO_IGMP = 2; { Internet Group Management Protocol}
128 IPPROTO_TCP = 6; { TCP }
129 IPPROTO_UDP = 17; { User Datagram Protocol }
130 IPPROTO_IPV6 = 41;
131 IPPROTO_ICMPV6 = 58;
132
133 IPPROTO_RAW = 255;
134 IPPROTO_MAX = 256;
135
136type
137 PInAddr = ^TInAddr;
138 TInAddr = packed record
139 case integer of
140 0: (S_bytes: packed array [0..3] of byte);
141 1: (S_addr: u_long);
142 end;
143
144 PSockAddrIn = ^TSockAddrIn;
145 TSockAddrIn = packed record
146 case Integer of
147 0: (sin_family: u_short;
148 sin_port: u_short;
149 sin_addr: TInAddr;
150 sin_zero: array[0..7] of Char);
151 1: (sa_family: u_short;
152 sa_data: array[0..13] of Char)
153 end;
154
155 TIP_mreq = record
156 imr_multiaddr: TInAddr; { IP multicast address of group }
157 imr_interface: TInAddr; { local IP address of interface }
158 end;
159
160 PInAddr6 = ^TInAddr6;
161 TInAddr6 = packed record
162 case integer of
163 0: (S6_addr: packed array [0..15] of byte);
164 1: (u6_addr8: packed array [0..15] of byte);
165 2: (u6_addr16: packed array [0..7] of word);
166 3: (u6_addr32: packed array [0..3] of integer);
167 end;
168
169 PSockAddrIn6 = ^TSockAddrIn6;
170 TSockAddrIn6 = packed record
171 sin6_family: u_short; // AF_INET6
172 sin6_port: u_short; // Transport level port number
173 sin6_flowinfo: u_long; // IPv6 flow information
174 sin6_addr: TInAddr6; // IPv6 address
175 sin6_scope_id: u_long; // Scope Id: IF number for link-local
176 // SITE id for site-local
177 end;
178
179 TIPv6_mreq = record
180 ipv6mr_multiaddr: TInAddr6; // IPv6 multicast address.
181 ipv6mr_interface: integer; // Interface index.
182 padding: u_long;
183 end;
184
185 PHostEnt = ^THostEnt;
186 THostent = record
187 h_name: PChar;
188 h_aliases: PPChar;
189 h_addrtype: Integer;
190 h_length: Cardinal;
191 case Byte of
192 0: (h_addr_list: PPChar);
193 1: (h_addr: PPChar);
194 end;
195
196 PNetEnt = ^TNetEnt;
197 TNetEnt = record
198 n_name: PChar;
199 n_aliases: PPChar;
200 n_addrtype: Integer;
201 n_net: uint32_t;
202 end;
203
204 PServEnt = ^TServEnt;
205 TServEnt = record
206 s_name: PChar;
207 s_aliases: PPChar;
208 s_port: Integer;
209 s_proto: PChar;
210 end;
211
212 PProtoEnt = ^TProtoEnt;
213 TProtoEnt = record
214 p_name: PChar;
215 p_aliases: ^PChar;
216 p_proto: u_short;
217 end;
218
219const
220 INADDR_ANY = $00000000;
221 INADDR_LOOPBACK = $7F000001;
222 INADDR_BROADCAST = $FFFFFFFF;
223 INADDR_NONE = $FFFFFFFF;
224 ADDR_ANY = INADDR_ANY;
225 INVALID_SOCKET = TSocket(NOT(0));
226 SOCKET_ERROR = -1;
227
228Const
229 IP_TOS = 1; { int; IP type of service and precedence. }
230 IP_TTL = 2; { int; IP time to live. }
231 IP_HDRINCL = 3; { int; Header is included with data. }
232 IP_OPTIONS = 4; { ip_opts; IP per-packet options. }
233 IP_ROUTER_ALERT = 5; { bool }
234 IP_RECVOPTS = 6; { bool }
235 IP_RETOPTS = 7; { bool }
236 IP_PKTINFO = 8; { bool }
237 IP_PKTOPTIONS = 9;
238 IP_PMTUDISC = 10; { obsolete name? }
239 IP_MTU_DISCOVER = 10; { int; see below }
240 IP_RECVERR = 11; { bool }
241 IP_RECVTTL = 12; { bool }
242 IP_RECVTOS = 13; { bool }
243 IP_MULTICAST_IF = 32; { in_addr; set/get IP multicast i/f }
244 IP_MULTICAST_TTL = 33; { u_char; set/get IP multicast ttl }
245 IP_MULTICAST_LOOP = 34; { i_char; set/get IP multicast loopback }
246 IP_ADD_MEMBERSHIP = 35; { ip_mreq; add an IP group membership }
247 IP_DROP_MEMBERSHIP = 36; { ip_mreq; drop an IP group membership }
248
249 SOL_SOCKET = 1;
250
251 SO_DEBUG = 1;
252 SO_REUSEADDR = 2;
253 SO_TYPE = 3;
254 SO_ERROR = 4;
255 SO_DONTROUTE = 5;
256 SO_BROADCAST = 6;
257 SO_SNDBUF = 7;
258 SO_RCVBUF = 8;
259 SO_KEEPALIVE = 9;
260 SO_OOBINLINE = 10;
261 SO_NO_CHECK = 11;
262 SO_PRIORITY = 12;
263 SO_LINGER = 13;
264 SO_BSDCOMPAT = 14;
265 SO_REUSEPORT = 15;
266 SO_PASSCRED = 16;
267 SO_PEERCRED = 17;
268 SO_RCVLOWAT = 18;
269 SO_SNDLOWAT = 19;
270 SO_RCVTIMEO = 20;
271 SO_SNDTIMEO = 21;
272{ Security levels - as per NRL IPv6 - don't actually do anything }
273 SO_SECURITY_AUTHENTICATION = 22;
274 SO_SECURITY_ENCRYPTION_TRANSPORT = 23;
275 SO_SECURITY_ENCRYPTION_NETWORK = 24;
276 SO_BINDTODEVICE = 25;
277{ Socket filtering }
278 SO_ATTACH_FILTER = 26;
279 SO_DETACH_FILTER = 27;
280
281 SOMAXCONN = 128;
282
283 IPV6_UNICAST_HOPS = 16;
284 IPV6_MULTICAST_IF = 17;
285 IPV6_MULTICAST_HOPS = 18;
286 IPV6_MULTICAST_LOOP = 19;
287 IPV6_JOIN_GROUP = 20;
288 IPV6_LEAVE_GROUP = 21;
289
290 MSG_NOSIGNAL = $4000; // Do not generate SIGPIPE.
291
292 // getnameinfo constants
293 NI_MAXHOST = 1025;
294 NI_MAXSERV = 32;
295 NI_NOFQDN = $4;
296 NI_NUMERICHOST = $1;
297 NI_NAMEREQD = $8;
298 NI_NUMERICSERV = $2;
299 NI_DGRAM = $10;
300
301const
302 SOCK_STREAM = 1; { stream socket }
303 SOCK_DGRAM = 2; { datagram socket }
304 SOCK_RAW = 3; { raw-protocol interface }
305 SOCK_RDM = 4; { reliably-delivered message }
306 SOCK_SEQPACKET = 5; { sequenced packet stream }
307
308{ TCP options. }
309 TCP_NODELAY = $0001;
310
311{ Address families. }
312
313 AF_UNSPEC = 0; { unspecified }
314 AF_INET = 2; { internetwork: UDP, TCP, etc. }
315 AF_INET6 = 10; { Internetwork Version 6 }
316 AF_MAX = 24;
317
318{ Protocol families, same as address families for now. }
319 PF_UNSPEC = AF_UNSPEC;
320 PF_INET = AF_INET;
321 PF_INET6 = AF_INET6;
322 PF_MAX = AF_MAX;
323
324type
325 { Structure used by kernel to store most addresses. }
326 PSockAddr = ^TSockAddr;
327 TSockAddr = TSockAddrIn;
328
329 { Structure used by kernel to pass protocol information in raw sockets. }
330 PSockProto = ^TSockProto;
331 TSockProto = packed record
332 sp_family: u_short;
333 sp_protocol: u_short;
334 end;
335
336type
337 PAddrInfo = ^TAddrInfo;
338 TAddrInfo = record
339 ai_flags: integer; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST.
340 ai_family: integer; // PF_xxx.
341 ai_socktype: integer; // SOCK_xxx.
342 ai_protocol: integer; // 0 or IPPROTO_xxx for IPv4 and IPv6.
343 ai_addrlen: u_int; // Length of ai_addr.
344 ai_addr: PSockAddr; // Binary address.
345 ai_canonname: PChar; // Canonical name for nodename.
346 ai_next: PAddrInfo; // Next structure in linked list.
347 end;
348
349const
350 // Flags used in "hints" argument to getaddrinfo().
351 AI_PASSIVE = $1; // Socket address will be used in bind() call.
352 AI_CANONNAME = $2; // Return canonical name in first ai_canonname.
353 AI_NUMERICHOST = $4; // Nodename must be a numeric address string.
354
355type
356{ Structure used for manipulating linger option. }
357 PLinger = ^TLinger;
358 TLinger = packed record
359 l_onoff: integer;
360 l_linger: integer;
361 end;
362
363const
364
365 MSG_OOB = $01; // Process out-of-band data.
366 MSG_PEEK = $02; // Peek at incoming messages.
367
368const
369 WSAEINTR = EINTR;
370 WSAEBADF = EBADF;
371 WSAEACCES = EACCES;
372 WSAEFAULT = EFAULT;
373 WSAEINVAL = EINVAL;
374 WSAEMFILE = EMFILE;
375 WSAEWOULDBLOCK = EWOULDBLOCK;
376 WSAEINPROGRESS = EINPROGRESS;
377 WSAEALREADY = EALREADY;
378 WSAENOTSOCK = ENOTSOCK;
379 WSAEDESTADDRREQ = EDESTADDRREQ;
380 WSAEMSGSIZE = EMSGSIZE;
381 WSAEPROTOTYPE = EPROTOTYPE;
382 WSAENOPROTOOPT = ENOPROTOOPT;
383 WSAEPROTONOSUPPORT = EPROTONOSUPPORT;
384 WSAESOCKTNOSUPPORT = ESOCKTNOSUPPORT;
385 WSAEOPNOTSUPP = EOPNOTSUPP;
386 WSAEPFNOSUPPORT = EPFNOSUPPORT;
387 WSAEAFNOSUPPORT = EAFNOSUPPORT;
388 WSAEADDRINUSE = EADDRINUSE;
389 WSAEADDRNOTAVAIL = EADDRNOTAVAIL;
390 WSAENETDOWN = ENETDOWN;
391 WSAENETUNREACH = ENETUNREACH;
392 WSAENETRESET = ENETRESET;
393 WSAECONNABORTED = ECONNABORTED;
394 WSAECONNRESET = ECONNRESET;
395 WSAENOBUFS = ENOBUFS;
396 WSAEISCONN = EISCONN;
397 WSAENOTCONN = ENOTCONN;
398 WSAESHUTDOWN = ESHUTDOWN;
399 WSAETOOMANYREFS = ETOOMANYREFS;
400 WSAETIMEDOUT = ETIMEDOUT;
401 WSAECONNREFUSED = ECONNREFUSED;
402 WSAELOOP = ELOOP;
403 WSAENAMETOOLONG = ENAMETOOLONG;
404 WSAEHOSTDOWN = EHOSTDOWN;
405 WSAEHOSTUNREACH = EHOSTUNREACH;
406 WSAENOTEMPTY = ENOTEMPTY;
407 WSAEPROCLIM = -1;
408 WSAEUSERS = EUSERS;
409 WSAEDQUOT = EDQUOT;
410 WSAESTALE = ESTALE;
411 WSAEREMOTE = EREMOTE;
412 WSASYSNOTREADY = -2;
413 WSAVERNOTSUPPORTED = -3;
414 WSANOTINITIALISED = -4;
415 WSAEDISCON = -5;
416 WSAHOST_NOT_FOUND = HOST_NOT_FOUND;
417 WSATRY_AGAIN = TRY_AGAIN;
418 WSANO_RECOVERY = NO_RECOVERY;
419 WSANO_DATA = -6;
420
421 EAI_BADFLAGS = -1; { Invalid value for `ai_flags' field. }
422 EAI_NONAME = -2; { NAME or SERVICE is unknown. }
423 EAI_AGAIN = -3; { Temporary failure in name resolution. }
424 EAI_FAIL = -4; { Non-recoverable failure in name res. }
425 EAI_NODATA = -5; { No address associated with NAME. }
426 EAI_FAMILY = -6; { `ai_family' not supported. }
427 EAI_SOCKTYPE = -7; { `ai_socktype' not supported. }
428 EAI_SERVICE = -8; { SERVICE not supported for `ai_socktype'. }
429 EAI_ADDRFAMILY = -9; { Address family for NAME not supported. }
430 EAI_MEMORY = -10; { Memory allocation failure. }
431 EAI_SYSTEM = -11; { System error returned in `errno'. }
432
433const
434 WSADESCRIPTION_LEN = 256;
435 WSASYS_STATUS_LEN = 128;
436type
437 PWSAData = ^TWSAData;
438 TWSAData = packed record
439 wVersion: Word;
440 wHighVersion: Word;
441 szDescription: array[0..WSADESCRIPTION_LEN] of Char;
442 szSystemStatus: array[0..WSASYS_STATUS_LEN] of Char;
443 iMaxSockets: Word;
444 iMaxUdpDg: Word;
445 lpVendorInfo: PChar;
446 end;
447
448 function IN6_IS_ADDR_UNSPECIFIED(const a: PInAddr6): boolean;
449 function IN6_IS_ADDR_LOOPBACK(const a: PInAddr6): boolean;
450 function IN6_IS_ADDR_LINKLOCAL(const a: PInAddr6): boolean;
451 function IN6_IS_ADDR_SITELOCAL(const a: PInAddr6): boolean;
452 function IN6_IS_ADDR_MULTICAST(const a: PInAddr6): boolean;
453 function IN6_ADDR_EQUAL(const a: PInAddr6; const b: PInAddr6):boolean;
454 procedure SET_IN6_IF_ADDR_ANY (const a: PInAddr6);
455 procedure SET_LOOPBACK_ADDR6 (const a: PInAddr6);
456var
457 in6addr_any, in6addr_loopback : TInAddr6;
458
459procedure FD_CLR(Socket: TSocket; var FDSet: TFDSet);
460function FD_ISSET(Socket: TSocket; var FDSet: TFDSet): Boolean;
461procedure FD_SET(Socket: TSocket; var FDSet: TFDSet);
462procedure FD_ZERO(var FDSet: TFDSet);
463
464{=============================================================================}
465
466type
467 TWSAStartup = function(wVersionRequired: Word; var WSData: TWSAData): Integer;
468 cdecl;
469 TWSACleanup = function: Integer;
470 cdecl;
471 TWSAGetLastError = function: Integer;
472 cdecl;
473 TGetServByName = function(name, proto: PChar): PServEnt;
474 cdecl;
475 TGetServByPort = function(port: Integer; proto: PChar): PServEnt;
476 cdecl;
477 TGetProtoByName = function(name: PChar): PProtoEnt;
478 cdecl;
479 TGetProtoByNumber = function(proto: Integer): PProtoEnt;
480 cdecl;
481 TGetHostByName = function(name: PChar): PHostEnt;
482 cdecl;
483 TGetHostByAddr = function(addr: Pointer; len, Struc: Integer): PHostEnt;
484 cdecl;
485 TGetHostName = function(name: PChar; len: Integer): Integer;
486 cdecl;
487 TShutdown = function(s: TSocket; how: Integer): Integer;
488 cdecl;
489 TSetSockOpt = function(s: TSocket; level, optname: Integer; optval: PChar;
490 optlen: Integer): Integer;
491 cdecl;
492 TGetSockOpt = function(s: TSocket; level, optname: Integer; optval: PChar;
493 var optlen: Integer): Integer;
494 cdecl;
495 TSendTo = function(s: TSocket; const Buf; len, flags: Integer; addrto: PSockAddr;
496 tolen: Integer): Integer;
497 cdecl;
498 TSend = function(s: TSocket; const Buf; len, flags: Integer): Integer;
499 cdecl;
500 TRecv = function(s: TSocket; var Buf; len, flags: Integer): Integer;
501 cdecl;
502 TRecvFrom = function(s: TSocket; var Buf; len, flags: Integer; from: PSockAddr;
503 var fromlen: Integer): Integer;
504 cdecl;
505 Tntohs = function(netshort: u_short): u_short;
506 cdecl;
507 Tntohl = function(netlong: u_long): u_long;
508 cdecl;
509 TListen = function(s: TSocket; backlog: Integer): Integer;
510 cdecl;
511 TIoctlSocket = function(s: TSocket; cmd: DWORD; var arg: integer): Integer;
512 cdecl;
513 TInet_ntoa = function(inaddr: TInAddr): PChar;
514 cdecl;
515 TInet_addr = function(cp: PChar): u_long;
516 cdecl;
517 Thtons = function(hostshort: u_short): u_short;
518 cdecl;
519 Thtonl = function(hostlong: u_long): u_long;
520 cdecl;
521 TGetSockName = function(s: TSocket; name: PSockAddr; var namelen: Integer): Integer;
522 cdecl;
523 TGetPeerName = function(s: TSocket; name: PSockAddr; var namelen: Integer): Integer;
524 cdecl;
525 TConnect = function(s: TSocket; name: PSockAddr; namelen: Integer): Integer;
526 cdecl;
527 TCloseSocket = function(s: TSocket): Integer;
528 cdecl;
529 TBind = function(s: TSocket; addr: PSockAddr; namelen: Integer): Integer;
530 cdecl;
531 TAccept = function(s: TSocket; addr: PSockAddr; var addrlen: Integer): TSocket;
532 cdecl;
533 TTSocket = function(af, Struc, Protocol: Integer): TSocket;
534 cdecl;
535 TSelect = function(nfds: Integer; readfds, writefds, exceptfds: PFDSet;
536 timeout: PTimeVal): Longint;
537 cdecl;
538
539 TGetAddrInfo = function(NodeName: PChar; ServName: PChar; Hints: PAddrInfo;
540 var Addrinfo: PAddrInfo): integer;
541 cdecl;
542 TFreeAddrInfo = procedure(ai: PAddrInfo);
543 cdecl;
544 TGetNameInfo = function( addr: PSockAddr; namelen: Integer; host: PChar;
545 hostlen: DWORD; serv: PChar; servlen: DWORD; flags: integer): integer;
546 cdecl;
547
548var
549 WSAStartup: TWSAStartup = nil;
550 WSACleanup: TWSACleanup = nil;
551 WSAGetLastError: TWSAGetLastError = nil;
552 GetServByName: TGetServByName = nil;
553 GetServByPort: TGetServByPort = nil;
554 GetProtoByName: TGetProtoByName = nil;
555 GetProtoByNumber: TGetProtoByNumber = nil;
556 GetHostByName: TGetHostByName = nil;
557 GetHostByAddr: TGetHostByAddr = nil;
558 ssGetHostName: TGetHostName = nil;
559 Shutdown: TShutdown = nil;
560 SetSockOpt: TSetSockOpt = nil;
561 GetSockOpt: TGetSockOpt = nil;
562 ssSendTo: TSendTo = nil;
563 ssSend: TSend = nil;
564 ssRecv: TRecv = nil;
565 ssRecvFrom: TRecvFrom = nil;
566 ntohs: Tntohs = nil;
567 ntohl: Tntohl = nil;
568 Listen: TListen = nil;
569 IoctlSocket: TIoctlSocket = nil;
570 Inet_ntoa: TInet_ntoa = nil;
571 Inet_addr: TInet_addr = nil;
572 htons: Thtons = nil;
573 htonl: Thtonl = nil;
574 ssGetSockName: TGetSockName = nil;
575 ssGetPeerName: TGetPeerName = nil;
576 ssConnect: TConnect = nil;
577 CloseSocket: TCloseSocket = nil;
578 ssBind: TBind = nil;
579 ssAccept: TAccept = nil;
580 Socket: TTSocket = nil;
581 Select: TSelect = nil;
582
583 GetAddrInfo: TGetAddrInfo = nil;
584 FreeAddrInfo: TFreeAddrInfo = nil;
585 GetNameInfo: TGetNameInfo = nil;
586
587function LSWSAStartup(wVersionRequired: Word; var WSData: TWSAData): Integer; cdecl;
588function LSWSACleanup: Integer; cdecl;
589function LSWSAGetLastError: Integer; cdecl;
590
591var
592 SynSockCS: SyncObjs.TCriticalSection;
593 SockEnhancedApi: Boolean;
594 SockWship6Api: Boolean;
595
596type
597 TVarSin = packed record
598 case integer of
599 0: (AddressFamily: u_short);
600 1: (
601 case sin_family: u_short of
602 AF_INET: (sin_port: u_short;
603 sin_addr: TInAddr;
604 sin_zero: array[0..7] of Char);
605 AF_INET6: (sin6_port: u_short;
606 sin6_flowinfo: u_long;
607 sin6_addr: TInAddr6;
608 sin6_scope_id: u_long);
609 );
610 end;
611
612function SizeOfVarSin(sin: TVarSin): integer;
613
614function Bind(s: TSocket; const addr: TVarSin): Integer;
615function Connect(s: TSocket; const name: TVarSin): Integer;
616function GetSockName(s: TSocket; var name: TVarSin): Integer;
617function GetPeerName(s: TSocket; var name: TVarSin): Integer;
618function GetHostName: string;
619function Send(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
620function Recv(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
621function SendTo(s: TSocket; Buf: TMemory; len, flags: Integer; addrto: TVarSin): Integer;
622function RecvFrom(s: TSocket; Buf: TMemory; len, flags: Integer; var from: TVarSin): Integer;
623function Accept(s: TSocket; var addr: TVarSin): TSocket;
624
625function IsNewApi(Family: integer): Boolean;
626function SetVarSin(var Sin: TVarSin; IP, Port: string; Family, SockProtocol, SockType: integer; PreferIP4: Boolean): integer;
627function GetSinIP(Sin: TVarSin): string;
628function GetSinPort(Sin: TVarSin): Integer;
629procedure ResolveNameToIP(Name: string; Family, SockProtocol, SockType: integer; const IPList: TStrings);
630function ResolveIPToName(IP: string; Family, SockProtocol, SockType: integer): string;
631function ResolvePort(Port: string; Family, SockProtocol, SockType: integer): Word;
632
633{==============================================================================}
634implementation
635
636var
637 SynSockCount: Integer = 0;
638 LibHandle: TLibHandle = 0;
639 Libwship6Handle: TLibHandle = 0;
640
641function IN6_IS_ADDR_UNSPECIFIED(const a: PInAddr6): boolean;
642begin
643 Result := ((a^.u6_addr32[0] = 0) and (a^.u6_addr32[1] = 0) and
644 (a^.u6_addr32[2] = 0) and (a^.u6_addr32[3] = 0));
645end;
646
647function IN6_IS_ADDR_LOOPBACK(const a: PInAddr6): boolean;
648begin
649 Result := ((a^.u6_addr32[0] = 0) and (a^.u6_addr32[1] = 0) and
650 (a^.u6_addr32[2] = 0) and
651 (a^.u6_addr8[12] = 0) and (a^.u6_addr8[13] = 0) and
652 (a^.u6_addr8[14] = 0) and (a^.u6_addr8[15] = 1));
653end;
654
655function IN6_IS_ADDR_LINKLOCAL(const a: PInAddr6): boolean;
656begin
657 Result := ((a^.u6_addr8[0] = $FE) and (a^.u6_addr8[1] = $80));
658end;
659
660function IN6_IS_ADDR_SITELOCAL(const a: PInAddr6): boolean;
661begin
662 Result := ((a^.u6_addr8[0] = $FE) and (a^.u6_addr8[1] = $C0));
663end;
664
665function IN6_IS_ADDR_MULTICAST(const a: PInAddr6): boolean;
666begin
667 Result := (a^.u6_addr8[0] = $FF);
668end;
669
670function IN6_ADDR_EQUAL(const a: PInAddr6; const b: PInAddr6): boolean;
671begin
672 Result := (CompareMem( a, b, sizeof(TInAddr6)));
673end;
674
675procedure SET_IN6_IF_ADDR_ANY (const a: PInAddr6);
676begin
677 FillChar(a^, sizeof(TInAddr6), 0);
678end;
679
680procedure SET_LOOPBACK_ADDR6 (const a: PInAddr6);
681begin
682 FillChar(a^, sizeof(TInAddr6), 0);
683 a^.u6_addr8[15] := 1;
684end;
685
686{=============================================================================}
687var
688{$IFNDEF VER1_0} //FTP version 1.0.x
689 errno_loc: function: PInteger cdecl = nil;
690{$ELSE}
691 errno_loc: function: PInteger = nil; cdecl;
692{$ENDIF}
693
694function LSWSAStartup(wVersionRequired: Word; var WSData: TWSAData): Integer;
695begin
696 with WSData do
697 begin
698 wVersion := wVersionRequired;
699 wHighVersion := $202;
700 szDescription := 'Synsock - Synapse Platform Independent Socket Layer';
701 szSystemStatus := 'Running on Linux';
702 iMaxSockets := 32768;
703 iMaxUdpDg := 8192;
704 end;
705 Result := 0;
706end;
707
708function LSWSACleanup: Integer;
709begin
710 Result := 0;
711end;
712
713function LSWSAGetLastError: Integer;
714var
715 p: PInteger;
716begin
717 p := errno_loc;
718 Result := p^;
719end;
720
721function __FDELT(Socket: TSocket): Integer;
722begin
723 Result := Socket div __NFDBITS;
724end;
725
726function __FDMASK(Socket: TSocket): __fd_mask;
727begin
728 Result := LongWord(1) shl (Socket mod __NFDBITS);
729end;
730
731function FD_ISSET(Socket: TSocket; var fdset: TFDSet): Boolean;
732begin
733 Result := (fdset.fds_bits[__FDELT(Socket)] and __FDMASK(Socket)) <> 0;
734end;
735
736procedure FD_SET(Socket: TSocket; var fdset: TFDSet);
737begin
738 fdset.fds_bits[__FDELT(Socket)] := fdset.fds_bits[__FDELT(Socket)] or __FDMASK(Socket);
739end;
740
741procedure FD_CLR(Socket: TSocket; var fdset: TFDSet);
742begin
743 fdset.fds_bits[__FDELT(Socket)] := fdset.fds_bits[__FDELT(Socket)] and (not __FDMASK(Socket));
744end;
745
746procedure FD_ZERO(var fdset: TFDSet);
747var
748 I: Integer;
749begin
750 with fdset do
751 for I := Low(fds_bits) to High(fds_bits) do
752 fds_bits[I] := 0;
753end;
754
755{=============================================================================}
756
757function SizeOfVarSin(sin: TVarSin): integer;
758begin
759 case sin.sin_family of
760 AF_INET:
761 Result := SizeOf(TSockAddrIn);
762 AF_INET6:
763 Result := SizeOf(TSockAddrIn6);
764 else
765 Result := 0;
766 end;
767end;
768
769{=============================================================================}
770
771function Bind(s: TSocket; const addr: TVarSin): Integer;
772begin
773 Result := ssBind(s, @addr, SizeOfVarSin(addr));
774end;
775
776function Connect(s: TSocket; const name: TVarSin): Integer;
777begin
778 Result := ssConnect(s, @name, SizeOfVarSin(name));
779end;
780
781function GetSockName(s: TSocket; var name: TVarSin): Integer;
782var
783 len: integer;
784begin
785 len := SizeOf(name);
786 FillChar(name, len, 0);
787 Result := ssGetSockName(s, @name, Len);
788end;
789
790function GetPeerName(s: TSocket; var name: TVarSin): Integer;
791var
792 len: integer;
793begin
794 len := SizeOf(name);
795 FillChar(name, len, 0);
796 Result := ssGetPeerName(s, @name, Len);
797end;
798
799function GetHostName: string;
800var
801 s: string;
802begin
803 Result := '';
804 setlength(s, 255);
805 ssGetHostName(pchar(s), Length(s) - 1);
806 Result := Pchar(s);
807end;
808
809function Send(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
810begin
811 Result := ssSend(s, Buf^, len, flags);
812end;
813
814function Recv(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
815begin
816 Result := ssRecv(s, Buf^, len, flags);
817end;
818
819function SendTo(s: TSocket; Buf: TMemory; len, flags: Integer; addrto: TVarSin): Integer;
820begin
821 Result := ssSendTo(s, Buf^, len, flags, @addrto, SizeOfVarSin(addrto));
822end;
823
824function RecvFrom(s: TSocket; Buf: TMemory; len, flags: Integer; var from: TVarSin): Integer;
825var
826 x: integer;
827begin
828 x := SizeOf(from);
829 Result := ssRecvFrom(s, Buf^, len, flags, @from, x);
830end;
831
832function Accept(s: TSocket; var addr: TVarSin): TSocket;
833var
834 x: integer;
835begin
836 x := SizeOf(addr);
837 Result := ssAccept(s, @addr, x);
838end;
839
840{=============================================================================}
841function IsNewApi(Family: integer): Boolean;
842begin
843 Result := SockEnhancedApi;
844 if not Result then
845 Result := (Family = AF_INET6) and SockWship6Api;
846end;
847
848function SetVarSin(var Sin: TVarSin; IP, Port: string; Family, SockProtocol, SockType: integer; PreferIP4: Boolean): integer;
849type
850 pu_long = ^u_long;
851var
852 ProtoEnt: PProtoEnt;
853 ServEnt: PServEnt;
854 HostEnt: PHostEnt;
855 r: integer;
856 Hints1, Hints2: TAddrInfo;
857 Sin1, Sin2: TVarSin;
858 TwoPass: boolean;
859
860 function GetAddr(const IP, port: string; Hints: TAddrInfo; var Sin: TVarSin): integer;
861 var
862 Addr: PAddrInfo;
863 begin
864 Addr := nil;
865 try
866 FillChar(Sin, Sizeof(Sin), 0);
867 if Hints.ai_socktype = SOCK_RAW then
868 begin
869 Hints.ai_socktype := 0;
870 Hints.ai_protocol := 0;
871 Result := synsock.GetAddrInfo(PChar(IP), nil, @Hints, Addr);
872 end
873 else
874 begin
875 if (IP = cAnyHost) or (IP = c6AnyHost) then
876 begin
877 Hints.ai_flags := AI_PASSIVE;
878 Result := synsock.GetAddrInfo(nil, PChar(Port), @Hints, Addr);
879 end
880 else
881 if (IP = cLocalhost) or (IP = c6Localhost) then
882 begin
883 Result := synsock.GetAddrInfo(nil, PChar(Port), @Hints, Addr);
884 end
885 else
886 begin
887 Result := synsock.GetAddrInfo(PChar(IP), PChar(Port), @Hints, Addr);
888 end;
889 end;
890 if Result = 0 then
891 if (Addr <> nil) then
892 Move(Addr^.ai_addr^, Sin, Addr^.ai_addrlen);
893 finally
894 if Assigned(Addr) then
895 synsock.FreeAddrInfo(Addr);
896 end;
897 end;
898
899begin
900 Result := 0;
901 FillChar(Sin, Sizeof(Sin), 0);
902 if not IsNewApi(family) then
903 begin
904 SynSockCS.Enter;
905 try
906 Sin.sin_family := AF_INET;
907 ProtoEnt := synsock.GetProtoByNumber(SockProtocol);
908 ServEnt := nil;
909 if ProtoEnt <> nil then
910 ServEnt := synsock.GetServByName(PChar(Port), ProtoEnt^.p_name);
911 if ServEnt = nil then
912 Sin.sin_port := synsock.htons(StrToIntDef(Port, 0))
913 else
914 Sin.sin_port := ServEnt^.s_port;
915 if IP = cBroadcast then
916 Sin.sin_addr.s_addr := u_long(INADDR_BROADCAST)
917 else
918 begin
919 Sin.sin_addr.s_addr := synsock.inet_addr(PChar(IP));
920 if Sin.sin_addr.s_addr = u_long(INADDR_NONE) then
921 begin
922 HostEnt := synsock.GetHostByName(PChar(IP));
923 Result := synsock.WSAGetLastError;
924 if HostEnt <> nil then
925 Sin.sin_addr.S_addr := u_long(Pu_long(HostEnt^.h_addr_list^)^);
926 end;
927 end;
928 finally
929 SynSockCS.Leave;
930 end;
931 end
932 else
933 begin
934 FillChar(Hints1, Sizeof(Hints1), 0);
935 FillChar(Hints2, Sizeof(Hints2), 0);
936 TwoPass := False;
937 if Family = AF_UNSPEC then
938 begin
939 if PreferIP4 then
940 begin
941 Hints1.ai_family := AF_INET;
942 Hints2.ai_family := AF_INET6;
943 TwoPass := True;
944 end
945 else
946 begin
947 Hints2.ai_family := AF_INET;
948 Hints1.ai_family := AF_INET6;
949 TwoPass := True;
950 end;
951 end
952 else
953 Hints1.ai_family := Family;
954
955 Hints1.ai_socktype := SockType;
956 Hints1.ai_protocol := SockProtocol;
957 Hints2.ai_socktype := Hints1.ai_socktype;
958 Hints2.ai_protocol := Hints1.ai_protocol;
959
960 r := GetAddr(IP, Port, Hints1, Sin1);
961 Result := r;
962 sin := sin1;
963 if r <> 0 then
964 if TwoPass then
965 begin
966 r := GetAddr(IP, Port, Hints2, Sin2);
967 Result := r;
968 if r = 0 then
969 sin := sin2;
970 end;
971 end;
972end;
973
974function GetSinIP(Sin: TVarSin): string;
975var
976 p: PChar;
977 host, serv: string;
978 hostlen, servlen: integer;
979 r: integer;
980begin
981 Result := '';
982 if not IsNewApi(Sin.AddressFamily) then
983 begin
984 p := synsock.inet_ntoa(Sin.sin_addr);
985 if p <> nil then
986 Result := p;
987 end
988 else
989 begin
990 hostlen := NI_MAXHOST;
991 servlen := NI_MAXSERV;
992 setlength(host, hostlen);
993 setlength(serv, servlen);
994 r := getnameinfo(@sin, SizeOfVarSin(sin), PChar(host), hostlen,
995 PChar(serv), servlen, NI_NUMERICHOST + NI_NUMERICSERV);
996 if r = 0 then
997 Result := PChar(host);
998 end;
999end;
1000
1001function GetSinPort(Sin: TVarSin): Integer;
1002begin
1003 if (Sin.sin_family = AF_INET6) then
1004 Result := synsock.ntohs(Sin.sin6_port)
1005 else
1006 Result := synsock.ntohs(Sin.sin_port);
1007end;
1008
1009procedure ResolveNameToIP(Name: string; Family, SockProtocol, SockType: integer; const IPList: TStrings);
1010type
1011 TaPInAddr = array[0..250] of PInAddr;
1012 PaPInAddr = ^TaPInAddr;
1013var
1014 Hints: TAddrInfo;
1015 Addr: PAddrInfo;
1016 AddrNext: PAddrInfo;
1017 r: integer;
1018 host, serv: string;
1019 hostlen, servlen: integer;
1020 RemoteHost: PHostEnt;
1021 IP: u_long;
1022 PAdrPtr: PaPInAddr;
1023 i: Integer;
1024 s: string;
1025 InAddr: TInAddr;
1026begin
1027 IPList.Clear;
1028 if not IsNewApi(Family) then
1029 begin
1030 IP := synsock.inet_addr(PChar(Name));
1031 if IP = u_long(INADDR_NONE) then
1032 begin
1033 SynSockCS.Enter;
1034 try
1035 RemoteHost := synsock.GetHostByName(PChar(Name));
1036 if RemoteHost <> nil then
1037 begin
1038 PAdrPtr := PAPInAddr(RemoteHost^.h_addr_list);
1039 i := 0;
1040 while PAdrPtr^[i] <> nil do
1041 begin
1042 InAddr := PAdrPtr^[i]^;
1043 s := Format('%d.%d.%d.%d', [InAddr.S_bytes[0], InAddr.S_bytes[1],
1044 InAddr.S_bytes[2], InAddr.S_bytes[3]]);
1045 IPList.Add(s);
1046 Inc(i);
1047 end;
1048 end;
1049 finally
1050 SynSockCS.Leave;
1051 end;
1052 end
1053 else
1054 IPList.Add(Name);
1055 end
1056 else
1057 begin
1058 Addr := nil;
1059 try
1060 FillChar(Hints, Sizeof(Hints), 0);
1061 Hints.ai_family := AF_UNSPEC;
1062 Hints.ai_socktype := SockType;
1063 Hints.ai_protocol := SockProtocol;
1064 Hints.ai_flags := 0;
1065 r := synsock.GetAddrInfo(PChar(Name), nil, @Hints, Addr);
1066 if r = 0 then
1067 begin
1068 AddrNext := Addr;
1069 while not(AddrNext = nil) do
1070 begin
1071 if not(((Family = AF_INET6) and (AddrNext^.ai_family = AF_INET))
1072 or ((Family = AF_INET) and (AddrNext^.ai_family = AF_INET6))) then
1073 begin
1074 hostlen := NI_MAXHOST;
1075 servlen := NI_MAXSERV;
1076 setlength(host, hostlen);
1077 setlength(serv, servlen);
1078 r := getnameinfo(AddrNext^.ai_addr, AddrNext^.ai_addrlen,
1079 PChar(host), hostlen, PChar(serv), servlen,
1080 NI_NUMERICHOST + NI_NUMERICSERV);
1081 if r = 0 then
1082 begin
1083 host := PChar(host);
1084 IPList.Add(host);
1085 end;
1086 end;
1087 AddrNext := AddrNext^.ai_next;
1088 end;
1089 end;
1090 finally
1091 if Assigned(Addr) then
1092 synsock.FreeAddrInfo(Addr);
1093 end;
1094 end;
1095 if IPList.Count = 0 then
1096 IPList.Add(cAnyHost);
1097end;
1098
1099function ResolvePort(Port: string; Family, SockProtocol, SockType: integer): Word;
1100var
1101 ProtoEnt: PProtoEnt;
1102 ServEnt: PServEnt;
1103 Hints: TAddrInfo;
1104 Addr: PAddrInfo;
1105 r: integer;
1106begin
1107 Result := 0;
1108 if not IsNewApi(Family) then
1109 begin
1110 SynSockCS.Enter;
1111 try
1112 ProtoEnt := synsock.GetProtoByNumber(SockProtocol);
1113 ServEnt := nil;
1114 if ProtoEnt <> nil then
1115 ServEnt := synsock.GetServByName(PChar(Port), ProtoEnt^.p_name);
1116 if ServEnt = nil then
1117 Result := StrToIntDef(Port, 0)
1118 else
1119 Result := synsock.htons(ServEnt^.s_port);
1120 finally
1121 SynSockCS.Leave;
1122 end;
1123 end
1124 else
1125 begin
1126 Addr := nil;
1127 try
1128 FillChar(Hints, Sizeof(Hints), 0);
1129 Hints.ai_family := AF_UNSPEC;
1130 Hints.ai_socktype := SockType;
1131 Hints.ai_protocol := Sockprotocol;
1132 Hints.ai_flags := AI_PASSIVE;
1133 r := synsock.GetAddrInfo(nil, PChar(Port), @Hints, Addr);
1134 if (r = 0) and Assigned(Addr) then
1135 begin
1136 if Addr^.ai_family = AF_INET then
1137 Result := synsock.htons(Addr^.ai_addr^.sin_port);
1138 if Addr^.ai_family = AF_INET6 then
1139 Result := synsock.htons(PSockAddrIn6(Addr^.ai_addr)^.sin6_port);
1140 end;
1141 finally
1142 if Assigned(Addr) then
1143 synsock.FreeAddrInfo(Addr);
1144 end;
1145 end;
1146end;
1147
1148function ResolveIPToName(IP: string; Family, SockProtocol, SockType: integer): string;
1149var
1150 Hints: TAddrInfo;
1151 Addr: PAddrInfo;
1152 r: integer;
1153 host, serv: string;
1154 hostlen, servlen: integer;
1155 RemoteHost: PHostEnt;
1156 IPn: u_long;
1157begin
1158 Result := IP;
1159 if not IsNewApi(Family) then
1160 begin
1161 IPn := synsock.inet_addr(PChar(IP));
1162 if IPn <> u_long(INADDR_NONE) then
1163 begin
1164 SynSockCS.Enter;
1165 try
1166 RemoteHost := GetHostByAddr(@IPn, SizeOf(IPn), AF_INET);
1167 if RemoteHost <> nil then
1168 Result := RemoteHost^.h_name;
1169 finally
1170 SynSockCS.Leave;
1171 end;
1172 end;
1173 end
1174 else
1175 begin
1176 Addr := nil;
1177 try
1178 FillChar(Hints, Sizeof(Hints), 0);
1179 Hints.ai_family := AF_UNSPEC;
1180 Hints.ai_socktype := SockType;
1181 Hints.ai_protocol := SockProtocol;
1182 Hints.ai_flags := 0;
1183 r := synsock.GetAddrInfo(PChar(IP), nil, @Hints, Addr);
1184 if (r = 0) and Assigned(Addr)then
1185 begin
1186 hostlen := NI_MAXHOST;
1187 servlen := NI_MAXSERV;
1188 setlength(host, hostlen);
1189 setlength(serv, servlen);
1190 r := getnameinfo(Addr^.ai_addr, Addr^.ai_addrlen,
1191 PChar(host), hostlen, PChar(serv), servlen,
1192 NI_NUMERICSERV);
1193 if r = 0 then
1194 Result := PChar(host);
1195 end;
1196 finally
1197 if Assigned(Addr) then
1198 synsock.FreeAddrInfo(Addr);
1199 end;
1200 end;
1201end;
1202
1203{=============================================================================}
1204
1205function InitSocketInterface(stack: string): Boolean;
1206begin
1207 Result := False;
1208 SockEnhancedApi := False;
1209 if stack = '' then
1210 stack := DLLStackName;
1211 SynSockCS.Enter;
1212 try
1213 if SynSockCount = 0 then
1214 begin
1215 SockEnhancedApi := False;
1216 SockWship6Api := False;
1217 Libc.Signal(Libc.SIGPIPE, TSignalHandler(Libc.SIG_IGN));
1218 LibHandle := LoadLibrary(PChar(Stack));
1219 if LibHandle <> 0 then
1220 begin
1221 errno_loc := GetProcAddress(LibHandle, PChar('__errno_location'));
1222 CloseSocket := GetProcAddress(LibHandle, PChar('close'));
1223 IoctlSocket := GetProcAddress(LibHandle, PChar('ioctl'));
1224 WSAGetLastError := LSWSAGetLastError;
1225 WSAStartup := LSWSAStartup;
1226 WSACleanup := LSWSACleanup;
1227 ssAccept := GetProcAddress(LibHandle, PChar('accept'));
1228 ssBind := GetProcAddress(LibHandle, PChar('bind'));
1229 ssConnect := GetProcAddress(LibHandle, PChar('connect'));
1230 ssGetPeerName := GetProcAddress(LibHandle, PChar('getpeername'));
1231 ssGetSockName := GetProcAddress(LibHandle, PChar('getsockname'));
1232 GetSockOpt := GetProcAddress(LibHandle, PChar('getsockopt'));
1233 Htonl := GetProcAddress(LibHandle, PChar('htonl'));
1234 Htons := GetProcAddress(LibHandle, PChar('htons'));
1235 Inet_Addr := GetProcAddress(LibHandle, PChar('inet_addr'));
1236 Inet_Ntoa := GetProcAddress(LibHandle, PChar('inet_ntoa'));
1237 Listen := GetProcAddress(LibHandle, PChar('listen'));
1238 Ntohl := GetProcAddress(LibHandle, PChar('ntohl'));
1239 Ntohs := GetProcAddress(LibHandle, PChar('ntohs'));
1240 ssRecv := GetProcAddress(LibHandle, PChar('recv'));
1241 ssRecvFrom := GetProcAddress(LibHandle, PChar('recvfrom'));
1242 Select := GetProcAddress(LibHandle, PChar('select'));
1243 ssSend := GetProcAddress(LibHandle, PChar('send'));
1244 ssSendTo := GetProcAddress(LibHandle, PChar('sendto'));
1245 SetSockOpt := GetProcAddress(LibHandle, PChar('setsockopt'));
1246 ShutDown := GetProcAddress(LibHandle, PChar('shutdown'));
1247 Socket := GetProcAddress(LibHandle, PChar('socket'));
1248 GetHostByAddr := GetProcAddress(LibHandle, PChar('gethostbyaddr'));
1249 GetHostByName := GetProcAddress(LibHandle, PChar('gethostbyname'));
1250 GetProtoByName := GetProcAddress(LibHandle, PChar('getprotobyname'));
1251 GetProtoByNumber := GetProcAddress(LibHandle, PChar('getprotobynumber'));
1252 GetServByName := GetProcAddress(LibHandle, PChar('getservbyname'));
1253 GetServByPort := GetProcAddress(LibHandle, PChar('getservbyport'));
1254 ssGetHostName := GetProcAddress(LibHandle, PChar('gethostname'));
1255
1256{$IFNDEF FORCEOLDAPI}
1257 GetAddrInfo := GetProcAddress(LibHandle, PChar('getaddrinfo'));
1258 FreeAddrInfo := GetProcAddress(LibHandle, PChar('freeaddrinfo'));
1259 GetNameInfo := GetProcAddress(LibHandle, PChar('getnameinfo'));
1260 SockEnhancedApi := Assigned(GetAddrInfo) and Assigned(FreeAddrInfo)
1261 and Assigned(GetNameInfo);
1262{$ENDIF}
1263 Result := True;
1264 end;
1265 end
1266 else Result := True;
1267 if Result then
1268 Inc(SynSockCount);
1269 finally
1270 SynSockCS.Leave;
1271 end;
1272end;
1273
1274function DestroySocketInterface: Boolean;
1275begin
1276 SynSockCS.Enter;
1277 try
1278 Dec(SynSockCount);
1279 if SynSockCount < 0 then
1280 SynSockCount := 0;
1281 if SynSockCount = 0 then
1282 begin
1283 if LibHandle <> 0 then
1284 begin
1285 FreeLibrary(libHandle);
1286 LibHandle := 0;
1287 end;
1288 if LibWship6Handle <> 0 then
1289 begin
1290 FreeLibrary(LibWship6Handle);
1291 LibWship6Handle := 0;
1292 end;
1293 end;
1294 finally
1295 SynSockCS.Leave;
1296 end;
1297 Result := True;
1298end;
1299
1300initialization
1301begin
1302 SynSockCS := SyncObjs.TCriticalSection.Create;
1303 SET_IN6_IF_ADDR_ANY (@in6addr_any);
1304 SET_LOOPBACK_ADDR6 (@in6addr_loopback);
1305end;
1306
1307finalization
1308begin
1309 SynSockCS.Free;
1310end;
1311
1312{$ENDIF}
1313
Note: See TracBrowser for help on using the repository browser.