[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