more cleanup, lots of comments/questions/debug code added, currently broken
Этот коммит содержится в:
родитель
371c23d833
Коммит
657083f27f
850
src/iperf_api.c
850
src/iperf_api.c
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
252
src/iperf_api.h
252
src/iperf_api.h
@ -10,148 +10,150 @@ typedef uint64_t iperf_size_t;
|
||||
struct iperf_interval_results
|
||||
{
|
||||
iperf_size_t bytes_transferred;
|
||||
struct timeval interval_time;
|
||||
float interval_duration;
|
||||
struct timeval interval_time;
|
||||
float interval_duration;
|
||||
#if defined(linux) || defined(__FreeBSD__)
|
||||
/* include getsockopt(TCP_INFO results here for Linux and FreeBSD */
|
||||
struct tcp_info tcpInfo;
|
||||
struct tcp_info tcpInfo; /* getsockopt(TCP_INFO) results here for
|
||||
* Linux and FreeBSD stored here */
|
||||
#endif
|
||||
struct iperf_interval_results *next;
|
||||
void * custom_data;
|
||||
void *custom_data;
|
||||
};
|
||||
|
||||
struct iperf_stream_result
|
||||
{
|
||||
iperf_size_t bytes_received;
|
||||
iperf_size_t bytes_sent;
|
||||
iperf_size_t bytes_received;
|
||||
iperf_size_t bytes_sent;
|
||||
struct timeval start_time;
|
||||
struct timeval end_time;
|
||||
struct iperf_interval_results *interval_results;
|
||||
void *data;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct iperf_settings
|
||||
{
|
||||
int socket_bufsize; // -w buffer size for setsockopt(), window size for TCP
|
||||
int socket_snd_bufsize; // overrides bufsize in the send direction
|
||||
int socket_rcv_bufsize; // overrides bufsize in the receive direction
|
||||
|
||||
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 ttl;
|
||||
int tos;
|
||||
iperf_size_t bytes; /* -n option */
|
||||
char unit_format; /* -f */
|
||||
int state; /* This is state of a stream/test */
|
||||
char cookie[37];
|
||||
int socket_bufsize; /* window size for TCP */
|
||||
int blksize; /* size of read/writes (-l) */
|
||||
uint64_t rate; /* target data rate, UDP only */
|
||||
int mss; /* for TCP MSS */
|
||||
int ttl;
|
||||
int tos;
|
||||
iperf_size_t bytes; /* -n option */
|
||||
char unit_format; /* -f */
|
||||
int state; /* This is state of a stream/test */
|
||||
char cookie[37]; /* XXX: why 37? This should be a constant
|
||||
* -blt */
|
||||
};
|
||||
|
||||
struct iperf_stream
|
||||
{
|
||||
/* configurable members */
|
||||
int local_port; // local port
|
||||
int remote_port; // remote machine port
|
||||
struct iperf_settings *settings; // pointer to structure settings
|
||||
int protocol; // protocol- TCP/UDP
|
||||
int local_port;
|
||||
int remote_port;
|
||||
struct iperf_settings *settings; /* pointer to structure settings */
|
||||
int protocol; /* TCP or UDP */
|
||||
|
||||
/* non configurable members */
|
||||
struct iperf_stream_result *result; //structure pointer to result
|
||||
int socket; // socket
|
||||
struct iperf_stream_result *result; /* structure pointer to result */
|
||||
int socket;
|
||||
struct timer *send_timer;
|
||||
char *buffer; /* data to send */
|
||||
|
||||
char *buffer;
|
||||
|
||||
/* for udp measurements - This can be a structure outside stream,
|
||||
and stream can have a pointer to this */
|
||||
int packet_count;
|
||||
int stream_id; // stream identity
|
||||
double jitter;
|
||||
double prev_transit;
|
||||
int outoforder_packets;
|
||||
int cnt_error;
|
||||
uint64_t target;
|
||||
/*
|
||||
* for udp measurements - This can be a structure outside stream, and
|
||||
* stream can have a pointer to this
|
||||
*/
|
||||
int packet_count;
|
||||
int stream_id; /* stream identity */
|
||||
double jitter;
|
||||
double prev_transit;
|
||||
int outoforder_packets;
|
||||
int cnt_error;
|
||||
uint64_t target;
|
||||
|
||||
struct sockaddr_storage local_addr;
|
||||
struct sockaddr_storage remote_addr;
|
||||
|
||||
int (*rcv)(struct iperf_stream *stream);
|
||||
int (*snd)(struct iperf_stream *stream);
|
||||
int (*update_stats)(struct iperf_stream *stream);
|
||||
int (*rcv) (struct iperf_stream * stream);
|
||||
int (*snd) (struct iperf_stream * stream);
|
||||
int (*update_stats) (struct iperf_stream * stream);
|
||||
|
||||
struct iperf_stream *next;
|
||||
|
||||
void *data;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct iperf_test
|
||||
{
|
||||
char role; // 'c'lient or 's'erver -s / -c
|
||||
int protocol;
|
||||
char role; /* c' lient or 's' erver */
|
||||
int protocol;
|
||||
char *server_hostname; /* -c option */
|
||||
int server_port;
|
||||
int duration; /* total duration of test (-t flag) */
|
||||
int listener_sock_tcp;
|
||||
int listener_sock_udp;
|
||||
|
||||
char *server_hostname; // arg of -c
|
||||
int server_port; // arg of -p
|
||||
int duration; // total duration of test -t
|
||||
int listener_sock_tcp;
|
||||
int listener_sock_udp;
|
||||
|
||||
/*boolen variables for Options */
|
||||
int daemon; // -D
|
||||
int no_delay; // -N
|
||||
int print_mss; // -m
|
||||
int domain; // -V
|
||||
/* boolen variables for Options */
|
||||
int daemon; /* -D option */
|
||||
int no_delay; /* -N option */
|
||||
int print_mss; /* -m option */
|
||||
int domain; /* -V option */
|
||||
|
||||
/* Select related parameters */
|
||||
int max_fd;
|
||||
fd_set read_set;
|
||||
fd_set temp_set;
|
||||
fd_set write_set;
|
||||
int max_fd;
|
||||
fd_set read_set;
|
||||
fd_set temp_set;
|
||||
fd_set write_set;
|
||||
|
||||
int (*accept)(struct iperf_test *);
|
||||
struct iperf_stream *(*new_stream)(struct iperf_test *);
|
||||
|
||||
int stats_interval; // time interval to gather stats -i
|
||||
void *(*stats_callback)(struct iperf_test *); // callback function pointer for stats
|
||||
|
||||
int reporter_interval; // time interval for reporter
|
||||
char *(*reporter_callback)(struct iperf_test *); // callback function pointer for reporter
|
||||
int reporter_fd; // file descriptor for reporter
|
||||
|
||||
int num_streams; // total streams in the test -P
|
||||
int tcp_info; /* display getsockopt(TCP_INFO) results */
|
||||
struct iperf_stream *streams; // pointer to list of struct stream
|
||||
int (*accept) (struct iperf_test *);
|
||||
struct iperf_stream *(*new_stream) (struct iperf_test *);
|
||||
int stats_interval; /* time interval to gather stats (-i) */
|
||||
void *(*stats_callback) (struct iperf_test *); /* callback function
|
||||
* pointer for stats */
|
||||
int reporter_interval;/* time interval for reporter */
|
||||
char *(*reporter_callback) (struct iperf_test *); /* callback function
|
||||
* pointer for reporter */
|
||||
int reporter_fd; /* file descriptor for reporter */
|
||||
int num_streams; /* total streams in the test (-P) */
|
||||
int tcp_info; /* display getsockopt(TCP_INFO) results */
|
||||
struct iperf_stream *streams; /* pointer to list of struct stream */
|
||||
struct iperf_settings *default_settings;
|
||||
};
|
||||
|
||||
struct udp_datagram
|
||||
{
|
||||
int state;
|
||||
int stream_id;
|
||||
int packet_count;
|
||||
int state;
|
||||
int stream_id;
|
||||
int packet_count;
|
||||
struct timeval sent_time;
|
||||
};
|
||||
|
||||
struct param_exchange
|
||||
{
|
||||
int state;
|
||||
int stream_id;
|
||||
int blksize;
|
||||
int recv_window;
|
||||
int send_window;
|
||||
int mss;
|
||||
char format;
|
||||
char cookie[37];
|
||||
int state;
|
||||
int stream_id;
|
||||
int blksize;
|
||||
int recv_window;
|
||||
int send_window;
|
||||
int mss;
|
||||
char format;
|
||||
char cookie[37]; /* size 37 makes total size 64 */
|
||||
};
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
/* default settings */
|
||||
Ptcp = SOCK_STREAM,
|
||||
Pudp = SOCK_DGRAM,
|
||||
PORT = 5001, /* default port to listen on */
|
||||
uS_TO_NS = 1000,
|
||||
RATE = 1000000,
|
||||
MAX_BUFFER_SIZE =10,
|
||||
DEFAULT_UDP_BLKSIZE = 1470,
|
||||
DEFAULT_TCP_BLKSIZE = 8192,
|
||||
SEC_TO_US = 1000000,
|
||||
RATE = 1024 * 1024, /* 1 Mbps */
|
||||
DURATION = 10, /* seconds */
|
||||
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_RUNNING = 2,
|
||||
RESULT_REQUEST = 3,
|
||||
@ -163,56 +165,55 @@ enum {
|
||||
ALL_STREAMS_END = 9,
|
||||
PARAM_EXCHANGE = 10,
|
||||
ACCESS_DENIED = -1,
|
||||
SEC_TO_US = 1000000,
|
||||
};
|
||||
|
||||
#define SEC_TO_NS 1000000000 /* too big for enum on some platforms */
|
||||
jmp_buf env;
|
||||
#define SEC_TO_NS 1000000000 /* too big for enum on some platforms */
|
||||
jmp_buf env;
|
||||
|
||||
/**
|
||||
* exchange_parameters - handles the param_Exchange part for client
|
||||
*
|
||||
*/
|
||||
void exchange_parameters(struct iperf_test *test);
|
||||
void exchange_parameters(struct iperf_test * test);
|
||||
|
||||
/**
|
||||
* param_received - handles the param_Exchange part for server
|
||||
* returns state on success, -1 on failure
|
||||
*
|
||||
*/
|
||||
int param_received(struct iperf_stream *sp, struct param_exchange *param);
|
||||
int param_received(struct iperf_stream * sp, struct param_exchange * param);
|
||||
|
||||
|
||||
/**
|
||||
* add_interval_list -- adds new interval to the interval_list
|
||||
*
|
||||
*/
|
||||
void add_interval_list(struct iperf_stream_result *rp, struct iperf_interval_results temp);
|
||||
void add_interval_list(struct iperf_stream_result * rp, struct iperf_interval_results temp);
|
||||
|
||||
/**
|
||||
* Display -- Displays interval results for test
|
||||
* Mainly for DEBUG purpose
|
||||
*
|
||||
*/
|
||||
void display_interval_list(struct iperf_stream_result *rp);
|
||||
void display_interval_list(struct iperf_stream_result * rp);
|
||||
|
||||
/**
|
||||
* send_result_to_client - sends result to client via
|
||||
* a new TCP connection
|
||||
*/
|
||||
void send_result_to_client(struct iperf_stream *sp);
|
||||
void send_result_to_client(struct iperf_stream * sp);
|
||||
|
||||
/**
|
||||
* receive_result_from_server - Receives result from server via
|
||||
* a new TCP connection
|
||||
*/
|
||||
void receive_result_from_server(struct iperf_test *test);
|
||||
void receive_result_from_server(struct iperf_test * test);
|
||||
|
||||
/**
|
||||
* getsock_tcp_mss - Returns the MSS size for TCP
|
||||
*
|
||||
*/
|
||||
int getsock_tcp_mss( int inSock );
|
||||
int getsock_tcp_mss(int inSock);
|
||||
|
||||
|
||||
/**
|
||||
@ -220,14 +221,14 @@ int getsock_tcp_mss( int inSock );
|
||||
*
|
||||
*
|
||||
*/
|
||||
int set_socket_options(struct iperf_stream *sp, struct iperf_test *test);
|
||||
int set_socket_options(struct iperf_stream * sp, struct iperf_test * test);
|
||||
|
||||
/**
|
||||
* connect_msg -- displays connection message
|
||||
* denoting senfer/receiver details
|
||||
*
|
||||
*/
|
||||
void connect_msg(struct iperf_stream *sp);
|
||||
void connect_msg(struct iperf_stream * sp);
|
||||
|
||||
|
||||
|
||||
@ -236,7 +237,7 @@ void connect_msg(struct iperf_stream *sp);
|
||||
* Mainly for DEBUG purpose
|
||||
*
|
||||
*/
|
||||
void Display(struct iperf_test *test);
|
||||
void Display(struct iperf_test * test);
|
||||
|
||||
|
||||
/**
|
||||
@ -246,7 +247,7 @@ void Display(struct iperf_test *test);
|
||||
*returns 0 on success
|
||||
*
|
||||
*/
|
||||
int iperf_tcp_accept(struct iperf_test *test);
|
||||
int iperf_tcp_accept(struct iperf_test * test);
|
||||
|
||||
/**
|
||||
* iperf_udp_accept -- accepts a new UDP connection
|
||||
@ -254,7 +255,7 @@ int iperf_tcp_accept(struct iperf_test *test);
|
||||
*returns 0 on success
|
||||
*
|
||||
*/
|
||||
int iperf_udp_accept(struct iperf_test *test);
|
||||
int iperf_udp_accept(struct iperf_test * test);
|
||||
|
||||
|
||||
/**
|
||||
@ -263,7 +264,7 @@ int iperf_udp_accept(struct iperf_test *test);
|
||||
*returns state of packet received
|
||||
*
|
||||
*/
|
||||
int iperf_tcp_recv(struct iperf_stream *sp);
|
||||
int iperf_tcp_recv(struct iperf_stream * sp);
|
||||
|
||||
/**
|
||||
* iperf_udp_recv -- receives the client data for UDP
|
||||
@ -271,23 +272,23 @@ int iperf_tcp_recv(struct iperf_stream *sp);
|
||||
*returns state of packet received
|
||||
*
|
||||
*/
|
||||
int iperf_udp_recv(struct iperf_stream *sp);
|
||||
int iperf_udp_recv(struct iperf_stream * sp);
|
||||
|
||||
/**
|
||||
* iperf_tcp_send -- sends the client data for TCP
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* iperf_stats_callback -- handles the statistic gathering
|
||||
@ -295,7 +296,7 @@ int iperf_udp_send(struct iperf_stream *sp);
|
||||
*returns void *
|
||||
*
|
||||
*/
|
||||
void *iperf_stats_callback(struct iperf_test *test);
|
||||
void *iperf_stats_callback(struct iperf_test * test);
|
||||
|
||||
|
||||
/**
|
||||
@ -304,7 +305,7 @@ void *iperf_stats_callback(struct iperf_test *test);
|
||||
*returns report
|
||||
*
|
||||
*/
|
||||
char *iperf_reporter_callback(struct iperf_test *test);
|
||||
char *iperf_reporter_callback(struct iperf_test * test);
|
||||
|
||||
|
||||
/**
|
||||
@ -313,19 +314,19 @@ char *iperf_reporter_callback(struct iperf_test *test);
|
||||
*returns stream
|
||||
*
|
||||
*/
|
||||
struct iperf_stream * find_stream_by_socket(struct iperf_test *test, int sock);
|
||||
struct iperf_stream *find_stream_by_socket(struct iperf_test * test, int sock);
|
||||
|
||||
/**
|
||||
* iperf_run_server -- Runs the server portion of a test
|
||||
*
|
||||
*/
|
||||
void iperf_run_server(struct iperf_test *test);
|
||||
void iperf_run_server(struct iperf_test * test);
|
||||
|
||||
/**
|
||||
* iperf_run_client -- Runs the client portion of a test
|
||||
*
|
||||
*/
|
||||
void iperf_run_client(struct iperf_test *test);
|
||||
void iperf_run_client(struct iperf_test * test);
|
||||
|
||||
/**
|
||||
* iperf_run -- runs the test either as client or server
|
||||
@ -333,7 +334,7 @@ void iperf_run_client(struct iperf_test *test);
|
||||
* returns status
|
||||
*
|
||||
*/
|
||||
int iperf_run(struct iperf_test *test);
|
||||
int iperf_run(struct iperf_test * test);
|
||||
|
||||
/**
|
||||
* iperf_new_test -- return a new iperf_test with default values
|
||||
@ -343,20 +344,20 @@ int iperf_run(struct iperf_test *test);
|
||||
*/
|
||||
struct iperf_test *iperf_new_test();
|
||||
|
||||
void iperf_defaults(struct iperf_test *testp);
|
||||
void iperf_defaults(struct iperf_test * testp);
|
||||
|
||||
/**
|
||||
* iperf_init_test -- perform pretest initialization (listen on sockets, etc)
|
||||
*
|
||||
*/
|
||||
void iperf_init_test(struct iperf_test *testp);
|
||||
void iperf_init_test(struct iperf_test * testp);
|
||||
|
||||
/**
|
||||
* iperf_free_test -- free resources used by test, calls iperf_free_stream to
|
||||
* free streams
|
||||
*
|
||||
*/
|
||||
void iperf_free_test(struct iperf_test *testp);
|
||||
void iperf_free_test(struct iperf_test * testp);
|
||||
|
||||
|
||||
/**
|
||||
@ -365,27 +366,26 @@ void iperf_free_test(struct iperf_test *testp);
|
||||
* returns NULL on failure
|
||||
*
|
||||
*/
|
||||
struct iperf_stream *iperf_new_stream(struct iperf_test *testp);
|
||||
struct iperf_stream *iperf_new_stream(struct iperf_test * testp);
|
||||
|
||||
struct iperf_stream *iperf_new_tcp_stream(struct iperf_test *testp);
|
||||
struct iperf_stream *iperf_new_udp_stream(struct iperf_test *testp);
|
||||
struct iperf_stream *iperf_new_tcp_stream(struct iperf_test * testp);
|
||||
struct iperf_stream *iperf_new_udp_stream(struct iperf_test * testp);
|
||||
|
||||
/**
|
||||
* iperf_add_stream -- add a stream to a test
|
||||
*
|
||||
* returns 1 on success 0 on failure
|
||||
*/
|
||||
int iperf_add_stream(struct iperf_test *test, struct iperf_stream *stream);
|
||||
int iperf_add_stream(struct iperf_test * test, struct iperf_stream * stream);
|
||||
|
||||
/**
|
||||
* iperf_init_stream -- init resources associated with test
|
||||
*
|
||||
*/
|
||||
void iperf_init_stream(struct iperf_stream *sp, struct iperf_test *testp);
|
||||
void iperf_init_stream(struct iperf_stream * sp, struct iperf_test * testp);
|
||||
|
||||
/**
|
||||
* iperf_free_stream -- free resources associated with test
|
||||
*
|
||||
*/
|
||||
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>
|
||||
|
||||
/* make connection to server */
|
||||
int
|
||||
netdial(int proto, char *client, int port)
|
||||
{
|
||||
@ -16,6 +17,7 @@ netdial(int proto, char *client, int port)
|
||||
struct sockaddr_in sa;
|
||||
socklen_t sn;
|
||||
|
||||
/* XXX: should this be called server?? -blt */
|
||||
if ((hent = gethostbyname(client)) == 0)
|
||||
{
|
||||
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
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* If bufsize > 0, set the TCP window size (via the socket buffer
|
||||
* sizes) for sock. Otherwise leave it as the system default.
|
||||
@ -75,104 +71,55 @@ extern "C"
|
||||
* 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
|
||||
set_tcp_windowsize(int sock, int bufsize, int dir)
|
||||
int
|
||||
set_tcp_windowsize(int sock, int bufsize, int dir)
|
||||
{
|
||||
int rc;
|
||||
int newbufsize;
|
||||
|
||||
assert(sock >= 0);
|
||||
|
||||
if (bufsize > 0)
|
||||
{
|
||||
#ifdef SO_SNDBUF
|
||||
int rc;
|
||||
int newbufsize;
|
||||
|
||||
assert(sock >= 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
|
||||
* some OS's don't show the corrected value until then.
|
||||
*/
|
||||
newbufsize = bufsize;
|
||||
rc = setsockopt(sock, SOL_SOCKET, dir, (char *) &newbufsize, sizeof newbufsize);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
#endif /* SO_SNDBUF */
|
||||
|
||||
return 0;
|
||||
/*
|
||||
* note: results are verified after connect() or listen(), since
|
||||
* some OS's don't show the corrected value until then.
|
||||
*/
|
||||
printf("Setting TCP buffer to size: %d\n", bufsize);
|
||||
newbufsize = bufsize;
|
||||
rc = setsockopt(sock, SOL_SOCKET, dir, (char *) &newbufsize, sizeof newbufsize);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
} else {
|
||||
printf("Using default TCP buffer size and assuming OS will do autotuning \n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* returns the TCP window size (on the sending buffer, SO_SNDBUF),
|
||||
* or -1 on error.
|
||||
* ------------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
getsock_tcp_windowsize(int sock, int dir)
|
||||
{
|
||||
int bufsize = 0;
|
||||
int
|
||||
get_tcp_windowsize(int sock, int dir)
|
||||
{
|
||||
int bufsize = 0;
|
||||
|
||||
#ifdef SO_SNDBUF
|
||||
int rc;
|
||||
socklen_t len;
|
||||
int rc;
|
||||
socklen_t len;
|
||||
|
||||
/* send buffer -- query for buffer size */
|
||||
len = sizeof bufsize;
|
||||
rc = getsockopt(sock, SOL_SOCKET, dir, (char *) &bufsize, &len);
|
||||
/* send buffer -- query for buffer size */
|
||||
len = sizeof bufsize;
|
||||
rc = getsockopt(sock, SOL_SOCKET, dir, (char *) &bufsize, &len);
|
||||
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
#endif
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
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 getsock_tcp_windowsize(int sock, int dir);
|
||||
int get_tcp_windowsize(int sock, int dir);
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user