diff options
author | Nick Mathewson <nickm@torproject.org> | 2018-09-20 12:46:47 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-09-20 12:46:47 -0400 |
commit | 1c1e84281db6a5a8cd2a66c63481e4df316c44d5 (patch) | |
tree | ca83484d16d9420122a5803e6a0d7709dcf2776b /src/lib/net/socket.c | |
parent | bd6007d8986d851bb9e76fc2d9a72143a03f04ac (diff) | |
download | tor-1c1e84281db6a5a8cd2a66c63481e4df316c44d5.tar.gz tor-1c1e84281db6a5a8cd2a66c63481e4df316c44d5.zip |
Add a tor_release_socket_ownership() function.
Diffstat (limited to 'src/lib/net/socket.c')
-rw-r--r-- | src/lib/net/socket.c | 88 |
1 files changed, 53 insertions, 35 deletions
diff --git a/src/lib/net/socket.c b/src/lib/net/socket.c index 06421b080d..cd7c9685cd 100644 --- a/src/lib/net/socket.c +++ b/src/lib/net/socket.c @@ -142,41 +142,6 @@ tor_close_socket_simple(tor_socket_t s) return r; } -/** As tor_close_socket_simple(), but keeps track of the number - * of open sockets. Returns 0 on success, -1 on failure. */ -MOCK_IMPL(int, -tor_close_socket,(tor_socket_t s)) -{ - int r = tor_close_socket_simple(s); - - socket_accounting_lock(); -#ifdef DEBUG_SOCKET_COUNTING - if (s > max_socket || ! bitarray_is_set(open_sockets, s)) { - log_warn(LD_BUG, "Closing a socket (%d) that wasn't returned by tor_open_" - "socket(), or that was already closed or something.", s); - } else { - tor_assert(open_sockets && s <= max_socket); - bitarray_clear(open_sockets, s); - } -#endif /* defined(DEBUG_SOCKET_COUNTING) */ - if (r == 0) { - --n_sockets_open; - } else { -#ifdef _WIN32 - if (r != WSAENOTSOCK) - --n_sockets_open; -#else - if (r != EBADF) - --n_sockets_open; // LCOV_EXCL_LINE -- EIO and EINTR too hard to force. -#endif /* defined(_WIN32) */ - r = -1; - } - - tor_assert_nonfatal(n_sockets_open >= 0); - socket_accounting_unlock(); - return r; -} - /** @{ */ #ifdef DEBUG_SOCKET_COUNTING /** Helper: if DEBUG_SOCKET_COUNTING is enabled, remember that <b>s</b> is @@ -201,11 +166,50 @@ mark_socket_open(tor_socket_t s) } bitarray_set(open_sockets, s); } +static inline void +mark_socket_closed(tor_socket_t s) +{ + if (s > max_socket || ! bitarray_is_set(open_sockets, s)) { + log_warn(LD_BUG, "Closing a socket (%d) that wasn't returned by tor_open_" + "socket(), or that was already closed or something.", s); + } else { + tor_assert(open_sockets && s <= max_socket); + bitarray_clear(open_sockets, s); + } +} #else /* !(defined(DEBUG_SOCKET_COUNTING)) */ #define mark_socket_open(s) ((void) (s)) +#define mark_socket_closed(s) ((void) (s)) #endif /* defined(DEBUG_SOCKET_COUNTING) */ /** @} */ +/** As tor_close_socket_simple(), but keeps track of the number + * of open sockets. Returns 0 on success, -1 on failure. */ +MOCK_IMPL(int, +tor_close_socket,(tor_socket_t s)) +{ + int r = tor_close_socket_simple(s); + + socket_accounting_lock(); + mark_socket_closed(s); + if (r == 0) { + --n_sockets_open; + } else { +#ifdef _WIN32 + if (r != WSAENOTSOCK) + --n_sockets_open; +#else + if (r != EBADF) + --n_sockets_open; // LCOV_EXCL_LINE -- EIO and EINTR too hard to force. +#endif /* defined(_WIN32) */ + r = -1; + } + + tor_assert_nonfatal(n_sockets_open >= 0); + socket_accounting_unlock(); + return r; +} + /** As socket(), but counts the number of open sockets. */ MOCK_IMPL(tor_socket_t, tor_open_socket,(int domain, int type, int protocol)) @@ -307,6 +311,20 @@ tor_take_socket_ownership(tor_socket_t s) socket_accounting_unlock(); } +/** + * For socket accounting: declare that we are no longer the owner of the + * socket <b>s</b>. This will prevent us from overallocating sockets, and + * prevent us from asserting later when we close the socket <b>s</b>. + */ +void +tor_release_socket_ownership(tor_socket_t s) +{ + socket_accounting_lock(); + --n_sockets_open; + mark_socket_closed(s); + socket_accounting_unlock(); +} + /** As accept(), but counts the number of open sockets. */ tor_socket_t tor_accept_socket(tor_socket_t sockfd, struct sockaddr *addr, socklen_t *len) |