vtest: Untie vtest from 127.0.0.1 and support IPv6 only setups

to support IPv6 only hosts, we try to resolve "localhost" if resolving
"127.0.0.1" fails.

Whatever address we determine is stored in the ${localhost}
macro. Because of the different address:port vs. [address]:port
formats for IPv4 vs. IPv6, we store "${localhost}:0" /
"[${localhost}]:0" in the ${listen_addr} macro.

Likewise we unify the *_sock macros to ${Xaddr}:${Xport} (the colon
used to be missing) for IPv4 and [${Xaddr}]:${Xport} for IPv6.

We also save ${listen_addr} in default_listen_addr for use from within
the vtest code whenever we want to bind to or listen on an emphemeral
port.

Ref #3490
parent 2aa9a8b0
......@@ -76,5 +76,5 @@ client c1 -connect ${v3_sock} {
expect resp.http.a0_sock == "${tmpdir}/v1.sock"
expect resp.http.a1_addr != "0.0.0.0"
expect resp.http.a1_port != "0"
expect resp.http.a1_sock ~ "[^ ]+ [^ ]+"
expect resp.http.a1_sock ~ "[^ ]+:[^ ]+"
} -run
......@@ -81,6 +81,7 @@ extern char *vmod_path;
extern struct vsb *params_vsb;
extern int leave_temp;
extern int ign_unknown_macro;
extern const char *default_listen_addr;
void init_server(void);
void init_syslog(void);
......
......@@ -41,6 +41,7 @@
#include "vtc.h"
#include "vtcp.h"
#include "vsa.h"
enum barrier_e {
BARRIER_NONE = 0,
......@@ -128,7 +129,10 @@ barrier_sock_thread(void *priv)
struct barrier *b;
struct vtclog *vl;
const char *err;
char abuf[16], pbuf[6];
char buf[vsa_suckaddr_len];
struct suckaddr *sua;
char abuf[VTCP_ADDRBUFSIZE], pbuf[VTCP_PORTBUFSIZE];
int i, sock, *conns;
struct pollfd pfd[1];
......@@ -140,7 +144,7 @@ barrier_sock_thread(void *priv)
vl = vtc_logopen("%s", b->name);
pthread_cleanup_push(vtc_logclose, vl);
sock = VTCP_listen_on("127.0.0.1:0", NULL, b->expected, &err);
sock = VTCP_listen_on(default_listen_addr, NULL, b->expected, &err);
if (sock < 0) {
AZ(pthread_cond_signal(&b->cond));
AZ(pthread_mutex_unlock(&b->mtx));
......@@ -149,11 +153,16 @@ barrier_sock_thread(void *priv)
}
assert(sock > 0);
VTCP_nonblocking(sock);
VTCP_myname(sock, abuf, sizeof abuf, pbuf, sizeof pbuf);
sua = VSA_getsockname(sock, buf, sizeof buf);
AN(sua);
VTCP_name(sua, abuf, sizeof abuf, pbuf, sizeof pbuf);
macro_def(vl, b->name, "addr", "%s", abuf);
macro_def(vl, b->name, "port", "%s", pbuf);
macro_def(vl, b->name, "sock", "%s:%s", abuf, pbuf);
if (VSA_Get_Proto(sua) == AF_INET)
macro_def(vl, b->name, "sock", "%s:%s", abuf, pbuf);
else
macro_def(vl, b->name, "sock", "[%s]:%s", abuf, pbuf);
AZ(pthread_cond_signal(&b->cond));
AZ(pthread_mutex_unlock(&b->mtx));
......
......@@ -106,7 +106,7 @@ client_tcp_connect(struct vtclog *vl, const char *addr, double tmo,
const char **errp)
{
int fd;
char mabuf[32], mpbuf[32];
char mabuf[VTCP_ADDRBUFSIZE], mpbuf[VTCP_PORTBUFSIZE];
AN(addr);
AN(errp);
......
......@@ -45,6 +45,7 @@
#include "vpf.h"
#include "vre.h"
#include "vtcp.h"
#include "vsa.h"
#include "vtim.h"
#define HAPROXY_PROGRAM_ENV_VAR "HAPROXY_PROGRAM"
......@@ -173,7 +174,7 @@ haproxy_cli_tcp_connect(struct vtclog *vl, const char *addr, double tmo,
const char **errp)
{
int fd;
char mabuf[32], mpbuf[32];
char mabuf[VTCP_ADDRBUFSIZE], mpbuf[VTCP_PORTBUFSIZE];
AN(addr);
AN(errp);
......@@ -519,16 +520,23 @@ haproxy_create_mcli(struct haproxy *h)
int sock;
const char *err;
char buf[128], addr[128], port[128];
char vsabuf[vsa_suckaddr_len];
struct suckaddr *sua;
sock = VTCP_listen_on("127.0.0.1:0", NULL, 100, &err);
sock = VTCP_listen_on(default_listen_addr, NULL, 100, &err);
if (err != NULL)
vtc_fatal(h->vl,
"Create listen socket failed: %s", err);
assert(sock > 0);
sua = VSA_getsockname(sock, vsabuf, sizeof vsabuf);
AN(sua);
VTCP_myname(sock, addr, sizeof addr, port, sizeof port);
VTCP_name(sua, addr, sizeof addr, port, sizeof port);
bprintf(buf, "%s_mcli", h->name);
macro_def(h->vl, buf, "sock", "%s %s", addr, port);
if (VSA_Get_Proto(sua) == AF_INET)
macro_def(h->vl, buf, "sock", "%s:%s", addr, port);
else
macro_def(h->vl, buf, "sock", "[%s]:%s", addr, port);
macro_def(h->vl, buf, "addr", "%s", addr);
macro_def(h->vl, buf, "port", "%s", port);
......@@ -558,6 +566,8 @@ haproxy_new(const char *name)
int closed_sock;
char addr[128], port[128];
const char *err;
char vsabuf[vsa_suckaddr_len];
struct suckaddr *sua;
ALLOC_OBJ(h, HAPROXY_MAGIC);
AN(h);
......@@ -597,8 +607,13 @@ haproxy_new(const char *name)
vtc_fatal(h->vl,
"Create listen socket failed: %s", err);
assert(closed_sock > 0);
VTCP_myname(closed_sock, addr, sizeof addr, port, sizeof port);
macro_def(h->vl, h->closed_sock, "sock", "%s %s", addr, port);
sua = VSA_getsockname(closed_sock, vsabuf, sizeof vsabuf);
AN(sua);
VTCP_name(sua, addr, sizeof addr, port, sizeof port);
if (VSA_Get_Proto(sua) == AF_INET)
macro_def(h->vl, h->closed_sock, "sock", "%s:%s", addr, port);
else
macro_def(h->vl, h->closed_sock, "sock", "[%s]:%s", addr, port);
macro_def(h->vl, h->closed_sock, "addr", "%s", addr);
macro_def(h->vl, h->closed_sock, "port", "%s", port);
VTCP_close(&closed_sock);
......@@ -836,6 +851,8 @@ haproxy_build_backends(struct haproxy *h, const char *vsb_data)
int sock;
char buf[128], addr[128], port[128];
const char *err;
char vsabuf[vsa_suckaddr_len];
struct suckaddr *sua;
p = strstr(p, HAPROXY_BE_FD_STR);
if (!p)
......@@ -853,10 +870,15 @@ haproxy_build_backends(struct haproxy *h, const char *vsb_data)
vtc_fatal(h->vl,
"Create listen socket failed: %s", err);
assert(sock > 0);
sua = VSA_getsockname(sock, vsabuf, sizeof vsabuf);
AN(sua);
VTCP_myname(sock, addr, sizeof addr, port, sizeof port);
VTCP_name(sua, addr, sizeof addr, port, sizeof port);
bprintf(buf, "%s_%s", h->name, p);
macro_def(h->vl, buf, "sock", "%s %s", addr, port);
if (VSA_Get_Proto(sua) == AF_INET)
macro_def(h->vl, buf, "sock", "%s:%s", addr, port);
else
macro_def(h->vl, buf, "sock", "[%s]:%s", addr, port);
macro_def(h->vl, buf, "addr", "%s", addr);
macro_def(h->vl, buf, "port", "%s", port);
......
......@@ -51,6 +51,7 @@
#include "vnum.h"
#include "vrnd.h"
#include "vss.h"
#include "vsa.h"
#include "vsub.h"
#include "vtcp.h"
#include "vtim.h"
......@@ -116,6 +117,7 @@ static int bad_backend_fd;
static int cleaner_fd = -1;
static pid_t cleaner_pid;
const char *default_listen_addr;
static struct buf *
get_buf(void)
......@@ -594,8 +596,13 @@ ip_magic(void)
sa = VSS_ResolveOne(NULL, "127.0.0.1", "0", 0, SOCK_STREAM, 0);
AN(sa);
bad_backend_fd = VTCP_bind(sa, NULL);
if (bad_backend_fd < 0) {
free(sa);
sa = VSS_ResolveFirst(NULL, "localhost", "0", 0, SOCK_STREAM, 0);
AN(sa);
bad_backend_fd = VTCP_bind(sa, NULL);
}
assert(bad_backend_fd >= 0);
free(sa);
VTCP_myname(bad_backend_fd, abuf, sizeof abuf, pbuf, sizeof(pbuf));
extmacro_def("localhost", "%s", abuf);
......@@ -609,7 +616,21 @@ ip_magic(void)
#endif
/* Expose a backend that is forever down. */
extmacro_def("bad_backend", "%s %s", abuf, pbuf);
if (VSA_Get_Proto(sa) == AF_INET)
extmacro_def("bad_backend", "%s:%s", abuf, pbuf);
else
extmacro_def("bad_backend", "[%s]:%s", abuf, pbuf);
/* our default bind/listen address */
if (VSA_Get_Proto(sa) == AF_INET)
bprintf(abuf, "%s:0", macro_get("localhost", NULL));
else
bprintf(abuf, "[%s]:0", macro_get("localhost", NULL));
extmacro_def("listen_addr", "%s", abuf);
default_listen_addr = strdup(abuf);
AN(default_listen_addr);
free(sa);
/*
* We need an IP number which will not repond, ever, and that is a
......
......@@ -39,6 +39,7 @@
#include <string.h>
#include <unistd.h>
#include "vsa.h"
#include "vtc.h"
#include "vtcp.h"
......@@ -59,8 +60,8 @@ struct server {
int sock;
int fd;
char listen[256];
char aaddr[32];
char aport[32];
char aaddr[VTCP_ADDRBUFSIZE];
char aport[VTCP_PORTBUFSIZE];
pthread_t tp;
};
......@@ -88,7 +89,7 @@ server_new(const char *name, struct vtclog *vl)
s->vsp = Sess_New(s->vl, name);
AN(s->vsp);
bprintf(s->listen, "%s", "127.0.0.1 0");
bprintf(s->listen, "%s", default_listen_addr);
s->depth = 10;
s->sock = -1;
s->fd = -1;
......@@ -183,17 +184,27 @@ server_listen_uds(struct server *s, const char **errp)
static void
server_listen_tcp(struct server *s, const char **errp)
{
char buf[vsa_suckaddr_len];
struct suckaddr *sua;
s->sock = VTCP_listen_on(s->listen, "0", s->depth, errp);
if (*errp != NULL)
return;
assert(s->sock > 0);
VTCP_myname(s->sock, s->aaddr, sizeof s->aaddr,
sua = VSA_getsockname(s->sock, buf, sizeof buf);
AN(sua);
VTCP_name(sua, s->aaddr, sizeof s->aaddr,
s->aport, sizeof s->aport);
/* Record the actual port, and reuse it on subsequent starts */
if (VSA_Get_Proto(sua) == AF_INET)
bprintf(s->listen, "%s:%s", s->aaddr, s->aport);
else
bprintf(s->listen, "[%s]:%s", s->aaddr, s->aport);
macro_def(s->vl, s->name, "addr", "%s", s->aaddr);
macro_def(s->vl, s->name, "port", "%s", s->aport);
macro_def(s->vl, s->name, "sock", "%s %s", s->aaddr, s->aport);
/* Record the actual port, and reuse it on subsequent starts */
bprintf(s->listen, "%s %s", s->aaddr, s->aport);
macro_def(s->vl, s->name, "sock", "%s", s->listen);
}
static void
......
......@@ -265,7 +265,7 @@ syslog_new(const char *name, struct vtclog *vl)
AN(s->vl);
vtc_log_set_cmd(s->vl, syslog_cmds);
bprintf(s->bind, "%s", "127.0.0.1 0");
bprintf(s->bind, "%s", default_listen_addr);
s->repeat = 1;
s->sock = -1;
s->lvl = -1;
......@@ -358,6 +358,8 @@ syslog_bind(struct syslog_srv *s)
const char *err;
char aaddr[VTCP_ADDRBUFSIZE];
char aport[VTCP_PORTBUFSIZE];
char buf[vsa_suckaddr_len];
struct suckaddr *sua;
CHECK_OBJ_NOTNULL(s, SYSLOG_SRV_MAGIC);
......@@ -369,10 +371,15 @@ syslog_bind(struct syslog_srv *s)
"Syslog server bind address (%s) cannot be resolved: %s",
s->bind, err);
assert(s->sock > 0);
VTCP_myname(s->sock, aaddr, sizeof aaddr, aport, sizeof aport);
sua = VSA_getsockname(s->sock, buf, sizeof buf);
AN(sua);
VTCP_name(sua, aaddr, sizeof aaddr, aport, sizeof aport);
macro_def(s->vl, s->name, "addr", "%s", aaddr);
macro_def(s->vl, s->name, "port", "%s", aport);
macro_def(s->vl, s->name, "sock", "%s %s", aaddr, aport);
if (VSA_Get_Proto(sua) == AF_INET)
macro_def(s->vl, s->name, "sock", "%s:%s", aaddr, aport);
else
macro_def(s->vl, s->name, "sock", "[%s]:%s", aaddr, aport);
/* Record the actual port, and reuse it on subsequent starts */
bprintf(s->bind, "%s %s", aaddr, aport);
}
......
......@@ -392,7 +392,7 @@ varnish_launch(struct varnish *v)
char *r = NULL;
/* Create listener socket */
v->cli_fd = VTCP_listen_on("127.0.0.1:0", NULL, 1, &err);
v->cli_fd = VTCP_listen_on(default_listen_addr, NULL, 1, &err);
if (err != NULL)
vtc_fatal(v->vl, "Create CLI listen socket failed: %s", err);
assert(v->cli_fd > 0);
......@@ -420,7 +420,7 @@ varnish_launch(struct varnish *v)
VSB_cat(vsb, " -p h2_initial_window_size=1m");
VSB_cat(vsb, " -p h2_rx_window_low_water=64k");
if (!v->has_a_arg) {
VSB_printf(vsb, " -a '%s'", "127.0.0.1:0");
VSB_printf(vsb, " -a '%s'", default_listen_addr);
if (v->proto != NULL)
VSB_printf(vsb, ",%s", v->proto);
}
......@@ -572,12 +572,14 @@ varnish_listen(const struct varnish *v, char *la)
AN(*a);
AN(*p);
if (*p != '-') {
bprintf(s, "%s %s", a, p);
} else {
if (*p == '-') {
bprintf(s, "%s", a);
a = "0.0.0.0";
p = "0";
} else if (strchr(a, ':')) {
bprintf(s, "[%s]:%s", a, p);
} else {
bprintf(s, "%s:%s", a, p);
}
if (first) {
......
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