[master] c6fdc39 Emit backend IP's as encoded struct suckaddr in the VGC code.

Poul-Henning Kamp phk at varnish-cache.org
Sun Oct 27 22:23:26 CET 2013


commit c6fdc3980f7c0d9b1cd15c2e7c5651305edfff23
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Sun Oct 27 21:12:40 2013 +0000

    Emit backend IP's as encoded struct suckaddr in the VGC code.

diff --git a/include/vsa.h b/include/vsa.h
index c1e5509..7293547 100644
--- a/include/vsa.h
+++ b/include/vsa.h
@@ -38,4 +38,6 @@ socklen_t VSA_Len(const void *);
 unsigned VSA_Port(const void *);
 int VSA_Compare(const void *, const void *);
 
+struct suckaddr *VSA_Malloc(const void *s, unsigned  sal);
+
 #endif
diff --git a/lib/libvarnish/vsa.c b/lib/libvarnish/vsa.c
index 000678d..5aadb4f 100644
--- a/lib/libvarnish/vsa.c
+++ b/lib/libvarnish/vsa.c
@@ -35,6 +35,7 @@
 
 #include <errno.h>
 #include <string.h>
+#include <stdlib.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 
@@ -197,6 +198,37 @@ VRT_VSA_GetPtr(const struct suckaddr *sua, const unsigned char ** dst)
 	}
 }
 
+/*
+ * Malloc a suckaddr from a sockaddr of some kind.
+ */
+
+struct suckaddr *
+VSA_Malloc(const void *s, unsigned  sal)
+{
+	struct suckaddr *sua = NULL;
+	const struct sockaddr *sa = s;
+	unsigned l = 0;
+
+	switch(sa->sa_family) {
+		case PF_INET:
+			if (sal == sizeof sua->sa4)
+				l = sal;
+			break;
+		case PF_INET6:
+			if (sal == sizeof sua->sa6)
+				l = sal;
+			break;
+		default:
+			break;
+	}
+	if (l != 0) {
+		sua = calloc(1, sizeof *sua);
+		if (sua != NULL)
+			memcpy(&sua->sa, s, l);
+	}
+	return (sua);
+}
+
 int
 VSA_Sane(const void *s)
 {
diff --git a/lib/libvcc/vcc_utils.c b/lib/libvcc/vcc_utils.c
index 5870af5..aa82bc8 100644
--- a/lib/libvcc/vcc_utils.c
+++ b/lib/libvcc/vcc_utils.c
@@ -31,6 +31,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netdb.h>
@@ -77,42 +78,47 @@ vcc_regexp(struct vcc *tl)
 
 /*
  * 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.
+ * struct sockaddr, see libvarnish/vsa.c for blow-by-blow account.
+ *
+ * There is no sane or even remotely portable way to initialize
+ * a sockaddr for random protocols 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.
+ * Instead we make sure the sockaddr is sane (for our values of
+ * sane) and dump it as our own "struct suckaddr" type, in binary,
+ * using the widest integertype, hoping that this will ensure sufficient
+ * alignment.
  */
 
 static const char *
 vcc_sockaddr(struct vcc *tl, const void *sa, unsigned sal)
 {
-	unsigned n = (sal + 7) / 8, len;
-	uint64_t b[n];
+	unsigned n = (vsa_suckaddr_len + 7) / 8, len;
+	unsigned long long b[n];
+	struct suckaddr *sua;
 	char *p;
 
+	assert(sizeof(unsigned long long) == 8);
+
 	assert(VSA_Sane(sa));
 	AN(sa);
 	AN(sal);
-	assert(sal < sizeof(struct sockaddr_storage));
-	assert(sizeof(unsigned long long) == 8);
+
+	sua = VSA_Malloc(sa, sal);
+	AN(sua);
 
 	p = TlAlloc(tl, 20);
+	AN(p);
 	sprintf(p, "sockaddr_%u", tl->unique++);
 
 	Fh(tl, 0, "static const unsigned long long");
 	Fh(tl, 0, " %s[%d] = {\n", p, n);
-	memcpy(b, sa, sal);
-	for (len = 0; len <n; len++) {
-		Fh(tl, 0, "%s    0x%016jx",
-		    len ? ",\n" : "",
-		    (uintmax_t)b[len]);
-	}
+	memcpy(b, sua, vsa_suckaddr_len);
+	free(sua);
+	for (len = 0; len < n; len++)
+		Fh(tl, 0, "%s    0x%016llx", len ? ",\n" : "", b[len]);
 	Fh(tl, 0, "\n};\n");
 	return (p);
 }



More information about the varnish-commit mailing list