aboutsummaryrefslogtreecommitdiff
path: root/src/wsocket.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wsocket.c')
-rw-r--r--src/wsocket.c29
1 files changed, 23 insertions, 6 deletions
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}