sslinux.inc 39 KB

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