Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/const.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// ----------------------------------------------------------------------------------

#define TOOL_NAME "NTTTCP for Linux"
#define TOOL_VERSION "1.4.3"
#define TOOL_VERSION "1.4.5"
#define AUTHOR_NAME "Shihua (Simon) Xiao, sixiao@microsoft.com"

#define TCP SOCK_STREAM
Expand Down
22 changes: 21 additions & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,23 @@ int run_ntttcp_sender(struct ntttcp_test_endpoint *tep)
reply_received = query_receiver_busy_state(tep->synch_socket);
if (reply_received == -1) {
PRINT_ERR("sender: failed to query receiver state");
if (test->no_synch == false)
close(tep->synch_socket);
return ERROR_GENERAL;
}
if (reply_received == 1) {
PRINT_ERR("sender: receiver is busy with another test");
if (test->no_synch == false)
close(tep->synch_socket);
return ERROR_GENERAL;
}

reply_received = negotiate_test_cycle_time(tep->synch_socket,
test->warmup + test->duration + test->cooldown);
if (reply_received == -1) {
PRINT_ERR("sender: failed to negotiate test cycle time with receiver");
if (test->no_synch == false)
close(tep->synch_socket);
return ERROR_GENERAL;
}
if (reply_received != test->duration) {
Expand Down Expand Up @@ -145,10 +151,14 @@ int run_ntttcp_sender(struct ntttcp_test_endpoint *tep)
tep->test->last_client ? (int)'L' : (int)'R');
if (reply_received == -1) {
PRINT_ERR("sender: failed to sync with receiver to start test");
if (test->no_synch == false)
close(tep->synch_socket);
return ERROR_GENERAL;
}
if (reply_received == 0) {
PRINT_ERR("sender: receiver refuse to start test right now");
if (test->no_synch == false)
close(tep->synch_socket);
return ERROR_GENERAL;
}

Expand All @@ -162,6 +172,8 @@ int run_ntttcp_sender(struct ntttcp_test_endpoint *tep)
if (tep->negotiated_test_cycle_time == 0) {
sleep(UINT_MAX);
/* either sleep has elapsed, or sleep was interrupted by a signal */
if (test->no_synch == false)
close(tep->synch_socket);
return err_code;
}

Expand Down Expand Up @@ -333,7 +345,15 @@ int main(int argc, char **argv)
exit(-1);
}

default_ntttcp_test(test);
// Handle error return from default_ntttcp_test
err_code = default_ntttcp_test(test);
if (err_code != NO_ERROR) {
PRINT_ERR("main: error when initializing default test parameters");
free(test->bind_address);
free(test);
exit(err_code);
}

err_code = parse_arguments(test, argc, argv);
if (err_code != NO_ERROR) {
PRINT_ERR("main: error when parsing args");
Expand Down
15 changes: 13 additions & 2 deletions src/ntttcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct ntttcp_test *new_ntttcp_test()
return test;
}

void default_ntttcp_test(struct ntttcp_test *test)
int default_ntttcp_test(struct ntttcp_test *test)
{
test->server_role = false;
test->client_role = false;
Expand All @@ -29,7 +29,6 @@ void default_ntttcp_test(struct ntttcp_test *test)
test->use_client_address = false;
test->exit_after_done = true;
test->mapping = "16,*,*";
test->bind_address = "0.0.0.0";
test->client_address = "0.0.0.0";
test->cpu_affinity = -1; /* no hard cpu affinity */
test->server_ports = DEFAULT_NUM_SERVER_PORTS; //default:16 */
Expand Down Expand Up @@ -59,6 +58,15 @@ void default_ntttcp_test(struct ntttcp_test *test)
test->json_log_filename = DEFAULT_JSON_LOG_FILE_NAME; /* "ntttcp-for-linux-log.json" */
test->quiet = false;
test->verbose = false;

/* Allocate bind_address last to ensure all other fields are initialized if allocation fails */
test->bind_address = strdup("0.0.0.0");
if (!test->bind_address) {
PRINT_ERR("failed to allocate memory for bind_address in defaults");
return ERROR_MEMORY_ALLOC;
}

return NO_ERROR;
}

bool is_running_tty(void)
Expand Down Expand Up @@ -228,6 +236,8 @@ void free_ntttcp_test_endpoint_and_test(struct ntttcp_test_endpoint *e)

for (i = 0; i < total_threads; i++)
free(e->results->threads[i]);

free(e->results->threads);
free(e->results->init_cpu_usage);
free(e->results->init_cpu_ps);
free(e->results->init_tcp_retrans);
Expand All @@ -236,6 +246,7 @@ void free_ntttcp_test_endpoint_and_test(struct ntttcp_test_endpoint *e)
free(e->results->final_tcp_retrans);
free(e->results);
free(e->threads);
free(e->test->bind_address);
free(e->test);
free(e);
}
Expand Down
2 changes: 1 addition & 1 deletion src/ntttcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ struct ntttcp_stream_server{
};

struct ntttcp_test *new_ntttcp_test();
void default_ntttcp_test(struct ntttcp_test *test);
int default_ntttcp_test(struct ntttcp_test *test);

struct ntttcp_test_endpoint *new_ntttcp_test_endpoint(struct ntttcp_test *test, int endpoint_role);
void set_ntttcp_test_endpoint_test_continuous(struct ntttcp_test_endpoint* e);
Expand Down
57 changes: 46 additions & 11 deletions src/parameter.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,12 +202,19 @@ int process_mappings(struct ntttcp_test *test)

state = S_THREADS;
char *element = strdup(test->mapping);
if (!element) {
PRINT_ERR("process_mappings: failed to allocate memory");
return ERROR_ARGS;
}
/* strsep() modifies the element pointer; save the original for proper free() in all paths */
char *element_start = element;

while ((token = strsep(&element, ",")) != NULL) {
if (S_THREADS == state) {
threads = atoi(token);

if (1 > threads) {
free(element_start);
return ERROR_ARGS;
}
test->server_ports = threads;
Expand All @@ -232,13 +239,21 @@ int process_mappings(struct ntttcp_test *test)
}
++state;
Comment on lines 239 to 240
} else if (S_HOST == state) {
test->bind_address = token;
free(test->bind_address);
test->bind_address = strdup(token);
if (!test->bind_address) {
PRINT_ERR("process_mappings: failed to allocate memory for bind_address");
free(element_start);
return ERROR_ARGS;
}
++state;
} else {
PRINT_ERR("process_mappings: unexpected parameters in mapping");
free(element_start);
return ERROR_ARGS;
}
}
free(element_start);
return NO_ERROR;
}

Expand All @@ -255,8 +270,14 @@ int verify_args(struct ntttcp_test *test)
return ERROR_ARGS;
}

if (test->domain == AF_INET6 && strcmp(test->bind_address, "0.0.0.0") == 0)
test->bind_address = "::";
if (test->domain == AF_INET6 && strcmp(test->bind_address, "0.0.0.0") == 0) {
free(test->bind_address);
test->bind_address = strdup("::");
if (!test->bind_address) {
PRINT_ERR("failed to allocate memory for bind_address");
return ERROR_ARGS;
}
}

if (test->domain == AF_INET6 && !strstr(test->bind_address, ":")) {
PRINT_ERR("invalid ipv6 address provided");
Expand Down Expand Up @@ -417,6 +438,7 @@ int parse_arguments(struct ntttcp_test *test, int argc, char **argv)
{0, 0, 0, 0}
};
int opt;
int err_code;

while ((opt = getopt_long(argc, argv, "r::s::DMLeHm:P:a:n:l:6up:f::b:B:W:t:C:NO::x::j::QVh", longopts, NULL)) != -1) {
switch (opt) {
Expand All @@ -429,10 +451,21 @@ int parse_arguments(struct ntttcp_test *test, int argc, char **argv)
}

if (optarg) {
test->bind_address = optarg;
free(test->bind_address);
test->bind_address = strdup(optarg);
if (!test->bind_address) {
PRINT_ERR("failed to allocate memory for bind_address");
exit(ERROR_ARGS);
}
} else {
if (optind < argc && NULL != argv[optind] && '\0' != argv[optind][0] && '-' != argv[optind][0])
test->bind_address = argv[optind++];
if (optind < argc && NULL != argv[optind] && '\0' != argv[optind][0] && '-' != argv[optind][0]) {
free(test->bind_address);
test->bind_address = strdup(argv[optind++]);
if (!test->bind_address) {
PRINT_ERR("failed to allocate memory for bind_address");
exit(ERROR_ARGS);
}
}
}
break;

Expand All @@ -458,17 +491,19 @@ int parse_arguments(struct ntttcp_test *test, int argc, char **argv)

case 'm':
test->mapping = optarg;
process_mappings(test);
err_code = process_mappings(test);
if (err_code != NO_ERROR)
return err_code;
break;

case 'P':
test->server_ports = atoi(optarg);
break;

case 'a':
test->client_address = optarg;
test->use_client_address = true;
break;
case 'a':
test->client_address = optarg;
test->use_client_address = true;
break;

case 'n':
test->threads_per_server_port = atoi(optarg);
Expand Down
Loading