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.
This commit is contained in:
Willy Tarreau 2020-12-04 14:43:36 +01:00
parent c31bc724d4
commit 73bed9ff13
3 changed files with 16 additions and 0 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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 <port> on IPv4 or IPv6 address <addr>. 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 <fd> which must be
* of family AF_INET (not AF_INET6), with <dir> indicating if we're a listener