[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