wsocket.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. /*=========================================================================*\
  2. * Socket compatibilization module for Win32
  3. * LuaSocket toolkit
  4. *
  5. * The penalty of calling select to avoid busy-wait is only paid when
  6. * the I/O call fail in the first place.
  7. \*=========================================================================*/
  8. #include <string.h>
  9. #include "socket.h"
  10. /* WinSock doesn't have a strerror... */
  11. static const char *wstrerror(int err);
  12. /*-------------------------------------------------------------------------*\
  13. * Initializes module
  14. \*-------------------------------------------------------------------------*/
  15. int socket_open(void) {
  16. WSADATA wsaData;
  17. WORD wVersionRequested = MAKEWORD(2, 0);
  18. int err = WSAStartup(wVersionRequested, &wsaData );
  19. if (err != 0) return 0;
  20. if ((LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) &&
  21. (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)) {
  22. WSACleanup();
  23. return 0;
  24. }
  25. return 1;
  26. }
  27. /*-------------------------------------------------------------------------*\
  28. * Close module
  29. \*-------------------------------------------------------------------------*/
  30. int socket_close(void) {
  31. WSACleanup();
  32. return 1;
  33. }
  34. /*-------------------------------------------------------------------------*\
  35. * Wait for readable/writable/connected socket with timeout
  36. \*-------------------------------------------------------------------------*/
  37. #define WAITFD_R 1
  38. #define WAITFD_W 2
  39. #define WAITFD_E 4
  40. #define WAITFD_C (WAITFD_E|WAITFD_W)
  41. int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
  42. int ret;
  43. fd_set rfds, wfds, efds, *rp = NULL, *wp = NULL, *ep = NULL;
  44. struct timeval tv, *tp = NULL;
  45. double t;
  46. if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */
  47. if (sw & WAITFD_R) {
  48. FD_ZERO(&rfds);
  49. FD_SET(*ps, &rfds);
  50. rp = &rfds;
  51. }
  52. if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; }
  53. if (sw & WAITFD_C) { FD_ZERO(&efds); FD_SET(*ps, &efds); ep = &efds; }
  54. if ((t = timeout_get(tm)) >= 0.0) {
  55. tv.tv_sec = (int) t;
  56. tv.tv_usec = (int) ((t-tv.tv_sec)*1.0e6);
  57. tp = &tv;
  58. }
  59. ret = select(0, rp, wp, ep, tp);
  60. if (ret == -1) return WSAGetLastError();
  61. if (ret == 0) return IO_TIMEOUT;
  62. if (sw == WAITFD_C && FD_ISSET(*ps, &efds)) return IO_CLOSED;
  63. return IO_DONE;
  64. }
  65. /*-------------------------------------------------------------------------*\
  66. * Select with int timeout in ms
  67. \*-------------------------------------------------------------------------*/
  68. int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,
  69. p_timeout tm) {
  70. struct timeval tv;
  71. double t = timeout_get(tm);
  72. tv.tv_sec = (int) t;
  73. tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6);
  74. if (n <= 0) {
  75. Sleep((DWORD) (1000*t));
  76. return 0;
  77. } else return select(0, rfds, wfds, efds, t >= 0.0? &tv: NULL);
  78. }
  79. /*-------------------------------------------------------------------------*\
  80. * Close and inutilize socket
  81. \*-------------------------------------------------------------------------*/
  82. void socket_destroy(p_socket ps) {
  83. if (*ps != SOCKET_INVALID) {
  84. socket_setblocking(ps); /* close can take a long time on WIN32 */
  85. closesocket(*ps);
  86. *ps = SOCKET_INVALID;
  87. }
  88. }
  89. /*-------------------------------------------------------------------------*\
  90. *
  91. \*-------------------------------------------------------------------------*/
  92. void socket_shutdown(p_socket ps, int how) {
  93. socket_setblocking(ps);
  94. shutdown(*ps, how);
  95. socket_setnonblocking(ps);
  96. }
  97. /*-------------------------------------------------------------------------*\
  98. * Creates and sets up a socket
  99. \*-------------------------------------------------------------------------*/
  100. int socket_create(p_socket ps, int domain, int type, int protocol) {
  101. *ps = socket(domain, type, protocol);
  102. if (*ps != SOCKET_INVALID) return IO_DONE;
  103. else return WSAGetLastError();
  104. }
  105. /*-------------------------------------------------------------------------*\
  106. * Connects or returns error message
  107. \*-------------------------------------------------------------------------*/
  108. int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) {
  109. int err;
  110. /* don't call on closed socket */
  111. if (*ps == SOCKET_INVALID) return IO_CLOSED;
  112. /* ask system to connect */
  113. if (connect(*ps, addr, len) == 0) return IO_DONE;
  114. /* make sure the system is trying to connect */
  115. err = WSAGetLastError();
  116. if (err != WSAEWOULDBLOCK && err != WSAEINPROGRESS) return err;
  117. /* zero timeout case optimization */
  118. if (timeout_iszero(tm)) return IO_TIMEOUT;
  119. /* we wait until something happens */
  120. err = socket_waitfd(ps, WAITFD_C, tm);
  121. if (err == IO_CLOSED) {
  122. int len = sizeof(err);
  123. /* give windows time to set the error (yes, disgusting) */
  124. Sleep(10);
  125. /* find out why we failed */
  126. getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
  127. /* we KNOW there was an error. if 'why' is 0, we will return
  128. * "unknown error", but it's not really our fault */
  129. return err > 0? err: IO_UNKNOWN;
  130. } else return err;
  131. }
  132. /*-------------------------------------------------------------------------*\
  133. * Binds or returns error message
  134. \*-------------------------------------------------------------------------*/
  135. int socket_bind(p_socket ps, SA *addr, socklen_t len) {
  136. int err = IO_DONE;
  137. socket_setblocking(ps);
  138. if (bind(*ps, addr, len) < 0) err = WSAGetLastError();
  139. socket_setnonblocking(ps);
  140. return err;
  141. }
  142. /*-------------------------------------------------------------------------*\
  143. *
  144. \*-------------------------------------------------------------------------*/
  145. int socket_listen(p_socket ps, int backlog) {
  146. int err = IO_DONE;
  147. socket_setblocking(ps);
  148. if (listen(*ps, backlog) < 0) err = WSAGetLastError();
  149. socket_setnonblocking(ps);
  150. return err;
  151. }
  152. /*-------------------------------------------------------------------------*\
  153. * Accept with timeout
  154. \*-------------------------------------------------------------------------*/
  155. int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len,
  156. p_timeout tm) {
  157. if (*ps == SOCKET_INVALID) return IO_CLOSED;
  158. for ( ;; ) {
  159. int err;
  160. /* try to get client socket */
  161. if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE;
  162. /* find out why we failed */
  163. err = WSAGetLastError();
  164. /* if we failed because there was no connectoin, keep trying */
  165. if (err != WSAEWOULDBLOCK && err != WSAECONNABORTED) return err;
  166. /* call select to avoid busy wait */
  167. if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
  168. }
  169. }
  170. /*-------------------------------------------------------------------------*\
  171. * Send with timeout
  172. * On windows, if you try to send 10MB, the OS will buffer EVERYTHING
  173. * this can take an awful lot of time and we will end up blocked.
  174. * Therefore, whoever calls this function should not pass a huge buffer.
  175. \*-------------------------------------------------------------------------*/
  176. int socket_send(p_socket ps, const char *data, size_t count,
  177. size_t *sent, p_timeout tm)
  178. {
  179. int err;
  180. *sent = 0;
  181. /* avoid making system calls on closed sockets */
  182. if (*ps == SOCKET_INVALID) return IO_CLOSED;
  183. /* loop until we send something or we give up on error */
  184. for ( ;; ) {
  185. /* try to send something */
  186. int put = send(*ps, data, (int) count, 0);
  187. /* if we sent something, we are done */
  188. if (put > 0) {
  189. *sent = put;
  190. return IO_DONE;
  191. }
  192. /* deal with failure */
  193. err = WSAGetLastError();
  194. /* we can only proceed if there was no serious error */
  195. if (err != WSAEWOULDBLOCK) return err;
  196. /* avoid busy wait */
  197. if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
  198. }
  199. }
  200. /*-------------------------------------------------------------------------*\
  201. * Sendto with timeout
  202. \*-------------------------------------------------------------------------*/
  203. int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,
  204. SA *addr, socklen_t len, p_timeout tm)
  205. {
  206. int err;
  207. *sent = 0;
  208. if (*ps == SOCKET_INVALID) return IO_CLOSED;
  209. for ( ;; ) {
  210. int put = sendto(*ps, data, (int) count, 0, addr, len);
  211. if (put > 0) {
  212. *sent = put;
  213. return IO_DONE;
  214. }
  215. err = WSAGetLastError();
  216. if (err != WSAEWOULDBLOCK) return err;
  217. if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
  218. }
  219. }
  220. /*-------------------------------------------------------------------------*\
  221. * Receive with timeout
  222. \*-------------------------------------------------------------------------*/
  223. int socket_recv(p_socket ps, char *data, size_t count, size_t *got,
  224. p_timeout tm)
  225. {
  226. int err, prev = IO_DONE;
  227. *got = 0;
  228. if (*ps == SOCKET_INVALID) return IO_CLOSED;
  229. for ( ;; ) {
  230. int taken = recv(*ps, data, (int) count, 0);
  231. if (taken > 0) {
  232. *got = taken;
  233. return IO_DONE;
  234. }
  235. if (taken == 0) return IO_CLOSED;
  236. err = WSAGetLastError();
  237. /* On UDP, a connreset simply means the previous send failed.
  238. * So we try again.
  239. * On TCP, it means our socket is now useless, so the error passes.
  240. * (We will loop again, exiting because the same error will happen) */
  241. if (err != WSAEWOULDBLOCK) {
  242. if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;
  243. prev = err;
  244. }
  245. if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
  246. }
  247. }
  248. /*-------------------------------------------------------------------------*\
  249. * Recvfrom with timeout
  250. \*-------------------------------------------------------------------------*/
  251. int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
  252. SA *addr, socklen_t *len, p_timeout tm)
  253. {
  254. int err, prev = IO_DONE;
  255. *got = 0;
  256. if (*ps == SOCKET_INVALID) return IO_CLOSED;
  257. for ( ;; ) {
  258. int taken = recvfrom(*ps, data, (int) count, 0, addr, len);
  259. if (taken > 0) {
  260. *got = taken;
  261. return IO_DONE;
  262. }
  263. if (taken == 0) return IO_CLOSED;
  264. err = WSAGetLastError();
  265. /* On UDP, a connreset simply means the previous send failed.
  266. * So we try again.
  267. * On TCP, it means our socket is now useless, so the error passes.
  268. * (We will loop again, exiting because the same error will happen) */
  269. if (err != WSAEWOULDBLOCK) {
  270. if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;
  271. prev = err;
  272. }
  273. if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
  274. }
  275. }
  276. /*-------------------------------------------------------------------------*\
  277. * Put socket into blocking mode
  278. \*-------------------------------------------------------------------------*/
  279. void socket_setblocking(p_socket ps) {
  280. u_long argp = 0;
  281. ioctlsocket(*ps, FIONBIO, &argp);
  282. }
  283. /*-------------------------------------------------------------------------*\
  284. * Put socket into non-blocking mode
  285. \*-------------------------------------------------------------------------*/
  286. void socket_setnonblocking(p_socket ps) {
  287. u_long argp = 1;
  288. ioctlsocket(*ps, FIONBIO, &argp);
  289. }
  290. /*-------------------------------------------------------------------------*\
  291. * DNS helpers
  292. \*-------------------------------------------------------------------------*/
  293. int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) {
  294. *hp = gethostbyaddr(addr, len, AF_INET);
  295. if (*hp) return IO_DONE;
  296. else return WSAGetLastError();
  297. }
  298. int socket_gethostbyname(const char *addr, struct hostent **hp) {
  299. *hp = gethostbyname(addr);
  300. if (*hp) return IO_DONE;
  301. else return WSAGetLastError();
  302. }
  303. /*-------------------------------------------------------------------------*\
  304. * Error translation functions
  305. \*-------------------------------------------------------------------------*/
  306. const char *socket_hoststrerror(int err) {
  307. if (err <= 0) return io_strerror(err);
  308. switch (err) {
  309. case WSAHOST_NOT_FOUND: return "host not found";
  310. default: return wstrerror(err);
  311. }
  312. }
  313. const char *socket_strerror(int err) {
  314. if (err <= 0) return io_strerror(err);
  315. switch (err) {
  316. case WSAEADDRINUSE: return "address already in use";
  317. case WSAECONNREFUSED: return "connection refused";
  318. case WSAEISCONN: return "already connected";
  319. case WSAEACCES: return "permission denied";
  320. case WSAECONNABORTED: return "closed";
  321. case WSAECONNRESET: return "closed";
  322. case WSAETIMEDOUT: return "timeout";
  323. default: return wstrerror(err);
  324. }
  325. }
  326. const char *socket_ioerror(p_socket ps, int err) {
  327. (void) ps;
  328. return socket_strerror(err);
  329. }
  330. static const char *wstrerror(int err) {
  331. switch (err) {
  332. case WSAEINTR: return "Interrupted function call";
  333. case WSAEACCES: return "Permission denied";
  334. case WSAEFAULT: return "Bad address";
  335. case WSAEINVAL: return "Invalid argument";
  336. case WSAEMFILE: return "Too many open files";
  337. case WSAEWOULDBLOCK: return "Resource temporarily unavailable";
  338. case WSAEINPROGRESS: return "Operation now in progress";
  339. case WSAEALREADY: return "Operation already in progress";
  340. case WSAENOTSOCK: return "Socket operation on nonsocket";
  341. case WSAEDESTADDRREQ: return "Destination address required";
  342. case WSAEMSGSIZE: return "Message too long";
  343. case WSAEPROTOTYPE: return "Protocol wrong type for socket";
  344. case WSAENOPROTOOPT: return "Bad protocol option";
  345. case WSAEPROTONOSUPPORT: return "Protocol not supported";
  346. case WSAESOCKTNOSUPPORT: return "Socket type not supported";
  347. case WSAEOPNOTSUPP: return "Operation not supported";
  348. case WSAEPFNOSUPPORT: return "Protocol family not supported";
  349. case WSAEAFNOSUPPORT:
  350. return "Address family not supported by protocol family";
  351. case WSAEADDRINUSE: return "Address already in use";
  352. case WSAEADDRNOTAVAIL: return "Cannot assign requested address";
  353. case WSAENETDOWN: return "Network is down";
  354. case WSAENETUNREACH: return "Network is unreachable";
  355. case WSAENETRESET: return "Network dropped connection on reset";
  356. case WSAECONNABORTED: return "Software caused connection abort";
  357. case WSAECONNRESET: return "Connection reset by peer";
  358. case WSAENOBUFS: return "No buffer space available";
  359. case WSAEISCONN: return "Socket is already connected";
  360. case WSAENOTCONN: return "Socket is not connected";
  361. case WSAESHUTDOWN: return "Cannot send after socket shutdown";
  362. case WSAETIMEDOUT: return "Connection timed out";
  363. case WSAECONNREFUSED: return "Connection refused";
  364. case WSAEHOSTDOWN: return "Host is down";
  365. case WSAEHOSTUNREACH: return "No route to host";
  366. case WSAEPROCLIM: return "Too many processes";
  367. case WSASYSNOTREADY: return "Network subsystem is unavailable";
  368. case WSAVERNOTSUPPORTED: return "Winsock.dll version out of range";
  369. case WSANOTINITIALISED:
  370. return "Successful WSAStartup not yet performed";
  371. case WSAEDISCON: return "Graceful shutdown in progress";
  372. case WSAHOST_NOT_FOUND: return "Host not found";
  373. case WSATRY_AGAIN: return "Nonauthoritative host not found";
  374. case WSANO_RECOVERY: return "Nonrecoverable name lookup error";
  375. case WSANO_DATA: return "Valid name, no data record of requested type";
  376. default: return "Unknown error";
  377. }
  378. }
  379. const char *socket_gaistrerror(int err) {
  380. if (err == 0) return NULL;
  381. switch (err) {
  382. case EAI_AGAIN: return "temporary failure in name resolution";
  383. case EAI_BADFLAGS: return "invalid value for ai_flags";
  384. #ifdef EAI_BADHINTS
  385. case EAI_BADHINTS: return "invalid value for hints";
  386. #endif
  387. case EAI_FAIL: return "non-recoverable failure in name resolution";
  388. case EAI_FAMILY: return "ai_family not supported";
  389. case EAI_MEMORY: return "memory allocation failure";
  390. case EAI_NONAME:
  391. return "host or service not provided, or not known";
  392. #ifdef EAI_OVERFLOW
  393. case EAI_OVERFLOW: return "argument buffer overflow";
  394. #endif
  395. #ifdef EAI_PROTOCOL
  396. case EAI_PROTOCOL: return "resolved protocol is unknown";
  397. #endif
  398. case EAI_SERVICE: return "service not supported for socket type";
  399. case EAI_SOCKTYPE: return "ai_socktype not supported";
  400. #ifdef EAI_SYSTEM
  401. case EAI_SYSTEM: return strerror(errno);
  402. #endif
  403. default: return gai_strerror(err);
  404. }
  405. }