From: Willy Tarreau Date: Fri, 4 Dec 2020 13:43:36 +0000 (+0100) Subject: MINOR: protocol: add a ->set_port() helper to address families X-Git-Tag: v2.4-dev3~53 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=73bed9ff135472c0e02b5aba08845b8a359eb268;p=thirdparty%2Fhaproxy.git MINOR: protocol: add a ->set_port() helper to address families At various places we need to set a port on an IPv4 or IPv6 address, and it requires casts that are easy to get wrong. Let's add a new set_port() helper to the address family to assist in this. It will be directly accessible from the protocol and will make the operation seamless. Right now this is only implemented for sock_inet as other families do not need a port. --- diff --git a/include/haproxy/protocol-t.h b/include/haproxy/protocol-t.h index 1306a32a52..2a599500d2 100644 --- a/include/haproxy/protocol-t.h +++ b/include/haproxy/protocol-t.h @@ -70,6 +70,7 @@ struct proto_fam { int (*bind)(struct receiver *rx, char **errmsg); /* bind a receiver */ int (*get_src)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve src addr */ int (*get_dst)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve dst addr */ + void (*set_port)(struct sockaddr_storage *, int port); /* set the port on the address; NULL if not implemented */ }; /* This structure contains all information needed to easily handle a protocol. diff --git a/include/haproxy/sock_inet.h b/include/haproxy/sock_inet.h index 5829fcf313..044de2c192 100644 --- a/include/haproxy/sock_inet.h +++ b/include/haproxy/sock_inet.h @@ -36,6 +36,7 @@ extern struct proto_fam proto_fam_inet6; int sock_inet4_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b); int sock_inet6_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b); +void sock_inet_set_port(struct sockaddr_storage *addr, int port); int sock_inet_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir); int sock_inet_is_foreign(int fd, sa_family_t family); int sock_inet4_make_foreign(int fd); diff --git a/src/sock_inet.c b/src/sock_inet.c index 6675be5833..6adaf184eb 100644 --- a/src/sock_inet.c +++ b/src/sock_inet.c @@ -42,6 +42,7 @@ struct proto_fam proto_fam_inet4 = { .bind = sock_inet_bind_receiver, .get_src = sock_get_src, .get_dst = sock_inet_get_dst, + .set_port = sock_inet_set_port, }; struct proto_fam proto_fam_inet6 = { @@ -54,6 +55,7 @@ struct proto_fam proto_fam_inet6 = { .bind = sock_inet_bind_receiver, .get_src = sock_get_src, .get_dst = sock_get_dst, + .set_port = sock_inet_set_port, }; /* PLEASE NOTE for function below: @@ -116,6 +118,18 @@ int sock_inet6_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_s return memcmp(&a6->sin6_addr, &b6->sin6_addr, sizeof(a6->sin6_addr)); } +/* Sets the port on IPv4 or IPv6 address . The address family is + * determined from the sockaddr_storage's address family. Nothing is done for + * other families. + */ +void sock_inet_set_port(struct sockaddr_storage *addr, int port) +{ + if (addr->ss_family == AF_INET) + ((struct sockaddr_in *)addr)->sin_port = htons(port); + else if (addr->ss_family == AF_INET6) + ((struct sockaddr_in6 *)addr)->sin6_port = htons(port); +} + /* * Retrieves the original destination address for the socket which must be * of family AF_INET (not AF_INET6), with indicating if we're a listener