lua_socket.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. /*=========================================================================*\
  2. * LuaSocket toolkit
  3. * Networking support for the Lua language
  4. * Diego Nehab
  5. * 26/11/1999
  6. *
  7. * This library is part of an effort to progressively increase the network
  8. * connectivity of the Lua language. The Lua interface to networking
  9. * functions follows the Sockets API closely, trying to simplify all tasks
  10. * involved in setting up both client and server connections. The provided
  11. * IO routines, however, follow the Lua style, being very similar to the
  12. * standard Lua read and write functions.
  13. *
  14. * Adapted to Squirrel by Domingo Alvarez Duarte on 04/01/2013
  15. *
  16. * RCS ID: $Id: luasocket.c,v 1.53 2005/10/07 04:40:59 diego Exp $
  17. \*=========================================================================*/
  18. #include "lua_socket.h"
  19. /*-------------------------------------------------------------------------*\
  20. * Initializes module
  21. \*-------------------------------------------------------------------------*/
  22. #ifdef WIN32
  23. /* WinSock doesn't have a strerror... */
  24. static const char *wstrerror(int err);
  25. #endif
  26. int lua_socket_open(void){
  27. #ifdef WIN32
  28. WSADATA wsaData;
  29. WORD wVersionRequested = MAKEWORD(2, 0);
  30. int err = WSAStartup(wVersionRequested, &wsaData );
  31. if (err != 0) return 0;
  32. if ((LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) &&
  33. (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)) {
  34. WSACleanup();
  35. return 0;
  36. }
  37. #else
  38. /* instals a handler to ignore sigpipe or it will crash us */
  39. signal(SIGPIPE, SIG_IGN);
  40. #endif
  41. return 1;
  42. }
  43. /*-------------------------------------------------------------------------*\
  44. * Close module
  45. \*-------------------------------------------------------------------------*/
  46. int lua_socket_close(void){
  47. #ifdef WIN32
  48. WSACleanup();
  49. #endif
  50. return 1;
  51. }
  52. /*-------------------------------------------------------------------------*\
  53. * Close and inutilize socket
  54. \*-------------------------------------------------------------------------*/
  55. void lua_socket_destroy(p_socket ps){
  56. if (*ps != SOCKET_INVALID) {
  57. lua_socket_setblocking(ps); /* close can take a long time on WIN32 */
  58. #ifdef WIN32
  59. closesocket(*ps);
  60. #else
  61. close(*ps);
  62. #endif
  63. *ps = SOCKET_INVALID;
  64. }
  65. }
  66. void lua_socket_shutdown(p_socket ps, int how){
  67. lua_socket_setblocking(ps);
  68. shutdown(*ps, how);
  69. lua_socket_setnonblocking(ps);
  70. }
  71. /*-------------------------------------------------------------------------*\
  72. * Wait for readable/writable/connected socket with timeout
  73. \*-------------------------------------------------------------------------*/
  74. #ifdef SOCKET_POLL
  75. #include <sys/poll.h>
  76. #define WAITFD_R POLLIN
  77. #define WAITFD_W POLLOUT
  78. #define WAITFD_C (POLLIN|POLLOUT)
  79. #else
  80. #define WAITFD_R 1
  81. #define WAITFD_W 2
  82. #define WAITFD_C (WAITFD_R|WAITFD_W)
  83. #endif
  84. int lua_socket_waitfd(p_socket ps, int sw, p_timeout tm){
  85. int ret;
  86. #ifdef WIN32
  87. #define WAITFD_E 4
  88. fd_set rfds, wfds, efds, *rp = NULL, *wp = NULL, *ep = NULL;
  89. struct timeval tv, *tp = NULL;
  90. double t;
  91. if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */
  92. if (sw & WAITFD_R) {
  93. FD_ZERO(&rfds);
  94. FD_SET(*ps, &rfds);
  95. rp = &rfds;
  96. }
  97. if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; }
  98. if (sw & WAITFD_C) { FD_ZERO(&efds); FD_SET(*ps, &efds); ep = &efds; }
  99. if ((t = lua_timeout_get(tm)) >= 0.0) {
  100. tv.tv_sec = (int) t;
  101. tv.tv_usec = (int) ((t-tv.tv_sec)*1.0e6);
  102. tp = &tv;
  103. }
  104. ret = select(0, rp, wp, ep, tp);
  105. if (ret == -1) return WSAGetLastError();
  106. if (ret == 0) return IO_TIMEOUT;
  107. if (sw == WAITFD_C && FD_ISSET(*ps, &efds)) return IO_CLOSED;
  108. #else
  109. #ifdef SOCKET_POLL
  110. struct pollfd pfd;
  111. pfd.fd = *ps;
  112. pfd.events = sw;
  113. pfd.revents = 0;
  114. if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */
  115. do {
  116. int t = (int)(timeout_getretry(tm)*1e3);
  117. ret = poll(&pfd, 1, t >= 0? t: -1);
  118. } while (ret == -1 && errno == EINTR);
  119. if (ret == -1) return errno;
  120. if (ret == 0) return IO_TIMEOUT;
  121. if (sw == WAITFD_C && (pfd.revents & (POLLIN|POLLERR))) return IO_CLOSED;
  122. #else
  123. fd_set rfds, wfds, *rp, *wp;
  124. struct timeval tv, *tp;
  125. double t;
  126. if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */
  127. do {
  128. /* must set bits within loop, because select may have modifed them */
  129. rp = wp = NULL;
  130. if (sw & WAITFD_R) { FD_ZERO(&rfds); FD_SET(*ps, &rfds); rp = &rfds; }
  131. if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; }
  132. t = lua_timeout_getretry(tm);
  133. tp = NULL;
  134. if (t >= 0.0) {
  135. tv.tv_sec = (int)t;
  136. tv.tv_usec = (int)((t-tv.tv_sec)*1.0e6);
  137. tp = &tv;
  138. }
  139. ret = select(*ps+1, rp, wp, NULL, tp);
  140. } while (ret == -1 && errno == EINTR);
  141. if (ret == -1) return errno;
  142. if (ret == 0) return IO_TIMEOUT;
  143. if (sw == WAITFD_C && FD_ISSET(*ps, &rfds)) return IO_CLOSED;
  144. #endif
  145. #endif
  146. return IO_DONE;
  147. }
  148. /*-------------------------------------------------------------------------*\
  149. * Sendto with timeout
  150. \*-------------------------------------------------------------------------*/
  151. int lua_socket_sendto(p_socket ps, const char *data, size_t count,
  152. size_t *sent, SA *addr, socklen_t addr_len, p_timeout tm){
  153. int err;
  154. *sent = 0;
  155. if (*ps == SOCKET_INVALID) return IO_CLOSED;
  156. for ( ;; ) {
  157. #ifdef WIN32
  158. int put = sendto(*ps, data, (int) count, 0, addr, addr_len);
  159. if (put > 0) {
  160. *sent = put;
  161. return IO_DONE;
  162. }
  163. err = WSAGetLastError();
  164. if (err != WSAEWOULDBLOCK) return err;
  165. #else
  166. long put = (long) sendto(*ps, data, count, 0, addr, addr_len);
  167. if (put > 0) {
  168. *sent = put;
  169. return IO_DONE;
  170. }
  171. err = errno;
  172. if (put == 0 || err == EPIPE) return IO_CLOSED;
  173. if (err == EINTR) continue;
  174. if (err != EAGAIN) return err;
  175. #endif
  176. if ((err = lua_socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
  177. }
  178. return IO_UNKNOWN;
  179. }
  180. int lua_socket_recvfrom(p_socket ps, char *data, size_t count,
  181. size_t *got, SA *addr, socklen_t *addr_len, p_timeout tm){
  182. int err;
  183. *got = 0;
  184. if (*ps == SOCKET_INVALID) return IO_CLOSED;
  185. for ( ;; ) {
  186. #ifdef WIN32
  187. int taken = recvfrom(*ps, data, (int) count, 0, addr, addr_len);
  188. if (taken > 0) {
  189. *got = taken;
  190. return IO_DONE;
  191. }
  192. if (taken == 0) return IO_CLOSED;
  193. err = WSAGetLastError();
  194. if (err != WSAEWOULDBLOCK) return err;
  195. #else
  196. long taken = (long) recvfrom(*ps, data, count, 0, addr, addr_len);
  197. if (taken > 0) {
  198. *got = taken;
  199. return IO_DONE;
  200. }
  201. err = errno;
  202. if (taken == 0) return IO_CLOSED;
  203. if (err == EINTR) continue;
  204. if (err != EAGAIN) return err;
  205. #endif
  206. if ((err = lua_socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
  207. }
  208. return IO_UNKNOWN;
  209. }
  210. /*-------------------------------------------------------------------------*\
  211. * Put socket into non-blocking mode
  212. \*-------------------------------------------------------------------------*/
  213. void lua_socket_setnonblocking(p_socket ps){
  214. #ifdef WIN32
  215. u_long argp = 1;
  216. ioctlsocket(*ps, FIONBIO, &argp);
  217. #else
  218. int flags = fcntl(*ps, F_GETFL, 0);
  219. flags |= O_NONBLOCK;
  220. fcntl(*ps, F_SETFL, flags);
  221. #endif
  222. }
  223. /*-------------------------------------------------------------------------*\
  224. * Put socket into blocking mode
  225. \*-------------------------------------------------------------------------*/
  226. void lua_socket_setblocking(p_socket ps){
  227. #ifdef WIN32
  228. u_long argp = 0;
  229. ioctlsocket(*ps, FIONBIO, &argp);
  230. #else
  231. int flags = fcntl(*ps, F_GETFL, 0);
  232. flags &= (~(O_NONBLOCK));
  233. fcntl(*ps, F_SETFL, flags);
  234. #endif
  235. }
  236. /*-------------------------------------------------------------------------*\
  237. * Select with int timeout in ms
  238. \*-------------------------------------------------------------------------*/
  239. int lua_socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,
  240. p_timeout tm){
  241. #ifdef WIN32
  242. struct timeval tv;
  243. double t = lua_timeout_get(tm);
  244. tv.tv_sec = (int) t;
  245. tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6);
  246. if (n <= 0) {
  247. Sleep((DWORD) (1000*t));
  248. return 0;
  249. } else return select(0, rfds, wfds, efds, t >= 0.0? &tv: NULL);
  250. #else
  251. int ret;
  252. do {
  253. struct timeval tv;
  254. double t = lua_timeout_getretry(tm);
  255. tv.tv_sec = (int) t;
  256. tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6);
  257. /* timeout = 0 means no wait */
  258. ret = select(n, rfds, wfds, efds, t >= 0.0 ? &tv: NULL);
  259. } while (ret < 0 && errno == EINTR);
  260. return ret;
  261. #endif
  262. }
  263. /*-------------------------------------------------------------------------*\
  264. * Connects or returns error message
  265. \*-------------------------------------------------------------------------*/
  266. int lua_socket_connect(p_socket ps, SA *addr, socklen_t addr_len, p_timeout tm){
  267. int err;
  268. /* don't call on closed socket */
  269. if (*ps == SOCKET_INVALID) return IO_CLOSED;
  270. #ifdef WIN32
  271. /* ask system to connect */
  272. if (connect(*ps, addr, addr_len) == 0) return IO_DONE;
  273. /* make sure the system is trying to connect */
  274. err = WSAGetLastError();
  275. if (err != WSAEWOULDBLOCK && err != WSAEINPROGRESS) return err;
  276. /* zero timeout case optimization */
  277. if (timeout_iszero(tm)) return IO_TIMEOUT;
  278. /* we wait until something happens */
  279. err = lua_socket_waitfd(ps, WAITFD_C, tm);
  280. if (err == IO_CLOSED) {
  281. int addr_len = sizeof(err);
  282. /* give windows time to set the error (yes, disgusting) */
  283. Sleep(10);
  284. /* find out why we failed */
  285. getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &addr_len);
  286. /* we KNOW there was an error. if 'why' is 0, we will return
  287. * "unknown error", but it's not really our fault */
  288. return err > 0? err: IO_UNKNOWN;
  289. } else return err;
  290. #else
  291. /* call connect until done or failed without being interrupted */
  292. do if (connect(*ps, addr, addr_len) == 0) return IO_DONE;
  293. while ((err = errno) == EINTR);
  294. /* if connection failed immediately, return error code */
  295. if (err != EINPROGRESS && err != EAGAIN) return err;
  296. /* zero timeout case optimization */
  297. if (timeout_iszero(tm)) return IO_TIMEOUT;
  298. /* wait until we have the result of the connection attempt or timeout */
  299. err = lua_socket_waitfd(ps, WAITFD_C, tm);
  300. if (err == IO_CLOSED) {
  301. if (recv(*ps, (char *) &err, 0, 0) == 0) return IO_DONE;
  302. else return errno;
  303. } else return err;
  304. #endif
  305. }
  306. /*-------------------------------------------------------------------------*\
  307. * Creates and sets up a socket
  308. \*-------------------------------------------------------------------------*/
  309. int lua_socket_create(p_socket ps, int domain, int type, int protocol){
  310. *ps = socket(domain, type, protocol);
  311. if (*ps != SOCKET_INVALID) return IO_DONE;
  312. #ifdef WIN32
  313. else return WSAGetLastError();
  314. #else
  315. else return errno;
  316. #endif
  317. }
  318. /*-------------------------------------------------------------------------*\
  319. * Binds or returns error message
  320. \*-------------------------------------------------------------------------*/
  321. int lua_socket_bind(p_socket ps, SA *addr, socklen_t addr_len){
  322. int err = IO_DONE;
  323. lua_socket_setblocking(ps);
  324. if (bind(*ps, addr, addr_len) < 0)
  325. #ifdef WIN32
  326. err = WSAGetLastError();
  327. #else
  328. err = errno;
  329. #endif
  330. lua_socket_setnonblocking(ps);
  331. return err;
  332. }
  333. int lua_socket_listen(p_socket ps, int backlog){
  334. int err = IO_DONE;
  335. lua_socket_setblocking(ps);
  336. if (listen(*ps, backlog) < 0)
  337. #ifdef WIN32
  338. err = WSAGetLastError();
  339. #else
  340. err = errno;
  341. #endif
  342. lua_socket_setnonblocking(ps);
  343. return err;
  344. }
  345. /*-------------------------------------------------------------------------*\
  346. * Accept with timeout
  347. \*-------------------------------------------------------------------------*/
  348. int lua_socket_accept(p_socket ps, p_socket pa, SA *addr,
  349. socklen_t *addr_len, p_timeout tm){
  350. SA daddr;
  351. socklen_t dlen = sizeof(daddr);
  352. if (*ps == SOCKET_INVALID) return IO_CLOSED;
  353. if (!addr) addr = &daddr;
  354. if (!addr_len) addr_len = &dlen;
  355. for ( ;; ) {
  356. int err;
  357. /* try to get client socket */
  358. if ((*pa = accept(*ps, addr, addr_len)) != SOCKET_INVALID) return IO_DONE;
  359. #ifdef WIN32
  360. /* find out why we failed */
  361. err = WSAGetLastError();
  362. /* if we failed because there was no connectoin, keep trying */
  363. if (err != WSAEWOULDBLOCK && err != WSAECONNABORTED) return err;
  364. #else
  365. err = errno;
  366. if (err == EINTR) continue;
  367. if (err != EAGAIN && err != ECONNABORTED) return err;
  368. #endif
  369. /* call select to avoid busy wait */
  370. if ((err = lua_socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
  371. }
  372. /* can't reach here */
  373. return IO_UNKNOWN;
  374. }
  375. /* these are perfect to use with the io abstraction module
  376. and the buffered input module */
  377. /*-------------------------------------------------------------------------*\
  378. * Send with timeout
  379. * On windows, if you try to send 10MB, the OS will buffer EVERYTHING
  380. * this can take an awful lot of time and we will end up blocked.
  381. * Therefore, whoever calls this function should not pass a huge buffer.
  382. \*-------------------------------------------------------------------------*/
  383. int lua_socket_send(p_socket ps, const char *data, size_t count,
  384. size_t *sent, p_timeout tm){
  385. int err;
  386. *sent = 0;
  387. /* avoid making system calls on closed sockets */
  388. if (*ps == SOCKET_INVALID) return IO_CLOSED;
  389. /* loop until we send something or we give up on error */
  390. for ( ;; ) {
  391. #ifdef WIN32
  392. /* try to send something */
  393. int put = send(*ps, data, (int) count, 0);
  394. /* if we sent something, we are done */
  395. if (put > 0) {
  396. *sent = put;
  397. return IO_DONE;
  398. }
  399. /* deal with failure */
  400. err = WSAGetLastError();
  401. /* we can only proceed if there was no serious error */
  402. if (err != WSAEWOULDBLOCK) return err;
  403. #else
  404. long put = (long) send(*ps, data, count, 0);
  405. /* if we sent anything, we are done */
  406. if (put > 0) {
  407. *sent = put;
  408. return IO_DONE;
  409. }
  410. err = errno;
  411. /* send can't really return 0, but EPIPE means the connection was
  412. closed */
  413. if (put == 0 || err == EPIPE) return IO_CLOSED;
  414. /* we call was interrupted, just try again */
  415. if (err == EINTR) continue;
  416. /* if failed fatal reason, report error */
  417. if (err != EAGAIN) return err;
  418. #endif
  419. /* avoid busy wait */
  420. /* wait until we can send something or we timeout */
  421. if ((err = lua_socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
  422. }
  423. /* can't reach here */
  424. return IO_UNKNOWN;
  425. }
  426. /*-------------------------------------------------------------------------*\
  427. * Receive with timeout
  428. \*-------------------------------------------------------------------------*/
  429. int lua_socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm){
  430. int err;
  431. *got = 0;
  432. if (*ps == SOCKET_INVALID) return IO_CLOSED;
  433. for ( ;; ) {
  434. #ifdef WIN32
  435. int taken = recv(*ps, data, (int) count, 0);
  436. if (taken > 0) {
  437. *got = taken;
  438. return IO_DONE;
  439. }
  440. if (taken == 0) return IO_CLOSED;
  441. err = WSAGetLastError();
  442. if (err != WSAEWOULDBLOCK) return err;
  443. #else
  444. long taken = (long) recv(*ps, data, count, 0);
  445. if (taken > 0) {
  446. *got = taken;
  447. return IO_DONE;
  448. }
  449. err = errno;
  450. if (taken == 0) return IO_CLOSED;
  451. if (err == EINTR) continue;
  452. if (err != EAGAIN) return err;
  453. #endif
  454. if ((err = lua_socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
  455. }
  456. return IO_UNKNOWN;
  457. }
  458. /*-------------------------------------------------------------------------*\
  459. * Error translation functions
  460. * Make sure important error messages are standard
  461. \*-------------------------------------------------------------------------*/
  462. #ifdef WIN32
  463. static const char *wstrerror(int err) {
  464. switch (err) {
  465. case WSAEINTR: return "Interrupted function call";
  466. case WSAEACCES: return "Permission denied";
  467. case WSAEFAULT: return "Bad address";
  468. case WSAEINVAL: return "Invalid argument";
  469. case WSAEMFILE: return "Too many open files";
  470. case WSAEWOULDBLOCK: return "Resource temporarily unavailable";
  471. case WSAEINPROGRESS: return "Operation now in progress";
  472. case WSAEALREADY: return "Operation already in progress";
  473. case WSAENOTSOCK: return "Socket operation on nonsocket";
  474. case WSAEDESTADDRREQ: return "Destination address required";
  475. case WSAEMSGSIZE: return "Message too long";
  476. case WSAEPROTOTYPE: return "Protocol wrong type for socket";
  477. case WSAENOPROTOOPT: return "Bad protocol option";
  478. case WSAEPROTONOSUPPORT: return "Protocol not supported";
  479. case WSAESOCKTNOSUPPORT: return "Socket type not supported";
  480. case WSAEOPNOTSUPP: return "Operation not supported";
  481. case WSAEPFNOSUPPORT: return "Protocol family not supported";
  482. case WSAEAFNOSUPPORT:
  483. return "Address family not supported by protocol family";
  484. case WSAEADDRINUSE: return "Address already in use";
  485. case WSAEADDRNOTAVAIL: return "Cannot assign requested address";
  486. case WSAENETDOWN: return "Network is down";
  487. case WSAENETUNREACH: return "Network is unreachable";
  488. case WSAENETRESET: return "Network dropped connection on reset";
  489. case WSAECONNABORTED: return "Software caused connection abort";
  490. case WSAECONNRESET: return "Connection reset by peer";
  491. case WSAENOBUFS: return "No buffer space available";
  492. case WSAEISCONN: return "Socket is already connected";
  493. case WSAENOTCONN: return "Socket is not connected";
  494. case WSAESHUTDOWN: return "Cannot send after socket shutdown";
  495. case WSAETIMEDOUT: return "Connection timed out";
  496. case WSAECONNREFUSED: return "Connection refused";
  497. case WSAEHOSTDOWN: return "Host is down";
  498. case WSAEHOSTUNREACH: return "No route to host";
  499. case WSAEPROCLIM: return "Too many processes";
  500. case WSASYSNOTREADY: return "Network subsystem is unavailable";
  501. case WSAVERNOTSUPPORTED: return "Winsock.dll version out of range";
  502. case WSANOTINITIALISED:
  503. return "Successful WSAStartup not yet performed";
  504. case WSAEDISCON: return "Graceful shutdown in progress";
  505. case WSAHOST_NOT_FOUND: return "Host not found";
  506. case WSATRY_AGAIN: return "Nonauthoritative host not found";
  507. case WSANO_RECOVERY: return "Nonrecoverable name lookup error";
  508. case WSANO_DATA: return "Valid name, no data record of requested type";
  509. default: return "Unknown error";
  510. }
  511. }
  512. #endif
  513. const char *lua_socket_strerror(int err){
  514. if (err <= 0) return lua_io_strerror(err);
  515. #ifdef WIN32
  516. switch (err) {
  517. case WSAEADDRINUSE: return "address already in use";
  518. case WSAECONNREFUSED: return "connection refused";
  519. case WSAEISCONN: return "already connected";
  520. case WSAEACCES: return "permission denied";
  521. case WSAECONNABORTED: return "closed";
  522. case WSAECONNRESET: return "closed";
  523. case WSAETIMEDOUT: return "timeout";
  524. default: return wstrerror(err);
  525. }
  526. #else
  527. switch (err) {
  528. case EADDRINUSE: return "address already in use";
  529. case EISCONN: return "already connected";
  530. case EACCES: return "permission denied";
  531. case ECONNREFUSED: return "connection refused";
  532. case ECONNABORTED: return "closed";
  533. case ECONNRESET: return "closed";
  534. case EPIPE: return "closed";
  535. case ETIMEDOUT: return "timeout";
  536. default: return strerror(errno);
  537. }
  538. #endif
  539. }
  540. const char *lua_socket_ioerror(p_socket ps, int err){
  541. (void) ps;
  542. return lua_socket_strerror(err);
  543. }
  544. const char *lua_socket_hoststrerror(int err){
  545. if (err <= 0) return lua_io_strerror(err);
  546. #ifdef WIN32
  547. switch (err) {
  548. case WSAHOST_NOT_FOUND: return "host not found";
  549. default: return wstrerror(err);
  550. }
  551. #else
  552. switch (err) {
  553. case HOST_NOT_FOUND: return "host not found";
  554. default: return hstrerror(err);
  555. }
  556. #endif
  557. }
  558. /*-------------------------------------------------------------------------*\
  559. * DNS helpers
  560. \*-------------------------------------------------------------------------*/
  561. int lua_socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp){
  562. *hp = gethostbyaddr(addr, len, AF_INET);
  563. if (*hp) return IO_DONE;
  564. #ifdef WIN32
  565. else return WSAGetLastError();
  566. #else
  567. else if (h_errno) return h_errno;
  568. else if (errno) return errno;
  569. else return IO_UNKNOWN;
  570. #endif
  571. }
  572. int lua_socket_gethostbyname(const char *addr, struct hostent **hp){
  573. *hp = gethostbyname(addr);
  574. if (*hp) return IO_DONE;
  575. #ifdef WIN32
  576. else return WSAGetLastError();
  577. #else
  578. else if (h_errno) return h_errno;
  579. else if (errno) return errno;
  580. else return IO_UNKNOWN;
  581. #endif
  582. }
  583. /*=========================================================================*\
  584. * Timeout Exported functions.
  585. \*=========================================================================*/
  586. #ifdef _WIN32
  587. #include <windows.h>
  588. #else
  589. #include <time.h>
  590. #include <sys/time.h>
  591. #endif
  592. /* min and max macros */
  593. #ifndef MIN
  594. #define MIN(x, y) ((x) < (y) ? x : y)
  595. #endif
  596. #ifndef MAX
  597. #define MAX(x, y) ((x) > (y) ? x : y)
  598. #endif
  599. /*-------------------------------------------------------------------------*\
  600. * Initialize structure
  601. \*-------------------------------------------------------------------------*/
  602. void lua_timeout_init(p_timeout tm, double block, double total) {
  603. tm->block = block;
  604. tm->total = total;
  605. }
  606. /*-------------------------------------------------------------------------*\
  607. * Determines how much time we have left for the next system call,
  608. * if the previous call was successful
  609. * Input
  610. * tm: timeout control structure
  611. * Returns
  612. * the number of ms left or -1 if there is no time limit
  613. \*-------------------------------------------------------------------------*/
  614. double lua_timeout_get(p_timeout tm) {
  615. if (tm->block < 0.0 && tm->total < 0.0) {
  616. return -1;
  617. } else if (tm->block < 0.0) {
  618. double t = tm->total - lua_timeout_gettime() + tm->start;
  619. return MAX(t, 0.0);
  620. } else if (tm->total < 0.0) {
  621. return tm->block;
  622. } else {
  623. double t = tm->total - lua_timeout_gettime() + tm->start;
  624. return MIN(tm->block, MAX(t, 0.0));
  625. }
  626. }
  627. /*-------------------------------------------------------------------------*\
  628. * Returns time since start of operation
  629. * Input
  630. * tm: timeout control structure
  631. * Returns
  632. * start field of structure
  633. \*-------------------------------------------------------------------------*/
  634. double lua_timeout_getstart(p_timeout tm) {
  635. return tm->start;
  636. }
  637. /*-------------------------------------------------------------------------*\
  638. * Determines how much time we have left for the next system call,
  639. * if the previous call was a failure
  640. * Input
  641. * tm: timeout control structure
  642. * Returns
  643. * the number of ms left or -1 if there is no time limit
  644. \*-------------------------------------------------------------------------*/
  645. double lua_timeout_getretry(p_timeout tm) {
  646. if (tm->block < 0.0 && tm->total < 0.0) {
  647. return -1;
  648. } else if (tm->block < 0.0) {
  649. double t = tm->total - lua_timeout_gettime() + tm->start;
  650. return MAX(t, 0.0);
  651. } else if (tm->total < 0.0) {
  652. double t = tm->block - lua_timeout_gettime() + tm->start;
  653. return MAX(t, 0.0);
  654. } else {
  655. double t = tm->total - lua_timeout_gettime() + tm->start;
  656. return MIN(tm->block, MAX(t, 0.0));
  657. }
  658. }
  659. /*-------------------------------------------------------------------------*\
  660. * Marks the operation start time in structure
  661. * Input
  662. * tm: timeout control structure
  663. \*-------------------------------------------------------------------------*/
  664. p_timeout lua_timeout_markstart(p_timeout tm) {
  665. tm->start = lua_timeout_gettime();
  666. return tm;
  667. }
  668. /*-------------------------------------------------------------------------*\
  669. * Gets time in s, relative to January 1, 1970 (UTC)
  670. * Returns
  671. * time in s.
  672. \*-------------------------------------------------------------------------*/
  673. #ifdef _WIN32
  674. double lua_timeout_gettime(void) {
  675. FILETIME ft;
  676. double t;
  677. GetSystemTimeAsFileTime(&ft);
  678. /* Windows file time (time since January 1, 1601 (UTC)) */
  679. t = ft.dwLowDateTime/1.0e7 + ft.dwHighDateTime*(4294967296.0/1.0e7);
  680. /* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */
  681. return (t - 11644473600.0);
  682. }
  683. #else
  684. double lua_timeout_gettime(void) {
  685. struct timeval v;
  686. gettimeofday(&v, (struct timezone *) NULL);
  687. /* Unix Epoch time (time since January 1, 1970 (UTC)) */
  688. return v.tv_sec + v.tv_usec/1.0e6;
  689. }
  690. #endif
  691. /*=========================================================================*\
  692. * IO Exported functions
  693. \*=========================================================================*/
  694. /*-------------------------------------------------------------------------*\
  695. * Initializes C structure
  696. \*-------------------------------------------------------------------------*/
  697. void lua_io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx) {
  698. io->send = send;
  699. io->recv = recv;
  700. io->error = error;
  701. io->ctx = ctx;
  702. }
  703. /*-------------------------------------------------------------------------*\
  704. * I/O error strings
  705. \*-------------------------------------------------------------------------*/
  706. const char *lua_io_strerror(int err) {
  707. switch (err) {
  708. case IO_DONE: return NULL;
  709. case IO_CLOSED: return "closed";
  710. case IO_TIMEOUT: return "timeout";
  711. default: return "unknown error";
  712. }
  713. }