diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 18:20:54 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 18:20:54 +0000 |
commit | 7c720bec5600a9e607c875c670ca30ed351fa4ba (patch) | |
tree | c38c9bedf07616180feee6b91a1dbea038500b54 /src/tcp_window_size.c | |
parent | Initial commit. (diff) | |
download | iperf-7c720bec5600a9e607c875c670ca30ed351fa4ba.tar.xz iperf-7c720bec5600a9e607c875c670ca30ed351fa4ba.zip |
Adding upstream version 2.1.9+dfsg.upstream/2.1.9+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/tcp_window_size.c')
-rw-r--r-- | src/tcp_window_size.c | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/src/tcp_window_size.c b/src/tcp_window_size.c new file mode 100644 index 0000000..4b5d79b --- /dev/null +++ b/src/tcp_window_size.c @@ -0,0 +1,227 @@ +/*--------------------------------------------------------------- + * Copyright (c) 1999,2000,2001,2002,2003 + * The Board of Trustees of the University of Illinois + * All Rights Reserved. + *--------------------------------------------------------------- + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software (Iperf) and associated + * documentation files (the "Software"), to deal in the Software + * without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and + * the following disclaimers. + * + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials + * provided with the distribution. + * + * + * Neither the names of the University of Illinois, NCSA, + * nor the names of its contributors may be used to endorse + * or promote products derived from this Software without + * specific prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * ________________________________________________________________ + * National Laboratory for Applied Network Research + * National Center for Supercomputing Applications + * University of Illinois at Urbana-Champaign + * http://www.ncsa.uiuc.edu + * ________________________________________________________________ + * + * tcp_window_size.c + * by Mark Gates <mgates@nlanr.net> + * ------------------------------------------------------------------- + * set/getsockopt + * ------------------------------------------------------------------- */ + +#include "headers.h" + +#include "util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------------------------------------------------------------- + * If inTCPWin > 0, set the TCP window size (via the socket buffer + * sizes) for inSock. Otherwise leave it as the system default. + * + * This must be called prior to calling listen() or connect() on + * the socket, for TCP window sizes > 64 KB to be effective. + * + * This now works on UNICOS also, by setting TCP_WINSHIFT. + * This now works on AIX, by enabling RFC1323. + * returns -1 on error, 0 on no error. + * ------------------------------------------------------------------- */ + +int setsock_tcp_windowsize (int inSock, int inTCPWin, int inSend) { +#ifdef SO_SNDBUF + int rc; + int newTCPWin; + + assert(inSock >= 0); + if (inTCPWin > 0) { +#ifdef TCP_WINSHIFT + /* UNICOS requires setting the winshift explicitly */ + if (inTCPWin > 65535) { + int winShift = 0; + int scaledWin = inTCPWin >> 16; + while (scaledWin > 0) { + scaledWin >>= 1; + winShift++; + } + + /* set TCP window shift */ + rc = setsockopt(inSock, IPPROTO_TCP, TCP_WINSHIFT, + (char*) &winShift, sizeof(winShift)); + if (rc < 0) { + return rc; + } + + /* Note: you cannot verify TCP window shift, since it returns + * a structure and not the same integer we use to set it. (ugh) */ + } +#endif /* TCP_WINSHIFT */ + +#ifdef TCP_RFC1323 + /* On AIX, RFC 1323 extensions can be set system-wide, + * using the 'no' network options command. But we can also set them + * per-socket, so let's try just in case. */ + if (inTCPWin > 65535) { + /* enable RFC 1323 */ + int on = 1; + rc = setsockopt(inSock, IPPROTO_TCP, TCP_RFC1323, + (char*) &on, sizeof(on)); + if (rc < 0) { + return rc; + } + } +#endif /* TCP_RFC1323 */ + + if (!inSend) { + /* receive buffer -- set + * note: results are verified after connect() or listen(), + * since some OS's don't show the corrected value until then. */ + newTCPWin = inTCPWin; + rc = setsockopt(inSock, SOL_SOCKET, SO_RCVBUF, + (char*) &newTCPWin, sizeof(newTCPWin)); + } else { + /* send buffer -- set + * note: results are verified after connect() or listen(), + * since some OS's don't show the corrected value until then. */ + newTCPWin = inTCPWin; + rc = setsockopt(inSock, SOL_SOCKET, SO_SNDBUF, + (char*) &newTCPWin, sizeof(newTCPWin)); + } + if (rc < 0) { + return rc; + } + } +#endif /* SO_SNDBUF */ + return 0; +} /* end setsock_tcp_windowsize */ + +/* ------------------------------------------------------------------- + * returns the TCP window size (on the sending buffer, SO_SNDBUF), + * or -1 on error. + * ------------------------------------------------------------------- */ + +int getsock_tcp_windowsize (int inSock, int inSend) { + int rc = -1; +#ifdef SO_SNDBUF + Socklen_t len; + int theTCPWin = 0; + /* send buffer -- query for buffer size */ + len = sizeof(theTCPWin); + if (inSend) { + rc = getsockopt(inSock, SOL_SOCKET, SO_SNDBUF, + (char*) &theTCPWin, &len); + } else { + rc = getsockopt(inSock, SOL_SOCKET, SO_RCVBUF, + (char*) &theTCPWin, &len); + } + if (rc == 0) { + rc = theTCPWin; + } +#endif + return rc; +} /* end getsock_tcp_windowsize */ + +#if HAVE_DECL_TCP_WINDOW_CLAMP +int setsock_tcp_windowclamp (int inSock, int clampsize) { + assert(inSock >= 0); + assert(clampsize > 0); + int rc; + Socklen_t len; + + len = sizeof(clampsize); + rc = setsockopt(inSock, IPPROTO_TCP, TCP_WINDOW_CLAMP, (char*)(&clampsize), len); + WARN_errno(rc == SOCKET_ERROR, "setsockopt TCP_WINDOW_CLAMP"); + return rc; +} + +int getsock_tcp_windowclamp (int inSock) { + assert(inSock >= 0); + int clamp = 0; + int rc; + Socklen_t len; + + /* send buffer -- query for buffer size */ + len = sizeof(clamp); + rc = getsockopt(inSock, IPPROTO_TCP, TCP_WINDOW_CLAMP, (char*)(&clamp), &len); + WARN_errno(rc == SOCKET_ERROR, "getsockopt TCP_WINDOW_CLAMP"); + if (rc < 0) { + return rc; + } + return clamp; +} +#endif + +#if HAVE_DECL_TCP_NOTSENT_LOWAT +int setsock_tcp_notsent_low_watermark (int inSock, int watermark) { + assert(inSock >= 0); + assert(watermark > 0); + int rc; + Socklen_t len; + + len = sizeof(watermark); + rc = setsockopt(inSock, IPPROTO_TCP, TCP_NOTSENT_LOWAT, (char*)(&watermark), len); + WARN_errno(rc == SOCKET_ERROR, "setsockopt TCP_NOTSENT_LOWAT"); + return rc; +} + +int getsock_tcp_notsent_low_watermark (int inSock) { + assert(inSock >= 0); + int watermark = 0; + int rc; + Socklen_t len; + + /* send buffer -- query for buffer size */ + len = sizeof(watermark); + rc = getsockopt(inSock, IPPROTO_TCP, TCP_NOTSENT_LOWAT, (char*)(&watermark), &len); + WARN_errno(rc == SOCKET_ERROR, "getsockopt TCP_NOTSENT_LOWAT"); + if (rc < 0) { + return rc; + } + return watermark; +} +#endif +#ifdef __cplusplus +} /* end extern "C" */ +#endif |