[master] 358f7331c VSA_BuildFAP: Build a suckaddr from Family, Address and Port
Nils Goroll
nils.goroll at uplex.de
Wed Apr 1 18:37:07 UTC 2020
commit 358f7331c3bcc595fb161370256c0b13b960ccda
Author: Nils Goroll <nils.goroll at uplex.de>
Date: Thu Dec 12 15:31:11 2019 +0100
VSA_BuildFAP: Build a suckaddr from Family, Address and Port
Follow the spirit of the vsa.c top level rant and spare callers the
hassle of creating sockaddrs specific to ip4/ip6 just to build a VSA,
which is intended to avoid having to special-case the protocols in the
first place.
diff --git a/bin/varnishd/proxy/cache_proxy_proto.c b/bin/varnishd/proxy/cache_proxy_proto.c
index 4eb5526ee..53851a24c 100644
--- a/bin/varnishd/proxy/cache_proxy_proto.c
+++ b/bin/varnishd/proxy/cache_proxy_proto.c
@@ -326,8 +326,6 @@ vpx_proto2(const struct worker *wrk, struct req *req)
const uint8_t *p;
char *d, *tlv_start;
sa_family_t pfam = 0xff;
- struct sockaddr_in sin4;
- struct sockaddr_in6 sin6;
struct suckaddr *sa = NULL;
char ha[VTCP_ADDRBUFSIZE];
char pa[VTCP_PORTBUFSIZE];
@@ -387,23 +385,17 @@ vpx_proto2(const struct worker *wrk, struct req *req)
}
l -= 12;
d += 12;
- memset(&sin4, 0, sizeof sin4);
- sin4.sin_family = pfam;
/* dst/server */
- memcpy(&sin4.sin_addr, p + 20, 4);
- memcpy(&sin4.sin_port, p + 26, 2);
if (! SES_Reserve_server_addr(req->sp, &sa))
return (vpx_ws_err(req));
- AN(VSA_Build(sa, &sin4, sizeof sin4));
+ AN(VSA_BuildFAP(sa, pfam, p + 20, 4, p + 26, 2));
VTCP_name(sa, ha, sizeof ha, pa, sizeof pa);
/* src/client */
- memcpy(&sin4.sin_addr, p + 16, 4);
- memcpy(&sin4.sin_port, p + 24, 2);
if (! SES_Reserve_client_addr(req->sp, &sa))
return (vpx_ws_err(req));
- AN(VSA_Build(sa, &sin4, sizeof sin4));
+ AN(VSA_BuildFAP(sa, pfam, p + 16, 4, p + 24, 2));
break;
case 0x21:
/* IPv6|TCP */
@@ -415,23 +407,17 @@ vpx_proto2(const struct worker *wrk, struct req *req)
}
l -= 36;
d += 36;
- memset(&sin6, 0, sizeof sin6);
- sin6.sin6_family = pfam;
/* dst/server */
- memcpy(&sin6.sin6_addr, p + 32, 16);
- memcpy(&sin6.sin6_port, p + 50, 2);
if (! SES_Reserve_server_addr(req->sp, &sa))
return (vpx_ws_err(req));
- AN(VSA_Build(sa, &sin6, sizeof sin6));
+ AN(VSA_BuildFAP(sa, pfam, p + 32, 16, p + 50, 2));
VTCP_name(sa, ha, sizeof ha, pa, sizeof pa);
/* src/client */
- memcpy(&sin6.sin6_addr, p + 16, 16);
- memcpy(&sin6.sin6_port, p + 48, 2);
if (! SES_Reserve_client_addr(req->sp, &sa))
return (vpx_ws_err(req));
- AN(VSA_Build(sa, &sin6, sizeof sin6));
+ AN(VSA_BuildFAP(sa, pfam, p + 16, 16, p + 48, 2));
break;
default:
/* Ignore proxy header */
diff --git a/include/vsa.h b/include/vsa.h
index e44544d55..eb6e4a2df 100644
--- a/include/vsa.h
+++ b/include/vsa.h
@@ -57,6 +57,18 @@ struct suckaddr *VSA_Malloc(const void *s, unsigned sal);
*/
struct suckaddr *VSA_Build(void *d, const void *s, unsigned sal);
+/* 'd' SHALL point to vsa_suckaddr_len aligned bytes of storage
+ *
+ * fam: address family
+ * a / al : address and length
+ * p / pl : port and length
+ *
+ * NULL or 0 length argument are ignored.
+ * argument of the wrong length are an error (NULL return value, EINVAL)
+ */
+struct suckaddr * VSA_BuildFAP(void *d, sa_family_t fam,
+ const void *a, unsigned al, const void *p, unsigned pl);
+
/*
* This VRT interface is for the VCC generated ACL code, which needs
* to know the address family and a pointer to the actual address.
diff --git a/lib/libvarnish/vsa.c b/lib/libvarnish/vsa.c
index 3ade79e14..3f842458d 100644
--- a/lib/libvarnish/vsa.c
+++ b/lib/libvarnish/vsa.c
@@ -187,16 +187,7 @@ const struct suckaddr *bogo_ip = &bogo_ip_vsa;
void
VSA_Init()
{
- struct addrinfo hints, *res = NULL;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_INET;
- hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
- hints.ai_socktype = SOCK_STREAM;
- AZ(getaddrinfo("0.0.0.0", "0", &hints, &res));
- AN(VSA_Build(&bogo_ip_vsa, res->ai_addr, res->ai_addrlen));
- assert(VSA_Sane(bogo_ip));
- freeaddrinfo(res);
+ AN(VSA_BuildFAP(&bogo_ip_vsa, PF_INET, NULL, 0, NULL, 0));
}
/*
@@ -266,6 +257,59 @@ VSA_Malloc(const void *s, unsigned sal)
return (VSA_Build(d, s, sal));
}
+/* 'd' SHALL point to vsa_suckaddr_len aligned bytes of storage
+ *
+ * fam: address family
+ * a / al : address and length
+ * p / pl : port and length
+ *
+ * NULL or 0 length argument are ignored.
+ * argument of the wrong length are an error (NULL return value, EINVAL)
+ */
+struct suckaddr *
+VSA_BuildFAP(void *d, sa_family_t fam, const void *a, unsigned al,
+ const void *p, unsigned pl)
+{
+ struct sockaddr_in sin4;
+ struct sockaddr_in6 sin6;
+
+ switch (fam) {
+ case PF_INET:
+ memset(&sin4, 0, sizeof sin4);
+ sin4.sin_family = fam;
+ if (a != NULL && al > 0) {
+ if (al != sizeof(sin4.sin_addr))
+ break;
+ memcpy(&sin4.sin_addr, a, al);
+ }
+ if (p != NULL && pl > 0) {
+ if (pl != sizeof(sin4.sin_port))
+ break;
+ memcpy(&sin4.sin_port, p, pl);
+ }
+ return (VSA_Build(d, &sin4, sizeof sin4));
+ case PF_INET6:
+ memset(&sin6, 0, sizeof sin6);
+ sin6.sin6_family = fam;
+ if (a != NULL && al > 0) {
+ if (al != sizeof(sin6.sin6_addr))
+ break;
+ memcpy(&sin6.sin6_addr, a, al);
+ }
+ if (p != NULL && pl > 0) {
+ if (pl != sizeof(sin6.sin6_port))
+ break;
+ memcpy(&sin6.sin6_port, p, pl);
+ }
+ return (VSA_Build(d, &sin6, sizeof sin6));
+ default:
+ errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+ errno = EINVAL;
+ return (NULL);
+}
+
/* 'd' SHALL point to vsa_suckaddr_len aligned bytes of storage */
struct suckaddr *
VSA_Build(void *d, const void *s, unsigned sal)
More information about the varnish-commit
mailing list