--- sshd.c +++ sshd.c @@ -253,6 +253,62 @@ static void do_ssh1_kex(void); static void do_ssh2_kex(void); +char * isaddr(struct addrinfo *addr, char *name); +void remove_duplicities(struct addrinfo *addr, char *port); + +/* + * returns port if addr equals name + */ + +char* +isaddr(struct addrinfo *addr, char *name) +{ + char ntop[NI_MAXHOST]; + char *strport; + + strport = (char*) malloc(NI_MAXSERV+1); + if (getnameinfo(addr->ai_addr, addr->ai_addrlen, + ntop, sizeof(ntop), strport, sizeof(strport), + NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + error("getnameinfo failed"); + free(strport); + return NULL; + } + if (!strcmp(ntop,name)) + return strport; + else{ + free(strport); + return NULL; + } + +} + +/* + * it removes all "0.0.0.0" elements with given port + * from the list + */ + +void +remove_duplicities(struct addrinfo *ai_start, char *port) +{ + struct addrinfo *ai, *ai1, *aiprev, *ainext; + char *port1; + + aiprev=ai_start; + for (ai = ai_start->ai_next; ai; ai = ainext) { + ainext = ai->ai_next; + port1 = isaddr(ai, "0.0.0.0"); + if (port1 && !strcmp(port,port1)){ + aiprev->ai_next = ainext; + free(ai); + free(port1); + } else { + if (port1) + free(port1); + aiprev = ai; + } + } +} /* * Close all listening sockets @@ -941,6 +997,7 @@ int ret, listen_sock, on = 1; struct addrinfo *ai; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + char *port; for (ai = options.listen_addrs; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) @@ -986,6 +1043,13 @@ continue; } listen_socks[num_listen_socks] = listen_sock; + + port = isaddr(ai,"::"); + if (port) { + remove_duplicities(ai, port); + free(port); + } + num_listen_socks++; /* Start listening on the port. */