From 98d5322a04a931e9fac2746bb7d2977294e76d5e Mon Sep 17 00:00:00 2001 From: des Date: Mon, 21 Aug 2006 17:26:11 +0000 Subject: [PATCH] Rename open_tcp() to TCP_open() and modify it to open only one socket of the appropriate type for the address that was passed in. Introduce TCP_parse(), which extracts an address and port from a string of the form "hostname:port", "i.p.v.4:port" or "[i:p:v:6]:port" (where "port" can be either a decimal number or a service name). Use TCP_parse() to parse the argument to -a (listen address), -b (backend address) and -T (telnet address). Eliminate -p (listen port). While there, rename a bunch of "fooflag" variables which aren't flags to "foo_arg". git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@872 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/common.h | 2 + varnish-cache/bin/varnishd/mgt.h | 7 +- varnish-cache/bin/varnishd/mgt_child.c | 6 +- varnish-cache/bin/varnishd/mgt_cli.c | 8 ++- varnish-cache/bin/varnishd/mgt_vcc.c | 23 +++--- varnish-cache/bin/varnishd/tcp.c | 71 +++++++++++-------- varnish-cache/bin/varnishd/varnishd.c | 97 ++++++++++++++------------ 7 files changed, 116 insertions(+), 98 deletions(-) diff --git a/varnish-cache/bin/varnishd/common.h b/varnish-cache/bin/varnishd/common.h index da45916e..8ba463c1 100644 --- a/varnish-cache/bin/varnishd/common.h +++ b/varnish-cache/bin/varnishd/common.h @@ -15,3 +15,5 @@ extern struct varnish_stats *VSL_stats; void TCP_name(struct sockaddr *addr, unsigned l, char *abuf, unsigned alen, char *pbuf, unsigned plen); void TCP_myname(int sock, char *abuf, unsigned alen, char *pbuf, unsigned plen); +int TCP_parse(const char *str, char **addr, char **port); +int TCP_open(const char *addr, const char *port, int http); diff --git a/varnish-cache/bin/varnishd/mgt.h b/varnish-cache/bin/varnishd/mgt.h index e6a13041..79ccff55 100644 --- a/varnish-cache/bin/varnishd/mgt.h +++ b/varnish-cache/bin/varnishd/mgt.h @@ -10,7 +10,7 @@ extern struct evbase *mgt_evb; /* mgt_child.c */ -void mgt_run(int dflag, const char *Tflag); +void mgt_run(int dflag, const char *T_arg); extern pid_t mgt_pid, child_pid; /* mgt_cli.c */ @@ -20,16 +20,13 @@ void mgt_cli_setup(int fdi, int fdo, int verbose); int mgt_cli_askchild(unsigned *status, char **resp, const char *fmt, ...); void mgt_cli_start_child(int fdi, int fdo); void mgt_cli_stop_child(void); -int mgt_cli_telnet(const char *port); +int mgt_cli_telnet(const char *T_arg); /* mgt_vcc.c */ void mgt_vcc_init(void); int mgt_vcc_default(const char *bflag, const char *fflag); int mgt_push_vcls_and_start(unsigned *status, char **p); -/* tcp.c */ -int open_tcp(const char *port, int http); - #include "stevedore.h" extern struct stevedore sma_stevedore; diff --git a/varnish-cache/bin/varnishd/mgt_child.c b/varnish-cache/bin/varnishd/mgt_child.c index 564f05df..d5bb8da4 100644 --- a/varnish-cache/bin/varnishd/mgt_child.c +++ b/varnish-cache/bin/varnishd/mgt_child.c @@ -278,7 +278,7 @@ mgt_sigint(struct ev *e, int what) */ void -mgt_run(int dflag, const char *Tflag) +mgt_run(int dflag, const char *T_arg) { struct sigaction sac; struct ev *e; @@ -292,8 +292,8 @@ mgt_run(int dflag, const char *Tflag) if (dflag) mgt_cli_setup(0, 1, 1); - if (Tflag) - mgt_cli_telnet(Tflag); + if (T_arg) + mgt_cli_telnet(T_arg); e = ev_new(); assert(e != NULL); diff --git a/varnish-cache/bin/varnishd/mgt_cli.c b/varnish-cache/bin/varnishd/mgt_cli.c index edac7c60..51da8fef 100644 --- a/varnish-cache/bin/varnishd/mgt_cli.c +++ b/varnish-cache/bin/varnishd/mgt_cli.c @@ -357,10 +357,14 @@ telnet_accept(struct ev *ev, int what) } int -mgt_cli_telnet(const char *port) +mgt_cli_telnet(const char *T_arg) { + char *addr, *port; - telnet_sock = open_tcp(port, 0); + TCP_parse(T_arg, &addr, &port); + telnet_sock = TCP_open(addr, port, 0); + free(addr); + free(port); if (telnet_sock < 0) { fprintf(stderr, "Could not open TELNET port\n"); exit (2); diff --git a/varnish-cache/bin/varnishd/mgt_vcc.c b/varnish-cache/bin/varnishd/mgt_vcc.c index a508b101..4d7f4f9d 100644 --- a/varnish-cache/bin/varnishd/mgt_vcc.c +++ b/varnish-cache/bin/varnishd/mgt_vcc.c @@ -118,8 +118,9 @@ mgt_vcc_delbyname(const char *name) /*--------------------------------------------------------------------*/ int -mgt_vcc_default(const char *bflag, const char *fflag) +mgt_vcc_default(const char *b_arg, const char *f_arg) { + char *addr, *port; char *buf, *vf; const char *p, *q; struct vsb *sb; @@ -127,7 +128,7 @@ mgt_vcc_default(const char *bflag, const char *fflag) sb = vsb_new(NULL, NULL, 0, VSB_AUTOEXTEND); assert(sb != NULL); - if (bflag != NULL) { + if (b_arg != NULL) { /* * XXX: should do a "HEAD /" on the -b argument to see that * XXX: it even works. On the other hand, we should do that @@ -136,26 +137,24 @@ mgt_vcc_default(const char *bflag, const char *fflag) * 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. */ - p = strchr(bflag, ' '); - if (p != NULL) { - q = p + 1; - } else { - p = strchr(bflag, '\0'); - assert(p != NULL); - q = "http"; + if (TCP_parse(b_arg, &addr, &port) != 0) { + fprintf(stderr, "invalid backend address\n"); + return (1); } buf = NULL; asprintf(&buf, "backend default {\n" - " set backend.host = \"%*.*s\";\n" + " set backend.host = \"%s\";\n" " set backend.port = \"%s\";\n" - "}\n", (int)(p - bflag), (int)(p - bflag), bflag, q); + "}\n", addr, port ? port : "http"); + free(addr); + free(port); assert(buf != NULL); vf = VCC_Compile(sb, buf, NULL); free(buf); } else { - vf = VCC_CompileFile(sb, fflag); + vf = VCC_CompileFile(sb, f_arg); } vsb_finish(sb); if (vsb_len(sb) > 0) { diff --git a/varnish-cache/bin/varnishd/tcp.c b/varnish-cache/bin/varnishd/tcp.c index e259fa2e..ac38dbca 100644 --- a/varnish-cache/bin/varnishd/tcp.c +++ b/varnish-cache/bin/varnishd/tcp.c @@ -74,38 +74,55 @@ accept_filter(int fd) } #endif -static int -try_sock(int family, const char *port, struct addrinfo **resp) +int +TCP_parse(const char *str, char **addr, char **port) +{ + const char *p; + + *addr = *port = NULL; + + if (str[0] == '[') { + /* IPv6 address of the form [::1]:80 */ + if ((p = strchr(str, ']')) == NULL || + p == str + 1 || + (p[1] != '\0' && p[1] != ':')) + return (-1); + *addr = strndup(str + 1, p - (str + 1)); + if (p[1] == ':') + *port = strdup(p + 2); + } else { + /* IPv4 address of the form 127.0.0.1:80, or non-numeric */ + p = strchr(str, ':'); + if (p == NULL) { + *addr = strdup(str); + } else { + if (p == str) + return (-1); + *addr = strndup(str, p - str); + *port = strdup(p + 1); + } + } + return (0); +} + +int +TCP_open(const char *addr, const char *port, int http) { struct addrinfo hints, *res; - int ret, sd; + int ret, sd, val; memset(&hints, 0, sizeof hints); - hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; - ret = getaddrinfo(NULL, port, &hints, &res); - if (ret != 0) + ret = getaddrinfo(addr, port, &hints, &res); + if (ret != 0) { + fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(ret)); return (-1); + } sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (sd < 0) - freeaddrinfo(res); - else - *resp = res; - return (sd); -} - -int -open_tcp(const char *port, int http) -{ - int sd, val; - struct addrinfo *res; - - sd = try_sock(AF_INET6, port, &res); - if (sd < 0) - sd = try_sock(AF_INET, port, &res); if (sd < 0) { - fprintf(stderr, "Failed to get listening socket\n"); + perror("socket()"); + freeaddrinfo(res); return (-1); } val = 1; @@ -115,14 +132,6 @@ open_tcp(const char *port, int http) close(sd); return (-1); } - val = 0; - if (res->ai_family == AF_INET6 && - setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof val) != 0) { - perror("setsockopt(IPV6_V6ONLY, 0)"); - freeaddrinfo(res); - close(sd); - return (-1); - } if (bind(sd, res->ai_addr, res->ai_addrlen) != 0) { perror("bind()"); freeaddrinfo(res); diff --git a/varnish-cache/bin/varnishd/varnishd.c b/varnish-cache/bin/varnishd/varnishd.c index 83a222c6..ad1eea12 100644 --- a/varnish-cache/bin/varnishd/varnishd.c +++ b/varnish-cache/bin/varnishd/varnishd.c @@ -47,25 +47,25 @@ cmp_hash(struct hash_slinger *s, const char *p, const char *q) } static void -setup_hash(const char *sflag) +setup_hash(const char *s_arg) { const char *p, *q; struct hash_slinger *hp; - p = strchr(sflag, ','); + p = strchr(s_arg, ','); if (p == NULL) - q = p = strchr(sflag, '\0'); + q = p = strchr(s_arg, '\0'); else q = p + 1; assert(p != NULL); assert(q != NULL); - if (!cmp_hash(&hcl_slinger, sflag, p)) { + if (!cmp_hash(&hcl_slinger, s_arg, p)) { hp = &hcl_slinger; - } else if (!cmp_hash(&hsl_slinger, sflag, p)) { + } else if (!cmp_hash(&hsl_slinger, s_arg, p)) { hp = &hsl_slinger; } else { fprintf(stderr, "Unknown hash method \"%.*s\"\n", - (int)(p - sflag), sflag); + (int)(p - s_arg), s_arg); exit (2); } heritage.hash = hp; @@ -92,25 +92,25 @@ cmp_storage(struct stevedore *s, const char *p, const char *q) } static void -setup_storage(const char *sflag) +setup_storage(const char *s_arg) { const char *p, *q; struct stevedore *stp; - p = strchr(sflag, ','); + p = strchr(s_arg, ','); if (p == NULL) - q = p = strchr(sflag, '\0'); + q = p = strchr(s_arg, '\0'); else q = p + 1; assert(p != NULL); assert(q != NULL); - if (!cmp_storage(&sma_stevedore, sflag, p)) { + if (!cmp_storage(&sma_stevedore, s_arg, p)) { stp = &sma_stevedore; - } else if (!cmp_storage(&smf_stevedore, sflag, p)) { + } else if (!cmp_storage(&smf_stevedore, s_arg, p)) { stp = &smf_stevedore; } else { fprintf(stderr, "Unknown storage method \"%.*s\"\n", - (int)(p - sflag), sflag); + (int)(p - s_arg), s_arg); exit (2); } heritage.stevedore = malloc(sizeof *heritage.stevedore); @@ -125,12 +125,14 @@ static void usage(void) { fprintf(stderr, "usage: varnishd [options]\n"); - fprintf(stderr, " %-28s # %s\n", "-b backend", - "backend location"); + fprintf(stderr, " %-28s # %s\n", "-a address:port", + "HTTP listen address and port"); + fprintf(stderr, " %-28s # %s\n", "-b address:port", + "backend address and port"); fprintf(stderr, " %-28s # %s\n", "", " -b "); fprintf(stderr, " %-28s # %s\n", "", - " -b ' '"); + " -b ':'"); fprintf(stderr, " %-28s # %s\n", "-d", "debug"); fprintf(stderr, " %-28s # %s\n", "-f file", "VCL_file"); fprintf(stderr, " %-28s # %s\n", @@ -143,7 +145,6 @@ usage(void) " -h classic,"); fprintf(stderr, " %-28s # %s\n", "", " -h classic,,"); - fprintf(stderr, " %-28s # %s\n", "-p number", "TCP listen port"); fprintf(stderr, " %-28s # %s\n", "-s kind[,storageoptions]", "Backend storage specification"); fprintf(stderr, " %-28s # %s\n", "", @@ -155,7 +156,8 @@ usage(void) fprintf(stderr, " %-28s # %s\n", "", " -s file,,"); fprintf(stderr, " %-28s # %s\n", "-t", "Default TTL"); - fprintf(stderr, " %-28s # %s\n", "-T port", "Telnet port"); + fprintf(stderr, " %-28s # %s\n", "-T address:port", + "Telnet listen address and port"); fprintf(stderr, " %-28s # %s\n", "-V", "version"); fprintf(stderr, " %-28s # %s\n", "-w int[,int[,int]]", "Number of worker threads"); @@ -317,13 +319,14 @@ int main(int argc, char *argv[]) { int o; - const char *portnumber = "8080"; - unsigned dflag = 0; - const char *bflag = NULL; - const char *fflag = NULL; - const char *sflag = "file"; - const char *hflag = "classic"; - const char *Tflag = NULL; + unsigned d_flag = 0; + char *addr, *port; + const char *a_arg = "0.0.0.0:http"; + const char *b_arg = NULL; + const char *f_arg = NULL; + const char *h_flag = "classic"; + const char *s_arg = "file"; + const char *T_arg = NULL; struct params param; setbuf(stdout, NULL); @@ -343,31 +346,31 @@ main(int argc, char *argv[]) params->send_timeout = 600; params->auto_restart = 1; - while ((o = getopt(argc, argv, "b:df:h:p:s:t:T:Vw:")) != -1) + while ((o = getopt(argc, argv, "a:b:df:h:s:t:T:Vw:")) != -1) switch (o) { + case 'a': + a_arg = optarg; + break; case 'b': - bflag = optarg; + b_arg = optarg; break; case 'd': - dflag++; + d_flag++; break; case 'f': - fflag = optarg; + f_arg = optarg; break; case 'h': - hflag = optarg; - break; - case 'p': - portnumber = optarg; + h_flag = optarg; break; case 's': - sflag = optarg; + s_arg = optarg; break; case 't': params->default_ttl = strtoul(optarg, NULL, 0); break; case 'T': - Tflag = optarg; + T_arg = optarg; break; case 'V': varnish_version("varnishd"); @@ -387,20 +390,20 @@ main(int argc, char *argv[]) usage(); } - if (bflag != NULL && fflag != NULL) { + if (b_arg != NULL && f_arg != NULL) { fprintf(stderr, "Only one of -b or -f can be specified\n"); usage(); } - if (bflag == NULL && fflag == NULL) { + if (b_arg == NULL && f_arg == NULL) { fprintf(stderr, "One of -b or -f must be specified\n"); usage(); } - if (mgt_vcc_default(bflag, fflag)) + if (mgt_vcc_default(b_arg, f_arg)) exit (2); - setup_storage(sflag); - setup_hash(hflag); + setup_storage(s_arg); + setup_hash(h_flag); /* * XXX: Lacking the suspend/resume facility (due to the socket API @@ -409,22 +412,26 @@ main(int argc, char *argv[]) * but do not answer. That, on the other hand, would eliminate the * possibility of doing a "no-glitch" restart of the child process. */ - heritage.socket = open_tcp(portnumber, 1); + if (TCP_parse(a_arg, &addr, &port) != 0) + fprintf(stderr, "invalid listen address\n"); + heritage.socket = TCP_open(addr, port ? port : "http", 1); + free(addr); + free(port); if (heritage.socket < 0) exit (2); VSL_MgtInit(SHMLOG_FILENAME, 8*1024*1024); - if (dflag == 1) + if (d_flag == 1) DebugStunt(); - if (dflag < 2) - daemon(dflag, dflag); - if (dflag == 1) + if (d_flag < 2) + daemon(d_flag, d_flag); + if (d_flag == 1) printf("%d\n", getpid()); mgt_cli_init(); - mgt_run(dflag, Tflag); + mgt_run(d_flag, T_arg); exit(0); } -- 2.39.5