diff options
author | Matthew Waters <ystreet00@gmail.com> | 2020-05-05 15:24:54 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-05 17:24:54 +0200 |
commit | de0006f90612bc66a1a71b22c4dae09cd40c1d91 (patch) | |
tree | f6dcd8f0bbd4d480c867b2cc8b00599360ee1f8c /usrsctplib | |
parent | 83dcca61125fce4c94d1279659c9dae07434f469 (diff) | |
download | usrsctp-de0006f90612bc66a1a71b22c4dae09cd40c1d91.tar.gz |
user_recv_thread: set fd to -1 when closing (#461)
Fixes a busy loop of the usrsctp UDP recv thread attempting to shutdown
usrsctp with usrsctp_finish().
Usually, destroying the udp socket in recv_thread_destroy() would result
in the udp receive thread returning an error (-1) with errno set to
(-9) EDABF. In other cases, sometimes recvmsg would return 0 without an
error being reported in errno. My assumption here is that the fd number
would be reused for some other purpose.
Explicitly set the socket/fd variables to -1 when performing a
close()/closesocket() on them so that any future recv*() calls will
return with an error.
Also move the thread closure to the fd close block so that the threads
are definitley closed before we continue.
Diffstat (limited to 'usrsctplib')
-rwxr-xr-x | usrsctplib/netinet/sctp_usrreq.c | 43 | ||||
-rwxr-xr-x | usrsctplib/user_recv_thread.c | 21 |
2 files changed, 21 insertions, 43 deletions
diff --git a/usrsctplib/netinet/sctp_usrreq.c b/usrsctplib/netinet/sctp_usrreq.c index 43cc14bf..ecdc184d 100755 --- a/usrsctplib/netinet/sctp_usrreq.c +++ b/usrsctplib/netinet/sctp_usrreq.c @@ -211,49 +211,6 @@ sctp_finish(void) #if defined(INET) || defined(INET6) recv_thread_destroy(); #endif -#if !defined(__Userspace_os_Windows) -#if defined(INET) || defined(INET6) - if (SCTP_BASE_VAR(userspace_route) != -1) { - pthread_join(SCTP_BASE_VAR(recvthreadroute), NULL); - } -#endif -#endif -#ifdef INET - if (SCTP_BASE_VAR(userspace_rawsctp) != -1) { -#if defined(__Userspace_os_Windows) - WaitForSingleObject(SCTP_BASE_VAR(recvthreadraw), INFINITE); - CloseHandle(SCTP_BASE_VAR(recvthreadraw)); -#else - pthread_join(SCTP_BASE_VAR(recvthreadraw), NULL); -#endif - } - if (SCTP_BASE_VAR(userspace_udpsctp) != -1) { -#if defined(__Userspace_os_Windows) - WaitForSingleObject(SCTP_BASE_VAR(recvthreadudp), INFINITE); - CloseHandle(SCTP_BASE_VAR(recvthreadudp)); -#else - pthread_join(SCTP_BASE_VAR(recvthreadudp), NULL); -#endif - } -#endif -#ifdef INET6 - if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) { -#if defined(__Userspace_os_Windows) - WaitForSingleObject(SCTP_BASE_VAR(recvthreadraw6), INFINITE); - CloseHandle(SCTP_BASE_VAR(recvthreadraw6)); -#else - pthread_join(SCTP_BASE_VAR(recvthreadraw6), NULL); -#endif - } - if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) { -#if defined(__Userspace_os_Windows) - WaitForSingleObject(SCTP_BASE_VAR(recvthreadudp6), INFINITE); - CloseHandle(SCTP_BASE_VAR(recvthreadudp6)); -#else - pthread_join(SCTP_BASE_VAR(recvthreadudp6), NULL); -#endif - } -#endif atomic_cmpset_int(&SCTP_BASE_VAR(timer_thread_should_exit), 0, 1); if (SCTP_BASE_VAR(timer_thread_started)) { #if defined(__Userspace_os_Windows) diff --git a/usrsctplib/user_recv_thread.c b/usrsctplib/user_recv_thread.c index d9e4ac8c..e9ddd820 100755 --- a/usrsctplib/user_recv_thread.c +++ b/usrsctplib/user_recv_thread.c @@ -1456,6 +1456,7 @@ recv_thread_destroy(void) #if defined(INET) || defined(INET6) if (SCTP_BASE_VAR(userspace_route) != -1) { close(SCTP_BASE_VAR(userspace_route)); + pthread_join(SCTP_BASE_VAR(recvthreadroute), NULL); } #endif #endif @@ -1463,15 +1464,25 @@ recv_thread_destroy(void) if (SCTP_BASE_VAR(userspace_rawsctp) != -1) { #if defined(__Userspace_os_Windows) closesocket(SCTP_BASE_VAR(userspace_rawsctp)); + SCTP_BASE_VAR(userspace_rawsctp) = -1; + WaitForSingleObject(SCTP_BASE_VAR(recvthreadraw), INFINITE); + CloseHandle(SCTP_BASE_VAR(recvthreadraw)); #else close(SCTP_BASE_VAR(userspace_rawsctp)); + SCTP_BASE_VAR(userspace_rawsctp) = -1; + pthread_join(SCTP_BASE_VAR(recvthreadraw), NULL); #endif } if (SCTP_BASE_VAR(userspace_udpsctp) != -1) { #if defined(__Userspace_os_Windows) closesocket(SCTP_BASE_VAR(userspace_udpsctp)); + SCTP_BASE_VAR(userspace_udpsctp) = -1; + WaitForSingleObject(SCTP_BASE_VAR(recvthreadudp), INFINITE); + CloseHandle(SCTP_BASE_VAR(recvthreadudp)); #else close(SCTP_BASE_VAR(userspace_udpsctp)); + SCTP_BASE_VAR(userspace_udpsctp) = -1; + pthread_join(SCTP_BASE_VAR(recvthreadudp), NULL); #endif } #endif @@ -1479,15 +1490,25 @@ recv_thread_destroy(void) if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) { #if defined(__Userspace_os_Windows) closesocket(SCTP_BASE_VAR(userspace_rawsctp6)); + SCTP_BASE_VAR(userspace_rawsctp6) = -1; + WaitForSingleObject(SCTP_BASE_VAR(recvthreadraw6), INFINITE); + CloseHandle(SCTP_BASE_VAR(recvthreadraw6)); #else close(SCTP_BASE_VAR(userspace_rawsctp6)); + SCTP_BASE_VAR(userspace_rawsctp6) = -1; + pthread_join(SCTP_BASE_VAR(recvthreadraw6), NULL); #endif } if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) { #if defined(__Userspace_os_Windows) + SCTP_BASE_VAR(userspace_udpsctp6) = -1; closesocket(SCTP_BASE_VAR(userspace_udpsctp6)); + WaitForSingleObject(SCTP_BASE_VAR(recvthreadudp6), INFINITE); + CloseHandle(SCTP_BASE_VAR(recvthreadudp6)); #else close(SCTP_BASE_VAR(userspace_udpsctp6)); + SCTP_BASE_VAR(userspace_udpsctp6) = -1; + pthread_join(SCTP_BASE_VAR(recvthreadudp6), NULL); #endif } #endif |