more cleanup, lots of comments/questions/debug code added, currently broken
Этот коммит содержится в:
родитель
371c23d833
Коммит
657083f27f
522
src/iperf_api.c
522
src/iperf_api.c
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
100
src/iperf_api.h
100
src/iperf_api.h
@ -13,8 +13,8 @@ struct iperf_interval_results
|
|||||||
struct timeval interval_time;
|
struct timeval interval_time;
|
||||||
float interval_duration;
|
float interval_duration;
|
||||||
#if defined(linux) || defined(__FreeBSD__)
|
#if defined(linux) || defined(__FreeBSD__)
|
||||||
/* include getsockopt(TCP_INFO results here for Linux and FreeBSD */
|
struct tcp_info tcpInfo; /* getsockopt(TCP_INFO) results here for
|
||||||
struct tcp_info tcpInfo;
|
* Linux and FreeBSD stored here */
|
||||||
#endif
|
#endif
|
||||||
struct iperf_interval_results *next;
|
struct iperf_interval_results *next;
|
||||||
void *custom_data;
|
void *custom_data;
|
||||||
@ -32,41 +32,39 @@ struct iperf_stream_result
|
|||||||
|
|
||||||
struct iperf_settings
|
struct iperf_settings
|
||||||
{
|
{
|
||||||
int socket_bufsize; // -w buffer size for setsockopt(), window size for TCP
|
int socket_bufsize; /* window size for TCP */
|
||||||
int socket_snd_bufsize; // overrides bufsize in the send direction
|
int blksize; /* size of read/writes (-l) */
|
||||||
int socket_rcv_bufsize; // overrides bufsize in the receive direction
|
uint64_t rate; /* target data rate, UDP only */
|
||||||
|
|
||||||
int blksize; // -l size of each read/write, in UDP this relates directly to packet_size
|
|
||||||
|
|
||||||
uint64_t rate; // target data rate, UDP only
|
|
||||||
int mss; /* for TCP MSS */
|
int mss; /* for TCP MSS */
|
||||||
int ttl;
|
int ttl;
|
||||||
int tos;
|
int tos;
|
||||||
iperf_size_t bytes; /* -n option */
|
iperf_size_t bytes; /* -n option */
|
||||||
char unit_format; /* -f */
|
char unit_format; /* -f */
|
||||||
int state; /* This is state of a stream/test */
|
int state; /* This is state of a stream/test */
|
||||||
char cookie[37];
|
char cookie[37]; /* XXX: why 37? This should be a constant
|
||||||
|
* -blt */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct iperf_stream
|
struct iperf_stream
|
||||||
{
|
{
|
||||||
/* configurable members */
|
/* configurable members */
|
||||||
int local_port; // local port
|
int local_port;
|
||||||
int remote_port; // remote machine port
|
int remote_port;
|
||||||
struct iperf_settings *settings; // pointer to structure settings
|
struct iperf_settings *settings; /* pointer to structure settings */
|
||||||
int protocol; // protocol- TCP/UDP
|
int protocol; /* TCP or UDP */
|
||||||
|
|
||||||
/* non configurable members */
|
/* non configurable members */
|
||||||
struct iperf_stream_result *result; //structure pointer to result
|
struct iperf_stream_result *result; /* structure pointer to result */
|
||||||
int socket; // socket
|
int socket;
|
||||||
struct timer *send_timer;
|
struct timer *send_timer;
|
||||||
|
char *buffer; /* data to send */
|
||||||
|
|
||||||
char *buffer;
|
/*
|
||||||
|
* for udp measurements - This can be a structure outside stream, and
|
||||||
/* for udp measurements - This can be a structure outside stream,
|
* stream can have a pointer to this
|
||||||
and stream can have a pointer to this */
|
*/
|
||||||
int packet_count;
|
int packet_count;
|
||||||
int stream_id; // stream identity
|
int stream_id; /* stream identity */
|
||||||
double jitter;
|
double jitter;
|
||||||
double prev_transit;
|
double prev_transit;
|
||||||
int outoforder_packets;
|
int outoforder_packets;
|
||||||
@ -87,20 +85,19 @@ struct iperf_stream
|
|||||||
|
|
||||||
struct iperf_test
|
struct iperf_test
|
||||||
{
|
{
|
||||||
char role; // 'c'lient or 's'erver -s / -c
|
char role; /* c' lient or 's' erver */
|
||||||
int protocol;
|
int protocol;
|
||||||
|
char *server_hostname; /* -c option */
|
||||||
char *server_hostname; // arg of -c
|
int server_port;
|
||||||
int server_port; // arg of -p
|
int duration; /* total duration of test (-t flag) */
|
||||||
int duration; // total duration of test -t
|
|
||||||
int listener_sock_tcp;
|
int listener_sock_tcp;
|
||||||
int listener_sock_udp;
|
int listener_sock_udp;
|
||||||
|
|
||||||
/* boolen variables for Options */
|
/* boolen variables for Options */
|
||||||
int daemon; // -D
|
int daemon; /* -D option */
|
||||||
int no_delay; // -N
|
int no_delay; /* -N option */
|
||||||
int print_mss; // -m
|
int print_mss; /* -m option */
|
||||||
int domain; // -V
|
int domain; /* -V option */
|
||||||
|
|
||||||
/* Select related parameters */
|
/* Select related parameters */
|
||||||
int max_fd;
|
int max_fd;
|
||||||
@ -110,17 +107,16 @@ struct iperf_test
|
|||||||
|
|
||||||
int (*accept) (struct iperf_test *);
|
int (*accept) (struct iperf_test *);
|
||||||
struct iperf_stream *(*new_stream) (struct iperf_test *);
|
struct iperf_stream *(*new_stream) (struct iperf_test *);
|
||||||
|
int stats_interval; /* time interval to gather stats (-i) */
|
||||||
int stats_interval; // time interval to gather stats -i
|
void *(*stats_callback) (struct iperf_test *); /* callback function
|
||||||
void *(*stats_callback)(struct iperf_test *); // callback function pointer for stats
|
* pointer for stats */
|
||||||
|
int reporter_interval;/* time interval for reporter */
|
||||||
int reporter_interval; // time interval for reporter
|
char *(*reporter_callback) (struct iperf_test *); /* callback function
|
||||||
char *(*reporter_callback)(struct iperf_test *); // callback function pointer for reporter
|
* pointer for reporter */
|
||||||
int reporter_fd; // file descriptor for reporter
|
int reporter_fd; /* file descriptor for reporter */
|
||||||
|
int num_streams; /* total streams in the test (-P) */
|
||||||
int num_streams; // total streams in the test -P
|
|
||||||
int tcp_info; /* display getsockopt(TCP_INFO) results */
|
int tcp_info; /* display getsockopt(TCP_INFO) results */
|
||||||
struct iperf_stream *streams; // pointer to list of struct stream
|
struct iperf_stream *streams; /* pointer to list of struct stream */
|
||||||
struct iperf_settings *default_settings;
|
struct iperf_settings *default_settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -141,17 +137,23 @@ struct param_exchange
|
|||||||
int send_window;
|
int send_window;
|
||||||
int mss;
|
int mss;
|
||||||
char format;
|
char format;
|
||||||
char cookie[37];
|
char cookie[37]; /* size 37 makes total size 64 */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum
|
||||||
|
{
|
||||||
|
/* default settings */
|
||||||
Ptcp = SOCK_STREAM,
|
Ptcp = SOCK_STREAM,
|
||||||
Pudp = SOCK_DGRAM,
|
Pudp = SOCK_DGRAM,
|
||||||
|
PORT = 5001, /* default port to listen on */
|
||||||
uS_TO_NS = 1000,
|
uS_TO_NS = 1000,
|
||||||
RATE = 1000000,
|
SEC_TO_US = 1000000,
|
||||||
MAX_BUFFER_SIZE =10,
|
RATE = 1024 * 1024, /* 1 Mbps */
|
||||||
DEFAULT_UDP_BLKSIZE = 1470,
|
DURATION = 10, /* seconds */
|
||||||
DEFAULT_TCP_BLKSIZE = 8192,
|
DEFAULT_UDP_BLKSIZE = 1450, /* 1 packet per ethernet frame, IPV6 too */
|
||||||
|
DEFAULT_TCP_BLKSIZE = 256 * 1024, /* default read/write block size */
|
||||||
|
|
||||||
|
/* other useful constants */
|
||||||
TEST_START = 1,
|
TEST_START = 1,
|
||||||
TEST_RUNNING = 2,
|
TEST_RUNNING = 2,
|
||||||
RESULT_REQUEST = 3,
|
RESULT_REQUEST = 3,
|
||||||
@ -163,7 +165,6 @@ enum {
|
|||||||
ALL_STREAMS_END = 9,
|
ALL_STREAMS_END = 9,
|
||||||
PARAM_EXCHANGE = 10,
|
PARAM_EXCHANGE = 10,
|
||||||
ACCESS_DENIED = -1,
|
ACCESS_DENIED = -1,
|
||||||
SEC_TO_US = 1000000,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SEC_TO_NS 1000000000 /* too big for enum on some platforms */
|
#define SEC_TO_NS 1000000000 /* too big for enum on some platforms */
|
||||||
@ -276,7 +277,7 @@ int iperf_udp_recv(struct iperf_stream *sp);
|
|||||||
/**
|
/**
|
||||||
* iperf_tcp_send -- sends the client data for TCP
|
* iperf_tcp_send -- sends the client data for TCP
|
||||||
* and the Param/result message exchanges
|
* and the Param/result message exchanges
|
||||||
*returns bytes sent
|
* returns: bytes sent
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int iperf_tcp_send(struct iperf_stream * sp);
|
int iperf_tcp_send(struct iperf_stream * sp);
|
||||||
@ -284,7 +285,7 @@ int iperf_tcp_send(struct iperf_stream *sp);
|
|||||||
/**
|
/**
|
||||||
* iperf_udp_send -- sends the client data for UDP
|
* iperf_udp_send -- sends the client data for UDP
|
||||||
*
|
*
|
||||||
*returns bytes sent
|
* returns: bytes sent
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int iperf_udp_send(struct iperf_stream * sp);
|
int iperf_udp_send(struct iperf_stream * sp);
|
||||||
@ -388,4 +389,3 @@ void iperf_init_stream(struct iperf_stream *sp, struct iperf_test *testp);
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void iperf_free_stream(struct iperf_test * test, struct iperf_stream * sp);
|
void iperf_free_stream(struct iperf_test * test, struct iperf_stream * sp);
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
/* make connection to server */
|
||||||
int
|
int
|
||||||
netdial(int proto, char *client, int port)
|
netdial(int proto, char *client, int port)
|
||||||
{
|
{
|
||||||
@ -16,6 +17,7 @@ netdial(int proto, char *client, int port)
|
|||||||
struct sockaddr_in sa;
|
struct sockaddr_in sa;
|
||||||
socklen_t sn;
|
socklen_t sn;
|
||||||
|
|
||||||
|
/* XXX: should this be called server?? -blt */
|
||||||
if ((hent = gethostbyname(client)) == 0)
|
if ((hent = gethostbyname(client)) == 0)
|
||||||
{
|
{
|
||||||
perror("gethostbyname");
|
perror("gethostbyname");
|
||||||
|
256
src/socket.c
256
src/socket.c
@ -1,256 +0,0 @@
|
|||||||
/*---------------------------------------------------------------
|
|
||||||
* 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
|
|
||||||
* ________________________________________________________________
|
|
||||||
*
|
|
||||||
* socket.c
|
|
||||||
* by Mark Gates <mgates@nlanr.net>
|
|
||||||
* -------------------------------------------------------------------
|
|
||||||
* set/getsockopt
|
|
||||||
* ------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
#include "headers.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
|
||||||
* If req_mss > 0, set the TCP maximum segment size for sock.
|
|
||||||
* Otherwise leave it as the system default.
|
|
||||||
* ------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
const char warn_mss_fail[] = "\
|
|
||||||
WARNING: attempt to set TCP maxmimum segment size to %d failed.\n\
|
|
||||||
Setting the MSS may not be implemented on this OS.\n";
|
|
||||||
|
|
||||||
const char warn_mss_notset[] =
|
|
||||||
"WARNING: attempt to set TCP maximum segment size to %d, but got %d\n";
|
|
||||||
|
|
||||||
void
|
|
||||||
setsock_tcp_mss(int sock, int req_mss)
|
|
||||||
{
|
|
||||||
#ifdef TCP_MAXSEG
|
|
||||||
int rc;
|
|
||||||
int new_mss;
|
|
||||||
Socklen_t len;
|
|
||||||
|
|
||||||
assert(sock != INVALID_SOCKET);
|
|
||||||
|
|
||||||
if (req_mss > 0)
|
|
||||||
{
|
|
||||||
/* set */
|
|
||||||
new_mss = req_mss;
|
|
||||||
len = sizeof(new_mss);
|
|
||||||
rc = setsockopt(sock, IPPROTO_TCP, TCP_MAXSEG, (char *) &new_mss, len);
|
|
||||||
if (rc == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
fprintf(stderr, warn_mss_fail, new_mss);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* verify results */
|
|
||||||
rc = getsockopt(sock, IPPROTO_TCP, TCP_MAXSEG, (char *) &new_mss, &len);
|
|
||||||
WARN_errno(rc == SOCKET_ERROR, "getsockopt TCP_MAXSEG");
|
|
||||||
if (new_mss != req_mss)
|
|
||||||
{
|
|
||||||
fprintf(stderr, warn_mss_notset, req_mss, new_mss);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
|
||||||
* returns the TCP maximum segment size
|
|
||||||
* ------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
int
|
|
||||||
getsock_tcp_mss(int sock)
|
|
||||||
{
|
|
||||||
int mss = 0;
|
|
||||||
|
|
||||||
#ifdef TCP_MAXSEG
|
|
||||||
int rc;
|
|
||||||
Socklen_t len;
|
|
||||||
assert(sock >= 0);
|
|
||||||
|
|
||||||
/* query for MSS */
|
|
||||||
len = sizeof(mss);
|
|
||||||
rc = getsockopt(sock, IPPROTO_TCP, TCP_MAXSEG, (char *) &mss, &len);
|
|
||||||
WARN_errno(rc == SOCKET_ERROR, "getsockopt TCP_MAXSEG");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return mss;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
|
||||||
* returns the TCP window size (on the sending buffer, SO_SNDBUF),
|
|
||||||
* or -1 on error.
|
|
||||||
* ------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
int
|
|
||||||
getsock_tcp_windowsize(int inSock, int inSend)
|
|
||||||
{
|
|
||||||
int theTCPWin = 0;
|
|
||||||
|
|
||||||
#ifdef SO_SNDBUF
|
|
||||||
int rc;
|
|
||||||
Socklen_t len;
|
|
||||||
|
|
||||||
/* 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)
|
|
||||||
{
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return theTCPWin;
|
|
||||||
}
|
|
@ -57,14 +57,10 @@
|
|||||||
* removed some cruft
|
* removed some cruft
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------
|
/* -------------------------------------------------------------------
|
||||||
* If bufsize > 0, set the TCP window size (via the socket buffer
|
* If bufsize > 0, set the TCP window size (via the socket buffer
|
||||||
* sizes) for sock. Otherwise leave it as the system default.
|
* sizes) for sock. Otherwise leave it as the system default.
|
||||||
@ -75,12 +71,12 @@ extern "C"
|
|||||||
* This now works on UNICOS also, by setting TCP_WINSHIFT.
|
* This now works on UNICOS also, by setting TCP_WINSHIFT.
|
||||||
* This now works on AIX, by enabling RFC1323.
|
* This now works on AIX, by enabling RFC1323.
|
||||||
* returns -1 on error, 0 on no error.
|
* returns -1 on error, 0 on no error.
|
||||||
* ------------------------------------------------------------------- */
|
* -------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
set_tcp_windowsize(int sock, int bufsize, int dir)
|
set_tcp_windowsize(int sock, int bufsize, int dir)
|
||||||
{
|
{
|
||||||
#ifdef SO_SNDBUF
|
|
||||||
int rc;
|
int rc;
|
||||||
int newbufsize;
|
int newbufsize;
|
||||||
|
|
||||||
@ -88,61 +84,18 @@ extern "C"
|
|||||||
|
|
||||||
if (bufsize > 0)
|
if (bufsize > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef TCP_WINSHIFT
|
|
||||||
/* XXX: audit -- do we care about UNICOS? */
|
|
||||||
/* UNICOS requires setting the winshift explicitly */
|
|
||||||
if (bufsize > 65535)
|
|
||||||
{
|
|
||||||
int winshift = 0;
|
|
||||||
int scaledwin = bufsize >> 16;
|
|
||||||
while (scaledwin > 0)
|
|
||||||
{
|
|
||||||
scaledwin >>= 1;
|
|
||||||
winshift++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set TCP window shift */
|
|
||||||
rc = setsockopt(sock, 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 (bufsize > 65535)
|
|
||||||
{
|
|
||||||
/* enable RFC 1323 */
|
|
||||||
int on = 1;
|
|
||||||
rc = setsockopt(sock, IPPROTO_TCP, TCP_RFC1323,
|
|
||||||
(char *) &on, sizeof(on));
|
|
||||||
if (rc < 0)
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
#endif /* TCP_RFC1323 */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* note: results are verified after connect() or listen(), since
|
* note: results are verified after connect() or listen(), since
|
||||||
* some OS's don't show the corrected value until then.
|
* some OS's don't show the corrected value until then.
|
||||||
*/
|
*/
|
||||||
|
printf("Setting TCP buffer to size: %d\n", bufsize);
|
||||||
newbufsize = bufsize;
|
newbufsize = bufsize;
|
||||||
rc = setsockopt(sock, SOL_SOCKET, dir, (char *) &newbufsize, sizeof newbufsize);
|
rc = setsockopt(sock, SOL_SOCKET, dir, (char *) &newbufsize, sizeof newbufsize);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
} else {
|
||||||
|
printf("Using default TCP buffer size and assuming OS will do autotuning \n");
|
||||||
}
|
}
|
||||||
#endif /* SO_SNDBUF */
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -153,11 +106,10 @@ extern "C"
|
|||||||
* ------------------------------------------------------------------- */
|
* ------------------------------------------------------------------- */
|
||||||
|
|
||||||
int
|
int
|
||||||
getsock_tcp_windowsize(int sock, int dir)
|
get_tcp_windowsize(int sock, int dir)
|
||||||
{
|
{
|
||||||
int bufsize = 0;
|
int bufsize = 0;
|
||||||
|
|
||||||
#ifdef SO_SNDBUF
|
|
||||||
int rc;
|
int rc;
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
|
|
||||||
@ -167,12 +119,7 @@ extern "C"
|
|||||||
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
#endif
|
|
||||||
|
|
||||||
return bufsize;
|
return bufsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* end extern "C" */
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
int set_tcp_windowsize(int sock, int bufsize, int dir);
|
int set_tcp_windowsize(int sock, int bufsize, int dir);
|
||||||
int getsock_tcp_windowsize(int sock, int dir);
|
int get_tcp_windowsize(int sock, int dir);
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user