Commit a10acac3 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Have VSS_resolve() call VSS_parse() and only use the provided port argument

as a default, if the host argument does not specify a port.

Elminate most separate calls to VSS_parse()

Make it possible to specify address and port of backends in VCL using
only the .host field.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@5117 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 3a31f98e
......@@ -542,7 +542,6 @@ void
mgt_cli_telnet(const char *T_arg)
{
struct vss_addr **ta;
char *addr, *port;
int i, n, sock, good;
struct telnet *tn;
char *p;
......@@ -553,9 +552,7 @@ mgt_cli_telnet(const char *T_arg)
AN(p);
strcpy(p, T_arg);
XXXAZ(VSS_parse(T_arg, &addr, &port));
n = VSS_resolve(addr, port, &ta);
n = VSS_resolve(T_arg, NULL, &ta);
if (n == 0) {
fprintf(stderr, "Could not open management port\n");
exit(2);
......@@ -578,19 +575,15 @@ mgt_cli_telnet(const char *T_arg)
}
free(ta);
if (good == 0) {
REPORT(LOG_ERR, "-T %s:%s could not be listened on.",
addr, port);
REPORT(LOG_ERR, "-T %s could not be listened on.", T_arg);
exit(2);
}
free(addr);
free(port);
}
/* Reverse CLI ("Master") connections --------------------------------*/
static int M_fd = -1;
static struct vev *M_poker, *M_conn;
static char *M_addr, *M_port;
static struct vss_addr **M_ta;
static int M_nta, M_nxt;
static double M_poll = 0.1;
......@@ -666,11 +659,7 @@ mgt_cli_master(const char *M_arg)
{
(void)M_arg;
if (VSS_parse(M_arg, &M_addr, &M_port) || M_port == NULL) {
fprintf(stderr, "Could not parse -M argument\n");
exit (1);
}
M_nta = VSS_resolve(M_addr, M_port, &M_ta);
M_nta = VSS_resolve(M_arg, NULL, &M_ta);
if (M_nta <= 0) {
fprintf(stderr, "Could resolve -M argument to address\n");
exit (1);
......
......@@ -378,18 +378,9 @@ tweak_listen_address(struct cli *cli, const struct parspec *par,
VTAILQ_INIT(&lsh);
for (i = 1; av[i] != NULL; i++) {
struct vss_addr **ta;
char *host, *port;
int j, n;
if (VSS_parse(av[i], &host, &port) != 0) {
cli_out(cli, "Invalid listen address ");
cli_quote(cli, av[i]);
cli_result(cli, CLIS_PARAM);
break;
}
n = VSS_resolve(host, port ? port : "http", &ta);
free(host);
free(port);
n = VSS_resolve(av[i], "http", &ta);
if (n == 0) {
cli_out(cli, "Invalid listen address ");
cli_quote(cli, av[i]);
......
......@@ -362,7 +362,6 @@ mgt_vcc_delbyname(const char *name)
int
mgt_vcc_default(const char *b_arg, const char *f_arg, char *vcl, int C_flag)
{
char *addr, *port;
char *vf;
struct vsb *sb;
struct vclprog *vp;
......@@ -381,26 +380,10 @@ mgt_vcc_default(const char *b_arg, const char *f_arg, char *vcl, int C_flag)
* XXX: a bug for a backend to not reply at that time, so then
* XXX: again: we should check it here in the "trivial" case.
*/
if (VSS_parse(b_arg, &addr, &port) != 0 || addr == NULL) {
/*
* (addr == NULL && port != NULL) is possible if
* the user incorrectly specified an address such
* as ":80", which is a valid listening address.
* In the future, we may want to interpret this as
* a shortcut for "localhost:80".
*/
free(port);
fprintf(stderr, "invalid backend address\n");
return (1);
}
bprintf(buf,
"backend default {\n"
" .host = \"%s\";\n"
" .port = \"%s\";\n"
"}\n", addr, port ? port : "http");
free(addr);
free(port);
"}\n", b_arg);
vcl = strdup(buf);
AN(vcl);
}
......
......@@ -678,16 +678,9 @@ init_connection(const char *address)
{
struct vss_addr **ta;
struct vss_addr *tap;
char *addr, *port;
int i, n;
if (VSS_parse(address, &addr, &port) != 0) {
thread_log(0, 0, "Invalid address");
exit(2);
}
n = VSS_resolve(addr, port, &ta);
free(addr);
free(port);
n = VSS_resolve(address, NULL, &ta);
if (n == 0) {
thread_log(0, 0, "Could not connect to server");
exit(2);
......
......@@ -79,7 +79,10 @@ struct vss_addr {
* "0.0.0.0" - "0.0.0.0:80"
* "[::1]" - "[::1]:80"
* "[::]" - "[::]:80"
*
* See also RFC5952
*/
int
VSS_parse(const char *str, char **addr, char **port)
{
......@@ -129,6 +132,9 @@ VSS_parse(const char *str, char **addr, char **port)
*
* The return value is the number of addresses resoved, or zero.
*
* If the addr argument contains a port specification, that takes
* precedence over the port argument.
*
* XXX: We need a function to free the allocated addresses.
*/
int
......@@ -137,15 +143,27 @@ VSS_resolve(const char *addr, const char *port, struct vss_addr ***vap)
struct addrinfo hints, *res0, *res;
struct vss_addr **va;
int i, ret;
char *adp, *hop;
memset(&hints, 0, sizeof hints);
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
ret = getaddrinfo(addr, port, &hints, &res0);
if (ret != 0) {
fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(ret));
ret = VSS_parse(addr, &hop, &adp);
if (ret)
return (0);
}
if (adp == NULL)
ret = getaddrinfo(addr, port, &hints, &res0);
else
ret = getaddrinfo(hop, adp, &hints, &res0);
free(hop);
free(adp);
if (ret != 0)
return (0);
XXXAN(res0);
for (res = res0, i = 0; res != NULL; res = res->ai_next, ++i)
/* nothing */ ;
......
......@@ -60,9 +60,11 @@ SVNID("$Id$")
#include <netdb.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "vsb.h"
#include "vss.h"
#include "vcc_priv.h"
#include "vcc_compile.h"
......@@ -74,22 +76,6 @@ struct host {
char *vgcname;
};
static const char *
CheckHostPort(const char *host, const char *port)
{
struct addrinfo *res, hint;
int error;
memset(&hint, 0, sizeof hint);
hint.ai_family = PF_UNSPEC;
hint.ai_socktype = SOCK_STREAM;
error = getaddrinfo(host, port, &hint, &res);
if (error)
return (gai_strerror(error));
freeaddrinfo(res);
return (NULL);
}
static int
emit_sockaddr(struct vcc *tl, void *sa, unsigned sal)
{
......@@ -122,21 +108,47 @@ emit_sockaddr(struct vcc *tl, void *sa, unsigned sal)
* and put it in an official sockaddr when we load the VCL.
*/
#include <stdio.h>
void
Emit_Sockaddr(struct vcc *tl, const struct token *t_host,
const char *port)
Emit_Sockaddr(struct vcc *tl, const struct token *t_host, const char *port)
{
struct addrinfo *res, *res0, *res1, hint;
int n4, n6, error, retval, x;
const char *emit, *multiple;
char hbuf[NI_MAXHOST];
char *hop, *pop;
AN(t_host->dec);
retval = 0;
memset(&hint, 0, sizeof hint);
hint.ai_family = PF_UNSPEC;
hint.ai_socktype = SOCK_STREAM;
error = getaddrinfo(t_host->dec, port, &hint, &res0);
if (VSS_parse(t_host->dec, &hop, &pop)) {
vsb_printf(tl->sb,
"Backend host '%.*s': wrong syntax (unbalanced [...] ?)\n",
PF(t_host) );
vcc_ErrWhere(tl, t_host);
return;
}
if (pop != NULL)
error = getaddrinfo(hop, pop, &hint, &res0);
else
error = getaddrinfo(t_host->dec, port, &hint, &res0);
free(hop);
free(pop);
if (error) {
vsb_printf(tl->sb,
"Backend host '%.*s'"
" could not be resolved to an IP address:\n", PF(t_host));
vsb_printf(tl->sb,
"\t%s\n"
"(Sorry if that error message is gibberish.)\n",
gai_strerror(error));
vcc_ErrWhere(tl, t_host);
return;
}
AZ(error);
n4 = n6 = 0;
multiple = NULL;
......@@ -432,7 +444,6 @@ vcc_ParseHostDef(struct vcc *tl, int serial, const char *vgcname)
struct token *t_port = NULL;
struct token *t_hosthdr = NULL;
unsigned saint = UINT_MAX;
const char *ep;
struct fld_spec *fs;
struct vsb *vsb;
unsigned u;
......@@ -567,26 +578,10 @@ vcc_ParseHostDef(struct vcc *tl, int serial, const char *vgcname)
/* Check that the hostname makes sense */
assert(t_host != NULL);
ep = CheckHostPort(t_host->dec, "80");
if (ep != NULL) {
vsb_printf(tl->sb, "Backend host '%.*s': %s\n", PF(t_host), ep);
vcc_ErrWhere(tl, t_host);
return;
}
/* Check that the portname makes sense */
if (t_port != NULL) {
ep = CheckHostPort("127.0.0.1", t_port->dec);
if (ep != NULL) {
vsb_printf(tl->sb,
"Backend port '%.*s': %s\n", PF(t_port), ep);
vcc_ErrWhere(tl, t_port);
return;
}
if (t_port != NULL)
Emit_Sockaddr(tl, t_host, t_port->dec);
} else {
else
Emit_Sockaddr(tl, t_host, "80");
}
ERRCHK(tl);
ExpectErr(tl, '}');
......
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