sslinux.inc 39 KB

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