aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormoteus <mimir@newmail.ru>2013-05-28 14:06:18 +0400
committermoteus <mimir@newmail.ru>2013-05-28 14:06:18 +0400
commit5167ddaf499cf198b10208a2f76c27629e99ae1b (patch)
tree193b3a7199ad5b0cfbe8a0d02e5fa469394608b6 /src
parent45ff0e17753201f4c42c714fdc28898c73e59eb9 (diff)
parent2d51d6168874cdb2b72ee4f56f414d9a9a9d92e5 (diff)
downloadluasocket-5167ddaf499cf198b10208a2f76c27629e99ae1b.tar.gz
luasocket-5167ddaf499cf198b10208a2f76c27629e99ae1b.tar.bz2
luasocket-5167ddaf499cf198b10208a2f76c27629e99ae1b.zip
Merge branch 'unstable' of git://github.com/diegonehab/luasocket into moteus-lua52
Diffstat (limited to 'src')
-rw-r--r--src/inet.c78
-rw-r--r--src/inet.h7
-rw-r--r--src/io.h2
-rw-r--r--src/makefile41
-rw-r--r--src/udp.c122
-rw-r--r--src/wsocket.c29
6 files changed, 145 insertions, 134 deletions
diff --git a/src/inet.c b/src/inet.c
index 0469756..1c44464 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -79,24 +79,22 @@ static int inet_global_tohostname(lua_State *L) {
79} 79}
80 80
81static int inet_global_getnameinfo(lua_State *L) { 81static int inet_global_getnameinfo(lua_State *L) {
82 char hbuf[NI_MAXHOST];
83 char sbuf[NI_MAXSERV];
82 int i, ret; 84 int i, ret;
83 char host[1024];
84 char serv[32];
85 struct addrinfo hints; 85 struct addrinfo hints;
86 struct addrinfo *resolved, *iter; 86 struct addrinfo *resolved, *iter;
87 const char *node = luaL_optstring(L, 1, NULL); 87 const char *host = luaL_optstring(L, 1, NULL);
88 const char *service = luaL_optstring(L, 2, NULL); 88 const char *serv = luaL_optstring(L, 2, NULL);
89 89
90 if (!(node || service)) 90 if (!(host || serv))
91 luaL_error(L, "You have to specify a hostname, a service, or both"); 91 luaL_error(L, "host and serv cannot be both nil");
92 92
93 memset(&hints, 0, sizeof(hints)); 93 memset(&hints, 0, sizeof(hints));
94 hints.ai_socktype = SOCK_STREAM; 94 hints.ai_socktype = SOCK_STREAM;
95 hints.ai_family = PF_UNSPEC; 95 hints.ai_family = PF_UNSPEC;
96 96
97 /* getaddrinfo must get a node and a service argument */ 97 ret = getaddrinfo(host, serv, &hints, &resolved);
98 ret = getaddrinfo(node ? node : "127.0.0.1", service ? service : "7",
99 &hints, &resolved);
100 if (ret != 0) { 98 if (ret != 0) {
101 lua_pushnil(L); 99 lua_pushnil(L);
102 lua_pushstring(L, socket_gaistrerror(ret)); 100 lua_pushstring(L, socket_gaistrerror(ret));
@@ -105,19 +103,19 @@ static int inet_global_getnameinfo(lua_State *L) {
105 103
106 lua_newtable(L); 104 lua_newtable(L);
107 for (i = 1, iter = resolved; iter; i++, iter = iter->ai_next) { 105 for (i = 1, iter = resolved; iter; i++, iter = iter->ai_next) {
108 getnameinfo(iter->ai_addr, (socklen_t) iter->ai_addrlen, host, 106 getnameinfo(iter->ai_addr, (socklen_t) iter->ai_addrlen,
109 node ? (socklen_t) sizeof(host) : 0, serv, service ? (socklen_t) sizeof(serv) : 0, 0); 107 hbuf, host? (socklen_t) sizeof(hbuf): 0,
110 108 sbuf, serv? (socklen_t) sizeof(sbuf): 0, 0);
111 if (node) { 109 if (host) {
112 lua_pushnumber(L, i); 110 lua_pushnumber(L, i);
113 lua_pushstring(L, host); 111 lua_pushstring(L, hbuf);
114 lua_settable(L, -3); 112 lua_settable(L, -3);
115 } 113 }
116 } 114 }
117 freeaddrinfo(resolved); 115 freeaddrinfo(resolved);
118 116
119 if (service) { 117 if (serv) {
120 lua_pushstring(L, serv); 118 lua_pushstring(L, sbuf);
121 return 2; 119 return 2;
122 } else { 120 } else {
123 return 1; 121 return 1;
@@ -176,20 +174,10 @@ static int inet_global_getaddrinfo(lua_State *L)
176 } 174 }
177 lua_newtable(L); 175 lua_newtable(L);
178 for (iterator = resolved; iterator; iterator = iterator->ai_next) { 176 for (iterator = resolved; iterator; iterator = iterator->ai_next) {
179 char hbuf[NI_MAXHOST] 177 char hbuf[NI_MAXHOST];
180#ifndef _WINDOWS 178 ret = getnameinfo(iterator->ai_addr, (socklen_t) iterator->ai_addrlen,
181 ,sbuf[NI_MAXSERV] 179 hbuf, (socklen_t) sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
182#endif 180 if (ret){
183 ;
184 ret = getnameinfo(iterator->ai_addr, (socklen_t) iterator->ai_addrlen, hbuf,
185 (socklen_t) sizeof(hbuf),
186#ifdef _WINDOWS
187 NULL, 0,
188#else
189 sbuf, 0,
190#endif
191 NI_NUMERICHOST);
192 if(ret){
193 lua_pushnil(L); 181 lua_pushnil(L);
194 lua_pushstring(L, socket_gaistrerror(ret)); 182 lua_pushstring(L, socket_gaistrerror(ret));
195 return 2; 183 return 2;
@@ -218,7 +206,6 @@ static int inet_global_getaddrinfo(lua_State *L)
218 return 1; 206 return 1;
219} 207}
220 208
221
222/*-------------------------------------------------------------------------*\ 209/*-------------------------------------------------------------------------*\
223* Gets the host name 210* Gets the host name
224\*-------------------------------------------------------------------------*/ 211\*-------------------------------------------------------------------------*/
@@ -237,7 +224,6 @@ static int inet_global_gethostname(lua_State *L)
237} 224}
238 225
239 226
240
241/*=========================================================================*\ 227/*=========================================================================*\
242* Lua methods 228* Lua methods
243\*=========================================================================*/ 229\*=========================================================================*/
@@ -520,7 +506,7 @@ const char *inet_trybind(p_socket ps, const char *address, const char *serv,
520* Some systems do not provide this so that we provide our own. It's not 506* Some systems do not provide this so that we provide our own. It's not
521* marvelously fast, but it works just fine. 507* marvelously fast, but it works just fine.
522\*-------------------------------------------------------------------------*/ 508\*-------------------------------------------------------------------------*/
523#ifdef INET_ATON 509#ifdef LUASOCKET_INET_ATON
524int inet_aton(const char *cp, struct in_addr *inp) 510int inet_aton(const char *cp, struct in_addr *inp)
525{ 511{
526 unsigned int a = 0, b = 0, c = 0, d = 0; 512 unsigned int a = 0, b = 0, c = 0, d = 0;
@@ -547,7 +533,7 @@ int inet_aton(const char *cp, struct in_addr *inp)
547* http://mingw-users.1079350.n2.nabble.com/IPv6-getaddrinfo-amp-inet-ntop-td5891996.html 533* http://mingw-users.1079350.n2.nabble.com/IPv6-getaddrinfo-amp-inet-ntop-td5891996.html
548\*-------------------------------------------------------------------------*/ 534\*-------------------------------------------------------------------------*/
549 535
550#ifdef INET_PTON 536#ifdef LUASOCKET_INET_PTON
551const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) 537const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
552{ 538{
553 if (af == AF_INET) { 539 if (af == AF_INET) {
@@ -572,19 +558,23 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
572 558
573int inet_pton(int af, const char *src, void *dst) 559int inet_pton(int af, const char *src, void *dst)
574{ 560{
575 struct addrinfo hints, *res, *ressave; 561 struct addrinfo hints, *res;
562 int ret = 1;
576 memset(&hints, 0, sizeof(struct addrinfo)); 563 memset(&hints, 0, sizeof(struct addrinfo));
577 hints.ai_family = af; 564 hints.ai_family = af;
578 if (getaddrinfo(src, NULL, &hints, &res) != 0) { 565 hints.ai_flags = AI_NUMERICHOST;
579 return -1; 566 if (getaddrinfo(src, NULL, &hints, &res) != 0) return -1;
580 } 567 if (af == AF_INET) {
581 ressave = res; 568 struct sockaddr_in *in = (struct sockaddr_in *) res->ai_addr;
582 while (res) { 569 memcpy(dst, &in->sin_addr, sizeof(in->sin_addr));
583 memcpy(dst, res->ai_addr, res->ai_addrlen); 570 } else if (af == AF_INET6) {
584 res = res->ai_next; 571 struct sockaddr_in6 *in = (struct sockaddr_in6 *) res->ai_addr;
572 memcpy(dst, &in->sin6_addr, sizeof(in->sin6_addr));
573 } else {
574 ret = -1;
585 } 575 }
586 freeaddrinfo(ressave); 576 freeaddrinfo(res);
587 return 0; 577 return ret;
588} 578}
589 579
590#endif 580#endif
diff --git a/src/inet.h b/src/inet.h
index 252e293..1f1a96a 100644
--- a/src/inet.h
+++ b/src/inet.h
@@ -19,8 +19,7 @@
19#include "timeout.h" 19#include "timeout.h"
20 20
21#ifdef _WIN32 21#ifdef _WIN32
22#define INET_ATON 22#define LUASOCKET_INET_ATON
23#define INET_PTON
24#endif 23#endif
25 24
26int inet_open(lua_State *L); 25int inet_open(lua_State *L);
@@ -39,11 +38,11 @@ int inet_meth_getsockname(lua_State *L, p_socket ps, int family);
39int inet_optfamily(lua_State* L, int narg, const char* def); 38int inet_optfamily(lua_State* L, int narg, const char* def);
40int inet_optsocktype(lua_State* L, int narg, const char* def); 39int inet_optsocktype(lua_State* L, int narg, const char* def);
41 40
42#ifdef INET_ATON 41#ifdef LUASOCKET_INET_ATON
43int inet_aton(const char *cp, struct in_addr *inp); 42int inet_aton(const char *cp, struct in_addr *inp);
44#endif 43#endif
45 44
46#ifdef INET_PTON 45#ifdef LUASOCKET_INET_PTON
47const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt); 46const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
48int inet_pton(int af, const char *src, void *dst); 47int inet_pton(int af, const char *src, void *dst);
49#endif 48#endif
diff --git a/src/io.h b/src/io.h
index 8cca08a..76a3e58 100644
--- a/src/io.h
+++ b/src/io.h
@@ -22,7 +22,7 @@ enum {
22 IO_DONE = 0, /* operation completed successfully */ 22 IO_DONE = 0, /* operation completed successfully */
23 IO_TIMEOUT = -1, /* operation timed out */ 23 IO_TIMEOUT = -1, /* operation timed out */
24 IO_CLOSED = -2, /* the connection has been closed */ 24 IO_CLOSED = -2, /* the connection has been closed */
25 IO_UNKNOWN = -3 25 IO_UNKNOWN = -3
26}; 26};
27 27
28/* interface to error message function */ 28/* interface to error message function */
diff --git a/src/makefile b/src/makefile
index fbb26a0..94a2f9f 100644
--- a/src/makefile
+++ b/src/makefile
@@ -63,12 +63,13 @@ LDIR_mingw?=lua/$(LUAV)/lua
63# LUAINC_win32: 63# LUAINC_win32:
64# LUALIB_win32: 64# LUALIB_win32:
65# where lua headers and libraries are found for win32 builds 65# where lua headers and libraries are found for win32 builds
66LUAINC_win32?="../../lua-5.1.3/src" 66LUAINC_win32_base?=
67LUALIB_win32?=/LIBPATH:"../../lua-5.1.3" lua$(LUAV).lib 67LUAINC_win32?=$(LUAINC_win32_base)/lua/$(LUAV)
68 68PLATFORM_win32?=Release
69LUAPREFIX_win32?= 69LUAPREFIX_win32?=
70CDIR_win32?=lua/$(LUAV) 70CDIR_win32?=lua/$(LUAV)/$(PLATFORM_win32)
71LDIR_win32?=lua/$(LUAV)/lua 71LDIR_win32?=lua/$(LUAV)/$(PLATFORM_win32)/lua
72LUALIB_win32?=$(LUAPREFIX_win32)/lua/$(LUAV)/$(PLATFORM_win32)
72 73
73# prefix: /usr/local /usr /opt/local /sw 74# prefix: /usr/local /usr /opt/local /sw
74# the top of the default install tree 75# the top of the default install tree
@@ -154,12 +155,12 @@ SOCKET_linux=usocket.o
154SO_mingw=dll 155SO_mingw=dll
155O_mingw=o 156O_mingw=o
156CC_mingw=gcc 157CC_mingw=gcc
157DEF_mingw= -DLUASOCKET_$(DEBUG) -DLUA_COMPAT_MODULE -DWINVER=0x0501 \ 158DEF_mingw= -DLUASOCKET_INET_PTON -DLUASOCKET_$(DEBUG) -DLUA_COMPAT_MODULE \
158 -DLUASOCKET_API='__declspec(dllexport)' \ 159 -DWINVER=0x0501 -DLUASOCKET_API='__declspec(dllexport)' \
159 -DMIME_API='__declspec(dllexport)' 160 -DMIME_API='__declspec(dllexport)'
160CFLAGS_mingw= -I$(LUAINC) $(DEF) -pedantic -Wall -O2 -fno-common \ 161CFLAGS_mingw= -I$(LUAINC) $(DEF) -pedantic -Wall -O2 -fno-common \
161 -fvisibility=hidden 162 -fvisibility=hidden
162LDFLAGS_mingw= $(LUALIB) -shared -Wl,-s -lwsock32 -lws2_32 -o 163LDFLAGS_mingw= $(LUALIB) -shared -Wl,-s -lws2_32 -o
163LD_mingw=gcc 164LD_mingw=gcc
164SOCKET_mingw=wsocket.o 165SOCKET_mingw=wsocket.o
165 166
@@ -170,23 +171,25 @@ SOCKET_mingw=wsocket.o
170SO_win32=dll 171SO_win32=dll
171O_win32=obj 172O_win32=obj
172CC_win32=cl 173CC_win32=cl
173DEF_win32= /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" \ 174DEF_win32= //D "WIN32" //D "NDEBUG" //D "_WINDOWS" //D "_USRDLL" \
174 /D "LUASOCKET_API=__declspec(dllexport)" /D "_CRT_SECURE_NO_WARNINGS" \ 175 //D "LUASOCKET_API=__declspec(dllexport)" //D "_CRT_SECURE_NO_WARNINGS" \
175 /D "_WINDLL" /D "LUA_COMPAT_MODULE" /D "MIME_API=__declspec(dllexport)" \ 176 //D "_WINDLL" //D "LUA_COMPAT_MODULE" \
176 /D "LUASOCKET_$(DEBUG)" 177 //D "MIME_API=__declspec(dllexport)" \
177CFLAGS_win32=/I "$(LUAINC)" $(DEF) /O2 /Ot /MD /W3 /nologo 178 //D "LUASOCKET_$(DEBUG)"
178LDFLAGS_win32= /nologo /link /NOLOGO /DLL /INCREMENTAL:NO \ 179CFLAGS_win32=//I "$(LUAINC)" $(DEF) //O2 //Ot //MD //W3 //nologo
179 /MANIFEST /MANIFESTFILE:"intermediate.manifest" \ 180LDFLAGS_win32= //nologo //link //NOLOGO //DLL //INCREMENTAL:NO \
180 /MANIFESTUAC:"level='asInvoker' uiAccess='false'" \ 181 //MANIFEST //MANIFESTFILE:"intermediate.manifest" \
181 /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /DYNAMICBASE:NO \ 182 //MANIFESTUAC:"level='asInvoker' uiAccess='false'" \
182 /MACHINE:X86 $(LUALIB) ws2_32.lib /OUT: 183 //SUBSYSTEM:WINDOWS //OPT:REF //OPT:ICF //DYNAMICBASE:NO \
184 //MACHINE:X86 /LIBPATH:"$(shell cmd //c echo $(LUALIB))" \
185 lua$(subst .,,$(LUAV)).lib ws2_32.lib //OUT:
183LD_win32=cl 186LD_win32=cl
184SOCKET_win32=wsocket.obj 187SOCKET_win32=wsocket.obj
185 188
186.SUFFIXES: .obj 189.SUFFIXES: .obj
187 190
188.c.obj: 191.c.obj:
189 $(CC) $(CFLAGS) /Fo"$@" /c $< 192 $(CC) $(CFLAGS) //Fo"$@" //c $<
190 193
191#------ 194#------
192# Output file names 195# Output file names
diff --git a/src/udp.c b/src/udp.c
index 2a51d1c..d48f6fe 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -155,31 +155,31 @@ static int meth_sendto(lua_State *L) {
155 p_timeout tm = &udp->tm; 155 p_timeout tm = &udp->tm;
156 int err; 156 int err;
157 switch (udp->family) { 157 switch (udp->family) {
158 case PF_INET: { 158 case PF_INET: {
159 struct sockaddr_in addr; 159 struct sockaddr_in addr;
160 memset(&addr, 0, sizeof(addr)); 160 memset(&addr, 0, sizeof(addr));
161 if (!inet_pton(AF_INET, ip, &addr.sin_addr)) 161 if (inet_pton(AF_INET, ip, &addr.sin_addr) != 1)
162 luaL_argerror(L, 3, "invalid ip address"); 162 luaL_argerror(L, 3, "invalid ip address");
163 addr.sin_family = AF_INET; 163 addr.sin_family = AF_INET;
164 addr.sin_port = htons(port); 164 addr.sin_port = htons(port);
165 timeout_markstart(tm); 165 timeout_markstart(tm);
166 err = socket_sendto(&udp->sock, data, count, &sent, 166 err = socket_sendto(&udp->sock, data, count, &sent,
167 (SA *) &addr, sizeof(addr), tm); 167 (SA *) &addr, sizeof(addr), tm);
168 break; 168 break;
169 } 169 }
170 case PF_INET6: { 170 case PF_INET6: {
171 struct sockaddr_in6 addr; 171 struct sockaddr_in6 addr;
172 memset(&addr, 0, sizeof(addr)); 172 memset(&addr, 0, sizeof(addr));
173 if (!inet_pton(AF_INET6, ip, &addr.sin6_addr)) 173 if (inet_pton(AF_INET6, ip, &addr.sin6_addr) != 1)
174 luaL_argerror(L, 3, "invalid ip address"); 174 luaL_argerror(L, 3, "invalid ip address");
175 addr.sin6_family = AF_INET6; 175 addr.sin6_family = AF_INET6;
176 addr.sin6_port = htons(port); 176 addr.sin6_port = htons(port);
177 timeout_markstart(tm); 177 timeout_markstart(tm);
178 err = socket_sendto(&udp->sock, data, count, &sent, 178 err = socket_sendto(&udp->sock, data, count, &sent,
179 (SA *) &addr, sizeof(addr), tm); 179 (SA *) &addr, sizeof(addr), tm);
180 break; 180 break;
181 } 181 }
182 default: 182 default:
183 lua_pushnil(L); 183 lua_pushnil(L);
184 lua_pushfstring(L, "unknown family %d", udp->family); 184 lua_pushfstring(L, "unknown family %d", udp->family);
185 return 2; 185 return 2;
@@ -229,38 +229,40 @@ static int meth_receivefrom(lua_State *L) {
229 timeout_markstart(tm); 229 timeout_markstart(tm);
230 count = MIN(count, sizeof(buffer)); 230 count = MIN(count, sizeof(buffer));
231 switch (udp->family) { 231 switch (udp->family) {
232 case PF_INET: { 232 case PF_INET: {
233 struct sockaddr_in addr; 233 struct sockaddr_in addr;
234 socklen_t addr_len = sizeof(addr); 234 socklen_t addr_len = sizeof(addr);
235 err = socket_recvfrom(&udp->sock, buffer, count, &got, 235 err = socket_recvfrom(&udp->sock, buffer, count, &got,
236 (SA *) &addr, &addr_len, tm); 236 (SA *) &addr, &addr_len, tm);
237 /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ 237 /* Unlike TCP, recv() of zero is not closed,
238 if (err == IO_CLOSED) 238 * but a zero-length packet. */
239 err = IO_DONE; 239 if (err == IO_CLOSED)
240 if (err == IO_DONE) { 240 err = IO_DONE;
241 char addrstr[INET_ADDRSTRLEN]; 241 if (err == IO_DONE) {
242 lua_pushlstring(L, buffer, got); 242 char addrstr[INET_ADDRSTRLEN];
243 if (!inet_ntop(AF_INET, &addr.sin_addr, 243 lua_pushlstring(L, buffer, got);
244 addrstr, sizeof(addrstr))) { 244 if (!inet_ntop(AF_INET, &addr.sin_addr,
245 lua_pushnil(L); 245 addrstr, sizeof(addrstr))) {
246 lua_pushstring(L, "invalid source address"); 246 lua_pushnil(L);
247 return 2; 247 lua_pushstring(L, "invalid source address");
248 } 248 return 2;
249 lua_pushstring(L, addrstr); 249 }
250 lua_pushnumber(L, ntohs(addr.sin_port)); 250 lua_pushstring(L, addrstr);
251 return 3; 251 lua_pushnumber(L, ntohs(addr.sin_port));
252 } 252 return 3;
253 break; 253 }
254 } 254 break;
255 case PF_INET6: { 255 }
256 struct sockaddr_in6 addr; 256 case PF_INET6: {
257 socklen_t addr_len = sizeof(addr); 257 struct sockaddr_in6 addr;
258 err = socket_recvfrom(&udp->sock, buffer, count, &got, 258 socklen_t addr_len = sizeof(addr);
259 (SA *) &addr, &addr_len, tm); 259 err = socket_recvfrom(&udp->sock, buffer, count, &got,
260 /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ 260 (SA *) &addr, &addr_len, tm);
261 if (err == IO_CLOSED) 261 /* Unlike TCP, recv() of zero is not closed,
262 * but a zero-length packet. */
263 if (err == IO_CLOSED)
262 err = IO_DONE; 264 err = IO_DONE;
263 if (err == IO_DONE) { 265 if (err == IO_DONE) {
264 char addrstr[INET6_ADDRSTRLEN]; 266 char addrstr[INET6_ADDRSTRLEN];
265 lua_pushlstring(L, buffer, got); 267 lua_pushlstring(L, buffer, got);
266 if (!inet_ntop(AF_INET6, &addr.sin6_addr, 268 if (!inet_ntop(AF_INET6, &addr.sin6_addr,
@@ -272,9 +274,9 @@ static int meth_receivefrom(lua_State *L) {
272 lua_pushstring(L, addrstr); 274 lua_pushstring(L, addrstr);
273 lua_pushnumber(L, ntohs(addr.sin6_port)); 275 lua_pushnumber(L, ntohs(addr.sin6_port));
274 return 3; 276 return 3;
275 } 277 }
276 break; 278 break;
277 } 279 }
278 default: 280 default:
279 lua_pushnil(L); 281 lua_pushnil(L);
280 lua_pushfstring(L, "unknown family %d", udp->family); 282 lua_pushfstring(L, "unknown family %d", udp->family);
@@ -413,7 +415,7 @@ static int meth_setsockname(lua_State *L) {
413 const char *address = luaL_checkstring(L, 2); 415 const char *address = luaL_checkstring(L, 2);
414 const char *port = luaL_checkstring(L, 3); 416 const char *port = luaL_checkstring(L, 3);
415 const char *err; 417 const char *err;
416 struct addrinfo bindhints; 418 struct addrinfo bindhints;
417 memset(&bindhints, 0, sizeof(bindhints)); 419 memset(&bindhints, 0, sizeof(bindhints));
418 bindhints.ai_socktype = SOCK_DGRAM; 420 bindhints.ai_socktype = SOCK_DGRAM;
419 bindhints.ai_family = udp->family; 421 bindhints.ai_family = udp->family;
@@ -461,9 +463,9 @@ static int udp_create(lua_State *L, int family) {
461} 463}
462 464
463static int global_create(lua_State *L) { 465static int global_create(lua_State *L) {
464 return udp_create(L, AF_INET); 466 return udp_create(L, AF_INET);
465} 467}
466 468
467static int global_create6(lua_State *L) { 469static int global_create6(lua_State *L) {
468 return udp_create(L, AF_INET6); 470 return udp_create(L, AF_INET6);
469} 471}
diff --git a/src/wsocket.c b/src/wsocket.c
index 65f76bc..b4a4384 100644
--- a/src/wsocket.c
+++ b/src/wsocket.c
@@ -238,8 +238,10 @@ int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,
238/*-------------------------------------------------------------------------*\ 238/*-------------------------------------------------------------------------*\
239* Receive with timeout 239* Receive with timeout
240\*-------------------------------------------------------------------------*/ 240\*-------------------------------------------------------------------------*/
241int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) { 241int socket_recv(p_socket ps, char *data, size_t count, size_t *got,
242 int err; 242 p_timeout tm)
243{
244 int err, prev = IO_DONE;
243 *got = 0; 245 *got = 0;
244 if (*ps == SOCKET_INVALID) return IO_CLOSED; 246 if (*ps == SOCKET_INVALID) return IO_CLOSED;
245 for ( ;; ) { 247 for ( ;; ) {
@@ -250,7 +252,14 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm
250 } 252 }
251 if (taken == 0) return IO_CLOSED; 253 if (taken == 0) return IO_CLOSED;
252 err = WSAGetLastError(); 254 err = WSAGetLastError();
253 if (err != WSAEWOULDBLOCK) return err; 255 /* On UDP, a connreset simply means the previous send failed.
256 * So we try again.
257 * On TCP, it means our socket is now useless, so the error passes.
258 * (We will loop again, exiting because the same error will happen) */
259 if (err != WSAEWOULDBLOCK) {
260 if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;
261 prev = err;
262 }
254 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; 263 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
255 } 264 }
256} 265}
@@ -259,8 +268,9 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm
259* Recvfrom with timeout 268* Recvfrom with timeout
260\*-------------------------------------------------------------------------*/ 269\*-------------------------------------------------------------------------*/
261int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, 270int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
262 SA *addr, socklen_t *len, p_timeout tm) { 271 SA *addr, socklen_t *len, p_timeout tm)
263 int err; 272{
273 int err, prev = IO_DONE;
264 *got = 0; 274 *got = 0;
265 if (*ps == SOCKET_INVALID) return IO_CLOSED; 275 if (*ps == SOCKET_INVALID) return IO_CLOSED;
266 for ( ;; ) { 276 for ( ;; ) {
@@ -271,7 +281,14 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
271 } 281 }
272 if (taken == 0) return IO_CLOSED; 282 if (taken == 0) return IO_CLOSED;
273 err = WSAGetLastError(); 283 err = WSAGetLastError();
274 if (err != WSAEWOULDBLOCK) return err; 284 /* On UDP, a connreset simply means the previous send failed.
285 * So we try again.
286 * On TCP, it means our socket is now useless, so the error passes.
287 * (We will loop again, exiting because the same error will happen) */
288 if (err != WSAEWOULDBLOCK) {
289 if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;
290 prev = err;
291 }
275 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; 292 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
276 } 293 }
277} 294}