source: trunk/Packages/synapse/source/lib/ssfpc.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: 28.0 KB
Line 
1{==============================================================================|
2| Project : Ararat Synapse | 001.001.004 |
3|==============================================================================|
4| Content: Socket Independent Platform Layer - FreePascal definition include |
5|==============================================================================|
6| Copyright (c)2006-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)2006-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{$IFDEF FPC}
48{For FreePascal 2.x.x}
49
50//{$DEFINE FORCEOLDAPI}
51{Note about define FORCEOLDAPI:
52If you activate this compiler directive, then is allways used old socket API
53for name resolution. If you leave this directive inactive, then the new API
54is used, when running system allows it.
55
56For IPv6 support you must have new API!
57}
58
59{$IFDEF FPC}
60 {$MODE DELPHI}
61{$ENDIF}
62{$H+}
63
64{$ifdef FreeBSD}
65{$DEFINE SOCK_HAS_SINLEN} // BSD definition of scoketaddr
66{$endif}
67{$ifdef darwin}
68{$DEFINE SOCK_HAS_SINLEN} // BSD definition of scoketaddr
69{$endif}
70
71interface
72
73uses
74 SyncObjs, SysUtils, Classes,
75 synafpc, BaseUnix, Unix, termio, sockets, netdb;
76
77function InitSocketInterface(stack: string): Boolean;
78function DestroySocketInterface: Boolean;
79
80const
81 DLLStackName = '';
82 WinsockLevel = $0202;
83
84 cLocalHost = '127.0.0.1';
85 cAnyHost = '0.0.0.0';
86 c6AnyHost = '::0';
87 c6Localhost = '::1';
88 cLocalHostStr = 'localhost';
89
90type
91 TSocket = longint;
92 TAddrFamily = integer;
93
94 TMemory = pointer;
95
96
97type
98 TFDSet = Baseunix.TFDSet;
99 PFDSet = ^TFDSet;
100 Ptimeval = Baseunix.ptimeval;
101 Ttimeval = Baseunix.ttimeval;
102
103const
104 FIONREAD = termio.FIONREAD;
105 FIONBIO = termio.FIONBIO;
106 FIOASYNC = termio.FIOASYNC;
107
108const
109 IPPROTO_IP = 0; { Dummy }
110 IPPROTO_ICMP = 1; { Internet Control Message Protocol }
111 IPPROTO_IGMP = 2; { Internet Group Management Protocol}
112 IPPROTO_TCP = 6; { TCP }
113 IPPROTO_UDP = 17; { User Datagram Protocol }
114 IPPROTO_IPV6 = 41;
115 IPPROTO_ICMPV6 = 58;
116 IPPROTO_RM = 113;
117
118 IPPROTO_RAW = 255;
119 IPPROTO_MAX = 256;
120
121type
122 PInAddr = ^TInAddr;
123 TInAddr = sockets.in_addr;
124
125 PSockAddrIn = ^TSockAddrIn;
126 TSockAddrIn = sockets.TInetSockAddr;
127
128
129 TIP_mreq = record
130 imr_multiaddr: TInAddr; // IP multicast address of group
131 imr_interface: TInAddr; // local IP address of interface
132 end;
133
134
135 PInAddr6 = ^TInAddr6;
136 TInAddr6 = sockets.Tin6_addr;
137
138 PSockAddrIn6 = ^TSockAddrIn6;
139 TSockAddrIn6 = sockets.TInetSockAddr6;
140
141
142 TIPv6_mreq = record
143 ipv6mr_multiaddr: TInAddr6; // IPv6 multicast address.
144 ipv6mr_interface: integer; // Interface index.
145 end;
146
147const
148 INADDR_ANY = $00000000;
149 INADDR_LOOPBACK = $7F000001;
150 INADDR_BROADCAST = $FFFFFFFF;
151 INADDR_NONE = $FFFFFFFF;
152 ADDR_ANY = INADDR_ANY;
153 INVALID_SOCKET = TSocket(NOT(0));
154 SOCKET_ERROR = -1;
155
156Const
157 IP_TOS = sockets.IP_TOS; { int; IP type of service and precedence. }
158 IP_TTL = sockets.IP_TTL; { int; IP time to live. }
159 IP_HDRINCL = sockets.IP_HDRINCL; { int; Header is included with data. }
160 IP_OPTIONS = sockets.IP_OPTIONS; { ip_opts; IP per-packet options. }
161// IP_ROUTER_ALERT = sockets.IP_ROUTER_ALERT; { bool }
162 IP_RECVOPTS = sockets.IP_RECVOPTS; { bool }
163 IP_RETOPTS = sockets.IP_RETOPTS; { bool }
164// IP_PKTINFO = sockets.IP_PKTINFO; { bool }
165// IP_PKTOPTIONS = sockets.IP_PKTOPTIONS;
166// IP_PMTUDISC = sockets.IP_PMTUDISC; { obsolete name? }
167// IP_MTU_DISCOVER = sockets.IP_MTU_DISCOVER; { int; see below }
168// IP_RECVERR = sockets.IP_RECVERR; { bool }
169// IP_RECVTTL = sockets.IP_RECVTTL; { bool }
170// IP_RECVTOS = sockets.IP_RECVTOS; { bool }
171 IP_MULTICAST_IF = sockets.IP_MULTICAST_IF; { in_addr; set/get IP multicast i/f }
172 IP_MULTICAST_TTL = sockets.IP_MULTICAST_TTL; { u_char; set/get IP multicast ttl }
173 IP_MULTICAST_LOOP = sockets.IP_MULTICAST_LOOP; { i_char; set/get IP multicast loopback }
174 IP_ADD_MEMBERSHIP = sockets.IP_ADD_MEMBERSHIP; { ip_mreq; add an IP group membership }
175 IP_DROP_MEMBERSHIP = sockets.IP_DROP_MEMBERSHIP; { ip_mreq; drop an IP group membership }
176
177 SOL_SOCKET = sockets.SOL_SOCKET;
178
179 SO_DEBUG = sockets.SO_DEBUG;
180 SO_REUSEADDR = sockets.SO_REUSEADDR;
181 SO_TYPE = sockets.SO_TYPE;
182 SO_ERROR = sockets.SO_ERROR;
183 SO_DONTROUTE = sockets.SO_DONTROUTE;
184 SO_BROADCAST = sockets.SO_BROADCAST;
185 SO_SNDBUF = sockets.SO_SNDBUF;
186 SO_RCVBUF = sockets.SO_RCVBUF;
187 SO_KEEPALIVE = sockets.SO_KEEPALIVE;
188 SO_OOBINLINE = sockets.SO_OOBINLINE;
189// SO_NO_CHECK = sockets.SO_NO_CHECK;
190// SO_PRIORITY = sockets.SO_PRIORITY;
191 SO_LINGER = sockets.SO_LINGER;
192// SO_BSDCOMPAT = sockets.SO_BSDCOMPAT;
193// SO_REUSEPORT = sockets.SO_REUSEPORT;
194// SO_PASSCRED = sockets.SO_PASSCRED;
195// SO_PEERCRED = sockets.SO_PEERCRED;
196 SO_RCVLOWAT = sockets.SO_RCVLOWAT;
197 SO_SNDLOWAT = sockets.SO_SNDLOWAT;
198 SO_RCVTIMEO = sockets.SO_RCVTIMEO;
199 SO_SNDTIMEO = sockets.SO_SNDTIMEO;
200{ Security levels - as per NRL IPv6 - don't actually do anything }
201// SO_SECURITY_AUTHENTICATION = sockets.SO_SECURITY_AUTHENTICATION;
202// SO_SECURITY_ENCRYPTION_TRANSPORT = sockets.SO_SECURITY_ENCRYPTION_TRANSPORT;
203// SO_SECURITY_ENCRYPTION_NETWORK = sockets.SO_SECURITY_ENCRYPTION_NETWORK;
204// SO_BINDTODEVICE = sockets.SO_BINDTODEVICE;
205{ Socket filtering }
206// SO_ATTACH_FILTER = sockets.SO_ATTACH_FILTER;
207// SO_DETACH_FILTER = sockets.SO_DETACH_FILTER;
208
209 SOMAXCONN = 1024;
210
211 IPV6_UNICAST_HOPS = sockets.IPV6_UNICAST_HOPS;
212 IPV6_MULTICAST_IF = sockets.IPV6_MULTICAST_IF;
213 IPV6_MULTICAST_HOPS = sockets.IPV6_MULTICAST_HOPS;
214 IPV6_MULTICAST_LOOP = sockets.IPV6_MULTICAST_LOOP;
215 IPV6_JOIN_GROUP = sockets.IPV6_JOIN_GROUP;
216 IPV6_LEAVE_GROUP = sockets.IPV6_LEAVE_GROUP;
217
218const
219 SOCK_STREAM = 1; { stream socket }
220 SOCK_DGRAM = 2; { datagram socket }
221 SOCK_RAW = 3; { raw-protocol interface }
222 SOCK_RDM = 4; { reliably-delivered message }
223 SOCK_SEQPACKET = 5; { sequenced packet stream }
224
225{ TCP options. }
226 TCP_NODELAY = $0001;
227
228{ Address families. }
229
230 AF_UNSPEC = 0; { unspecified }
231 AF_INET = 2; { internetwork: UDP, TCP, etc. }
232 AF_INET6 = 10; { Internetwork Version 6 }
233 AF_MAX = 24;
234
235{ Protocol families, same as address families for now. }
236 PF_UNSPEC = AF_UNSPEC;
237 PF_INET = AF_INET;
238 PF_INET6 = AF_INET6;
239 PF_MAX = AF_MAX;
240
241type
242{ Structure used for manipulating linger option. }
243 PLinger = ^TLinger;
244 TLinger = packed record
245 l_onoff: integer;
246 l_linger: integer;
247 end;
248
249const
250
251 MSG_OOB = sockets.MSG_OOB; // Process out-of-band data.
252 MSG_PEEK = sockets.MSG_PEEK; // Peek at incoming messages.
253 {$ifdef DARWIN}
254 MSG_NOSIGNAL = $20000; // Do not generate SIGPIPE.
255 // Works under MAC OS X, but is undocumented,
256 // So FPC doesn't include it
257 {$else}
258 MSG_NOSIGNAL = sockets.MSG_NOSIGNAL; // Do not generate SIGPIPE.
259 {$endif}
260
261const
262 WSAEINTR = ESysEINTR;
263 WSAEBADF = ESysEBADF;
264 WSAEACCES = ESysEACCES;
265 WSAEFAULT = ESysEFAULT;
266 WSAEINVAL = ESysEINVAL;
267 WSAEMFILE = ESysEMFILE;
268 WSAEWOULDBLOCK = ESysEWOULDBLOCK;
269 WSAEINPROGRESS = ESysEINPROGRESS;
270 WSAEALREADY = ESysEALREADY;
271 WSAENOTSOCK = ESysENOTSOCK;
272 WSAEDESTADDRREQ = ESysEDESTADDRREQ;
273 WSAEMSGSIZE = ESysEMSGSIZE;
274 WSAEPROTOTYPE = ESysEPROTOTYPE;
275 WSAENOPROTOOPT = ESysENOPROTOOPT;
276 WSAEPROTONOSUPPORT = ESysEPROTONOSUPPORT;
277 WSAESOCKTNOSUPPORT = ESysESOCKTNOSUPPORT;
278 WSAEOPNOTSUPP = ESysEOPNOTSUPP;
279 WSAEPFNOSUPPORT = ESysEPFNOSUPPORT;
280 WSAEAFNOSUPPORT = ESysEAFNOSUPPORT;
281 WSAEADDRINUSE = ESysEADDRINUSE;
282 WSAEADDRNOTAVAIL = ESysEADDRNOTAVAIL;
283 WSAENETDOWN = ESysENETDOWN;
284 WSAENETUNREACH = ESysENETUNREACH;
285 WSAENETRESET = ESysENETRESET;
286 WSAECONNABORTED = ESysECONNABORTED;
287 WSAECONNRESET = ESysECONNRESET;
288 WSAENOBUFS = ESysENOBUFS;
289 WSAEISCONN = ESysEISCONN;
290 WSAENOTCONN = ESysENOTCONN;
291 WSAESHUTDOWN = ESysESHUTDOWN;
292 WSAETOOMANYREFS = ESysETOOMANYREFS;
293 WSAETIMEDOUT = ESysETIMEDOUT;
294 WSAECONNREFUSED = ESysECONNREFUSED;
295 WSAELOOP = ESysELOOP;
296 WSAENAMETOOLONG = ESysENAMETOOLONG;
297 WSAEHOSTDOWN = ESysEHOSTDOWN;
298 WSAEHOSTUNREACH = ESysEHOSTUNREACH;
299 WSAENOTEMPTY = ESysENOTEMPTY;
300 WSAEPROCLIM = -1;
301 WSAEUSERS = ESysEUSERS;
302 WSAEDQUOT = ESysEDQUOT;
303 WSAESTALE = ESysESTALE;
304 WSAEREMOTE = ESysEREMOTE;
305 WSASYSNOTREADY = -2;
306 WSAVERNOTSUPPORTED = -3;
307 WSANOTINITIALISED = -4;
308 WSAEDISCON = -5;
309 WSAHOST_NOT_FOUND = 1;
310 WSATRY_AGAIN = 2;
311 WSANO_RECOVERY = 3;
312 WSANO_DATA = -6;
313
314const
315 WSADESCRIPTION_LEN = 256;
316 WSASYS_STATUS_LEN = 128;
317type
318 PWSAData = ^TWSAData;
319 TWSAData = packed record
320 wVersion: Word;
321 wHighVersion: Word;
322 szDescription: array[0..WSADESCRIPTION_LEN] of Char;
323 szSystemStatus: array[0..WSASYS_STATUS_LEN] of Char;
324 iMaxSockets: Word;
325 iMaxUdpDg: Word;
326 lpVendorInfo: PChar;
327 end;
328
329 function IN6_IS_ADDR_UNSPECIFIED(const a: PInAddr6): boolean;
330 function IN6_IS_ADDR_LOOPBACK(const a: PInAddr6): boolean;
331 function IN6_IS_ADDR_LINKLOCAL(const a: PInAddr6): boolean;
332 function IN6_IS_ADDR_SITELOCAL(const a: PInAddr6): boolean;
333 function IN6_IS_ADDR_MULTICAST(const a: PInAddr6): boolean;
334 function IN6_ADDR_EQUAL(const a: PInAddr6; const b: PInAddr6):boolean;
335 procedure SET_IN6_IF_ADDR_ANY (const a: PInAddr6);
336 procedure SET_LOOPBACK_ADDR6 (const a: PInAddr6);
337
338var
339 in6addr_any, in6addr_loopback : TInAddr6;
340
341procedure FD_CLR(Socket: TSocket; var FDSet: TFDSet);
342function FD_ISSET(Socket: TSocket; var FDSet: TFDSet): Boolean;
343procedure FD_SET(Socket: TSocket; var FDSet: TFDSet);
344procedure FD_ZERO(var FDSet: TFDSet);
345
346{=============================================================================}
347
348var
349 SynSockCS: SyncObjs.TCriticalSection;
350 SockEnhancedApi: Boolean;
351 SockWship6Api: Boolean;
352
353type
354 TVarSin = packed record
355 {$ifdef SOCK_HAS_SINLEN}
356 sin_len : cuchar;
357 {$endif}
358 case integer of
359 0: (AddressFamily: sa_family_t);
360 1: (
361 case sin_family: sa_family_t of
362 AF_INET: (sin_port: word;
363 sin_addr: TInAddr;
364 sin_zero: array[0..7] of Char);
365 AF_INET6: (sin6_port: word;
366 sin6_flowinfo: longword;
367 sin6_addr: TInAddr6;
368 sin6_scope_id: longword);
369 );
370 end;
371
372function SizeOfVarSin(sin: TVarSin): integer;
373
374 function WSAStartup(wVersionRequired: Word; var WSData: TWSAData): Integer;
375 function WSACleanup: Integer;
376 function WSAGetLastError: Integer;
377 function GetHostName: string;
378 function Shutdown(s: TSocket; how: Integer): Integer;
379 function SetSockOpt(s: TSocket; level, optname: Integer; optval: TMemory;
380 optlen: Integer): Integer;
381 function GetSockOpt(s: TSocket; level, optname: Integer; optval: TMemory;
382 var optlen: Integer): Integer;
383 function Send(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
384 function Recv(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
385 function SendTo(s: TSocket; Buf: TMemory; len, flags: Integer; addrto: TVarSin): Integer;
386 function RecvFrom(s: TSocket; Buf: TMemory; len, flags: Integer; var from: TVarSin): Integer;
387 function ntohs(netshort: word): word;
388 function ntohl(netlong: longword): longword;
389 function Listen(s: TSocket; backlog: Integer): Integer;
390 function IoctlSocket(s: TSocket; cmd: DWORD; var arg: integer): Integer;
391 function htons(hostshort: word): word;
392 function htonl(hostlong: longword): longword;
393 function GetSockName(s: TSocket; var name: TVarSin): Integer;
394 function GetPeerName(s: TSocket; var name: TVarSin): Integer;
395 function Connect(s: TSocket; const name: TVarSin): Integer;
396 function CloseSocket(s: TSocket): Integer;
397 function Bind(s: TSocket; const addr: TVarSin): Integer;
398 function Accept(s: TSocket; var addr: TVarSin): TSocket;
399 function Socket(af, Struc, Protocol: Integer): TSocket;
400 function Select(nfds: Integer; readfds, writefds, exceptfds: PFDSet;
401 timeout: PTimeVal): Longint;
402
403function IsNewApi(Family: integer): Boolean;
404function SetVarSin(var Sin: TVarSin; IP, Port: string; Family, SockProtocol, SockType: integer; PreferIP4: Boolean): integer;
405function GetSinIP(Sin: TVarSin): string;
406function GetSinPort(Sin: TVarSin): Integer;
407procedure ResolveNameToIP(Name: string; Family, SockProtocol, SockType: integer; const IPList: TStrings);
408function ResolveIPToName(IP: string; Family, SockProtocol, SockType: integer): string;
409function ResolvePort(Port: string; Family, SockProtocol, SockType: integer): Word;
410
411
412{==============================================================================}
413implementation
414
415
416function IN6_IS_ADDR_UNSPECIFIED(const a: PInAddr6): boolean;
417begin
418 Result := ((a^.u6_addr32[0] = 0) and (a^.u6_addr32[1] = 0) and
419 (a^.u6_addr32[2] = 0) and (a^.u6_addr32[3] = 0));
420end;
421
422function IN6_IS_ADDR_LOOPBACK(const a: PInAddr6): boolean;
423begin
424 Result := ((a^.u6_addr32[0] = 0) and (a^.u6_addr32[1] = 0) and
425 (a^.u6_addr32[2] = 0) and
426 (a^.u6_addr8[12] = 0) and (a^.u6_addr8[13] = 0) and
427 (a^.u6_addr8[14] = 0) and (a^.u6_addr8[15] = 1));
428end;
429
430function IN6_IS_ADDR_LINKLOCAL(const a: PInAddr6): boolean;
431begin
432 Result := ((a^.u6_addr8[0] = $FE) and (a^.u6_addr8[1] = $80));
433end;
434
435function IN6_IS_ADDR_SITELOCAL(const a: PInAddr6): boolean;
436begin
437 Result := ((a^.u6_addr8[0] = $FE) and (a^.u6_addr8[1] = $C0));
438end;
439
440function IN6_IS_ADDR_MULTICAST(const a: PInAddr6): boolean;
441begin
442 Result := (a^.u6_addr8[0] = $FF);
443end;
444
445function IN6_ADDR_EQUAL(const a: PInAddr6; const b: PInAddr6): boolean;
446begin
447 Result := (CompareMem( a, b, sizeof(TInAddr6)));
448end;
449
450procedure SET_IN6_IF_ADDR_ANY (const a: PInAddr6);
451begin
452 FillChar(a^, sizeof(TInAddr6), 0);
453end;
454
455procedure SET_LOOPBACK_ADDR6 (const a: PInAddr6);
456begin
457 FillChar(a^, sizeof(TInAddr6), 0);
458 a^.u6_addr8[15] := 1;
459end;
460
461{=============================================================================}
462
463function WSAStartup(wVersionRequired: Word; var WSData: TWSAData): Integer;
464begin
465 with WSData do
466 begin
467 wVersion := wVersionRequired;
468 wHighVersion := $202;
469 szDescription := 'Synsock - Synapse Platform Independent Socket Layer';
470 szSystemStatus := 'Running on Unix/Linux by FreePascal';
471 iMaxSockets := 32768;
472 iMaxUdpDg := 8192;
473 end;
474 Result := 0;
475end;
476
477function WSACleanup: Integer;
478begin
479 Result := 0;
480end;
481
482function WSAGetLastError: Integer;
483begin
484 Result := fpGetErrno;
485end;
486
487function FD_ISSET(Socket: TSocket; var fdset: TFDSet): Boolean;
488begin
489 Result := fpFD_ISSET(socket, fdset) <> 0;
490end;
491
492procedure FD_SET(Socket: TSocket; var fdset: TFDSet);
493begin
494 fpFD_SET(Socket, fdset);
495end;
496
497procedure FD_CLR(Socket: TSocket; var fdset: TFDSet);
498begin
499 fpFD_CLR(Socket, fdset);
500end;
501
502procedure FD_ZERO(var fdset: TFDSet);
503begin
504 fpFD_ZERO(fdset);
505end;
506
507{=============================================================================}
508
509function SizeOfVarSin(sin: TVarSin): integer;
510begin
511 case sin.sin_family of
512 AF_INET:
513 Result := SizeOf(TSockAddrIn);
514 AF_INET6:
515 Result := SizeOf(TSockAddrIn6);
516 else
517 Result := 0;
518 end;
519end;
520
521{=============================================================================}
522
523function Bind(s: TSocket; const addr: TVarSin): Integer;
524begin
525 if fpBind(s, @addr, SizeOfVarSin(addr)) = 0 then
526 Result := 0
527 else
528 Result := SOCKET_ERROR;
529end;
530
531function Connect(s: TSocket; const name: TVarSin): Integer;
532begin
533 if fpConnect(s, @name, SizeOfVarSin(name)) = 0 then
534 Result := 0
535 else
536 Result := SOCKET_ERROR;
537end;
538
539function GetSockName(s: TSocket; var name: TVarSin): Integer;
540var
541 len: integer;
542begin
543 len := SizeOf(name);
544 FillChar(name, len, 0);
545 Result := fpGetSockName(s, @name, @Len);
546end;
547
548function GetPeerName(s: TSocket; var name: TVarSin): Integer;
549var
550 len: integer;
551begin
552 len := SizeOf(name);
553 FillChar(name, len, 0);
554 Result := fpGetPeerName(s, @name, @Len);
555end;
556
557function GetHostName: string;
558begin
559 Result := unix.GetHostName;
560end;
561
562function Send(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
563begin
564 Result := fpSend(s, pointer(Buf), len, flags);
565end;
566
567function Recv(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
568begin
569 Result := fpRecv(s, pointer(Buf), len, flags);
570end;
571
572function SendTo(s: TSocket; Buf: TMemory; len, flags: Integer; addrto: TVarSin): Integer;
573begin
574 Result := fpSendTo(s, pointer(Buf), len, flags, @addrto, SizeOfVarSin(addrto));
575end;
576
577function RecvFrom(s: TSocket; Buf: TMemory; len, flags: Integer; var from: TVarSin): Integer;
578var
579 x: integer;
580begin
581 x := SizeOf(from);
582 Result := fpRecvFrom(s, pointer(Buf), len, flags, @from, @x);
583end;
584
585function Accept(s: TSocket; var addr: TVarSin): TSocket;
586var
587 x: integer;
588begin
589 x := SizeOf(addr);
590 Result := fpAccept(s, @addr, @x);
591end;
592
593function Shutdown(s: TSocket; how: Integer): Integer;
594begin
595 Result := fpShutdown(s, how);
596end;
597
598function SetSockOpt(s: TSocket; level, optname: Integer; optval: Tmemory;
599 optlen: Integer): Integer;
600begin
601 Result := fpsetsockopt(s, level, optname, pointer(optval), optlen);
602end;
603
604function GetSockOpt(s: TSocket; level, optname: Integer; optval: Tmemory;
605 var optlen: Integer): Integer;
606begin
607 Result := fpgetsockopt(s, level, optname, pointer(optval), @optlen);
608end;
609
610function ntohs(netshort: word): word;
611begin
612 Result := sockets.ntohs(NetShort);
613end;
614
615function ntohl(netlong: longword): longword;
616begin
617 Result := sockets.ntohl(NetLong);
618end;
619
620function Listen(s: TSocket; backlog: Integer): Integer;
621begin
622 if fpListen(s, backlog) = 0 then
623 Result := 0
624 else
625 Result := SOCKET_ERROR;
626end;
627
628function IoctlSocket(s: TSocket; cmd: DWORD; var arg: integer): Integer;
629begin
630 Result := fpIoctl(s, cmd, @arg);
631end;
632
633function htons(hostshort: word): word;
634begin
635 Result := sockets.htons(Hostshort);
636end;
637
638function htonl(hostlong: longword): longword;
639begin
640 Result := sockets.htonl(HostLong);
641end;
642
643function CloseSocket(s: TSocket): Integer;
644begin
645 Result := sockets.CloseSocket(s);
646end;
647
648function Socket(af, Struc, Protocol: Integer): TSocket;
649begin
650 Result := fpSocket(af, struc, protocol);
651end;
652
653function Select(nfds: Integer; readfds, writefds, exceptfds: PFDSet;
654 timeout: PTimeVal): Longint;
655begin
656 Result := fpSelect(nfds, readfds, writefds, exceptfds, timeout);
657end;
658
659{=============================================================================}
660function IsNewApi(Family: integer): Boolean;
661begin
662 Result := SockEnhancedApi;
663 if not Result then
664 Result := (Family = AF_INET6) and SockWship6Api;
665end;
666
667function SetVarSin(var Sin: TVarSin; IP, Port: string; Family, SockProtocol, SockType: integer; PreferIP4: Boolean): integer;
668var
669 TwoPass: boolean;
670 f1, f2: integer;
671
672 function GetAddr(f:integer): integer;
673 var
674 a4: array [1..1] of in_addr;
675 a6: array [1..1] of Tin6_addr;
676 he: THostEntry;
677 begin
678 Result := WSAEPROTONOSUPPORT;
679 case f of
680 AF_INET:
681 begin
682 if IP = cAnyHost then
683 begin
684 Sin.sin_family := AF_INET;
685 Result := 0;
686 end
687 else
688 begin
689 if lowercase(IP) = cLocalHostStr then
690 a4[1].s_addr := htonl(INADDR_LOOPBACK)
691 else
692 begin
693 a4[1].s_addr := 0;
694 Result := WSAHOST_NOT_FOUND;
695 a4[1] := StrTonetAddr(IP);
696 if a4[1].s_addr = INADDR_ANY then
697 if GetHostByName(ip, he) then
698 a4[1]:=HostToNet(he.Addr)
699 else
700 Resolvename(ip, a4);
701 end;
702 if a4[1].s_addr <> INADDR_ANY then
703 begin
704 Sin.sin_family := AF_INET;
705 sin.sin_addr := a4[1];
706 Result := 0;
707 end;
708 end;
709 end;
710 AF_INET6:
711 begin
712 if IP = c6AnyHost then
713 begin
714 Sin.sin_family := AF_INET6;
715 Result := 0;
716 end
717 else
718 begin
719 if lowercase(IP) = cLocalHostStr then
720 SET_LOOPBACK_ADDR6(@a6[1])
721 else
722 begin
723 Result := WSAHOST_NOT_FOUND;
724 SET_IN6_IF_ADDR_ANY(@a6[1]);
725 a6[1] := StrTonetAddr6(IP);
726 if IN6_IS_ADDR_UNSPECIFIED(@a6[1]) then
727 Resolvename6(ip, a6);
728 end;
729 if not IN6_IS_ADDR_UNSPECIFIED(@a6[1]) then
730 begin
731 Sin.sin_family := AF_INET6;
732 sin.sin6_addr := a6[1];
733 Result := 0;
734 end;
735 end;
736 end;
737 end;
738 end;
739begin
740 Result := 0;
741 FillChar(Sin, Sizeof(Sin), 0);
742 Sin.sin_port := Resolveport(port, family, SockProtocol, SockType);
743 TwoPass := False;
744 if Family = AF_UNSPEC then
745 begin
746 if PreferIP4 then
747 begin
748 f1 := AF_INET;
749 f2 := AF_INET6;
750 TwoPass := True;
751 end
752 else
753 begin
754 f2 := AF_INET;
755 f1 := AF_INET6;
756 TwoPass := True;
757 end;
758 end
759 else
760 f1 := Family;
761 Result := GetAddr(f1);
762 if Result <> 0 then
763 if TwoPass then
764 Result := GetAddr(f2);
765end;
766
767function GetSinIP(Sin: TVarSin): string;
768begin
769 Result := '';
770 case sin.AddressFamily of
771 AF_INET:
772 begin
773 result := NetAddrToStr(sin.sin_addr);
774 end;
775 AF_INET6:
776 begin
777 result := NetAddrToStr6(sin.sin6_addr);
778 end;
779 end;
780end;
781
782function GetSinPort(Sin: TVarSin): Integer;
783begin
784 if (Sin.sin_family = AF_INET6) then
785 Result := synsock.ntohs(Sin.sin6_port)
786 else
787 Result := synsock.ntohs(Sin.sin_port);
788end;
789
790procedure ResolveNameToIP(Name: string; Family, SockProtocol, SockType: integer; const IPList: TStrings);
791var
792 x, n: integer;
793 a4: array [1..255] of in_addr;
794 a6: array [1..255] of Tin6_addr;
795 he: THostEntry;
796begin
797 IPList.Clear;
798 if (family = AF_INET) or (family = AF_UNSPEC) then
799 begin
800 if lowercase(name) = cLocalHostStr then
801 IpList.Add(cLocalHost)
802 else
803 begin
804 a4[1] := StrTonetAddr(name);
805 if a4[1].s_addr = INADDR_ANY then
806 if GetHostByName(name, he) then
807 begin
808 a4[1]:=HostToNet(he.Addr);
809 x := 1;
810 end
811 else
812 x := Resolvename(name, a4)
813 else
814 x := 1;
815 for n := 1 to x do
816 IpList.Add(netaddrToStr(a4[n]));
817 end;
818 end;
819
820 if (family = AF_INET6) or (family = AF_UNSPEC) then
821 begin
822 if lowercase(name) = cLocalHostStr then
823 IpList.Add(c6LocalHost)
824 else
825 begin
826 a6[1] := StrTonetAddr6(name);
827 if IN6_IS_ADDR_UNSPECIFIED(@a6[1]) then
828 x := Resolvename6(name, a6)
829 else
830 x := 1;
831 for n := 1 to x do
832 IpList.Add(netaddrToStr6(a6[n]));
833 end;
834 end;
835
836 if IPList.Count = 0 then
837 IPList.Add(cLocalHost);
838end;
839
840function ResolvePort(Port: string; Family, SockProtocol, SockType: integer): Word;
841var
842 ProtoEnt: TProtocolEntry;
843 ServEnt: TServiceEntry;
844begin
845 Result := synsock.htons(StrToIntDef(Port, 0));
846 if Result = 0 then
847 begin
848 ProtoEnt.Name := '';
849 GetProtocolByNumber(SockProtocol, ProtoEnt);
850 ServEnt.port := 0;
851 GetServiceByName(Port, ProtoEnt.Name, ServEnt);
852 Result := ServEnt.port;
853 end;
854end;
855
856function ResolveIPToName(IP: string; Family, SockProtocol, SockType: integer): string;
857var
858 n: integer;
859 a4: array [1..1] of in_addr;
860 a6: array [1..1] of Tin6_addr;
861 a: array [1..1] of string;
862begin
863 Result := IP;
864 a4[1] := StrToNetAddr(IP);
865 if a4[1].s_addr <> INADDR_ANY then
866 begin
867//why ResolveAddress need address in HOST order? :-O
868 n := ResolveAddress(nettohost(a4[1]), a);
869 if n > 0 then
870 Result := a[1];
871 end
872 else
873 begin
874 a6[1] := StrToNetAddr6(IP);
875 n := ResolveAddress6(a6[1], a);
876 if n > 0 then
877 Result := a[1];
878 end;
879end;
880
881{=============================================================================}
882
883function InitSocketInterface(stack: string): Boolean;
884begin
885 SockEnhancedApi := False;
886 SockWship6Api := False;
887// Libc.Signal(Libc.SIGPIPE, TSignalHandler(Libc.SIG_IGN));
888 Result := True;
889end;
890
891function DestroySocketInterface: Boolean;
892begin
893 Result := True;
894end;
895
896initialization
897begin
898 SynSockCS := SyncObjs.TCriticalSection.Create;
899 SET_IN6_IF_ADDR_ANY (@in6addr_any);
900 SET_LOOPBACK_ADDR6 (@in6addr_loopback);
901end;
902
903finalization
904begin
905 SynSockCS.Free;
906end;
907
908{$ENDIF}
909
Note: See TracBrowser for help on using the repository browser.