Hello again, since you are not completely convinced, I undertook the labour to develop a your original code into a domain agnostic version.
Remember in all your experiments, that any outcome is influenced by many factors: mapping of IPv4 addresses to IPv6 addresses, the value of "net.ipv6.bindv6only", the fact that Xinetd prefers a dual stacked server, a choice between nc6 from "netcat6", ncat from "nmap". In particular these last two do not treat address mapping in a fully identical way, You will certainly recognise most of your original code in the following rewrite. There is a particular passage that tries to enforce a dual-stacked listener, but other- wise the recipe is standard practice. #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> void write_client_addr(int fd) { struct sockaddr_storage addr; socklen_t addr_l; char addrbuff[256]; char outputbuff[256]; int outputsize; addr_l = sizeof(addr); getpeername(fd, (struct sockaddr *) &addr, &addr_l); getnameinfo((struct sockaddr *) &addr, addr_l, addrbuff, sizeof(addrbuff), NULL, 0, NI_NUMERICHOST); outputsize = snprintf(outputbuff, sizeof(outputbuff), "Your address is %s\n", addrbuff); write(fd, outputbuff, outputsize); } int main(int argc, char *argv[]) { int client_fd = 0; if (argc == 1) { int status, val, s; const char *portstr = "1942"; struct addrinfo hints, *res, *ai; struct sockaddr_storage farAddr; socklen_t farAddrL; s = -1; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if ( (status = getaddrinfo(NULL, portstr, &hints, &res)) == 0) { /* We want to get IPv6 if at all possible. */ for (ai = res; ai != NULL; ai = ai->ai_next) if (ai->ai_family == AF_INET6) break; if (ai == NULL) ai = res; /* Failure: roll back. */ for ( ; ai != NULL; ai = ai->ai_next) { if ( (s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0) continue; val = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) fprintf(stderr, "setsockopt() failed.\n"); val = 0; if ((ai->ai_family == AF_INET6) && (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) < 0)) fprintf(stderr, "Failed in creating dual-stacked listener.\n"); if ( bind(s, ai->ai_addr, ai->ai_addrlen) == 0 ) if ( listen(s, 10) >= 0 ) break; close(s); /* Try next candidate address. */ s = -1; } freeaddrinfo(res); if ( ai == NULL ) { fprintf(stderr, "Failed at establishing a listener.\n"); return EXIT_FAILURE; } } else { /* Failed at obtaining even an address. */ fprintf(stderr, "getaddrinfo() failed: %s\n", gai_strerror(status)); return EXIT_FAILURE; } farAddrL = sizeof(farAddr); client_fd = accept(s, (struct sockaddr *) &farAddr, &farAddrL); } write_client_addr(client_fd); return EXIT_SUCCESS; } -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org