All error handling is now handled by iperf_error. Also cleaned up some code
Этот коммит содержится в:
родитель
3118b42010
Коммит
b60a49dd37
23
src/iperf.h
23
src/iperf.h
@ -147,33 +147,10 @@ struct iperf_test
|
||||
|
||||
iperf_size_t bytes_sent;
|
||||
|
||||
/* iperf error reporting
|
||||
* - errtype: (0,1,2)
|
||||
* 0: use perror(errno)
|
||||
* 1: use herror(errno)
|
||||
* 2: use ierror(errno)
|
||||
*/
|
||||
//int errtype;
|
||||
//int errno;
|
||||
|
||||
struct iperf_stream *streams; /* pointer to list of struct stream */
|
||||
struct iperf_settings *default_settings;
|
||||
};
|
||||
|
||||
struct param_exchange
|
||||
{
|
||||
int state;
|
||||
int protocol;
|
||||
int num_streams;
|
||||
int reverse;
|
||||
int blksize;
|
||||
int recv_window;
|
||||
int send_window;
|
||||
int mss;
|
||||
char format;
|
||||
char cookie[COOKIE_SIZE];
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
/* default settings */
|
||||
|
169
src/iperf_api.c
169
src/iperf_api.c
@ -28,6 +28,7 @@
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "net.h"
|
||||
#include "iperf.h"
|
||||
#include "iperf_api.h"
|
||||
#include "iperf_udp.h"
|
||||
@ -265,11 +266,11 @@ all_data_sent(struct iperf_test * test)
|
||||
{
|
||||
if (test->default_settings->bytes > 0) {
|
||||
if (test->bytes_sent >= (test->num_streams * test->default_settings->bytes)) {
|
||||
return 1;
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
@ -287,7 +288,6 @@ iperf_send(struct iperf_test *test)
|
||||
|
||||
result = select(test->max_fd + 1, NULL, &temp_write_set, NULL, &tv);
|
||||
if (result < 0 && errno != EINTR) {
|
||||
// perror("select iperf_send");
|
||||
i_errno = IESELECT;
|
||||
return (-1);
|
||||
}
|
||||
@ -295,7 +295,6 @@ iperf_send(struct iperf_test *test)
|
||||
for (sp = test->streams; sp != NULL; sp = sp->next) {
|
||||
if (FD_ISSET(sp->socket, &temp_write_set)) {
|
||||
if ((bytes_sent = sp->snd(sp)) < 0) {
|
||||
// perror("iperf stream->snd");
|
||||
i_errno = IESTREAMWRITE;
|
||||
return (-1);
|
||||
}
|
||||
@ -305,7 +304,7 @@ iperf_send(struct iperf_test *test)
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
@ -323,7 +322,6 @@ iperf_recv(struct iperf_test *test)
|
||||
|
||||
result = select(test->max_fd + 1, &temp_read_set, NULL, NULL, &tv);
|
||||
if (result < 0) {
|
||||
// perror("select iperf_recv");
|
||||
i_errno = IESELECT;
|
||||
return (-1);
|
||||
}
|
||||
@ -331,7 +329,6 @@ iperf_recv(struct iperf_test *test)
|
||||
for (sp = test->streams; sp != NULL; sp = sp->next) {
|
||||
if (FD_ISSET(sp->socket, &temp_read_set)) {
|
||||
if ((bytes_sent = sp->rcv(sp)) < 0) {
|
||||
// perror("sp->rcv(sp)");
|
||||
i_errno = IESTREAMREAD;
|
||||
return (-1);
|
||||
}
|
||||
@ -341,10 +338,10 @@ iperf_recv(struct iperf_test *test)
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
iperf_init_test(struct iperf_test *test)
|
||||
{
|
||||
char *prot;
|
||||
@ -358,8 +355,11 @@ iperf_init_test(struct iperf_test *test)
|
||||
|
||||
assert(dtargus != 0);
|
||||
|
||||
for (sp = test->streams; sp; sp = sp->next)
|
||||
for (sp = test->streams; sp; sp = sp->next) {
|
||||
sp->send_timer = new_timer(dtargus / SEC_TO_US, dtargus % SEC_TO_US);
|
||||
if (sp->send_timer == NULL)
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
prot = "TCP";
|
||||
}
|
||||
@ -367,6 +367,8 @@ iperf_init_test(struct iperf_test *test)
|
||||
/* Set timers */
|
||||
if (test->default_settings->bytes == 0) {
|
||||
test->timer = new_timer(test->duration, 0);
|
||||
if (test->timer == NULL)
|
||||
return (-1);
|
||||
printf(test_start_time, prot, test->num_streams, test->default_settings->blksize,
|
||||
test->duration);
|
||||
} else {
|
||||
@ -374,14 +376,26 @@ iperf_init_test(struct iperf_test *test)
|
||||
test->default_settings->bytes);
|
||||
}
|
||||
|
||||
if (test->stats_interval != 0)
|
||||
if (test->stats_interval != 0) {
|
||||
test->stats_timer = new_timer(test->stats_interval, 0);
|
||||
if (test->reporter_interval != 0)
|
||||
if (test->stats_timer == NULL)
|
||||
return (-1);
|
||||
}
|
||||
if (test->reporter_interval != 0) {
|
||||
test->reporter_timer = new_timer(test->reporter_interval, 0);
|
||||
if (test->reporter_timer == NULL)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Set start time */
|
||||
for (sp = test->streams; sp; sp = sp->next)
|
||||
gettimeofday(&sp->result->start_time, NULL);
|
||||
for (sp = test->streams; sp; sp = sp->next) {
|
||||
if (gettimeofday(&sp->result->start_time, NULL) < 0) {
|
||||
i_errno = IEINITTEST;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@ -445,7 +459,7 @@ package_parameters(struct iperf_test *test)
|
||||
|
||||
*pstring = (char) (strlen(pstring) - 1);
|
||||
|
||||
if (Nwrite(test->ctrl_sck, pstring, (size_t) strlen(pstring), Ptcp) < 0) {
|
||||
if (Nwrite(test->ctrl_sck, pstring, strlen(pstring), Ptcp) < 0) {
|
||||
i_errno = IESENDPARAMS;
|
||||
return (-1);
|
||||
}
|
||||
@ -461,33 +475,29 @@ parse_parameters(struct iperf_test *test)
|
||||
char *param, **params;
|
||||
char len, ch;
|
||||
char pstring[256];
|
||||
char readbuf[256];
|
||||
|
||||
memset(pstring, 0, 256 * sizeof(char));
|
||||
|
||||
if (read(test->ctrl_sck, &len, sizeof(char)) < 0) {
|
||||
perror("read len");
|
||||
return -1;
|
||||
if (Nread(test->ctrl_sck, &len, sizeof(char), Ptcp) < 0) {
|
||||
i_errno = IERECVPARAMS;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
memset(readbuf, 0, 256 * sizeof(char));
|
||||
if ((len -= read(test->ctrl_sck, readbuf, (size_t) len)) < 0) {
|
||||
perror("read pstring");
|
||||
return -1;
|
||||
}
|
||||
strcat(pstring, readbuf);
|
||||
if (Nread(test->ctrl_sck, pstring, len, Ptcp) < 0) {
|
||||
i_errno = IERECVPARAMS;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
for (param = strtok(pstring, " "), n = 0, params = NULL; param; param = strtok(NULL, " ")) {
|
||||
if ((params = realloc(params, (n+1)*sizeof(char *))) == NULL) {
|
||||
perror("realloc");
|
||||
return -1;
|
||||
i_errno = IERECVPARAMS;
|
||||
return (-1);
|
||||
}
|
||||
params[n] = param;
|
||||
n++;
|
||||
}
|
||||
|
||||
// XXX: Should we check for parameters exceeding maximum values here?
|
||||
while ((ch = getopt(n, params, "pt:n:m:uNP:Rw:l:b:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'p':
|
||||
@ -533,7 +543,7 @@ parse_parameters(struct iperf_test *test)
|
||||
|
||||
free(params);
|
||||
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -553,12 +563,16 @@ iperf_exchange_parameters(struct iperf_test * test)
|
||||
return (-1);
|
||||
|
||||
} else {
|
||||
parse_parameters(test);
|
||||
if (parse_parameters(test) < 0)
|
||||
return (-1);
|
||||
|
||||
printf(" cookie: %s\n", test->default_settings->cookie);
|
||||
|
||||
if (test->protocol == Pudp) {
|
||||
test->listener_udp = netannounce(test->protocol, NULL, test->server_port);
|
||||
if ((test->listener_udp = netannounce(test->protocol, NULL, test->server_port)) < 0) {
|
||||
i_errno = IELISTEN;
|
||||
return (-1);
|
||||
}
|
||||
FD_SET(test->listener_udp, &test->read_set);
|
||||
test->max_fd = (test->listener_udp > test->max_fd) ? test->listener_udp : test->max_fd;
|
||||
} else if (test->protocol == Ptcp) {
|
||||
@ -566,28 +580,28 @@ iperf_exchange_parameters(struct iperf_test * test)
|
||||
FD_CLR(test->listener_tcp, &test->read_set);
|
||||
close(test->listener_tcp);
|
||||
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
perror("socket tcp listener mss");
|
||||
i_errno = IELISTEN;
|
||||
return (-1);
|
||||
}
|
||||
if (test->no_delay) {
|
||||
opt = 1;
|
||||
if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)) < 0) {
|
||||
perror("setsockopt TCP_NODELAY");
|
||||
i_errno = IESETNODELAY;
|
||||
return (-1);
|
||||
}
|
||||
printf(" TCP NODELAY: on\n");
|
||||
}
|
||||
// XXX: Setting MSS is very buggy!
|
||||
if (opt = test->default_settings->mss) {
|
||||
if ((opt = test->default_settings->mss)) {
|
||||
if (setsockopt(s, IPPROTO_TCP, TCP_MAXSEG, &opt, sizeof(opt)) < 0) {
|
||||
perror("setsockopt TCP_MAXSEG");
|
||||
i_errno = IESETMSS;
|
||||
return (-1);
|
||||
}
|
||||
printf(" TCP MSS: %d\n", opt);
|
||||
}
|
||||
opt = 1;
|
||||
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
|
||||
perror("setsockopt SO_REUSEADDR");
|
||||
i_errno = IEREUSEADDR;
|
||||
return (-1);
|
||||
}
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
@ -596,11 +610,14 @@ iperf_exchange_parameters(struct iperf_test * test)
|
||||
sa.sin_port = htons(test->server_port);
|
||||
if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
|
||||
close(s);
|
||||
perror("bind tcp mss/nodelay listener");
|
||||
i_errno = IELISTEN;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
listen(s, 5);
|
||||
if (listen(s, 5) < 0) {
|
||||
i_errno = IELISTEN;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
test->listener_tcp = s;
|
||||
test->max_fd = (s > test->max_fd) ? s : test->max_fd;
|
||||
@ -612,13 +629,13 @@ iperf_exchange_parameters(struct iperf_test * test)
|
||||
// Send the control message to create streams and start the test
|
||||
test->state = CREATE_STREAMS;
|
||||
if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) {
|
||||
perror("Nwrite CREATE_STREAMS");
|
||||
return -1;
|
||||
i_errno = IESENDMESSAGE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
@ -642,7 +659,6 @@ iperf_exchange_results(struct iperf_test *test)
|
||||
sp->cnt_error, sp->packet_count);
|
||||
size += strlen(buf);
|
||||
if ((results = realloc(results, size+1)) == NULL) {
|
||||
// perror("realloc results");
|
||||
i_errno = IEPACKAGERESULTS;
|
||||
return (-1);
|
||||
}
|
||||
@ -653,12 +669,10 @@ iperf_exchange_results(struct iperf_test *test)
|
||||
size++;
|
||||
size = htonl(size);
|
||||
if (Nwrite(test->ctrl_sck, &size, sizeof(size), Ptcp) < 0) {
|
||||
// perror("Nwrite size");
|
||||
i_errno = IESENDRESULTS;
|
||||
return (-1);
|
||||
}
|
||||
if (Nwrite(test->ctrl_sck, results, ntohl(size), Ptcp) < 0) {
|
||||
// perror("Nwrite results");
|
||||
i_errno = IESENDRESULTS;
|
||||
return (-1);
|
||||
}
|
||||
@ -666,19 +680,16 @@ iperf_exchange_results(struct iperf_test *test)
|
||||
|
||||
/* Get server results string */
|
||||
if (Nread(test->ctrl_sck, &size, sizeof(size), Ptcp) < 0) {
|
||||
// perror("Nread size");
|
||||
i_errno = IERECVRESULTS;
|
||||
return (-1);
|
||||
}
|
||||
size = ntohl(size);
|
||||
results = (char *) malloc(size * sizeof(char));
|
||||
if (results == NULL) {
|
||||
// perror("malloc results");
|
||||
i_errno = IERECVRESULTS;
|
||||
return (-1);
|
||||
}
|
||||
if (Nread(test->ctrl_sck, results, size, Ptcp) < 0) {
|
||||
// perror("Nread results");
|
||||
i_errno = IERECVRESULTS;
|
||||
return (-1);
|
||||
}
|
||||
@ -692,21 +703,23 @@ iperf_exchange_results(struct iperf_test *test)
|
||||
} else {
|
||||
/* Get client results string */
|
||||
if (Nread(test->ctrl_sck, &size, sizeof(size), Ptcp) < 0) {
|
||||
perror("Nread size");
|
||||
i_errno = IERECVRESULTS;
|
||||
return (-1);
|
||||
}
|
||||
size = ntohl(size);
|
||||
results = (char *) malloc(size * sizeof(char));
|
||||
if (results == NULL) {
|
||||
perror("malloc results");
|
||||
i_errno = IERECVRESULTS;
|
||||
return (-1);
|
||||
}
|
||||
if (Nread(test->ctrl_sck, results, size, Ptcp) < 0) {
|
||||
perror("Nread results");
|
||||
i_errno = IERECVRESULTS;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
parse_results(test, results);
|
||||
// XXX: Same issue as with client
|
||||
if (parse_results(test, results) < 0)
|
||||
return (-1);
|
||||
|
||||
free(results);
|
||||
|
||||
@ -719,7 +732,7 @@ iperf_exchange_results(struct iperf_test *test)
|
||||
sp->cnt_error, sp->packet_count);
|
||||
size += strlen(buf);
|
||||
if ((results = realloc(results, size+1)) == NULL) {
|
||||
perror("realloc results");
|
||||
i_errno = IEPACKAGERESULTS;
|
||||
return (-1);
|
||||
}
|
||||
if (sp == test->streams)
|
||||
@ -729,18 +742,18 @@ iperf_exchange_results(struct iperf_test *test)
|
||||
size++;
|
||||
size = htonl(size);
|
||||
if (Nwrite(test->ctrl_sck, &size, sizeof(size), Ptcp) < 0) {
|
||||
perror("Nwrite size");
|
||||
i_errno = IESENDRESULTS;
|
||||
return (-1);
|
||||
}
|
||||
if (Nwrite(test->ctrl_sck, results, ntohl(size), Ptcp) < 0) {
|
||||
perror("Nwrite results");
|
||||
i_errno = IESENDRESULTS;
|
||||
return (-1);
|
||||
}
|
||||
free(results);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
@ -950,49 +963,43 @@ iperf_create_streams(struct iperf_test *test)
|
||||
if (test->no_delay) {
|
||||
opt = 1;
|
||||
if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)) < 0) {
|
||||
// perror("setsockopt");
|
||||
i_errno = IECREATESTREAM;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
if (opt = test->default_settings->mss) {
|
||||
if (setsockopt(s, IPPROTO_TCP, TCP_MAXSEG, &opt, sizeof(opt)) < 0) {
|
||||
// perror("setsockopt");
|
||||
i_errno = IECREATESTREAM;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
if (connect(s, (struct sockaddr *) &sa, sizeof(sa)) < 0 && errno != EINPROGRESS) {
|
||||
// perror("connect tcp stream");
|
||||
i_errno = IECREATESTREAM;
|
||||
i_errno = IESTREAMCONNECT;
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
s = netdial(test->protocol, test->server_hostname, test->server_port);
|
||||
if (s < 0) {
|
||||
// perror("netdial stream");
|
||||
i_errno = IECREATESTREAM;
|
||||
i_errno = IESTREAMCONNECT;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (test->protocol == Ptcp) {
|
||||
if (Nwrite(s, test->default_settings->cookie, COOKIE_SIZE, Ptcp) < 0) {
|
||||
// perror("Nwrite COOKIE\n");
|
||||
i_errno = IESTREAMWRITE;
|
||||
i_errno = IESENDCOOKIE;
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
/* Write to the UDP stream to give the server this stream's credentials */
|
||||
if (write(s, &buf, sizeof(i)) < 0) {
|
||||
// perror("write data");
|
||||
// XXX: Should this be changed to IESTREAMCONNECT?
|
||||
i_errno = IESTREAMWRITE;
|
||||
return (-1);
|
||||
}
|
||||
/* Wait until the server confirms the client UDP write */
|
||||
// XXX: Should this read be TCP instead?
|
||||
if (read(s, &buf, sizeof(i)) < 0) {
|
||||
// perror("read data");
|
||||
i_errno = IESTREAMREAD;
|
||||
return (-1);
|
||||
}
|
||||
@ -1028,7 +1035,6 @@ iperf_handle_message_client(struct iperf_test *test)
|
||||
i_errno = IECTRLCLOSE;
|
||||
return (-1);
|
||||
} else {
|
||||
// perror("read ctrl_sck");
|
||||
i_errno = IERECVMESSAGE;
|
||||
return (-1);
|
||||
}
|
||||
@ -1044,7 +1050,8 @@ iperf_handle_message_client(struct iperf_test *test)
|
||||
return (-1);
|
||||
break;
|
||||
case TEST_START:
|
||||
iperf_init_test(test);
|
||||
if (iperf_init_test(test) < 0)
|
||||
return (-1);
|
||||
break;
|
||||
case TEST_RUNNING:
|
||||
break;
|
||||
@ -1058,16 +1065,12 @@ iperf_handle_message_client(struct iperf_test *test)
|
||||
case IPERF_DONE:
|
||||
break;
|
||||
case SERVER_TERMINATE:
|
||||
// fprintf(stderr, "The server has terminated. Exiting...\n");
|
||||
i_errno = IESERVERTERM;
|
||||
return (-1);
|
||||
case ACCESS_DENIED:
|
||||
// fprintf(stderr, "The server is busy running a test. Try again later.\n");
|
||||
// exit(0);
|
||||
i_errno = IEACCESSDENIED;
|
||||
return (-1);
|
||||
default:
|
||||
// printf("How did you get here? test->state = %d\n", test->state);
|
||||
i_errno = IEMESSAGE;
|
||||
return (-1);
|
||||
}
|
||||
@ -1094,7 +1097,7 @@ iperf_connect(struct iperf_test *test)
|
||||
}
|
||||
|
||||
if (Nwrite(test->ctrl_sck, test->default_settings->cookie, COOKIE_SIZE, Ptcp) < 0) {
|
||||
i_errno = IECTRLWRITE; // XXX: should this set IECONNECT instead?
|
||||
i_errno = IESENDCOOKIE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -1357,7 +1360,6 @@ iperf_new_stream(struct iperf_test *testp)
|
||||
|
||||
sp = (struct iperf_stream *) malloc(sizeof(struct iperf_stream));
|
||||
if (!sp) {
|
||||
// perror("malloc");
|
||||
i_errno = IECREATESTREAM;
|
||||
return (NULL);
|
||||
}
|
||||
@ -1368,17 +1370,14 @@ iperf_new_stream(struct iperf_test *testp)
|
||||
sp->result = (struct iperf_stream_result *) malloc(sizeof(struct iperf_stream_result));
|
||||
|
||||
if (!sp->buffer) {
|
||||
// perror("Malloc sp->buffer");
|
||||
i_errno = IECREATESTREAM;
|
||||
return (NULL);
|
||||
}
|
||||
if (!sp->settings) {
|
||||
// perror("Malloc sp->settings");
|
||||
i_errno = IECREATESTREAM;
|
||||
return (NULL);
|
||||
}
|
||||
if (!sp->result) {
|
||||
// perror("Malloc sp->result");
|
||||
i_errno = IECREATESTREAM;
|
||||
return (NULL);
|
||||
}
|
||||
@ -1444,6 +1443,7 @@ iperf_init_stream(struct iperf_stream * sp, struct iperf_test * testp)
|
||||
// set_tcp_options(sp->socket, testp->no_delay, testp->default_settings->mss);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
@ -1484,11 +1484,11 @@ iperf_client_end(struct iperf_test *test)
|
||||
|
||||
test->state = IPERF_DONE;
|
||||
if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) {
|
||||
perror("Nwrite IPERF_DONE");
|
||||
return -1;
|
||||
i_errno = IESENDMESSAGE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1506,19 +1506,16 @@ iperf_run_client(struct iperf_test * test)
|
||||
|
||||
/* Start the client and connect to the server */
|
||||
if (iperf_connect(test) < 0) {
|
||||
// set error and return
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// XXX: Do we need to check signal() for errors?
|
||||
signal(SIGINT, sig_handler);
|
||||
if (setjmp(env)) {
|
||||
fprintf(stderr, "Exiting...\n");
|
||||
test->state = CLIENT_TERMINATE;
|
||||
if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) {
|
||||
i_errno = IESENDMESSAGE;
|
||||
return (-1);
|
||||
// fprintf(stderr, "Unable to send CLIENT_TERMINATE message to server\n");
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
@ -1532,7 +1529,6 @@ iperf_run_client(struct iperf_test * test)
|
||||
|
||||
result = select(test->max_fd + 1, &temp_read_set, &temp_write_set, NULL, &tv);
|
||||
if (result < 0 && errno != EINTR) {
|
||||
// perror("select");
|
||||
i_errno = IESELECT;
|
||||
return (-1);
|
||||
} else if (result > 0) {
|
||||
@ -1556,11 +1552,13 @@ iperf_run_client(struct iperf_test * test)
|
||||
/* Perform callbacks */
|
||||
if (timer_expired(test->stats_timer)) {
|
||||
test->stats_callback(test);
|
||||
update_timer(test->stats_timer, test->stats_interval, 0);
|
||||
if (update_timer(test->stats_timer, test->stats_interval, 0) < 0)
|
||||
return (-1);
|
||||
}
|
||||
if (timer_expired(test->reporter_timer)) {
|
||||
test->reporter_callback(test);
|
||||
update_timer(test->reporter_timer, test->reporter_interval, 0);
|
||||
if (update_timer(test->reporter_timer, test->reporter_interval, 0) < 0)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Send TEST_END if all data has been sent or timer expired */
|
||||
@ -1568,7 +1566,6 @@ iperf_run_client(struct iperf_test * test)
|
||||
test->stats_callback(test);
|
||||
test->state = TEST_END;
|
||||
if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) {
|
||||
// perror("Nwrite TEST_END");
|
||||
i_errno = IESENDMESSAGE;
|
||||
return (-1);
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ int iperf_create_streams(struct iperf_test *);
|
||||
int iperf_handle_message_client(struct iperf_test *);
|
||||
int iperf_exchange_results(struct iperf_test *);
|
||||
int parse_results(struct iperf_test *, char *);
|
||||
void iperf_init_test(struct iperf_test *);
|
||||
int iperf_init_test(struct iperf_test *);
|
||||
int iperf_parse_arguments(struct iperf_test *, int, char **);
|
||||
|
||||
#endif
|
||||
|
@ -7,8 +7,175 @@
|
||||
|
||||
int i_errno;
|
||||
|
||||
char *
|
||||
iperf_strerror(int i_errno)
|
||||
{
|
||||
static char errstr[256];
|
||||
int len;
|
||||
|
||||
len = sizeof(errstr);
|
||||
memset(errstr, 0, len);
|
||||
|
||||
switch (i_errno) {
|
||||
case IENONE:
|
||||
snprintf(errstr, len, "no error");
|
||||
break;
|
||||
case IESERVCLIENT:
|
||||
snprintf(errstr, len, "iperf cannot be both server and client");
|
||||
break;
|
||||
case IENOROLE:
|
||||
snprintf(errstr, len, "iperf instance must either be a client (-c) or server (-s)");
|
||||
break;
|
||||
case IECLIENTONLY:
|
||||
snprintf(errstr, len, "some option you are trying to set is client only");
|
||||
break;
|
||||
case IEDURATION:
|
||||
snprintf(errstr, len, "test duration too long (maximum = %d seconds)", MAX_TIME);
|
||||
break;
|
||||
case IENUMSTREAMS:
|
||||
snprintf(errstr, len, "number of parallel streams too large (maximum = %d)", MAX_STREAMS);
|
||||
break;
|
||||
case IEBLOCKSIZE:
|
||||
snprintf(errstr, len, "block size too large (maximum = %d bytes)", MAX_BLOCKSIZE);
|
||||
break;
|
||||
case IEBUFSIZE:
|
||||
snprintf(errstr, len, "socket buffer size too large (maximum = %d bytes)", MAX_TCP_BUFFER);
|
||||
break;
|
||||
case IEINTERVAL:
|
||||
snprintf(errstr, len, "report interval too large (maximum = %d seconds)", MAX_INTERVAL);
|
||||
break;
|
||||
case IEMSS:
|
||||
snprintf(errstr, len, "TCP MSS too large (maximum = %d bytes)", MAX_MSS);
|
||||
break;
|
||||
case IENEWTEST:
|
||||
snprintf(errstr, len, "unable to create a new test");
|
||||
break;
|
||||
case IEINITTEST:
|
||||
snprintf(errstr, len, "test initialization failed");
|
||||
break;
|
||||
case IELISTEN:
|
||||
snprintf(errstr, len, "unable to start listener for connections");
|
||||
break;
|
||||
case IECONNECT:
|
||||
snprintf(errstr, len, "unable to connect to server");
|
||||
break;
|
||||
case IEACCEPT:
|
||||
snprintf(errstr, len, "unable to accept connection from client");
|
||||
break;
|
||||
case IESENDCOOKIE:
|
||||
snprintf(errstr, len, "unable to send cookie to server");
|
||||
break;
|
||||
case IERECVCOOKIE:
|
||||
snprintf(errstr, len, "unable to receive cookie to server");
|
||||
break;
|
||||
case IECTRLWRITE:
|
||||
snprintf(errstr, len, "unable to write to the control socket");
|
||||
break;
|
||||
case IECTRLREAD:
|
||||
snprintf(errstr, len, "unable to read from the control socket");
|
||||
break;
|
||||
case IECTRLCLOSE:
|
||||
snprintf(errstr, len, "control socket has closed unexpectedly");
|
||||
break;
|
||||
case IEMESSAGE:
|
||||
snprintf(errstr, len, "received an unknown control message");
|
||||
break;
|
||||
case IESENDMESSAGE:
|
||||
snprintf(errstr, len, "unable to send control message");
|
||||
break;
|
||||
case IERECVMESSAGE:
|
||||
snprintf(errstr, len, "unable to receive control message");
|
||||
break;
|
||||
case IESENDPARAMS:
|
||||
snprintf(errstr, len, "unable to send parameters to server");
|
||||
break;
|
||||
case IERECVPARAMS:
|
||||
snprintf(errstr, len, "unable to receive parameters from client");
|
||||
break;
|
||||
case IEPACKAGERESULTS:
|
||||
snprintf(errstr, len, "unable to package results");
|
||||
break;
|
||||
case IESENDRESULTS:
|
||||
snprintf(errstr, len, "unable to send results");
|
||||
break;
|
||||
case IERECVRESULTS:
|
||||
snprintf(errstr, len, "unable to receive results");
|
||||
break;
|
||||
case IESELECT:
|
||||
snprintf(errstr, len, "select failed");
|
||||
break;
|
||||
case IESERVERTERM:
|
||||
snprintf(errstr, len, "the server has terminated");
|
||||
break;
|
||||
case IEACCESSDENIED:
|
||||
snprintf(errstr, len, "the server is busy running a test. try again later.");
|
||||
break;
|
||||
case IESETNODELAY:
|
||||
snprintf(errstr, len, "unable to set TCP NODELAY");
|
||||
break;
|
||||
case IESETMSS:
|
||||
snprintf(errstr, len, "unable to set TCP MSS");
|
||||
break;
|
||||
case IEREUSEADDR:
|
||||
snprintf(errstr, len, "unable to reuse address on socket");
|
||||
break;
|
||||
case IENONBLOCKING:
|
||||
snprintf(errstr, len, "unable to set socket to non-blocking");
|
||||
break;
|
||||
case IESETWINDOWSIZE:
|
||||
snprintf(errstr, len, "unable to set socket window size");
|
||||
break;
|
||||
case IECREATESTREAM:
|
||||
snprintf(errstr, len, "unable to create a new stream");
|
||||
break;
|
||||
case IEINITSTREAM:
|
||||
snprintf(errstr, len, "unable to initialize stream");
|
||||
break;
|
||||
case IESTREAMCONNECT:
|
||||
snprintf(errstr, len, "unable to connect stream");
|
||||
break;
|
||||
case IESTREAMACCEPT:
|
||||
snprintf(errstr, len, "unable to accept stream connection");
|
||||
break;
|
||||
case IESTREAMWRITE:
|
||||
snprintf(errstr, len, "unable to write to stream socket");
|
||||
break;
|
||||
case IESTREAMREAD:
|
||||
snprintf(errstr, len, "unable to read from stream socket");
|
||||
break;
|
||||
case IESTREAMCLOSE:
|
||||
snprintf(errstr, len, "stream socket has closed unexpectedly");
|
||||
break;
|
||||
case IESTREAMID:
|
||||
snprintf(errstr, len, "stream has an invalid id");
|
||||
break;
|
||||
case IENEWTIMER:
|
||||
snprintf(errstr, len, "unable to create new timer");
|
||||
break;
|
||||
case IEUPDATETIMER:
|
||||
snprintf(errstr, len, "unable to update timer");
|
||||
break;
|
||||
}
|
||||
|
||||
return (errstr);
|
||||
}
|
||||
|
||||
void
|
||||
ierror(char *estr)
|
||||
iperf_error(char *estr)
|
||||
{
|
||||
fprintf(stderr, "%s: ", estr);
|
||||
fprintf(stderr, "%s", iperf_strerror(i_errno));
|
||||
if (errno)
|
||||
fprintf(stderr, ": %s", strerror(errno));
|
||||
else if (h_errno)
|
||||
fprintf(stderr, ": %s", hstrerror(h_errno));
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
void
|
||||
iperf_error(char *estr)
|
||||
{
|
||||
fprintf(stderr, "%s: ", estr);
|
||||
|
||||
@ -166,5 +333,90 @@ ierror(char *estr)
|
||||
else
|
||||
fprintf(stderr, "unable to receive control message\n");
|
||||
break;
|
||||
case IESENDCOOKIE:
|
||||
if (errno)
|
||||
fprintf(stderr, "unable to send cookie to server: %s\n", strerror(errno));
|
||||
else
|
||||
fprintf(stderr, "unable to send cookie to server\n");
|
||||
break;
|
||||
case IERECVCOOKIE:
|
||||
if (errno)
|
||||
fprintf(stderr, "unable to receive cookie to server: %s\n", strerror(errno));
|
||||
else
|
||||
fprintf(stderr, "unable to receive cookie to server\n");
|
||||
break;
|
||||
case IELISTEN:
|
||||
if (errno)
|
||||
fprintf(stderr, "unable to start listener for connections: %s\n", strerror(errno));
|
||||
else
|
||||
fprintf(stderr, "unable to start listener for connections\n");
|
||||
break;
|
||||
case IEACCEPT:
|
||||
if (errno)
|
||||
fprintf(stderr, "unable to accept connection from client: %s\n", strerror(errno));
|
||||
else if (h_errno)
|
||||
fprintf(stderr, "unable to accept connection from client: %s\n", hstrerror(h_errno));
|
||||
else
|
||||
fprintf(stderr, "unable to accept connection from client\n");
|
||||
break;
|
||||
case IESETNODELAY:
|
||||
if (errno)
|
||||
fprintf(stderr, "unable to set TCP NODELAY: %s\n", strerror(errno));
|
||||
else
|
||||
fprintf(stderr, "unable to set TCP NODELAY\n");
|
||||
break;
|
||||
case IESETMSS:
|
||||
if (errno)
|
||||
fprintf(stderr, "unable to set TCP MSS: %s\n", strerror(errno));
|
||||
else
|
||||
fprintf(stderr, "unable to set TCP MSS\n");
|
||||
break;
|
||||
case IEREUSEADDR:
|
||||
if (errno)
|
||||
fprintf(stderr, "unable to reuse address on socket: %s\n", strerror(errno));
|
||||
else
|
||||
fprintf(stderr, "unable to reuse address on socket\n");
|
||||
break;
|
||||
case IESTREAMCONNECT:
|
||||
if (errno)
|
||||
fprintf(stderr, "unable to connect stream: %s\n", strerror(errno));
|
||||
else if (h_errno)
|
||||
fprintf(stderr, "unable to connect stream: %s\n", hstrerror(h_errno));
|
||||
else
|
||||
fprintf(stderr, "unable to connect stream\n");
|
||||
break;
|
||||
case IESTREAMACCEPT:
|
||||
if (errno)
|
||||
fprintf(stderr, "unable to accept stream connection: %s\n", strerror(errno));
|
||||
else
|
||||
fprintf(stderr, "unable to accept stream connection\n");
|
||||
break;
|
||||
case IENONBLOCKING:
|
||||
if (errno)
|
||||
fprintf(stderr, "unable to set socket to non-blocking: %s\n", strerror(errno));
|
||||
else
|
||||
fprintf(stderr, "unable to set socket to non-blocking\n");
|
||||
break;
|
||||
case IEUPDATETIMER:
|
||||
if (errno)
|
||||
fprintf(stderr, "unable to update timer: %s\n", strerror(errno));
|
||||
else
|
||||
fprintf(stderr, "unable to update timer\n");
|
||||
break;
|
||||
case IENEWTIMER:
|
||||
if (errno)
|
||||
fprintf(stderr, "unable to create new timer: %s\n", strerror(errno));
|
||||
else
|
||||
fprintf(stderr, "unable to create new timer\n");
|
||||
break;
|
||||
case IEINITTEST:
|
||||
if (errno)
|
||||
fprintf(stderr, "test initialization failed: %s\n", strerror(errno));
|
||||
else
|
||||
fprintf(stderr, "test initialization failed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
@ -6,11 +6,15 @@
|
||||
#ifndef __IPERF_ERROR_H
|
||||
#define __IPERF_ERROR_H
|
||||
|
||||
void ierror(char *);
|
||||
void iperf_error(char *);
|
||||
|
||||
char *iperf_strerror(int);
|
||||
|
||||
extern int i_errno;
|
||||
|
||||
enum {
|
||||
/* Parameter errors */
|
||||
IENONE = 0, // No error
|
||||
IESERVCLIENT = 1, // Iperf cannot be both server and client
|
||||
IENOROLE = 2, // Iperf must either be a client (-c) or server (-s)
|
||||
IECLIENTONLY = 3, // This option is client only
|
||||
@ -20,29 +24,48 @@ enum {
|
||||
IEBUFSIZE = 7, // Socket buffer size too large. Maximum value = %dMAX_TCP_BUFFER
|
||||
IEINTERVAL = 8, // Report interval too large. Maxumum value = %dMAX_INTERVAL
|
||||
IEMSS = 9, // MSS too large. Maximum value = %dMAX_MSS
|
||||
IECTRLWRITE = 10, // Unable to write to the control socket (check perror)
|
||||
IECTRLREAD = 11, // Unable to read from the control socket (check perror)
|
||||
IECTRLCLOSE = 12, // Control socket has closed unexpectedly
|
||||
IESTREAMWRITE = 13, // Unable to write to stream socket (check perror)
|
||||
IESTREAMREAD = 14, // Unable to read from stream (check perror)
|
||||
IESTREAMCLOSE = 15, // Stream has closed unexpectedly
|
||||
IENEWTEST = 16, // Unable to create a new test (check perror)
|
||||
IECONNECT = 17, // Unable to connect to server (check herror/perror) [from netdial]
|
||||
IESELECT = 18, // Select failed (check perror)
|
||||
IESENDPARAMS = 19, // Unable to send parameters to server (check perror)
|
||||
IERECVPARAMS = 20, // Unable to receive parameters from client (check perror)
|
||||
IECREATESTREAM = 21, // Unable to create a new stream (check herror/perror)
|
||||
IEINITSTREAM = 22, // Unable to initialize stream (check herror/perror)
|
||||
IESETWINDOWSIZE = 23, // Unable to set socket window size (check perror)
|
||||
IEPACKAGERESULTS = 24, // Unable to package results (check perror)
|
||||
IESENDRESULTS = 25, // Unable to send results to client/server (check perror)
|
||||
IERECVRESULTS = 26, // Unable to receive results from client/server (check perror)
|
||||
IESTREAMID = 27, // Stream has invalid ID
|
||||
IESERVERTERM = 28, // The server has terminated
|
||||
IEACCESSDENIED = 29, // The server is busy running a test. Try again later.
|
||||
IEMESSAGE = 30, // Received an unknown message
|
||||
IESENDMESSAGE = 31, // Unable to send control message to client/server (check perror)
|
||||
IERECVMESSAGE = 32, // Unable to receive control message from client/server (check perror)
|
||||
|
||||
/* Test errors */
|
||||
IENEWTEST = 10, // Unable to create a new test (check perror)
|
||||
IEINITTEST = 11, // Test initialization failed (check perror)
|
||||
IELISTEN = 12, // Unable to listen for connections (check perror)
|
||||
IECONNECT = 13, // Unable to connect to server (check herror/perror) [from netdial]
|
||||
IEACCEPT = 14, // Unable to accept connection from client (check herror/perror)
|
||||
IESENDCOOKIE = 15, // Unable to send cookie to server (check perror)
|
||||
IERECVCOOKIE = 16, // Unable to receive cookie from client (check perror)
|
||||
IECTRLWRITE = 17, // Unable to write to the control socket (check perror)
|
||||
IECTRLREAD = 18, // Unable to read from the control socket (check perror)
|
||||
IECTRLCLOSE = 19, // Control socket has closed unexpectedly
|
||||
IEMESSAGE = 20, // Received an unknown message
|
||||
IESENDMESSAGE = 21, // Unable to send control message to client/server (check perror)
|
||||
IERECVMESSAGE = 22, // Unable to receive control message from client/server (check perror)
|
||||
IESENDPARAMS = 23, // Unable to send parameters to server (check perror)
|
||||
IERECVPARAMS = 24, // Unable to receive parameters from client (check perror)
|
||||
IEPACKAGERESULTS = 25, // Unable to package results (check perror)
|
||||
IESENDRESULTS = 26, // Unable to send results to client/server (check perror)
|
||||
IERECVRESULTS = 27, // Unable to receive results from client/server (check perror)
|
||||
IESELECT = 28, // Select failed (check perror)
|
||||
IESERVERTERM = 29, // The server has terminated
|
||||
IEACCESSDENIED = 30, // The server is busy running a test. Try again later.
|
||||
IESETNODELAY = 31, // Unable to set TCP NODELAY (check perror)
|
||||
IESETMSS = 32, // Unable to set TCP MSS (check perror)
|
||||
IEREUSEADDR = 33, // Unable to set reuse address on socket (check perror)
|
||||
IENONBLOCKING = 34, // Unable to set socket to non-blocking (check perror)
|
||||
IESETWINDOWSIZE = 35, // Unable to set socket window size (check perror)
|
||||
|
||||
/* Stream errors */
|
||||
IECREATESTREAM = 36, // Unable to create a new stream (check herror/perror)
|
||||
IEINITSTREAM = 37, // Unable to initialize stream (check herror/perror)
|
||||
IESTREAMCONNECT = 38, // Unable to connect stream (check herror/perror)
|
||||
IESTREAMACCEPT = 39, // Unable to accepte stream connection (check perror)
|
||||
IESTREAMWRITE = 40, // Unable to write to stream socket (check perror)
|
||||
IESTREAMREAD = 41, // Unable to read from stream (check perror)
|
||||
IESTREAMCLOSE = 42, // Stream has closed unexpectedly
|
||||
IESTREAMID = 43, // Stream has invalid ID
|
||||
|
||||
/* Timer errors */
|
||||
IENEWTIMER = 44, // Unable to create new timer (check perror)
|
||||
IEUPDATETIMER = 45, // Unable to update timer (check perror)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "iperf_api.h"
|
||||
#include "iperf_udp.h"
|
||||
#include "iperf_tcp.h"
|
||||
#include "iperf_error.h"
|
||||
#include "timer.h"
|
||||
#include "net.h"
|
||||
#include "units.h"
|
||||
@ -51,9 +52,8 @@ iperf_server_listen(struct iperf_test *test)
|
||||
int x;
|
||||
|
||||
if((test->listener_tcp = netannounce(Ptcp, NULL, test->server_port)) < 0) {
|
||||
// Needs to set some sort of error number/message
|
||||
perror("netannounce test->listener_tcp");
|
||||
return -1;
|
||||
i_errno = IELISTEN;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
printf("-----------------------------------------------------------\n");
|
||||
@ -95,83 +95,68 @@ iperf_accept(struct iperf_test *test)
|
||||
{
|
||||
int s;
|
||||
int rbuf = ACCESS_DENIED;
|
||||
char ipl[512], ipr[512];
|
||||
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;
|
||||
struct iperf_stream *sp;
|
||||
static int streams_accepted;
|
||||
|
||||
len = sizeof(addr);
|
||||
if ((s = accept(test->listener_tcp, (struct sockaddr *) &addr, &len)) < 0) {
|
||||
perror("accept");
|
||||
return -1;
|
||||
i_errno = IEACCEPT;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (test->ctrl_sck == -1) {
|
||||
/* Server free, accept new client */
|
||||
if (Nread(s, test->default_settings->cookie, COOKIE_SIZE, Ptcp) < 0) {
|
||||
perror("Nread COOKIE\n");
|
||||
return -1;
|
||||
i_errno = IERECVCOOKIE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
FD_SET(s, &test->read_set);
|
||||
FD_SET(s, &test->write_set);
|
||||
test->max_fd = (s > test->max_fd) ? s : test->max_fd;
|
||||
test->ctrl_sck = s;
|
||||
streams_accepted = 0;
|
||||
|
||||
len = sizeof(struct sockaddr_in);
|
||||
if (getsockname(s, (struct sockaddr *) &temp1, &len) < 0)
|
||||
perror("getsockname");
|
||||
if (getpeername(s, (struct sockaddr *) &temp2, &len) < 0)
|
||||
perror("getpeername");
|
||||
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) {
|
||||
perror("Nwrite PARAM_EXCHANGE\n");
|
||||
exit(1);
|
||||
i_errno = IESENDMESSAGE;
|
||||
return (-1);
|
||||
}
|
||||
if (iperf_exchange_parameters(test) < 0) {
|
||||
return (-1);
|
||||
}
|
||||
iperf_exchange_parameters(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) {
|
||||
perror("Nread COOKIE\n");
|
||||
return -1;
|
||||
i_errno = IERECVCOOKIE;
|
||||
return (-1);
|
||||
}
|
||||
if ((strcmp(test->default_settings->cookie, cookie) == 0) && (test->state == CREATE_STREAMS)) {
|
||||
sp = test->new_stream(test);
|
||||
sp->socket = s;
|
||||
iperf_init_stream(sp, test);
|
||||
iperf_add_stream(test, sp);
|
||||
FD_SET(s, &test->read_set);
|
||||
FD_SET(s, &test->write_set);
|
||||
test->max_fd = (s > test->max_fd) ? s : test->max_fd;
|
||||
connect_msg(sp);
|
||||
|
||||
++streams_accepted;
|
||||
if (streams_accepted == test->num_streams) {
|
||||
test->state = TEST_START;
|
||||
if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) {
|
||||
perror("Nwrite TEST_START\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (Nwrite(s, &rbuf, sizeof(int), Ptcp) < 0) {
|
||||
perror("Nwrite ACCESS_DENIED");
|
||||
return -1;
|
||||
i_errno = IESENDMESSAGE;
|
||||
return (-1);
|
||||
}
|
||||
close(s);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@ -187,20 +172,23 @@ iperf_accept_tcp_stream(struct iperf_test *test)
|
||||
|
||||
len = sizeof(addr);
|
||||
if ((s = accept(test->listener_tcp, (struct sockaddr *) &addr, &len)) < 0) {
|
||||
perror("accept tcp stream");
|
||||
i_errno = IESTREAMCONNECT;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (Nread(s, cookie, COOKIE_SIZE, Ptcp) < 0) {
|
||||
perror("Nread cookie");
|
||||
i_errno = IERECVCOOKIE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (strcmp(test->default_settings->cookie, cookie) == 0) {
|
||||
// XXX: CANNOT USE iperf_tcp_accept since stream is alread accepted at this point. New model needed!
|
||||
// XXX: CANNOT USE iperf_tcp_accept since stream is already accepted at this point. New model needed!
|
||||
sp = test->new_stream(test);
|
||||
if (!sp)
|
||||
return (-1);
|
||||
sp->socket = s;
|
||||
iperf_init_stream(sp, test);
|
||||
if (iperf_init_stream(sp, test) < 0)
|
||||
return (-1);
|
||||
iperf_add_stream(test, sp);
|
||||
FD_SET(s, &test->read_set);
|
||||
FD_SET(s, &test->write_set);
|
||||
@ -209,7 +197,7 @@ iperf_accept_tcp_stream(struct iperf_test *test)
|
||||
connect_msg(sp);
|
||||
} else {
|
||||
if (Nwrite(s, &rbuf, sizeof(char), Ptcp) < 0) {
|
||||
perror("Nwrite ACCESS_DENIED");
|
||||
i_errno = IESENDMESSAGE;
|
||||
return (-1);
|
||||
}
|
||||
close(s);
|
||||
@ -217,14 +205,6 @@ iperf_accept_tcp_stream(struct iperf_test *test)
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
iperf_accept_udp_stream(struct iperf_test *test)
|
||||
{
|
||||
// do nothing for now
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
int
|
||||
iperf_handle_message_server(struct iperf_test *test)
|
||||
@ -232,14 +212,16 @@ iperf_handle_message_server(struct iperf_test *test)
|
||||
int rval;
|
||||
struct iperf_stream *sp;
|
||||
|
||||
if ((rval = read(test->ctrl_sck, &test->state, sizeof(char))) <= 0) {
|
||||
// XXX: Need to rethink how this behaves to fit API
|
||||
if ((rval = Nread(test->ctrl_sck, &test->state, sizeof(char), Ptcp)) <= 0) {
|
||||
if (rval == 0) {
|
||||
fprintf(stderr, "The client has unexpectedly closed the connection.\n");
|
||||
i_errno = IECTRLCLOSE;
|
||||
test->state = IPERF_DONE;
|
||||
return 0;
|
||||
return (0);
|
||||
} else {
|
||||
perror("read ctrl_sck");
|
||||
return -1;
|
||||
i_errno = IERECVMESSAGE;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,14 +237,15 @@ iperf_handle_message_server(struct iperf_test *test)
|
||||
}
|
||||
test->state = EXCHANGE_RESULTS;
|
||||
if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) {
|
||||
perror("Nwrite EXCHANGE_RESULTS");
|
||||
exit(1);
|
||||
i_errno = IESENDMESSAGE;
|
||||
return (-1);
|
||||
}
|
||||
iperf_exchange_results(test);
|
||||
if (iperf_exchange_results(test) < 0)
|
||||
return (-1);
|
||||
test->state = DISPLAY_RESULTS;
|
||||
if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) {
|
||||
perror("Nwrite DISPLAY_RESULTS");
|
||||
exit(1);
|
||||
i_errno = IESENDMESSAGE;
|
||||
return (-1);
|
||||
}
|
||||
test->reporter_callback(test);
|
||||
break;
|
||||
@ -278,12 +261,11 @@ iperf_handle_message_server(struct iperf_test *test)
|
||||
test->state = IPERF_DONE;
|
||||
break;
|
||||
default:
|
||||
// XXX: This needs to be replaced by actual error handling
|
||||
fprintf(stderr, "Unrecognized state: %d\n", test->state);
|
||||
return -1;
|
||||
i_errno = IEMESSAGE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
@ -344,18 +326,16 @@ iperf_run_server(struct iperf_test *test)
|
||||
|
||||
// Open socket and listen
|
||||
if (iperf_server_listen(test) < 0) {
|
||||
// XXX: This needs to be replaced by more formal error handling
|
||||
fprintf(stderr, "An error occurred. Exiting.\n");
|
||||
exit(1);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
signal(SIGINT, sig_handler);
|
||||
if (setjmp(env)) {
|
||||
fprintf(stderr, "Exiting...\n");
|
||||
test->state = SERVER_TERMINATE;
|
||||
if (test->ctrl_sck >= 0) {
|
||||
if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) {
|
||||
fprintf(stderr, "Unable to send SERVER_TERMINATE message to client\n");
|
||||
i_errno = IESENDMESSAGE;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -374,21 +354,20 @@ iperf_run_server(struct iperf_test *test)
|
||||
|
||||
result = select(test->max_fd + 1, &temp_read_set, &temp_write_set, NULL, &tv);
|
||||
if (result < 0 && errno != EINTR) {
|
||||
// Change the way this handles errors
|
||||
perror("select");
|
||||
exit(1);
|
||||
i_errno = IESELECT;
|
||||
return (-1);
|
||||
} else if (result > 0) {
|
||||
if (FD_ISSET(test->listener_tcp, &temp_read_set)) {
|
||||
if (test->state != CREATE_STREAMS) {
|
||||
if (iperf_accept(test) < 0) {
|
||||
fprintf(stderr, "iperf_accept: error accepting control socket. exiting...\n");
|
||||
exit(1);
|
||||
return (-1);
|
||||
}
|
||||
FD_CLR(test->listener_tcp, &temp_read_set);
|
||||
}
|
||||
}
|
||||
if (FD_ISSET(test->ctrl_sck, &temp_read_set)) {
|
||||
iperf_handle_message_server(test);
|
||||
if (iperf_handle_message_server(test) < 0)
|
||||
return (-1);
|
||||
FD_CLR(test->ctrl_sck, &temp_read_set);
|
||||
}
|
||||
|
||||
@ -396,16 +375,14 @@ iperf_run_server(struct iperf_test *test)
|
||||
if (test->protocol == Ptcp) {
|
||||
if (FD_ISSET(test->listener_tcp, &temp_read_set)) {
|
||||
if (iperf_accept_tcp_stream(test) < 0) {
|
||||
fprintf(stderr, "iperf_accept_tcp_stream: an error occurred.\n");
|
||||
exit(1);
|
||||
return (-1);
|
||||
}
|
||||
FD_CLR(test->listener_tcp, &temp_read_set);
|
||||
}
|
||||
} else {
|
||||
if (FD_ISSET(test->listener_udp, &temp_read_set)) {
|
||||
if (iperf_udp_accept(test) < 0) {
|
||||
fprintf(stderr, "iperf_accept_udp_stream: an error occurred.\n");
|
||||
exit(1);
|
||||
return (-1);
|
||||
}
|
||||
FD_CLR(test->listener_udp, &temp_read_set);
|
||||
}
|
||||
@ -420,7 +397,7 @@ iperf_run_server(struct iperf_test *test)
|
||||
FD_CLR(test->listener_tcp, &test->read_set);
|
||||
close(test->listener_tcp);
|
||||
if ((s = netannounce(Ptcp, NULL, test->server_port)) < 0) {
|
||||
perror("reconnect tcp listener");
|
||||
i_errno = IELISTEN;
|
||||
return (-1);
|
||||
}
|
||||
test->listener_tcp = s;
|
||||
@ -430,14 +407,15 @@ iperf_run_server(struct iperf_test *test)
|
||||
}
|
||||
test->state = TEST_START;
|
||||
if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) {
|
||||
perror("Nwrite TEST_START");
|
||||
return -1;
|
||||
i_errno = IESENDMESSAGE;
|
||||
return (-1);
|
||||
}
|
||||
iperf_init_test(test);
|
||||
if (iperf_init_test(test) < 0)
|
||||
return (-1);
|
||||
test->state = TEST_RUNNING;
|
||||
if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) {
|
||||
perror("Nwrite TEST_RUNNING");
|
||||
return -1;
|
||||
i_errno = IESENDMESSAGE;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -445,20 +423,24 @@ iperf_run_server(struct iperf_test *test)
|
||||
if (test->state == TEST_RUNNING) {
|
||||
if (test->reverse) {
|
||||
// Reverse mode. Server sends.
|
||||
iperf_send(test);
|
||||
if (iperf_send(test) < 0)
|
||||
return (-1);
|
||||
} else {
|
||||
// Regular mode. Server receives.
|
||||
iperf_recv(test);
|
||||
if (iperf_recv(test) < 0)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Perform callbacks */
|
||||
if (timer_expired(test->stats_timer)) {
|
||||
test->stats_callback(test);
|
||||
update_timer(test->stats_timer, test->stats_interval, 0);
|
||||
if (update_timer(test->stats_timer, test->stats_interval, 0) < 0)
|
||||
return (-1);
|
||||
}
|
||||
if (timer_expired(test->reporter_timer)) {
|
||||
test->reporter_callback(test);
|
||||
update_timer(test->reporter_timer, test->reporter_interval, 0);
|
||||
if (update_timer(test->reporter_timer, test->reporter_interval, 0) < 0)
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -470,6 +452,6 @@ iperf_run_server(struct iperf_test *test)
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -55,10 +55,6 @@ iperf_tcp_recv(struct iperf_stream * sp)
|
||||
int result = 0;
|
||||
int size = sp->settings->blksize;
|
||||
|
||||
if (!sp->buffer) {
|
||||
fprintf(stderr, "iperf_tcp_recv: receive buffer not allocated\n");
|
||||
return -1;
|
||||
}
|
||||
#ifdef USE_RECV
|
||||
/*
|
||||
* NOTE: Nwrite/Nread seems to be 10-15% faster than send/recv for
|
||||
@ -70,9 +66,8 @@ iperf_tcp_recv(struct iperf_stream * sp)
|
||||
#else
|
||||
result = Nread(sp->socket, sp->buffer, size, Ptcp);
|
||||
#endif
|
||||
if (result == -1) {
|
||||
perror("Read error");
|
||||
return -1;
|
||||
if (result < 0) {
|
||||
return (-1);
|
||||
}
|
||||
sp->result->bytes_received += result;
|
||||
sp->result->bytes_received_this_interval += result;
|
||||
@ -94,18 +89,14 @@ iperf_tcp_send(struct iperf_stream * sp)
|
||||
int result;
|
||||
int size = sp->settings->blksize;
|
||||
|
||||
if (!sp->buffer) {
|
||||
fprintf(stderr, "iperf_tcp_send: transmit buffer not allocated\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef USE_SEND
|
||||
result = send(sp->socket, sp->buffer, size, 0);
|
||||
#else
|
||||
result = Nwrite(sp->socket, sp->buffer, size, Ptcp);
|
||||
#endif
|
||||
if (result < 0)
|
||||
perror("Nwrite error");
|
||||
if (result < 0) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
sp->result->bytes_sent += result;
|
||||
sp->result->bytes_sent_this_interval += result;
|
||||
@ -121,7 +112,6 @@ iperf_new_tcp_stream(struct iperf_test * testp)
|
||||
|
||||
sp = (struct iperf_stream *) iperf_new_stream(testp);
|
||||
if (!sp) {
|
||||
perror("malloc");
|
||||
return (NULL);
|
||||
}
|
||||
sp->rcv = iperf_tcp_recv; /* pointer to receive function */
|
||||
@ -135,7 +125,7 @@ iperf_new_tcp_stream(struct iperf_test * testp)
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
/**
|
||||
/** XXX: This function is not currently in use!
|
||||
* iperf_tcp_accept -- accepts a new TCP connection
|
||||
* on tcp_listener_socket for TCP data and param/result
|
||||
* exchange messages
|
||||
@ -159,9 +149,6 @@ iperf_tcp_accept(struct iperf_test * test)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// XXX: Nonblocking off. OKAY since we use select.
|
||||
// setnonblocking(peersock);
|
||||
|
||||
// XXX: This doesn't fit our API model!
|
||||
sp = test->new_stream(test);
|
||||
sp->socket = peersock;
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "iperf.h"
|
||||
#include "iperf_api.h"
|
||||
#include "iperf_udp.h"
|
||||
#include "iperf_error.h"
|
||||
#include "timer.h"
|
||||
#include "net.h"
|
||||
#include "locale.h"
|
||||
@ -68,7 +69,6 @@ iperf_udp_recv(struct iperf_stream *sp)
|
||||
#endif
|
||||
|
||||
if (result < 0) {
|
||||
perror("Nread udp result");
|
||||
return (-1);
|
||||
}
|
||||
sp->result->bytes_received += result;
|
||||
@ -95,9 +95,8 @@ iperf_udp_recv(struct iperf_stream *sp)
|
||||
}
|
||||
|
||||
/* jitter measurement */
|
||||
if (gettimeofday(&arrival_time, NULL) < 0) {
|
||||
perror("gettimeofday");
|
||||
}
|
||||
gettimeofday(&arrival_time, NULL);
|
||||
|
||||
transit = timeval_diff(&sent_time, &arrival_time);
|
||||
d = transit - sp->prev_transit;
|
||||
if (d < 0)
|
||||
@ -129,8 +128,8 @@ iperf_udp_send(struct iperf_stream *sp)
|
||||
|
||||
assert(dtargus != 0);
|
||||
|
||||
if (gettimeofday(&before, 0) < 0)
|
||||
perror("gettimeofday");
|
||||
gettimeofday(&before, 0);
|
||||
|
||||
++sp->packet_count;
|
||||
sec = htonl(before.tv_sec);
|
||||
usec = htonl(before.tv_usec);
|
||||
@ -147,13 +146,12 @@ iperf_udp_send(struct iperf_stream *sp)
|
||||
#endif
|
||||
|
||||
if (result < 0)
|
||||
perror("Nwrite udp error");
|
||||
return (-1);
|
||||
|
||||
sp->result->bytes_sent += result;
|
||||
sp->result->bytes_sent_this_interval += result;
|
||||
|
||||
if (gettimeofday(&after, 0) < 0)
|
||||
perror("gettimeofday");
|
||||
gettimeofday(&after, 0);
|
||||
|
||||
adjustus = dtargus;
|
||||
adjustus += (before.tv_sec - after.tv_sec) * SEC_TO_US;
|
||||
@ -163,7 +161,8 @@ iperf_udp_send(struct iperf_stream *sp)
|
||||
dtargus = adjustus;
|
||||
}
|
||||
|
||||
update_timer(sp->send_timer, 0, dtargus);
|
||||
if (update_timer(sp->send_timer, 0, dtargus) < 0)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -177,7 +176,6 @@ iperf_new_udp_stream(struct iperf_test * testp)
|
||||
|
||||
sp = (struct iperf_stream *) iperf_new_stream(testp);
|
||||
if (!sp) {
|
||||
perror("malloc");
|
||||
return (NULL);
|
||||
}
|
||||
sp->rcv = iperf_udp_recv;
|
||||
@ -209,41 +207,44 @@ iperf_udp_accept(struct iperf_test *test)
|
||||
|
||||
len = sizeof sa_peer;
|
||||
if ((sz = recvfrom(test->listener_udp, &buf, sizeof(buf), 0, (struct sockaddr *) &sa_peer, &len)) < 0) {
|
||||
perror("recvfrom in udp accept");
|
||||
i_errno = IESTREAMACCEPT;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (connect(s, (struct sockaddr *) &sa_peer, len) < 0) {
|
||||
perror("iperf_udp_accept: connect error");
|
||||
return -1;
|
||||
i_errno = IESTREAMACCEPT;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
sp = test->new_stream(test);
|
||||
if (!sp)
|
||||
return (-1);
|
||||
sp->socket = s;
|
||||
iperf_init_stream(sp, test);
|
||||
if (iperf_init_stream(sp, test) < 0)
|
||||
return (-1);
|
||||
iperf_add_stream(test, sp);
|
||||
FD_SET(s, &test->read_set);
|
||||
FD_SET(s, &test->write_set);
|
||||
test->max_fd = (s > test->max_fd) ? s : test->max_fd;
|
||||
|
||||
test->listener_udp = netannounce(Pudp, NULL, test->server_port);
|
||||
if (test->listener_udp < 0)
|
||||
return -1;
|
||||
if (test->listener_udp < 0) {
|
||||
i_errno = IELISTEN;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
FD_SET(test->listener_udp, &test->read_set);
|
||||
test->max_fd = (test->max_fd < test->listener_udp) ? test->listener_udp : test->max_fd;
|
||||
|
||||
/* Let the client know we're ready "accept" another UDP "stream" */
|
||||
if (write(sp->socket, &buf, sizeof(buf)) < 0) {
|
||||
perror("write listen message");
|
||||
return -1;
|
||||
i_errno = IESTREAMWRITE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
connect_msg(sp);
|
||||
test->streams_accepted++;
|
||||
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -77,20 +77,20 @@ main(int argc, char **argv)
|
||||
|
||||
test = iperf_new_test();
|
||||
if (!test) {
|
||||
ierror("create new test error");
|
||||
iperf_error("create new test error");
|
||||
exit(1);
|
||||
}
|
||||
iperf_defaults(test); /* sets defaults */
|
||||
|
||||
if (iperf_parse_arguments(test, argc, argv) < 0) {
|
||||
ierror("parameter error");
|
||||
iperf_error("parameter error");
|
||||
fprintf(stderr, "\n");
|
||||
usage_long();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (iperf_run(test) < 0) {
|
||||
ierror("error");
|
||||
iperf_error("error");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
15
src/net.c
15
src/net.c
@ -29,13 +29,11 @@ netdial(int proto, char *client, int port)
|
||||
|
||||
/* XXX: This is not working for non-fully qualified host names use getaddrinfo() instead? */
|
||||
if ((hent = gethostbyname(client)) == 0) {
|
||||
// perror("gethostbyname");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
s = socket(AF_INET, proto, 0);
|
||||
if (s < 0) {
|
||||
// perror("socket");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -45,7 +43,6 @@ netdial(int proto, char *client, int port)
|
||||
sa.sin_family = AF_INET;
|
||||
|
||||
if (connect(s, (struct sockaddr *) & sa, sizeof sa) < 0 && errno != EINPROGRESS) {
|
||||
// perror("netdial: connect error");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -53,7 +50,6 @@ netdial(int proto, char *client, int port)
|
||||
|
||||
// XXX: Is there a reason to call getpeername() if none of the return values are used?
|
||||
if (getpeername(s, (struct sockaddr *) & sa, &sn) < 0) {
|
||||
// perror("getpeername error");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -73,7 +69,6 @@ netannounce(int proto, char *local, int port)
|
||||
|
||||
s = socket(AF_INET, proto, 0);
|
||||
if (s < 0) {
|
||||
perror("socket");
|
||||
return (-1);
|
||||
}
|
||||
int opt = 1;
|
||||
@ -84,12 +79,14 @@ netannounce(int proto, char *local, int port)
|
||||
|
||||
if (bind(s, (struct sockaddr *) & sa, sizeof(struct sockaddr_in)) < 0) {
|
||||
close(s);
|
||||
perror("bind");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (proto == SOCK_STREAM)
|
||||
listen(s, 5);
|
||||
if (proto == SOCK_STREAM) {
|
||||
if (listen(s, 5) < 0) {
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
@ -195,6 +192,7 @@ getsock_tcp_mss(int inSock)
|
||||
/*************************************************************/
|
||||
|
||||
/* sets TCP_NODELAY and TCP_MAXSEG if requested */
|
||||
// XXX: This function is not being used.
|
||||
|
||||
int
|
||||
set_tcp_options(int sock, int no_delay, int mss)
|
||||
@ -244,6 +242,7 @@ set_tcp_options(int sock, int no_delay, int mss)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
// XXX: This function is not being used.
|
||||
int
|
||||
setnonblocking(int sock)
|
||||
{
|
||||
|
25
src/timer.c
25
src/timer.c
@ -8,6 +8,7 @@
|
||||
#include <time.h>
|
||||
|
||||
#include "timer.h"
|
||||
#include "iperf_error.h"
|
||||
|
||||
double
|
||||
timeval_to_double(struct timeval * tv)
|
||||
@ -34,10 +35,7 @@ timer_expired(struct timer * tp)
|
||||
struct timeval now;
|
||||
int64_t end = 0, current = 0;
|
||||
|
||||
if (gettimeofday(&now, NULL) < 0) {
|
||||
perror("gettimeofday");
|
||||
return -1;
|
||||
}
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
end += tp->end.tv_sec * 1000000;
|
||||
end += tp->end.tv_usec;
|
||||
@ -48,17 +46,19 @@ timer_expired(struct timer * tp)
|
||||
return current > end;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
update_timer(struct timer * tp, time_t sec, suseconds_t usec)
|
||||
{
|
||||
if (gettimeofday(&tp->begin, NULL) < 0) {
|
||||
perror("gettimeofday");
|
||||
i_errno = IEUPDATETIMER;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec;
|
||||
tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec;
|
||||
|
||||
tp->expired = timer_expired;
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct timer *
|
||||
@ -67,13 +67,13 @@ new_timer(time_t sec, suseconds_t usec)
|
||||
struct timer *tp = NULL;
|
||||
tp = (struct timer *) calloc(1, sizeof(struct timer));
|
||||
if (tp == NULL) {
|
||||
perror("malloc");
|
||||
return NULL;
|
||||
i_errno = IENEWTIMER;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (gettimeofday(&tp->begin, NULL) < 0) {
|
||||
perror("gettimeofday");
|
||||
return NULL;
|
||||
i_errno = IENEWTIMER;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec;
|
||||
@ -131,10 +131,7 @@ timer_remaining(struct timer * tp)
|
||||
struct timeval now;
|
||||
long int end_time = 0, current_time = 0, diff = 0;
|
||||
|
||||
if (gettimeofday(&now, NULL) < 0) {
|
||||
perror("gettimeofday");
|
||||
return -1;
|
||||
}
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
end_time += tp->end.tv_sec * 1000000;
|
||||
end_time += tp->end.tv_usec;
|
||||
|
@ -18,7 +18,7 @@ double timeval_to_double(struct timeval *tv);
|
||||
|
||||
double timeval_diff(struct timeval *tv0, struct timeval *tv1);
|
||||
|
||||
void update_timer(struct timer *tp, time_t sec, suseconds_t usec);
|
||||
int update_timer(struct timer *tp, time_t sec, suseconds_t usec);
|
||||
|
||||
int64_t timer_remaining(struct timer *tp);
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user