X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/4cfa6156e37d9c3b75ea4be11b766a1246370481..ac1d2d338450eb005abf03002f5784097caf7e19:/clientname.c diff --git a/clientname.c b/clientname.c index 22c77502..4f85dcf3 100644 --- a/clientname.c +++ b/clientname.c @@ -55,13 +55,11 @@ char *client_addr(int fd) initialised = 1; - if (am_server) { - /* daemon over --rsh mode */ + if (am_server) { /* daemon over --rsh mode */ strcpy(addr_buf, "0.0.0.0"); if ((ssh_client = getenv("SSH_CLIENT")) != NULL) { /* truncate SSH_CLIENT to just IP address */ - p = strchr(ssh_client, ' '); - if (p) { + if ((p = strchr(ssh_client, ' ')) != NULL) { len = MIN((unsigned int) (p - ssh_client), sizeof addr_buf - 1); strncpy(addr_buf, ssh_client, len); @@ -102,11 +100,7 @@ char *client_name(int fd) static char name_buf[100]; static char port_buf[100]; static int initialised; - struct sockaddr_storage ss, *ssp; - struct sockaddr_in sin; -#ifdef INET6 - struct sockaddr_in6 sin6; -#endif + struct sockaddr_storage ss; socklen_t ss_len; if (initialised) @@ -115,46 +109,45 @@ char *client_name(int fd) strcpy(name_buf, default_name); initialised = 1; - if (am_server) { - /* daemon over --rsh mode */ + memset(&ss, 0, sizeof ss); + if (am_server) { /* daemon over --rsh mode */ char *addr = client_addr(fd); -#ifdef INET6 - int dots = 0; - char *p; + struct addrinfo hint, *answer; + int err; - for (p = addr; *p && (dots <= 3); p++) { - if (*p == '.') - dots++; + memset(&hint, 0, sizeof hint); + + hint.ai_flags = AI_NUMERICHOST; + hint.ai_socktype = SOCK_STREAM; + + if ((err = getaddrinfo(addr, NULL, &hint, &answer)) != 0) { + rprintf(FERROR, RSYNC_NAME ": malformed address %s: %s\n", + addr, gai_strerror(err)); + return name_buf; } - if (dots > 3) { - /* more than 4 parts to IP address, must be ipv6 */ - ssp = (struct sockaddr_storage *) &sin6; - ss_len = sizeof sin6; - memset(ssp, 0, ss_len); - inet_pton(AF_INET6, addr, &sin6.sin6_addr); - sin6.sin6_family = AF_INET6; - } else + + switch (answer->ai_family) { + case AF_INET: + ss_len = sizeof (struct sockaddr_in); + memcpy(&ss, answer->ai_addr, ss_len); + break; +#ifdef INET6 + case AF_INET6: + ss_len = sizeof (struct sockaddr_in6); + memcpy(&ss, answer->ai_addr, ss_len); + break; #endif - { - ssp = (struct sockaddr_storage *) &sin; - ss_len = sizeof sin; - memset(ssp, 0, ss_len); - inet_pton(AF_INET, addr, &sin.sin_addr); - sin.sin_family = AF_INET; } - + freeaddrinfo(answer); } else { ss_len = sizeof ss; - ssp = &ss; - client_sockaddr(fd, &ss, &ss_len); - } - if (!lookup_name(fd, ssp, ss_len, name_buf, sizeof name_buf, + if (!lookup_name(fd, &ss, ss_len, name_buf, sizeof name_buf, port_buf, sizeof port_buf)) - check_name(fd, ssp, name_buf); + check_name(fd, &ss, name_buf); return name_buf; } @@ -181,7 +174,7 @@ void client_sockaddr(int fd, } #ifdef INET6 - if (get_sockaddr_family(ss) == AF_INET6 && + if (get_sockaddr_family(ss) == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)ss)->sin6_addr)) { /* OK, so ss is in the IPv6 family, but it is really * an IPv4 address: something like @@ -207,7 +200,7 @@ void client_sockaddr(int fd, * to be present in the Linux headers. */ memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12], sizeof sin->sin_addr); - } + } #endif } @@ -270,8 +263,9 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai, return memcmp(&sin1->sin_addr, &sin2->sin_addr, sizeof sin1->sin_addr); } + #ifdef INET6 - else if (ss_family == AF_INET6) { + if (ss_family == AF_INET6) { const struct sockaddr_in6 *sin1, *sin2; sin1 = (const struct sockaddr_in6 *) ss; @@ -295,10 +289,9 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai, return 0; } #endif /* INET6 */ - else { - /* don't know */ - return 1; - } + + /* don't know */ + return 1; }