diff --git a/include/haproxy/protocol-t.h b/include/haproxy/protocol-t.h index 1306a32a5..2a599500d 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 5829fcf31..044de2c19 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 6675be583..6adaf184e 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