From 5668fb5c22e3726e732e4f5160aed93fa2c2b12e Mon Sep 17 00:00:00 2001 From: Leonid Evdokimov Date: Mon, 24 Jan 2011 23:31:52 +0200 Subject: Enforce NODELAY on setsockopt(). --- nodelay.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/nodelay.c b/nodelay.c index 134a95a..c391f65 100644 --- a/nodelay.c +++ b/nodelay.c @@ -13,6 +13,7 @@ #include #include #include +#include #if defined(__GNUC__) && (__GNUC__ >= 3) # define unlikely(x) __builtin_expect (!!(x), 0) @@ -21,13 +22,25 @@ #endif static int (*real_socket)(int, int, int); +static int (*real_setsockopt)(int , int , int , const void *, socklen_t); + +static int nodelay_value; void __attribute__ ((constructor)) nodelay_init(void) { - real_socket = dlsym(RTLD_NEXT, "socket"); + char* nodelay = getenv("NODELAY"); + if (nodelay) + nodelay_value = atoi(nodelay); + else + nodelay_value = 1; + real_socket = dlsym(RTLD_NEXT, "socket"); if (!real_socket || dlerror()) _exit(1); + + real_setsockopt = dlsym(RTLD_NEXT, "setsockopt"); + if (!real_setsockopt || dlerror()) + _exit(1); } int socket(int domain, int type, int protocol) @@ -44,12 +57,27 @@ int socket(int domain, int type, int protocol) type == SOCK_STREAM && domain == PF_INET) { int orig_errno = errno; - int optval = 1; + int optval = nodelay_value; /* don't care too much if it fails */ - setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(int)); + real_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(int)); errno = orig_errno; } return fd; } + +int setsockopt(int sockfd, int level, int optname, const void *poptval, socklen_t optlen) +{ + int optval; + + if (unlikely(!real_socket)) + nodelay_init(); + + optval = nodelay_value; + if (level == IPPROTO_TCP && optname == TCP_NODELAY) { + poptval = &optval; + optlen = sizeof(optval); + } + return real_setsockopt(sockfd, level, optname, poptval, optlen); +} -- cgit v1.2.3-24-ge0c7