]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - utils/statd/rmtcall.c
rpc.statd: Fix socket binding loop.
[nfs-utils.git] / utils / statd / rmtcall.c
index 1a97684a21a5887721a55bb69d5e6bb3c6a55eae..fd576d9158b6fa54dd530147401056d9b6b4419d 100644 (file)
@@ -68,24 +68,22 @@ 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 = INADDR_ANY;
+               sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
 
                if (bindresvport(sockfd, &sin) < 0) {
                        xlog(D_GENERAL, "%s: can't bind to reserved port",
@@ -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;
 }
@@ -125,6 +132,15 @@ recv_rply(u_long *portp)
        xid = nsm_parse_reply(&xdr);
        if (xid == 0)
                goto done;
+       if (sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {
+               struct in_addr addr = sin.sin_addr;
+               char buf[INET_ADDRSTRLEN];
+
+               xlog_warn("%s: Unrecognized reply from %s", __func__,
+                               inet_ntop(AF_INET, &addr, buf,
+                                               (socklen_t)sizeof(buf)));
+               goto done;
+       }
 
        for (lp = notify; lp != NULL; lp = lp->next) {
                /* LH - this was a bug... it should have been checking
@@ -132,15 +148,6 @@ recv_rply(u_long *portp)
                 * not the static, internal xid */
                if (lp->xid != xid)
                        continue;
-               if (lp->addr.s_addr != sin.sin_addr.s_addr) {
-                       char addr [18];
-                       strncpy (addr, inet_ntoa(lp->addr),
-                                sizeof (addr) - 1);
-                       addr [sizeof (addr) - 1] = '\0';
-                       xlog_warn("%s: address mismatch: "
-                               "expected %s, got %s", __func__,
-                               addr, inet_ntoa(sin.sin_addr));
-               }
                if (lp->port == 0)
                        *portp = nsm_recv_getport(&xdr);
                break;
@@ -160,8 +167,8 @@ process_entry(notify_list *lp)
        struct sockaddr_in      sin;
 
        if (NL_TIMES(lp) == 0) {
-               xlog(D_GENERAL, "%s: Cannot notify %s, giving up",
-                               __func__, inet_ntoa(NL_ADDR(lp)));
+               xlog(D_GENERAL, "%s: Cannot notify localhost, giving up",
+                               __func__);
                return 0;
        }
 
@@ -226,8 +233,8 @@ process_reply(FD_SET_TYPE *rfds)
                        nlist_insert_timer(&notify, lp);
                        return 1;
                }
-               xlog_warn("%s: [%s] service %d not registered",
-                       __func__, inet_ntoa(lp->addr), NL_MY_PROG(lp));
+               xlog_warn("%s: service %d not registered on localhost",
+                       __func__, NL_MY_PROG(lp));
        } else {
                xlog(D_GENERAL, "%s: Callback to %s (for %d) succeeded",
                        __func__, NL_MY_NAME(lp), NL_MON_NAME(lp));