Added callback functions to the iperf API

This commit is contained in:
sethdelliott 2010-07-23 20:46:58 +00:00
parent 112a907cc3
commit 4df383f6d8
5 changed files with 103 additions and 33 deletions

View File

@ -157,6 +157,12 @@ struct iperf_test
struct iperf_settings *settings;
SLIST_HEAD(slisthead, protocol) protocols;
/* callback functions */
void (*on_new_stream)(struct iperf_stream *);
void (*on_test_start)(struct iperf_test *);
void (*on_connect)(struct iperf_test *);
void (*on_test_finish)(struct iperf_test *);
};
enum

View File

@ -44,7 +44,7 @@
jmp_buf env; /* to handle longjmp on signal */
/*************************************************************/
/*************************** Print usage functions ****************************/
void
usage()
@ -61,6 +61,8 @@ usage_long()
}
/********************** Get/set test protocol structure ***********************/
struct protocol *
get_protocol(struct iperf_test *test, int prot_id)
{
@ -77,7 +79,6 @@ get_protocol(struct iperf_test *test, int prot_id)
return (prot);
}
int
set_protocol(struct iperf_test *test, int prot_id)
{
@ -95,6 +96,63 @@ set_protocol(struct iperf_test *test, int prot_id)
return (-1);
}
/************************** Iperf callback functions **************************/
void
iperf_on_new_stream(struct iperf_stream *sp)
{
connect_msg(sp);
}
void
iperf_on_test_start(struct iperf_test *test)
{
if (test->verbose) {
if (test->settings->bytes) {
printf(test_start_bytes, test->protocol->name, test->num_streams,
test->settings->blksize, test->settings->bytes);
} else {
printf(test_start_time, test->protocol->name, test->num_streams,
test->settings->blksize, test->duration);
}
}
}
void
iperf_on_connect(struct iperf_test *test)
{
char ipl[INET6_ADDRSTRLEN], ipr[INET6_ADDRSTRLEN];
struct sockaddr_in temp;
socklen_t len;
if (test->role == 'c') {
printf("Connecting to host %s, port %d\n", test->server_hostname,
test->server_port);
} else {
len = sizeof(struct sockaddr_in);
getpeername(test->ctrl_sck, (struct sockaddr *) &temp, &len);
inet_ntop(AF_INET, (void *) &temp.sin_addr, ipr, sizeof(ipr));
printf("Accepted connection from %s, port %d\n", ipr, ntohs(temp.sin_port));
}
if (test->verbose) {
printf(" Cookie: %s\n", test->cookie);
}
}
void
iperf_on_test_finish(struct iperf_test *test)
{
if (test->verbose) {
printf("Test Complete. Summary Results:\n");
}
}
/******************************************************************************/
int
iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
{
@ -392,11 +450,15 @@ iperf_init_test(struct iperf_test *test)
test->timer = new_timer(test->duration, 0);
if (test->timer == NULL)
return (-1);
/*
printf(test_start_time, test->protocol->name, test->num_streams, test->settings->blksize,
test->duration);
*/
} else {
/*
printf(test_start_bytes, test->protocol->name, test->num_streams, test->settings->blksize,
test->settings->bytes);
*/
}
if (test->stats_interval != 0) {
@ -418,6 +480,9 @@ iperf_init_test(struct iperf_test *test)
}
}
if (test->on_test_start)
test->on_test_start(test);
return (0);
}
@ -588,8 +653,6 @@ iperf_exchange_parameters(struct iperf_test * test)
if (parse_parameters(test) < 0)
return (-1);
printf(" cookie: %s\n", test->cookie);
if ((s = test->protocol->listen(test)) < 0)
return (-1);
FD_SET(s, &test->read_set);
@ -756,7 +819,7 @@ parse_results(struct iperf_test *test, char *results)
sp->result->bytes_sent = bytes_transferred;
}
return 0;
return (0);
}
@ -888,6 +951,11 @@ iperf_defaults(struct iperf_test * testp)
set_protocol(testp, Ptcp);
testp->on_new_stream = iperf_on_new_stream;
testp->on_test_start = iperf_on_test_start;
testp->on_connect = iperf_on_connect;
testp->on_test_finish = iperf_on_test_finish;
return (0);
}
@ -908,12 +976,13 @@ iperf_create_streams(struct iperf_test *test)
FD_SET(s, &test->write_set);
test->max_fd = (test->max_fd < s) ? s : test->max_fd;
// XXX: This doesn't fit our API model!
sp = iperf_new_stream(test, s);
if (!sp)
return (-1);
connect_msg(sp);
/* Perform the new stream callback */
if (test->on_new_stream)
test->on_new_stream(sp);
}
return (0);
@ -926,7 +995,6 @@ iperf_handle_message_client(struct iperf_test *test)
if ((rval = read(test->ctrl_sck, &test->state, sizeof(char))) <= 0) {
if (rval == 0) {
// fprintf(stderr, "The server has unexpectedly closed the connection. Exiting...\n");
i_errno = IECTRLCLOSE;
return (-1);
} else {
@ -939,6 +1007,8 @@ iperf_handle_message_client(struct iperf_test *test)
case PARAM_EXCHANGE:
if (iperf_exchange_parameters(test) < 0)
return (-1);
if (test->on_connect)
test->on_connect(test);
break;
case CREATE_STREAMS:
if (iperf_create_streams(test) < 0)
@ -955,6 +1025,8 @@ iperf_handle_message_client(struct iperf_test *test)
return (-1);
break;
case DISPLAY_RESULTS:
if (test->on_test_finish)
test->on_test_finish(test);
iperf_client_end(test);
break;
case IPERF_DONE:
@ -977,7 +1049,7 @@ iperf_handle_message_client(struct iperf_test *test)
int
iperf_connect(struct iperf_test *test)
{
printf("Connecting to host %s, port %d\n", test->server_hostname, test->server_port);
// printf("Connecting to host %s, port %d\n", test->server_hostname, test->server_port);
FD_ZERO(&test->read_set);
FD_ZERO(&test->write_set);
@ -1000,7 +1072,7 @@ iperf_connect(struct iperf_test *test)
FD_SET(test->ctrl_sck, &test->write_set);
test->max_fd = (test->ctrl_sck > test->max_fd) ? test->ctrl_sck : test->max_fd;
return 0;
return (0);
}
/**************************************************************************/
@ -1065,7 +1137,6 @@ iperf_stats_callback(struct iperf_test * test)
//temp.interval_duration = timeval_diff(&temp.interval_start_time, &temp.interval_end_time);
if (test->tcp_info)
get_tcpinfo(test, &temp);
//printf(" iperf_stats_callback: adding to interval list: \n");
add_to_interval_list(rp, &temp);
rp->bytes_sent_this_interval = rp->bytes_received_this_interval = 0;
@ -1354,7 +1425,6 @@ int
iperf_client_end(struct iperf_test *test)
{
struct iperf_stream *sp, *np;
printf("Test Complete. Summary Results:\n");
/* show final summary */
test->reporter_callback(test);

View File

@ -120,6 +120,11 @@ int iperf_parse_arguments(struct iperf_test *, int, char **);
struct protocol *get_protocol(struct iperf_test *, int);
int set_protocol(struct iperf_test *, int);
void iperf_on_new_stream(struct iperf_stream *);
void iperf_on_test_start(struct iperf_test *);
void iperf_on_connect(struct iperf_test *);
void iperf_on_test_finish(struct iperf_test *);
extern jmp_buf env;
#endif

View File

@ -96,11 +96,9 @@ iperf_accept(struct iperf_test *test)
{
int s;
int rbuf = ACCESS_DENIED;
char ipl[512], ipr[512]; // XXX: This is overkill. Max length of IPv6 address = 46 (INET6_ADDRSTRLEN)
char cookie[COOKIE_SIZE];
socklen_t len;
struct sockaddr_in addr;
struct sockaddr_in temp1, temp2;
len = sizeof(addr);
if ((s = accept(test->listener, (struct sockaddr *) &addr, &len)) < 0) {
@ -120,22 +118,6 @@ iperf_accept(struct iperf_test *test)
test->max_fd = (s > test->max_fd) ? s : test->max_fd;
test->ctrl_sck = s;
len = sizeof(struct sockaddr_in);
if (getsockname(s, (struct sockaddr *) &temp1, &len) < 0) {
i_errno = IEACCEPT;
return (-1);
}
if (getpeername(s, (struct sockaddr *) &temp2, &len) < 0) {
i_errno = IEACCEPT;
return (-1);
}
// XXX: Check inet_ntop for errors?
inet_ntop(AF_INET, (void *) &temp1.sin_addr, ipl, sizeof(ipl));
inet_ntop(AF_INET, (void *) &temp2.sin_addr, ipr, sizeof(ipr));
printf(report_peer, s, ipl, ntohs(temp1.sin_port), ipr, ntohs(temp2.sin_port));
test->state = PARAM_EXCHANGE;
if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) {
i_errno = IESENDMESSAGE;
@ -144,6 +126,9 @@ iperf_accept(struct iperf_test *test)
if (iperf_exchange_parameters(test) < 0) {
return (-1);
}
if (test->on_connect) {
test->on_connect(test);
}
} else {
// XXX: Do we even need to receive cookie if we're just going to deny anyways?
if (Nread(s, cookie, COOKIE_SIZE, Ptcp) < 0) {
@ -203,6 +188,8 @@ iperf_handle_message_server(struct iperf_test *test)
i_errno = IESENDMESSAGE;
return (-1);
}
if (test->on_test_finish)
test->on_test_finish(test);
test->reporter_callback(test);
break;
case IPERF_DONE:
@ -344,7 +331,9 @@ iperf_run_server(struct iperf_test *test)
test->max_fd = (s > test->max_fd) ? s : test->max_fd;
streams_accepted++;
connect_msg(sp);
// connect_msg(sp);
if (test->on_new_stream)
test->on_new_stream(sp);
}
FD_CLR(test->prot_listener, &temp_read_set);
}

View File

@ -88,13 +88,13 @@ set_tcp_windowsize(int sock, int bufsize, int dir)
* 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);
// 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");
// printf(" Using default TCP buffer size and assuming OS will do autotuning\n");
}
return 0;