summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Bright <sean.bright@gmail.com>2017-03-18 13:30:32 -0400
committerSean Bright <sean.bright@gmail.com>2017-03-20 08:55:05 -0400
commitfc71c18a9b572296e171eb6b1f87aee5c2256c8c (patch)
tree8c1123cca9cfe951f7562dcd80a4b8d24e0bb9f6
parentb05d2fda0c8b3473c3d6d7bd1cc0473e2728b744 (diff)
thread safety: Don't use getprotobyname()
POSIX does not require getprotobyname() to be thread safe and some implementations use static memory which causes issues when multiple threads are used. Further, our usage of it today is just to ultimately get IPPROTO_TCP for calls to setsockopt(). So instead we just use IPPROTO_TCP directly. Change-Id: I2e14e58674808f7ce99b2f5e900d0f90d0d8da48
-rw-r--r--channels/chan_skinny.c9
-rw-r--r--include/asterisk/network.h5
-rw-r--r--main/http.c3
-rw-r--r--main/manager.c4
4 files changed, 11 insertions, 10 deletions
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index a3a2f87fb..d1c2b927a 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -7639,7 +7639,6 @@ static void *accept_thread(void *ignore)
struct sockaddr_in sin;
socklen_t sinlen;
struct skinnysession *s;
- struct protoent *p;
int arg = 1;
for (;;) {
@@ -7656,12 +7655,10 @@ static void *accept_thread(void *ignore)
continue;
}
- p = getprotobyname("tcp");
- if(p) {
- if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
- ast_log(LOG_WARNING, "Failed to set Skinny tcp connection to TCP_NODELAY mode: %s\n", strerror(errno));
- }
+ if (setsockopt(as, IPPROTO_TCP, TCP_NODELAY, (char *) &arg, sizeof(arg)) < 0) {
+ ast_log(LOG_WARNING, "Failed to set TCP_NODELAY on Skinny TCP connection: %s\n", strerror(errno));
}
+
if (!(s = ast_calloc(1, sizeof(struct skinnysession)))) {
close(as);
ast_atomic_fetchadd_int(&unauth_sessions, -1);
diff --git a/include/asterisk/network.h b/include/asterisk/network.h
index 3371e5895..5216f4c61 100644
--- a/include/asterisk/network.h
+++ b/include/asterisk/network.h
@@ -86,6 +86,11 @@ const char *ast_inet_ntoa(struct in_addr ia);
#endif
#define inet_ntoa __dont__use__inet_ntoa__use__ast_inet_ntoa__instead__
+#ifdef getprotobyname
+#undef getprotobyname
+#endif
+#define getprotobyname __getprotobyname_is_not_threadsafe__do_not_use__
+
/*! \brief Compares the source address and port of two sockaddr_in */
static force_inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
{
diff --git a/main/http.c b/main/http.c
index 0db6ee7b6..ea85a2823 100644
--- a/main/http.c
+++ b/main/http.c
@@ -1917,9 +1917,8 @@ static void *httpd_helper_thread(void *data)
* This is necessary to prevent delays (caused by buffering) as we
* write to the socket in bits and pieces.
*/
- if (setsockopt(ast_iostream_get_fd(ser->stream), IPPROTO_TCP, TCP_NODELAY, (char *) &arg, sizeof(arg) ) < 0) {
+ if (setsockopt(ast_iostream_get_fd(ser->stream), IPPROTO_TCP, TCP_NODELAY, (char *) &arg, sizeof(arg)) < 0) {
ast_log(LOG_WARNING, "Failed to set TCP_NODELAY on HTTP connection: %s\n", strerror(errno));
- ast_log(LOG_WARNING, "Some HTTP requests may be slow to respond.\n");
}
ast_iostream_nonblock(ser->stream);
diff --git a/main/manager.c b/main/manager.c
index eae1ca52a..c1d73dce7 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -6647,8 +6647,8 @@ static void *session_do(void *data)
/* here we set TCP_NODELAY on the socket to disable Nagle's algorithm.
* This is necessary to prevent delays (caused by buffering) as we
* write to the socket in bits and pieces. */
- if (setsockopt(ast_iostream_get_fd(ser->stream), IPPROTO_TCP, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0) {
- ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY mode: %s\nSome manager actions may be slow to respond.\n", strerror(errno));
+ if (setsockopt(ast_iostream_get_fd(ser->stream), IPPROTO_TCP, TCP_NODELAY, (char *) &arg, sizeof(arg)) < 0) {
+ ast_log(LOG_WARNING, "Failed to set TCP_NODELAY on manager connection: %s\n", strerror(errno));
}
ast_iostream_nonblock(ser->stream);