From 559f37d7b334f81ab2d3bbb3f15c539bed0da436 Mon Sep 17 00:00:00 2001 From: Achim Kraus Date: Thu, 18 Jan 2024 09:10:18 +0100 Subject: [PATCH] dtls-client.c: apply option for local port. The previous version ignores the option for the local port. That may be caused by issues using the same default local port for the server and client. This enables the use of an specific local port and changes the default to an ephemeral free port, similar to quite a lot of other UDP clients. The DEFAULT_PORT is therefore only used for the destination. Signed-off-by: Achim Kraus --- tests/dtls-client.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/tests/dtls-client.c b/tests/dtls-client.c index 0bdb5ce..669926d 100644 --- a/tests/dtls-client.c +++ b/tests/dtls-client.c @@ -376,9 +376,11 @@ usage( const char *program, const char *version) { #endif /* DTLS_PSK */ "\t-o file\t\toutput received data to this file\n" "\t \t\t(use '-' for STDOUT)\n" - "\t-p port\t\tlisten on specified port (default is %d)\n" + "\t-p port\t\tlisten on specified port\n" + "\t \t\t(default is an ephemeral free port).\n" "\t-r\t\tforce renegotiation info (RFC5746)\n" - "\t-v num\t\tverbosity level (default: 3)\n", + "\t-v num\t\tverbosity level (default: 3)\n" + "\tDefault destination port: %d\n", DEFAULT_PORT); } @@ -412,21 +414,22 @@ main(int argc, char **argv) { fd_set rfds, wfds; struct timeval timeout; unsigned short dst_port = 0; - unsigned short port = DEFAULT_PORT; - char port_str[NI_MAXSERV] = "0"; + unsigned short local_port = 0; log_t log_level = DTLS_LOG_WARN; int fd; ssize_t result; int on = 1; int opt, res; session_t dst; + session_t listen; char buf[200]; size_t len = 0; int buf_ready = 0; memset(&dst, 0, sizeof(session_t)); + memset(&listen, 0, sizeof(session_t)); + dtls_init(); - snprintf(port_str, sizeof(port_str), "%d", port); #ifdef DTLS_PSK psk_id_length = strlen(PSK_DEFAULT_IDENTITY); @@ -475,8 +478,7 @@ main(int argc, char **argv) { } break; case 'p' : - strncpy(port_str, optarg, NI_MAXSERV-1); - port_str[NI_MAXSERV - 1] = '\0'; + local_port = atoi(optarg); break; case 'r' : force_renegotiation_info = 1; @@ -561,6 +563,24 @@ main(int argc, char **argv) { } } + if (local_port) { + listen.addr = dst.addr; + listen.size = dst.size; + if (listen.addr.sa.sa_family == AF_INET6) { + listen.addr.sin6.sin6_addr = in6addr_any; + listen.addr.sin6.sin6_port = htons(local_port); + dtls_info("bind to local IPv6, port %u\n", local_port); + } else { + listen.addr.sin.sin_addr.s_addr = INADDR_ANY; + listen.addr.sin.sin_port = htons(local_port); + dtls_info("bind to local IPv4, port %u\n", local_port); + } + if (bind(fd, (struct sockaddr *)&listen.addr.sa, listen.size) < 0) { + dtls_alert("bind: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + } + if (signal(SIGINT, dtls_handle_signal) == SIG_ERR) { dtls_alert("An error occurred while setting a signal handler.\n"); return EXIT_FAILURE;