diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2009-05-18 11:03:54 -0400 |
---|---|---|
committer | Steve Dickson <steved@redhat.com> | 2009-05-18 11:03:54 -0400 |
commit | 3ab7ab5db0f825fdd95d017cdd6d6ee5d207dbe8 (patch) | |
tree | 58fe0e6841e42e23d6a0064618b34c37a8aaed4a /utils/statd | |
parent | c88c4091db87c0fc23ed67e76d63439b59a82369 (diff) | |
download | nfs-utils-3ab7ab5db0f825fdd95d017cdd6d6ee5d207dbe8.tar.gz nfs-utils-3ab7ab5db0f825fdd95d017cdd6d6ee5d207dbe8.tar.xz nfs-utils-3ab7ab5db0f825fdd95d017cdd6d6ee5d207dbe8.zip |
sm-notify: Don't orphan addrinfo structs
sm-notify orphans an addrinfo struct in its address list rotation
logic if only a single result was returned from getaddrinfo(3).
For each host, the first time through notify_host(), we want to
send a PMAP_GETPORT request. ->ai is NULL, and retries is set to 100,
forcing a DNS lookup and an address rotation. If only a single
addrinfo struct is returned, the rotation logic causes a NULL to be
planted in ->ai, copied from the ai_next field of the returned result.
This means that the second time through notify_host() (to perform the
actual SM_NOTIFY call) we do a second DNS lookup, since ->ai is NULL.
The result of the first lookup has been orphaned, and extra network
traffic is generated.
This scenario is actually fairly common. Since we pass
.ai_protocol = IPPROTO_UDP,
to getaddrinfo(3), for most hosts, which have a single forward and
reverse pointer in the DNS database, we get back a single addrinfo
struct as a result.
To address this problem, only perform the address list rotation if
there is more than one element on the list returned by getaddrinfo(3).
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
Diffstat (limited to 'utils/statd')
-rw-r--r-- | utils/statd/sm-notify.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/utils/statd/sm-notify.c b/utils/statd/sm-notify.c index f1fc619..78d0a59 100644 --- a/utils/statd/sm-notify.c +++ b/utils/statd/sm-notify.c @@ -424,19 +424,27 @@ notify_host(int sock, struct nsm_host *host) * point. */ if (host->retries >= 4) { - struct addrinfo *first = host->ai; - struct addrinfo **next = &host->ai; - - /* remove the first entry from the list */ - host->ai = first->ai_next; - first->ai_next = NULL; - /* find the end of the list */ - next = &first->ai_next; - while ( *next ) - next = & (*next)->ai_next; - /* put first entry at end */ - *next = first; - memcpy(&host->addr, first->ai_addr, first->ai_addrlen); + /* don't rotate if there is only one addrinfo */ + if (host->ai->ai_next == NULL) + memcpy(&host->addr, host->ai->ai_addr, + host->ai->ai_addrlen); + else { + struct addrinfo *first = host->ai; + struct addrinfo **next = &host->ai; + + /* remove the first entry from the list */ + host->ai = first->ai_next; + first->ai_next = NULL; + /* find the end of the list */ + next = &first->ai_next; + while ( *next ) + next = & (*next)->ai_next; + /* put first entry at end */ + *next = first; + memcpy(&host->addr, first->ai_addr, + first->ai_addrlen); + } + smn_set_port((struct sockaddr *)&host->addr, 0); host->retries = 0; } |