rpc.statd: Fix socket binding loop.
authorHemmo Nieminen <hemmo.nieminen@iki.fi>
Wed, 16 Jan 2013 20:29:14 +0000 (15:29 -0500)
committerSteve Dickson <steved@redhat.com>
Wed, 16 Jan 2013 20:33:29 +0000 (15:33 -0500)
From: Hemmo Nieminen <hemmo.nieminen@iki.fi>

Instead of closing the sockets before requesting a new one, keep them
open until a suitable one is found. Otherwise bindresvport will return
the same port over and over again.

Signed-off-by: Steve Dickson <steved@redhat.com>
utils/statd/rmtcall.c

index 4ecb03c..fd576d9 100644 (file)
@@ -68,21 +68,19 @@ statd_get_socket(void)
 {
        struct sockaddr_in      sin;
        struct servent *se;
-       int loopcnt = 100;
+       const int loopcnt = 100;
+       int i, tmp_sockets[loopcnt];
 
        if (sockfd >= 0)
                return sockfd;
 
-       while (loopcnt-- > 0) {
-
-               if (sockfd >= 0) close(sockfd);
+       for (i = 0; i < loopcnt; ++i) {
 
                if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
                        xlog(L_ERROR, "%s: Can't create socket: %m", __func__);
-                       return -1;
+                       break;
                }
 
-
                memset(&sin, 0, sizeof(sin));
                sin.sin_family = AF_INET;
                sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
@@ -96,7 +94,16 @@ statd_get_socket(void)
                if (se == NULL)
                        break;
                /* rather not use that port, try again */
+
+               tmp_sockets[i] = sockfd;
        }
+
+       while (--i >= 0)
+               close(tmp_sockets[i]);
+
+       if (sockfd < 0)
+               return -1;
+
        FD_SET(sockfd, &SVC_FDSET);
        return sockfd;
 }