- /* Look up the remote host name. */
- if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
- sizeof(sockin->sin_addr),
- AF_INET))) {
- strlcpy(name_buf,(char *)hp->h_name,sizeof(name_buf));
+#ifdef INET6
+ if (ss.ss_family == AF_INET6 &&
+ IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&ss)->sin6_addr)) {
+ struct sockaddr_in6 sin6;
+ struct sockaddr_in *sin;
+
+ memcpy(&sin6, &ss, sizeof(sin6));
+ sin = (struct sockaddr_in *)&ss;
+ memset(sin, 0, sizeof(*sin));
+ sin->sin_family = AF_INET;
+ length = sizeof(struct sockaddr_in);
+#ifdef HAVE_SOCKADDR_LEN
+ sin->sin_len = length;
+#endif
+ sin->sin_port = sin6.sin6_port;
+ memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12],
+ sizeof(sin->sin_addr));
+ }
+#endif
+
+ /* reverse lookup */
+ if (getnameinfo((struct sockaddr *)&ss, length,
+ name_buf, sizeof(name_buf), port_buf, sizeof(port_buf),
+ NI_NAMEREQD | NI_NUMERICSERV) != 0) {
+ strcpy(name_buf, def);
+ rprintf(FERROR, "reverse name lookup failed\n");
+ }
+
+ /* forward lookup */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_socktype = SOCK_STREAM;
+ error = getaddrinfo(name_buf, port_buf, &hints, &res0);
+ if (error) {
+ strcpy(name_buf, def);
+ rprintf(FERROR,
+ RSYNC_NAME ": forward name lookup for %s failed: %s\n",
+ port_buf,
+ gai_strerror(error));
+ return name_buf;
+ }
+
+ /* XXX sin6_flowinfo and other fields */
+ for (res = res0; res; res = res->ai_next) {
+ if (res->ai_family != ss.ss_family)
+ continue;
+ if (res->ai_addrlen != length)
+ continue;
+ if (memcmp(res->ai_addr, &ss, res->ai_addrlen) == 0)
+ break;