From af70b448ee6988d62bdc1c1a4268479a9c80de29 Mon Sep 17 00:00:00 2001 From: sethdelliott Date: Wed, 30 Jun 2010 22:09:45 +0000 Subject: [PATCH] All communications are now on port 5201 (including streams) --- src/iperf.h | 2 +- src/iperf_api.c | 56 ++++++------- src/iperf_server_api.c | 183 +++++++++++++++++++++++++---------------- 3 files changed, 137 insertions(+), 104 deletions(-) diff --git a/src/iperf.h b/src/iperf.h index 0b165e8..9067b3b 100644 --- a/src/iperf.h +++ b/src/iperf.h @@ -114,7 +114,7 @@ struct iperf_test int ctrl_sck; // Server is the only one that needs these - int listener; + int listener_tcp; int prot_listener; diff --git a/src/iperf_api.c b/src/iperf_api.c index bb2fdd5..95f12c1 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -253,11 +253,6 @@ package_parameters(struct iperf_test *test) strcat(pstring, optbuf); } - if (strcmp(test->default_settings->cookie, "") != 0) { - sprintf(optbuf, "-C %s ", test->default_settings->cookie); - strcat(pstring, optbuf); - } - *pstring = (char) (strlen(pstring) - 1); if (write(test->ctrl_sck, pstring, (size_t) strlen(pstring)) < 0) { @@ -303,7 +298,7 @@ parse_parameters(struct iperf_test *test) n++; } - while ((ch = getopt(n, params, "puP:Rw:f:C:")) != -1) { + while ((ch = getopt(n, params, "puP:Rw:")) != -1) { switch (ch) { case 'p': test->protocol = Ptcp; @@ -320,9 +315,6 @@ parse_parameters(struct iperf_test *test) case 'w': test->default_settings->socket_bufsize = atoi(optarg); break; - case 'C': - memcpy(test->default_settings->cookie, optarg, COOKIE_SIZE); - break; } } // XXX: optreset is not needed on ubuntu @@ -344,10 +336,6 @@ iperf_exchange_parameters(struct iperf_test * test) { if (test->role == 'c') { - // XXX: Probably should get the cookie at the start of iperf client rather than - // waiting till here - get_uuid(test->default_settings->cookie); - package_parameters(test); } else { @@ -356,9 +344,11 @@ iperf_exchange_parameters(struct iperf_test * test) printf(" cookie: %s\n", test->default_settings->cookie); - test->prot_listener = netannounce(test->protocol, NULL, test->server_port + 1); - FD_SET(test->prot_listener, &test->read_set); - test->max_fd = (test->prot_listener > test->max_fd) ? test->prot_listener : test->max_fd; + if (test->protocol == Pudp) { + test->prot_listener = netannounce(test->protocol, NULL, test->server_port); + FD_SET(test->prot_listener, &test->read_set); + test->max_fd = (test->prot_listener > test->max_fd) ? test->prot_listener : test->max_fd; + } // Send the control message to create streams and start the test test->state = CREATE_STREAMS; @@ -667,12 +657,19 @@ iperf_create_streams(struct iperf_test *test) int i, s; for (i = 0; i < test->num_streams; ++i) { - s = netdial(test->protocol, test->server_hostname, test->server_port + 1); + s = netdial(test->protocol, test->server_hostname, test->server_port); if (s < 0) { perror("netdial stream"); return -1; } - // printf("File descriptor for stream %d: %d\n", i, s); + + if (test->protocol == Ptcp) { + if (Nwrite(s, test->default_settings->cookie, COOKIE_SIZE, Ptcp) < 0) { + perror("Nwrite COOKIE\n"); + return -1; + } + } + FD_SET(s, &test->read_set); FD_SET(s, &test->write_set); test->max_fd = (test->max_fd < s) ? s : test->max_fd; @@ -707,6 +704,9 @@ iperf_handle_message_client(struct iperf_test *test) break; case TEST_END: break; + case PARAM_EXCHANGE: + iperf_exchange_parameters(test); + break; case EXCHANGE_RESULTS: iperf_exchange_results(test); break; @@ -722,7 +722,7 @@ iperf_handle_message_client(struct iperf_test *test) fprintf(stderr, "The server is busy running a test. Try again later.\n"); exit(0); default: - // XXX: This needs to be replaced + // XXX: This needs to be removed from the production version printf("How did you get here? test->state = %d\n", test->state); break; } @@ -739,27 +739,23 @@ iperf_connect(struct iperf_test *test) FD_ZERO(&test->read_set); FD_ZERO(&test->write_set); + get_uuid(test->default_settings->cookie); + /* Create and connect the control channel */ test->ctrl_sck = netdial(test->protocol, test->server_hostname, test->server_port); if (test->ctrl_sck < 0) { return -1; } + if (Nwrite(test->ctrl_sck, test->default_settings->cookie, COOKIE_SIZE, Ptcp) < 0) { + perror("Nwrite COOKIE\n"); + return -1; + } + FD_SET(test->ctrl_sck, &test->read_set); FD_SET(test->ctrl_sck, &test->write_set); test->max_fd = (test->ctrl_sck > test->max_fd) ? test->ctrl_sck : test->max_fd; - /* Exchange parameters */ - test->state = PARAM_EXCHANGE; - if (write(test->ctrl_sck, &test->state, sizeof(char)) < 0) { - perror("write PARAM_EXCHANGE"); - return -1; - } - if (iperf_exchange_parameters(test) < 0) { - fprintf(stderr, "iperf_exchange_parameters failed\n"); - return -1; - } - return 0; } diff --git a/src/iperf_server_api.c b/src/iperf_server_api.c index f504005..02e4890 100644 --- a/src/iperf_server_api.c +++ b/src/iperf_server_api.c @@ -50,9 +50,9 @@ iperf_server_listen(struct iperf_test *test) char ubuf[UNIT_LEN]; int x; - if((test->listener = netannounce(Ptcp, NULL, test->server_port)) < 0) { + if((test->listener_tcp = netannounce(Ptcp, NULL, test->server_port)) < 0) { // Needs to set some sort of error number/message - perror("netannounce test->listener"); + perror("netannounce test->listener_tcp"); return -1; } @@ -82,8 +82,8 @@ iperf_server_listen(struct iperf_test *test) FD_ZERO(&test->read_set); FD_ZERO(&test->write_set); - FD_SET(test->listener, &test->read_set); - test->max_fd = (test->listener > test->max_fd) ? test->listener : test->max_fd; + FD_SET(test->listener_tcp, &test->read_set); + test->max_fd = (test->listener_tcp > test->max_fd) ? test->listener_tcp : test->max_fd; return 0; } @@ -94,19 +94,30 @@ iperf_accept(struct iperf_test *test) int s; int rbuf = ACCESS_DENIED; char ipl[512], ipr[512]; + char cookie[COOKIE_SIZE]; socklen_t len; struct sockaddr_in addr; struct sockaddr_in temp1, temp2; + struct iperf_stream *sp; + static int streams_accepted; + + if ((s = accept(test->listener_tcp, (struct sockaddr *) &addr, &len)) < 0) { + perror("accept"); + return -1; + } if (test->ctrl_sck == -1) { - if ((s = accept(test->listener, (struct sockaddr *) &addr, &len)) < 0) { - perror("accept"); + /* Server free, accept new client */ + if (Nread(s, test->default_settings->cookie, COOKIE_SIZE, Ptcp) < 0) { + perror("Nread COOKIE\n"); 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) @@ -118,21 +129,46 @@ iperf_accept(struct iperf_test *test) 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)); - return 0; - + test->state = PARAM_EXCHANGE; + if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { + perror("Nwrite PARAM_EXCHANGE\n"); + exit(1); + } + iperf_exchange_parameters(test); } else { - // This message needs to be sent to the client - if ((s = accept(test->listener, (struct sockaddr *) &addr, &len)) < 0) { - perror("accept"); + if (Nread(s, cookie, COOKIE_SIZE, Ptcp) < 0) { + perror("Nread COOKIE\n"); return -1; } - if (write(s, &rbuf, sizeof(int)) < 0) { - perror("write"); - return -1; + if ((strcmp(test->default_settings->cookie, cookie) == 0) && (test->state == CREATE_STREAMS)) { + // XXX: CANNOT USE iperf_tcp_accept since stream is alread accepted at this point. New model needed! + 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 (write(s, &rbuf, sizeof(int)) < 0) { + perror("write"); + return -1; + } + close(s); } - close(s); - return 0; } + + return 0; } /**************************************************************************/ @@ -217,8 +253,8 @@ iperf_test_reset(struct iperf_test *test) FD_ZERO(&test->read_set); FD_ZERO(&test->write_set); - FD_SET(test->listener, &test->read_set); - test->max_fd = test->listener; + FD_SET(test->listener_tcp, &test->read_set); + test->max_fd = test->listener_tcp; test->num_streams = 1; test->default_settings->socket_bufsize = 0; @@ -256,69 +292,70 @@ iperf_run_server(struct iperf_test *test) for (;;) { - test->state = IPERF_START; - streams_accepted = 0; - - while (test->state != IPERF_DONE) { + test->state = IPERF_START; + streams_accepted = 0; - memcpy(&temp_read_set, &test->read_set, sizeof(fd_set)); - memcpy(&temp_write_set, &test->write_set, sizeof(fd_set)); - tv.tv_sec = 15; - tv.tv_usec = 0; + while (test->state != IPERF_DONE) { - 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); - } else if (result > 0) { - if (FD_ISSET(test->listener, &temp_read_set)) { - if (iperf_accept(test) < 0) { - fprintf(stderr, "iperf_accept: error accepting control socket. exiting...\n"); - exit(1); - } - FD_CLR(test->listener, &temp_read_set); - } - if (FD_ISSET(test->ctrl_sck, &temp_read_set)) { - // Handle control messages - iperf_handle_message_server(test); - FD_CLR(test->ctrl_sck, &temp_read_set); - } - - if (test->state == CREATE_STREAMS) { - if (FD_ISSET(test->prot_listener, &temp_read_set)) { - // Spawn new streams - // XXX: This works, but should it check cookies for authenticity - // Also, currently it uses 5202 for stream connections. - // Should this be fixed to use 5201 instead? - iperf_tcp_accept(test); - ++streams_accepted; - FD_CLR(test->prot_listener, &temp_read_set); + memcpy(&temp_read_set, &test->read_set, sizeof(fd_set)); + memcpy(&temp_write_set, &test->write_set, sizeof(fd_set)); + tv.tv_sec = 15; + tv.tv_usec = 0; + + 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); + } else if (result > 0) { + if (FD_ISSET(test->listener_tcp, &temp_read_set)) { + if (iperf_accept(test) < 0) { + fprintf(stderr, "iperf_accept: error accepting control socket. exiting...\n"); + exit(1); + } + FD_CLR(test->listener_tcp, &temp_read_set); } - if (streams_accepted == test->num_streams) { - FD_CLR(test->prot_listener, &test->read_set); - close(test->prot_listener); - test->state = TEST_START; - if (write(test->ctrl_sck, &test->state, sizeof(char)) < 0) { - perror("write TEST_START"); - return -1; + if (FD_ISSET(test->ctrl_sck, &temp_read_set)) { + iperf_handle_message_server(test); + FD_CLR(test->ctrl_sck, &temp_read_set); + } + +/* + if (test->state == CREATE_STREAMS) { + if (FD_ISSET(test->prot_listener, &temp_read_set)) { + // Spawn new streams + // XXX: This works, but should it check cookies for authenticity + // Also, currently it uses 5202 for stream connections. + // Should this be fixed to use 5201 instead? + iperf_tcp_accept(test); + ++streams_accepted; + FD_CLR(test->prot_listener, &temp_read_set); + } + if (streams_accepted == test->num_streams) { + FD_CLR(test->prot_listener, &test->read_set); + close(test->prot_listener); + test->state = TEST_START; + if (write(test->ctrl_sck, &test->state, sizeof(char)) < 0) { + perror("write TEST_START"); + return -1; + } } } - } - - if (test->reverse) { - // Reverse mode. Server sends. - iperf_send(test); - } else { - // Regular mode. Server receives. - iperf_recv(test); +*/ + + if (test->reverse) { + // Reverse mode. Server sends. + iperf_send(test); + } else { + // Regular mode. Server receives. + iperf_recv(test); + } } } - } - /* Clean up the last test */ - iperf_test_reset(test); - printf("\n"); + /* Clean up the last test */ + iperf_test_reset(test); + printf("\n"); }