]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
CLEANUP: tools: make ipcpy() preserve the original port
authorWilly Tarreau <w@1wt.eu>
Fri, 4 Nov 2016 17:47:01 +0000 (18:47 +0100)
committerWilly Tarreau <w@1wt.eu>
Sat, 5 Nov 2016 12:56:04 +0000 (13:56 +0100)
ipcpy() is used to replace an IP address with another one, but it
doesn't preserve the original port so all callers have to do it
manually while it's trivial to do there. Better do it inside the
function.

src/server.c
src/standard.c

index 68fa8009f42f1976d9382d2f1eeb88e3d2bc2e91..00e776aed3600421b21d88f5cc32924e96958e24 100644 (file)
@@ -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 */
index e25d38ef1837beb3568331d4336b3c4d8e35c8b2..fed847777fe93716901b9e518756975abe399fa7 100644 (file)
@@ -2598,20 +2598,29 @@ int ipcmp(struct sockaddr_storage *ss1, struct sockaddr_storage *ss2)
 }
 
 /* copy IP address from <source> into <dest>
- * the caller must allocate and clear <dest> before calling.
- * Returns a pointer to the destination.
+ * The caller must allocate and clear <dest> 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;
        }