From 3264aa98f7cadf3dd22b8dbd12a2ce6723a18011 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 95f4a9de..c7fb016a 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;