MINOR: protocol: properly assign the sock_domain and sock_family
When we finally split sock_domain from sock_family in 2.3, something was not cleanly finished. The family is what should be stored in the address while the domain is what is supposed to be passed to socket(). But for the custom addresses, we did the opposite, just because the protocol_lookup() function was acting on the domain, not the family (both of which are equal for non-custom addresses). This is an API bug but there's no point backporting it since it does not have visible effects. It was visible in the code since a few places were using PF_UNIX while others were comparing the domain against AF_MAX instead of comparing the family. This patch clarifies this in the comments on top of proto_fam, addresses the indexing issue and properly reconfigures the two custom families.
This commit is contained in:
parent
67bf1d6c9e
commit
732913f848
|
@ -70,7 +70,17 @@ enum proto_type {
|
||||||
#define PROTO_F_REUSEPORT_TESTED 0x00000002 /* SO_REUSEPORT support was tested */
|
#define PROTO_F_REUSEPORT_TESTED 0x00000002 /* SO_REUSEPORT support was tested */
|
||||||
|
|
||||||
/* protocol families define standard functions acting on a given address family
|
/* protocol families define standard functions acting on a given address family
|
||||||
* for a socket implementation, such as AF_INET/PF_INET for example.
|
* for a socket implementation, such as AF_INET/PF_INET for example. There is
|
||||||
|
* permanent confusion between domain and family. Here's how it works:
|
||||||
|
* - the domain defines the format of addresses (e.g. sockaddr_in etc),
|
||||||
|
* it is passed as the first argument to socket()
|
||||||
|
* - the family is part of the address and is stored in receivers, servers
|
||||||
|
* and everywhere there is an address. It's also a proto_fam selector.
|
||||||
|
* Domains are often PF_xxx though man 2 socket on Linux quotes 4.x BSD's man
|
||||||
|
* that says AF_* can be used everywhere. At least it tends to keep the code
|
||||||
|
* clearer about the intent. In HAProxy we're defining new address families
|
||||||
|
* with AF_CUST_* which appear in addresses, and they cannot be used for the
|
||||||
|
* domain, the socket() call must use sock_domain instead.
|
||||||
*/
|
*/
|
||||||
struct proto_fam {
|
struct proto_fam {
|
||||||
char name[PROTO_NAME_LEN]; /* family name, zero-terminated */
|
char name[PROTO_NAME_LEN]; /* family name, zero-terminated */
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
|
|
||||||
struct proto_fam proto_fam_rhttp = {
|
struct proto_fam proto_fam_rhttp = {
|
||||||
.name = "rhttp",
|
.name = "rhttp",
|
||||||
.sock_domain = AF_CUST_RHTTP_SRV,
|
.sock_domain = AF_INET,
|
||||||
.sock_family = AF_INET,
|
.sock_family = AF_CUST_RHTTP_SRV,
|
||||||
.bind = rhttp_bind_receiver,
|
.bind = rhttp_bind_receiver,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,8 @@ struct connection *sockpair_accept_conn(struct listener *l, int *status);
|
||||||
|
|
||||||
struct proto_fam proto_fam_sockpair = {
|
struct proto_fam proto_fam_sockpair = {
|
||||||
.name = "sockpair",
|
.name = "sockpair",
|
||||||
.sock_domain = AF_CUST_SOCKPAIR,
|
.sock_domain = AF_UNIX,
|
||||||
.sock_family = AF_UNIX,
|
.sock_family = AF_CUST_SOCKPAIR,
|
||||||
.sock_addrlen = sizeof(struct sockaddr_un),
|
.sock_addrlen = sizeof(struct sockaddr_un),
|
||||||
.l3_addrlen = sizeof(((struct sockaddr_un*)0)->sun_path),
|
.l3_addrlen = sizeof(((struct sockaddr_un*)0)->sun_path),
|
||||||
.addrcmp = NULL,
|
.addrcmp = NULL,
|
||||||
|
|
|
@ -38,14 +38,14 @@ __decl_spinlock(proto_lock);
|
||||||
/* Registers the protocol <proto> */
|
/* Registers the protocol <proto> */
|
||||||
void protocol_register(struct protocol *proto)
|
void protocol_register(struct protocol *proto)
|
||||||
{
|
{
|
||||||
int sock_domain = proto->fam->sock_domain;
|
int sock_family = proto->fam->sock_family;
|
||||||
|
|
||||||
BUG_ON(sock_domain < 0 || sock_domain >= AF_CUST_MAX);
|
BUG_ON(sock_family < 0 || sock_family >= AF_CUST_MAX);
|
||||||
BUG_ON(proto->proto_type >= PROTO_NUM_TYPES);
|
BUG_ON(proto->proto_type >= PROTO_NUM_TYPES);
|
||||||
|
|
||||||
HA_SPIN_LOCK(PROTO_LOCK, &proto_lock);
|
HA_SPIN_LOCK(PROTO_LOCK, &proto_lock);
|
||||||
LIST_APPEND(&protocols, &proto->list);
|
LIST_APPEND(&protocols, &proto->list);
|
||||||
__protocol_by_family[sock_domain]
|
__protocol_by_family[sock_family]
|
||||||
[proto->proto_type]
|
[proto->proto_type]
|
||||||
[proto->xprt_type == PROTO_TYPE_DGRAM] = proto;
|
[proto->xprt_type == PROTO_TYPE_DGRAM] = proto;
|
||||||
HA_SPIN_UNLOCK(PROTO_LOCK, &proto_lock);
|
HA_SPIN_UNLOCK(PROTO_LOCK, &proto_lock);
|
||||||
|
|
|
@ -1147,7 +1147,7 @@ int _sock_supports_reuseport(const struct proto_fam *fam, int type, int protocol
|
||||||
fd1 = fd2 = -1;
|
fd1 = fd2 = -1;
|
||||||
|
|
||||||
/* ignore custom sockets */
|
/* ignore custom sockets */
|
||||||
if (!fam || fam->sock_domain >= AF_MAX)
|
if (!fam || fam->sock_family >= AF_MAX)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
fd1 = socket(fam->sock_domain, type, protocol);
|
fd1 = socket(fam->sock_domain, type, protocol);
|
||||||
|
|
Loading…
Reference in New Issue