From: Ben Pfaff Date: Wed, 3 Apr 2013 18:24:27 +0000 (-0500) Subject: socket-util: Log kernel-chosen bound ports in inet_open_passive(). X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=df451457ad9a02bcd9793126b66be445f4d5a8a7;p=sliver-openvswitch.git socket-util: Log kernel-chosen bound ports in inet_open_passive(). Usually, for passive sockets, one wishes to bind a particular well-known port, so that clients can easily connect. But automated tests cannot necessarily bind a well-known port, because that would cause multiple concurrent tests to interfere with each other or with a real instance of the service running on the system. They could bind to a randomly selected port chosen by the user (the Open vSwitch automated tests currently do this) but this leads to occasional "false negative" test failures when the port selected happens to be in use. The best alternative for automated tests is to let the kernel choose a port that is not otherwise in use, which can be accomplished by specifying port 0. But in that case there is no easy way for other software to know what port the kernel chose. This commit fixes that problem one way by logging the bound port when it is chosen by the kernel. Signed-off-by: Ben Pfaff --- diff --git a/lib/socket-util.c b/lib/socket-util.c index 9fea7bdab..4f9b5b891 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -684,6 +684,7 @@ int inet_open_passive(int style, const char *target, int default_port, struct sockaddr_in *sinp, uint8_t dscp) { + bool kernel_chooses_port; struct sockaddr_in sin; int fd = 0, error; unsigned int yes = 1; @@ -733,9 +734,10 @@ inet_open_passive(int style, const char *target, int default_port, goto error; } - if (sinp) { + kernel_chooses_port = sin.sin_port == htons(0); + if (sinp || kernel_chooses_port) { socklen_t sin_len = sizeof sin; - if (getsockname(fd, (struct sockaddr *) &sin, &sin_len) < 0){ + if (getsockname(fd, (struct sockaddr *) &sin, &sin_len) < 0) { error = errno; VLOG_ERR("%s: getsockname: %s", target, strerror(error)); goto error; @@ -745,7 +747,13 @@ inet_open_passive(int style, const char *target, int default_port, VLOG_ERR("%s: getsockname: invalid socket name", target); goto error; } - *sinp = sin; + if (sinp) { + *sinp = sin; + } + if (kernel_chooses_port) { + VLOG_INFO("%s: listening on port %"PRIu16, + target, ntohs(sin.sin_port)); + } } return fd;