inet.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. /*=========================================================================*\
  2. * Internet domain functions
  3. * LuaSocket toolkit
  4. \*=========================================================================*/
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include "lua.h"
  9. #include "lauxlib.h"
  10. #include "inet.h"
  11. /*=========================================================================*\
  12. * Internal function prototypes.
  13. \*=========================================================================*/
  14. static int inet_global_toip(lua_State *L);
  15. static int inet_global_getaddrinfo(lua_State *L);
  16. static int inet_global_tohostname(lua_State *L);
  17. static int inet_global_getnameinfo(lua_State *L);
  18. static void inet_pushresolved(lua_State *L, struct hostent *hp);
  19. static int inet_global_gethostname(lua_State *L);
  20. /* DNS functions */
  21. static luaL_Reg func[] = {
  22. { "toip", inet_global_toip},
  23. { "getaddrinfo", inet_global_getaddrinfo},
  24. { "tohostname", inet_global_tohostname},
  25. { "getnameinfo", inet_global_getnameinfo},
  26. { "gethostname", inet_global_gethostname},
  27. { NULL, NULL}
  28. };
  29. /*=========================================================================*\
  30. * Exported functions
  31. \*=========================================================================*/
  32. /*-------------------------------------------------------------------------*\
  33. * Initializes module
  34. \*-------------------------------------------------------------------------*/
  35. int inet_open(lua_State *L)
  36. {
  37. lua_pushstring(L, "dns");
  38. lua_newtable(L);
  39. #if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE)
  40. luaL_setfuncs(L, func, 0);
  41. #else
  42. luaL_openlib(L, NULL, func, 0);
  43. #endif
  44. lua_settable(L, -3);
  45. return 0;
  46. }
  47. /*=========================================================================*\
  48. * Global Lua functions
  49. \*=========================================================================*/
  50. /*-------------------------------------------------------------------------*\
  51. * Returns all information provided by the resolver given a host name
  52. * or ip address
  53. \*-------------------------------------------------------------------------*/
  54. static int inet_gethost(const char *address, struct hostent **hp) {
  55. struct in_addr addr;
  56. if (inet_aton(address, &addr))
  57. return socket_gethostbyaddr((char *) &addr, sizeof(addr), hp);
  58. else
  59. return socket_gethostbyname(address, hp);
  60. }
  61. /*-------------------------------------------------------------------------*\
  62. * Returns all information provided by the resolver given a host name
  63. * or ip address
  64. \*-------------------------------------------------------------------------*/
  65. static int inet_global_tohostname(lua_State *L) {
  66. const char *address = luaL_checkstring(L, 1);
  67. struct hostent *hp = NULL;
  68. int err = inet_gethost(address, &hp);
  69. if (err != IO_DONE) {
  70. lua_pushnil(L);
  71. lua_pushstring(L, socket_hoststrerror(err));
  72. return 2;
  73. }
  74. lua_pushstring(L, hp->h_name);
  75. inet_pushresolved(L, hp);
  76. return 2;
  77. }
  78. static int inet_global_getnameinfo(lua_State *L) {
  79. char hbuf[NI_MAXHOST];
  80. char sbuf[NI_MAXSERV];
  81. int i, ret;
  82. struct addrinfo hints;
  83. struct addrinfo *resolved, *iter;
  84. const char *host = luaL_optstring(L, 1, NULL);
  85. const char *serv = luaL_optstring(L, 2, NULL);
  86. if (!(host || serv))
  87. luaL_error(L, "host and serv cannot be both nil");
  88. memset(&hints, 0, sizeof(hints));
  89. hints.ai_socktype = SOCK_STREAM;
  90. hints.ai_family = PF_UNSPEC;
  91. ret = getaddrinfo(host, serv, &hints, &resolved);
  92. if (ret != 0) {
  93. lua_pushnil(L);
  94. lua_pushstring(L, socket_gaistrerror(ret));
  95. return 2;
  96. }
  97. lua_newtable(L);
  98. for (i = 1, iter = resolved; iter; i++, iter = iter->ai_next) {
  99. getnameinfo(iter->ai_addr, (socklen_t) iter->ai_addrlen,
  100. hbuf, host? (socklen_t) sizeof(hbuf): 0,
  101. sbuf, serv? (socklen_t) sizeof(sbuf): 0, 0);
  102. if (host) {
  103. lua_pushnumber(L, i);
  104. lua_pushstring(L, hbuf);
  105. lua_settable(L, -3);
  106. }
  107. }
  108. freeaddrinfo(resolved);
  109. if (serv) {
  110. lua_pushstring(L, sbuf);
  111. return 2;
  112. } else {
  113. return 1;
  114. }
  115. }
  116. /*-------------------------------------------------------------------------*\
  117. * Returns all information provided by the resolver given a host name
  118. * or ip address
  119. \*-------------------------------------------------------------------------*/
  120. static int inet_global_toip(lua_State *L)
  121. {
  122. const char *address = luaL_checkstring(L, 1);
  123. struct hostent *hp = NULL;
  124. int err = inet_gethost(address, &hp);
  125. if (err != IO_DONE) {
  126. lua_pushnil(L);
  127. lua_pushstring(L, socket_hoststrerror(err));
  128. return 2;
  129. }
  130. lua_pushstring(L, inet_ntoa(*((struct in_addr *) hp->h_addr)));
  131. inet_pushresolved(L, hp);
  132. return 2;
  133. }
  134. int inet_optfamily(lua_State* L, int narg, const char* def)
  135. {
  136. static const char* optname[] = { "unspec", "inet", "inet6", NULL };
  137. static int optvalue[] = { PF_UNSPEC, PF_INET, PF_INET6, 0 };
  138. return optvalue[luaL_checkoption(L, narg, def, optname)];
  139. }
  140. int inet_optsocktype(lua_State* L, int narg, const char* def)
  141. {
  142. static const char* optname[] = { "stream", "dgram", NULL };
  143. static int optvalue[] = { SOCK_STREAM, SOCK_DGRAM, 0 };
  144. return optvalue[luaL_checkoption(L, narg, def, optname)];
  145. }
  146. static int inet_global_getaddrinfo(lua_State *L)
  147. {
  148. const char *hostname = luaL_checkstring(L, 1);
  149. struct addrinfo *iterator = NULL, *resolved = NULL;
  150. struct addrinfo hints;
  151. int i = 1, ret = 0;
  152. memset(&hints, 0, sizeof(hints));
  153. hints.ai_socktype = SOCK_STREAM;
  154. hints.ai_family = PF_UNSPEC;
  155. ret = getaddrinfo(hostname, NULL, &hints, &resolved);
  156. if (ret != 0) {
  157. lua_pushnil(L);
  158. lua_pushstring(L, socket_gaistrerror(ret));
  159. return 2;
  160. }
  161. lua_newtable(L);
  162. for (iterator = resolved; iterator; iterator = iterator->ai_next) {
  163. char hbuf[NI_MAXHOST];
  164. ret = getnameinfo(iterator->ai_addr, (socklen_t) iterator->ai_addrlen,
  165. hbuf, (socklen_t) sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
  166. if (ret){
  167. lua_pushnil(L);
  168. lua_pushstring(L, socket_gaistrerror(ret));
  169. return 2;
  170. }
  171. lua_pushnumber(L, i);
  172. lua_newtable(L);
  173. switch (iterator->ai_family) {
  174. case AF_INET:
  175. lua_pushliteral(L, "family");
  176. lua_pushliteral(L, "inet");
  177. lua_settable(L, -3);
  178. break;
  179. case AF_INET6:
  180. lua_pushliteral(L, "family");
  181. lua_pushliteral(L, "inet6");
  182. lua_settable(L, -3);
  183. break;
  184. }
  185. lua_pushliteral(L, "addr");
  186. lua_pushstring(L, hbuf);
  187. lua_settable(L, -3);
  188. lua_settable(L, -3);
  189. i++;
  190. }
  191. freeaddrinfo(resolved);
  192. return 1;
  193. }
  194. /*-------------------------------------------------------------------------*\
  195. * Gets the host name
  196. \*-------------------------------------------------------------------------*/
  197. static int inet_global_gethostname(lua_State *L)
  198. {
  199. char name[257];
  200. name[256] = '\0';
  201. if (gethostname(name, 256) < 0) {
  202. lua_pushnil(L);
  203. lua_pushstring(L, socket_strerror(errno));
  204. return 2;
  205. } else {
  206. lua_pushstring(L, name);
  207. return 1;
  208. }
  209. }
  210. /*=========================================================================*\
  211. * Lua methods
  212. \*=========================================================================*/
  213. /*-------------------------------------------------------------------------*\
  214. * Retrieves socket peer name
  215. \*-------------------------------------------------------------------------*/
  216. int inet_meth_getpeername(lua_State *L, p_socket ps, int family)
  217. {
  218. int err;
  219. struct sockaddr_storage peer;
  220. socklen_t peer_len = sizeof(peer);
  221. char name[INET6_ADDRSTRLEN];
  222. char port[6]; /* 65535 = 5 bytes + 0 to terminate it */
  223. if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) {
  224. lua_pushnil(L);
  225. lua_pushstring(L, socket_strerror(errno));
  226. return 2;
  227. }
  228. err = getnameinfo((struct sockaddr *) &peer, peer_len,
  229. name, INET6_ADDRSTRLEN,
  230. port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
  231. if (err) {
  232. lua_pushnil(L);
  233. lua_pushstring(L, gai_strerror(err));
  234. return 2;
  235. }
  236. lua_pushstring(L, name);
  237. lua_pushinteger(L, (int) strtol(port, (char **) NULL, 10));
  238. if (family == PF_INET) {
  239. lua_pushliteral(L, "inet");
  240. } else if (family == PF_INET6) {
  241. lua_pushliteral(L, "inet6");
  242. } else {
  243. lua_pushliteral(L, "uknown family");
  244. }
  245. return 3;
  246. }
  247. /*-------------------------------------------------------------------------*\
  248. * Retrieves socket local name
  249. \*-------------------------------------------------------------------------*/
  250. int inet_meth_getsockname(lua_State *L, p_socket ps, int family)
  251. {
  252. int err;
  253. struct sockaddr_storage peer;
  254. socklen_t peer_len = sizeof(peer);
  255. char name[INET6_ADDRSTRLEN];
  256. char port[6]; /* 65535 = 5 bytes + 0 to terminate it */
  257. if (getsockname(*ps, (SA *) &peer, &peer_len) < 0) {
  258. lua_pushnil(L);
  259. lua_pushstring(L, socket_strerror(errno));
  260. return 2;
  261. }
  262. err=getnameinfo((struct sockaddr *)&peer, peer_len,
  263. name, INET6_ADDRSTRLEN, port, 6, NI_NUMERICHOST | NI_NUMERICSERV);
  264. if (err) {
  265. lua_pushnil(L);
  266. lua_pushstring(L, gai_strerror(err));
  267. return 2;
  268. }
  269. lua_pushstring(L, name);
  270. lua_pushstring(L, port);
  271. if (family == PF_INET) {
  272. lua_pushliteral(L, "inet");
  273. } else if (family == PF_INET6) {
  274. lua_pushliteral(L, "inet6");
  275. } else {
  276. lua_pushliteral(L, "uknown family");
  277. }
  278. return 3;
  279. }
  280. /*=========================================================================*\
  281. * Internal functions
  282. \*=========================================================================*/
  283. /*-------------------------------------------------------------------------*\
  284. * Passes all resolver information to Lua as a table
  285. \*-------------------------------------------------------------------------*/
  286. static void inet_pushresolved(lua_State *L, struct hostent *hp)
  287. {
  288. char **alias;
  289. struct in_addr **addr;
  290. int i, resolved;
  291. lua_newtable(L); resolved = lua_gettop(L);
  292. lua_pushstring(L, "name");
  293. lua_pushstring(L, hp->h_name);
  294. lua_settable(L, resolved);
  295. lua_pushstring(L, "ip");
  296. lua_pushstring(L, "alias");
  297. i = 1;
  298. alias = hp->h_aliases;
  299. lua_newtable(L);
  300. if (alias) {
  301. while (*alias) {
  302. lua_pushnumber(L, i);
  303. lua_pushstring(L, *alias);
  304. lua_settable(L, -3);
  305. i++; alias++;
  306. }
  307. }
  308. lua_settable(L, resolved);
  309. i = 1;
  310. lua_newtable(L);
  311. addr = (struct in_addr **) hp->h_addr_list;
  312. if (addr) {
  313. while (*addr) {
  314. lua_pushnumber(L, i);
  315. lua_pushstring(L, inet_ntoa(**addr));
  316. lua_settable(L, -3);
  317. i++; addr++;
  318. }
  319. }
  320. lua_settable(L, resolved);
  321. }
  322. /*-------------------------------------------------------------------------*\
  323. * Tries to create a new inet socket
  324. \*-------------------------------------------------------------------------*/
  325. const char *inet_trycreate(p_socket ps, int family, int type) {
  326. return socket_strerror(socket_create(ps, family, type, 0));
  327. }
  328. /*-------------------------------------------------------------------------*\
  329. * "Disconnects" a DGRAM socket
  330. \*-------------------------------------------------------------------------*/
  331. const char *inet_trydisconnect(p_socket ps, int family, p_timeout tm)
  332. {
  333. switch (family) {
  334. case PF_INET: {
  335. struct sockaddr_in sin;
  336. memset((char *) &sin, 0, sizeof(sin));
  337. sin.sin_family = AF_UNSPEC;
  338. sin.sin_addr.s_addr = INADDR_ANY;
  339. return socket_strerror(socket_connect(ps, (SA *) &sin,
  340. sizeof(sin), tm));
  341. }
  342. case PF_INET6: {
  343. struct sockaddr_in6 sin6;
  344. struct in6_addr addrany = IN6ADDR_ANY_INIT;
  345. memset((char *) &sin6, 0, sizeof(sin6));
  346. sin6.sin6_family = AF_UNSPEC;
  347. sin6.sin6_addr = addrany;
  348. return socket_strerror(socket_connect(ps, (SA *) &sin6,
  349. sizeof(sin6), tm));
  350. }
  351. }
  352. return NULL;
  353. }
  354. /*-------------------------------------------------------------------------*\
  355. * Tries to connect to remote address (address, port)
  356. \*-------------------------------------------------------------------------*/
  357. const char *inet_tryconnect(p_socket ps, int *family, const char *address,
  358. const char *serv, p_timeout tm, struct addrinfo *connecthints)
  359. {
  360. struct addrinfo *iterator = NULL, *resolved = NULL;
  361. const char *err = NULL;
  362. /* try resolving */
  363. err = socket_gaistrerror(getaddrinfo(address, serv,
  364. connecthints, &resolved));
  365. if (err != NULL) {
  366. if (resolved) freeaddrinfo(resolved);
  367. return err;
  368. }
  369. for (iterator = resolved; iterator; iterator = iterator->ai_next) {
  370. timeout_markstart(tm);
  371. /* create new socket if necessary. if there was no
  372. * bind, we need to create one for every new family
  373. * that shows up while iterating. if there was a
  374. * bind, all families will be the same and we will
  375. * not enter this branch. */
  376. if (*family != iterator->ai_family) {
  377. socket_destroy(ps);
  378. err = socket_strerror(socket_create(ps, iterator->ai_family,
  379. iterator->ai_socktype, iterator->ai_protocol));
  380. if (err != NULL) {
  381. freeaddrinfo(resolved);
  382. return err;
  383. }
  384. *family = iterator->ai_family;
  385. /* all sockets initially non-blocking */
  386. socket_setnonblocking(ps);
  387. }
  388. /* try connecting to remote address */
  389. err = socket_strerror(socket_connect(ps, (SA *) iterator->ai_addr,
  390. (socklen_t) iterator->ai_addrlen, tm));
  391. /* if success, break out of loop */
  392. if (err == NULL) break;
  393. }
  394. freeaddrinfo(resolved);
  395. /* here, if err is set, we failed */
  396. return err;
  397. }
  398. /*-------------------------------------------------------------------------*\
  399. * Tries to accept a socket
  400. \*-------------------------------------------------------------------------*/
  401. const char *inet_tryaccept(p_socket server, int family, p_socket client,
  402. p_timeout tm)
  403. {
  404. socklen_t len;
  405. t_sockaddr_storage addr;
  406. if (family == PF_INET6) {
  407. len = sizeof(struct sockaddr_in6);
  408. } else {
  409. len = sizeof(struct sockaddr_in);
  410. }
  411. return socket_strerror(socket_accept(server, client, (SA *) &addr,
  412. &len, tm));
  413. }
  414. /*-------------------------------------------------------------------------*\
  415. * Tries to bind socket to (address, port)
  416. \*-------------------------------------------------------------------------*/
  417. const char *inet_trybind(p_socket ps, const char *address, const char *serv,
  418. struct addrinfo *bindhints)
  419. {
  420. struct addrinfo *iterator = NULL, *resolved = NULL;
  421. const char *err = NULL;
  422. t_socket sock = *ps;
  423. /* translate luasocket special values to C */
  424. if (strcmp(address, "*") == 0) address = NULL;
  425. if (!serv) serv = "0";
  426. /* try resolving */
  427. err = socket_gaistrerror(getaddrinfo(address, serv, bindhints, &resolved));
  428. if (err) {
  429. if (resolved) freeaddrinfo(resolved);
  430. return err;
  431. }
  432. /* iterate over resolved addresses until one is good */
  433. for (iterator = resolved; iterator; iterator = iterator->ai_next) {
  434. if(sock == SOCKET_INVALID) {
  435. err = socket_strerror(socket_create(&sock, iterator->ai_family,
  436. iterator->ai_socktype, iterator->ai_protocol));
  437. if(err)
  438. continue;
  439. }
  440. /* try binding to local address */
  441. err = socket_strerror(socket_bind(&sock,
  442. (SA *) iterator->ai_addr,
  443. (socklen_t) iterator->ai_addrlen));
  444. /* keep trying unless bind succeeded */
  445. if (err) {
  446. if(sock != *ps)
  447. socket_destroy(&sock);
  448. } else {
  449. /* remember what we connected to, particularly the family */
  450. *bindhints = *iterator;
  451. break;
  452. }
  453. }
  454. /* cleanup and return error */
  455. freeaddrinfo(resolved);
  456. *ps = sock;
  457. return err;
  458. }
  459. /*-------------------------------------------------------------------------*\
  460. * Some systems do not provide these so that we provide our own.
  461. \*-------------------------------------------------------------------------*/
  462. #ifdef LUASOCKET_INET_ATON
  463. int inet_aton(const char *cp, struct in_addr *inp)
  464. {
  465. unsigned int a = 0, b = 0, c = 0, d = 0;
  466. int n = 0, r;
  467. unsigned long int addr = 0;
  468. r = sscanf(cp, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n);
  469. if (r == 0 || n == 0) return 0;
  470. cp += n;
  471. if (*cp) return 0;
  472. if (a > 255 || b > 255 || c > 255 || d > 255) return 0;
  473. if (inp) {
  474. addr += a; addr <<= 8;
  475. addr += b; addr <<= 8;
  476. addr += c; addr <<= 8;
  477. addr += d;
  478. inp->s_addr = htonl(addr);
  479. }
  480. return 1;
  481. }
  482. #endif
  483. #ifdef LUASOCKET_INET_PTON
  484. int inet_pton(int af, const char *src, void *dst)
  485. {
  486. struct addrinfo hints, *res;
  487. int ret = 1;
  488. memset(&hints, 0, sizeof(struct addrinfo));
  489. hints.ai_family = af;
  490. hints.ai_flags = AI_NUMERICHOST;
  491. if (getaddrinfo(src, NULL, &hints, &res) != 0) return -1;
  492. if (af == AF_INET) {
  493. struct sockaddr_in *in = (struct sockaddr_in *) res->ai_addr;
  494. memcpy(dst, &in->sin_addr, sizeof(in->sin_addr));
  495. } else if (af == AF_INET6) {
  496. struct sockaddr_in6 *in = (struct sockaddr_in6 *) res->ai_addr;
  497. memcpy(dst, &in->sin6_addr, sizeof(in->sin6_addr));
  498. } else {
  499. ret = -1;
  500. }
  501. freeaddrinfo(res);
  502. return ret;
  503. }
  504. #endif