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