From 369ce38ac1dacd16a87f91694a05c5c143e18d80 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 19 Apr 2020 23:29:21 +0200 Subject: tests: run the TFTP test server on a dynamic port number Picking a dynamic unused port is better than a fixed to avoid the collision risk. Closes #5265 --- tests/server/tftpd.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 6 deletions(-) (limited to 'tests/server') diff --git a/tests/server/tftpd.c b/tests/server/tftpd.c index 9972ab0e4..46b09b562 100644 --- a/tests/server/tftpd.c +++ b/tests/server/tftpd.c @@ -210,6 +210,7 @@ static const char *ipv_inuse = "IPv4"; const char *serverlogfile = DEFAULT_LOGFILE; static const char *pidname = ".tftpd.pid"; +static const char *portfile = NULL; static int serverlogslocked = 0; static int wrotepidfile = 0; @@ -574,6 +575,11 @@ int main(int argc, char **argv) if(argc>arg) pidname = argv[arg++]; } + else if(!strcmp("--portfile", argv[arg])) { + arg++; + if(argc>arg) + portfile = argv[arg++]; + } else if(!strcmp("--logfile", argv[arg])) { arg++; if(argc>arg) @@ -598,12 +604,6 @@ int main(int argc, char **argv) if(argc>arg) { char *endptr; unsigned long ulnum = strtoul(argv[arg], &endptr, 10); - if((endptr != argv[arg] + strlen(argv[arg])) || - (ulnum < 1025UL) || (ulnum > 65535UL)) { - fprintf(stderr, "tftpd: invalid --port argument (%s)\n", - argv[arg]); - return 0; - } port = curlx_ultous(ulnum); arg++; } @@ -690,12 +690,64 @@ int main(int argc, char **argv) goto tftpd_cleanup; } + if(!port) { + /* The system was supposed to choose a port number, figure out which + port we actually got and update the listener port value with it. */ + curl_socklen_t la_size; + srvr_sockaddr_union_t localaddr; +#ifdef ENABLE_IPV6 + if(!use_ipv6) +#endif + la_size = sizeof(localaddr.sa4); +#ifdef ENABLE_IPV6 + else + la_size = sizeof(localaddr.sa6); +#endif + memset(&localaddr.sa, 0, (size_t)la_size); + if(getsockname(sock, &localaddr.sa, &la_size) < 0) { + error = SOCKERRNO; + logmsg("getsockname() failed with error: (%d) %s", + error, strerror(error)); + sclose(sock); + return CURL_SOCKET_BAD; + } + switch(localaddr.sa.sa_family) { + case AF_INET: + port = ntohs(localaddr.sa4.sin_port); + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + port = ntohs(localaddr.sa6.sin6_port); + break; +#endif + default: + break; + } + if(!port) { + /* Real failure, listener port shall not be zero beyond this point. */ + logmsg("Apparently getsockname() succeeded, with listener port zero."); + logmsg("A valid reason for this failure is a binary built without"); + logmsg("proper network library linkage. This might not be the only"); + logmsg("reason, but double check it before anything else."); + result = 2; + goto tftpd_cleanup; + } + } + wrotepidfile = write_pidfile(pidname); if(!wrotepidfile) { result = 1; goto tftpd_cleanup; } + if(portfile) { + wrotepidfile = write_portfile(portfile, port); + if(!wrotepidfile) { + result = 1; + goto tftpd_cleanup; + } + } + logmsg("Running %s version on port UDP/%d", ipv_inuse, (int)port); for(;;) { @@ -800,6 +852,8 @@ tftpd_cleanup: if(wrotepidfile) unlink(pidname); + if(portfile) + unlink(portfile); if(serverlogslocked) { serverlogslocked = 0; -- cgit v1.2.3