Commit 2314365f authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

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

parent b3a2823c
...@@ -150,13 +150,13 @@ VBE_DropRefConn(struct backend *b) ...@@ -150,13 +150,13 @@ VBE_DropRefConn(struct backend *b)
*/ */
static void 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); *sa = calloc(sizeof **sa, 1);
XXXAN(*sa); XXXAN(*sa);
memcpy(*sa, src + 1, *src); memcpy(*sa, src, VSA_Len(src));
assert(VSA_Sane(*sa)); assert(VSA_Sane(*sa));
} }
...@@ -183,10 +183,10 @@ VBE_AddBackend(struct cli *cli, const struct vrt_backend *vb) ...@@ -183,10 +183,10 @@ VBE_AddBackend(struct cli *cli, const struct vrt_backend *vb)
if (strcmp(b->vcl_name, vb->vcl_name)) if (strcmp(b->vcl_name, vb->vcl_name))
continue; continue;
if (vb->ipv4_sockaddr != NULL && if (vb->ipv4_sockaddr != NULL &&
VSA_Compare(b->ipv4, vb->ipv4_sockaddr + 1)) VSA_Compare(b->ipv4, vb->ipv4_sockaddr))
continue; continue;
if (vb->ipv6_sockaddr != NULL && if (vb->ipv6_sockaddr != NULL &&
VSA_Compare(b->ipv6, vb->ipv6_sockaddr + 1)) VSA_Compare(b->ipv6, vb->ipv6_sockaddr))
continue; continue;
b->refcount++; b->refcount++;
b->vsc->vcls++; b->vsc->vcls++;
......
...@@ -124,8 +124,8 @@ struct vrt_backend { ...@@ -124,8 +124,8 @@ struct vrt_backend {
const char *ipv6_addr; const char *ipv6_addr;
const char *port; const char *port;
const unsigned char *ipv4_sockaddr; const void *ipv4_sockaddr;
const unsigned char *ipv6_sockaddr; const void *ipv6_sockaddr;
const char *hosthdr; const char *hosthdr;
......
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
#include "vcc_compile.h" #include "vcc_compile.h"
#include "vss.h" #include "vss.h"
#include "vsa.h"
struct host { struct host {
VTAILQ_ENTRY(host) list; VTAILQ_ENTRY(host) list;
...@@ -68,27 +69,38 @@ struct host { ...@@ -68,27 +69,38 @@ struct host {
char *vgcname; 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 static int
emit_sockaddr(struct vcc *tl, void *sa, unsigned sal) emit_sockaddr(struct vcc *tl, const void *sa, unsigned sal)
{ {
unsigned len; unsigned n = (sal + 7) / 8, len;
uint8_t *u; uint64_t b[n];
assert(VSA_Sane(sa));
AN(sa); AN(sa);
AN(sal); AN(sal);
assert(sal < 256); assert(sal < 256);
Fh(tl, 0, "\nstatic const unsigned char sockaddr_%u[%d] = {\n", assert(sizeof(unsigned long long) == 8);
tl->unique, sal + 1); Fh(tl, 0, "\nstatic const unsigned long long");
Fh(tl, 0, " %3u, /* Length */\n", sal); Fh(tl, 0, " sockaddr_%u[%d] = {\n", tl->unique, n);
u = sa; memcpy(b, sa, sal);
for (len = 0; len <sal; len++) { for (len = 0; len <n; len++) {
if ((len % 8) == 0) Fh(tl, 0, "%s 0x%016jx",
Fh(tl, 0, " "); len ? ",\n" : "",
Fh(tl, 0, " %3u", u[len]); (uintmax_t)b[len]);
if (len + 1 < sal)
Fh(tl, 0, ",");
if ((len % 8) == 7)
Fh(tl, 0, "\n");
} }
Fh(tl, 0, "\n};\n"); Fh(tl, 0, "\n};\n");
return (tl->unique++); return (tl->unique++);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment