diff --git a/src/server.c b/src/server.c index 68fa8009f..00e776aed 100644 --- a/src/server.c +++ b/src/server.c @@ -2667,25 +2667,16 @@ const char *update_server_addr_port(struct server *s, const char *addr, const ch chunk_appendf(msg, "no need to change the addr"); goto port; } - current_port = get_host_port(&s->addr); - memset(&s->addr, '\0', sizeof(s->addr)); ipcpy(&sa, &s->addr); - set_host_port(&s->addr, current_port); /* we also need to update check's ADDR only if it uses the server's one */ if ((s->check.state & CHK_ST_CONFIGURED) && (s->flags & SRV_F_CHECKADDR)) { - current_port = get_host_port(&s->check.addr); - memset(&s->check.addr, '\0', sizeof(s->check.addr)); ipcpy(&sa, &s->check.addr); - set_host_port(&s->check.addr, current_port); } /* we also need to update agent ADDR only if it use the server's one */ if ((s->agent.state & CHK_ST_CONFIGURED) && (s->flags & SRV_F_AGENTADDR)) { - current_port = get_host_port(&s->agent.addr); - memset(&s->agent.addr, '\0', sizeof(s->agent.addr)); ipcpy(&sa, &s->agent.addr); - set_host_port(&s->agent.addr, current_port); } /* update report for caller */ diff --git a/src/standard.c b/src/standard.c index e25d38ef1..fed847777 100644 --- a/src/standard.c +++ b/src/standard.c @@ -2598,20 +2598,29 @@ int ipcmp(struct sockaddr_storage *ss1, struct sockaddr_storage *ss2) } /* copy IP address from into - * the caller must allocate and clear before calling. - * Returns a pointer to the destination. + * The caller must allocate and clear before calling. + * The source must be in either AF_INET or AF_INET6 family, or the destination + * address will be undefined. If the destination address used to hold a port, + * it is preserved, so that this function can be used to switch to another + * address family with no risk. Returns a pointer to the destination. */ struct sockaddr_storage *ipcpy(struct sockaddr_storage *source, struct sockaddr_storage *dest) { + int prev_port; + + prev_port = get_net_port(dest); + memset(dest, 0, sizeof(*dest)); dest->ss_family = source->ss_family; /* copy new addr and apply it */ switch (source->ss_family) { case AF_INET: ((struct sockaddr_in *)dest)->sin_addr.s_addr = ((struct sockaddr_in *)source)->sin_addr.s_addr; + ((struct sockaddr_in *)dest)->sin_port = prev_port; break; case AF_INET6: memcpy(((struct sockaddr_in6 *)dest)->sin6_addr.s6_addr, ((struct sockaddr_in6 *)source)->sin6_addr.s6_addr, sizeof(struct in6_addr)); + ((struct sockaddr_in6 *)dest)->sin6_port = prev_port; break; }