[master] 2314365 Change the way VCC emit sockaddr's, explain why.

Poul-Henning Kamp phk at varnish-cache.org
Tue Aug 6 11:31:28 CEST 2013


commit 2314365f4b2bb70d24f82ee3b1d0bde7804606f5
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Aug 6 09:30:38 2013 +0000

    Change the way VCC emit sockaddr's, explain why.

diff --git a/bin/varnishd/cache/cache_backend_cfg.c b/bin/varnishd/cache/cache_backend_cfg.c
index b07252e..c3e7c8c 100644
--- a/bin/varnishd/cache/cache_backend_cfg.c
+++ b/bin/varnishd/cache/cache_backend_cfg.c
@@ -150,13 +150,13 @@ VBE_DropRefConn(struct backend *b)
  */
 
 static void
-copy_sockaddr(struct sockaddr_storage **sa, const unsigned char *src)
+copy_sockaddr(struct sockaddr_storage **sa, const void *src)
 {
 
-	assert(*src > 0);
+	assert(VSA_Sane(src));
 	*sa = calloc(sizeof **sa, 1);
 	XXXAN(*sa);
-	memcpy(*sa, src + 1, *src);
+	memcpy(*sa, src, VSA_Len(src));
 	assert(VSA_Sane(*sa));
 }
 
@@ -183,10 +183,10 @@ VBE_AddBackend(struct cli *cli, const struct vrt_backend *vb)
 		if (strcmp(b->vcl_name, vb->vcl_name))
 			continue;
 		if (vb->ipv4_sockaddr != NULL &&
-		    VSA_Compare(b->ipv4, vb->ipv4_sockaddr + 1))
+		    VSA_Compare(b->ipv4, vb->ipv4_sockaddr))
 			continue;
 		if (vb->ipv6_sockaddr != NULL &&
-		    VSA_Compare(b->ipv6, vb->ipv6_sockaddr + 1))
+		    VSA_Compare(b->ipv6, vb->ipv6_sockaddr))
 			continue;
 		b->refcount++;
 		b->vsc->vcls++;
diff --git a/include/vrt.h b/include/vrt.h
index 1394668..8b6e8a8 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -124,8 +124,8 @@ struct vrt_backend {
 	const char			*ipv6_addr;
 	const char			*port;
 
-	const unsigned char		*ipv4_sockaddr;
-	const unsigned char		*ipv6_sockaddr;
+	const void			*ipv4_sockaddr;
+	const void 			*ipv6_sockaddr;
 
 	const char			*hosthdr;
 
diff --git a/lib/libvcl/vcc_backend.c b/lib/libvcl/vcc_backend.c
index 09604cb..9bab3ce 100644
--- a/lib/libvcl/vcc_backend.c
+++ b/lib/libvcl/vcc_backend.c
@@ -61,6 +61,7 @@
 #include "vcc_compile.h"
 
 #include "vss.h"
+#include "vsa.h"
 
 struct host {
 	VTAILQ_ENTRY(host)      list;
@@ -68,27 +69,38 @@ struct host {
 	char			*vgcname;
 };
 
+/*
+ * The IPv6 crew royally screwed up the entire idea behind
+ * struct sockaddr, and combined with various other incomptency
+ * in the OS business, that means that there is no sane or even
+ * remotely portable way to initialize a sockaddr at compile time.
+ *
+ * In our case it is slightly more tricky than that, because we don't
+ * even want to #include the struct sockaddr* definitions.
+ *
+ * Instead we make sure the sockaddr is sane (for our values of sane)
+ * and dump it in binary, using a 64 bit integertype, hoping that this
+ * will ensure good enough alignment.
+ */
+
 static int
-emit_sockaddr(struct vcc *tl, void *sa, unsigned sal)
+emit_sockaddr(struct vcc *tl, const void *sa, unsigned sal)
 {
-	unsigned len;
-	uint8_t *u;
+	unsigned n = (sal + 7) / 8, len;
+	uint64_t b[n];
 
+	assert(VSA_Sane(sa));
 	AN(sa);
 	AN(sal);
 	assert(sal < 256);
-	Fh(tl, 0, "\nstatic const unsigned char sockaddr_%u[%d] = {\n",
-	    tl->unique, sal + 1);
-	Fh(tl, 0, "    %3u, /* Length */\n",  sal);
-	u = sa;
-	for (len = 0; len <sal; len++) {
-		if ((len % 8) == 0)
-			Fh(tl, 0, "   ");
-		Fh(tl, 0, " %3u", u[len]);
-		if (len + 1 < sal)
-			Fh(tl, 0, ",");
-		if ((len % 8) == 7)
-			Fh(tl, 0, "\n");
+	assert(sizeof(unsigned long long) == 8);
+	Fh(tl, 0, "\nstatic const unsigned long long");
+	Fh(tl, 0, " sockaddr_%u[%d] = {\n", tl->unique, n);
+	memcpy(b, sa, sal);
+	for (len = 0; len <n; len++) {
+		Fh(tl, 0, "%s    0x%016jx",
+		    len ? ",\n" : "",
+		    (uintmax_t)b[len]);
 	}
 	Fh(tl, 0, "\n};\n");
 	return (tl->unique++);



More information about the varnish-commit mailing list