sslinux.pas 39 KB

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