diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2009-04-24 14:20:25 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2009-04-24 14:20:25 +0000 |
commit | f5e309798cb03dc46e8b5e0d066ffb8ffd8afbf2 (patch) | |
tree | 9eef321e8f1fe97444d1a4221afac4edb16eafda | |
parent | 937f09733fdb4f68610763fc5c51fa6288ac8521 (diff) |
Allow UDP and/or TCP redirections instead of just TCP.
Thanks to Marek Grzybowski for feedback and testing.
ok jmc@ (manpage bits)
-rw-r--r-- | usr.sbin/relayd/parse.y | 57 | ||||
-rw-r--r-- | usr.sbin/relayd/pfe_filter.c | 10 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.conf.5 | 29 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.h | 3 |
4 files changed, 73 insertions, 26 deletions
diff --git a/usr.sbin/relayd/parse.y b/usr.sbin/relayd/parse.y index c8227685918..40c76274f64 100644 --- a/usr.sbin/relayd/parse.y +++ b/usr.sbin/relayd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.132 2009/04/17 09:37:25 reyk Exp $ */ +/* $OpenBSD: parse.y,v 1.133 2009/04/24 14:20:24 reyk Exp $ */ /* * Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org> @@ -102,9 +102,9 @@ static int nodedirection; struct address *host_v4(const char *); struct address *host_v6(const char *); int host_dns(const char *, struct addresslist *, - int, struct portrange *, const char *); + int, struct portrange *, const char *, int); int host(const char *, struct addresslist *, - int, struct portrange *, const char *); + int, struct portrange *, const char *, int); struct table *table_inherit(struct table *); int getservice(char *); @@ -141,8 +141,9 @@ typedef struct { %token <v.number> NUMBER %type <v.string> hostname interface table %type <v.number> http_type loglevel mark parent -%type <v.number> direction dstmode flag forwardmode proto_type retry +%type <v.number> direction dstmode flag forwardmode retry %type <v.number> optssl optsslclient sslcache +%type <v.number> redirect_proto relay_proto %type <v.port> port %type <v.host> host %type <v.tv> timeout @@ -211,7 +212,7 @@ hostname : /* empty */ { } ; -proto_type : /* empty */ { $$ = RELAY_PROTO_TCP; } +relay_proto : /* empty */ { $$ = RELAY_PROTO_TCP; } | TCP { $$ = RELAY_PROTO_TCP; } | STRING { if (strcmp("http", $1) == 0) { @@ -227,6 +228,22 @@ proto_type : /* empty */ { $$ = RELAY_PROTO_TCP; } } ; +redirect_proto : /* empty */ { $$ = IPPROTO_TCP; } + | TCP { $$ = IPPROTO_TCP; } + | STRING { + struct protoent *p; + + if ((p = getprotobyname($1)) == NULL) { + yyerror("invalid protocol: %s", $1); + free($1); + YYERROR; + } + free($1); + + $$ = p->p_proto; + } + ; + eflags_l : eflags comma eflags_l | eflags ; @@ -450,18 +467,18 @@ rdroptsl : forwardmode TO tablespec interface { $3->conf.rdrid = rdr->conf.id; $3->conf.flags |= F_USED; } - | LISTEN ON STRING port interface { + | LISTEN ON STRING redirect_proto port interface { if (host($3, &rdr->virts, - SRV_MAX_VIRTS, &$4, $5) <= 0) { + SRV_MAX_VIRTS, &$5, $6, $4) <= 0) { yyerror("invalid virtual ip: %s", $3); free($3); - free($5); + free($6); YYERROR; } free($3); - free($5); + free($6); if (rdr->conf.port == 0) - rdr->conf.port = $4.val[0]; + rdr->conf.port = $5.val[0]; tableport = rdr->conf.port; } | DISABLE { rdr->conf.flags |= F_DISABLE; } @@ -731,7 +748,7 @@ digest : DIGEST STRING } ; -proto : proto_type PROTO STRING { +proto : relay_proto PROTO STRING { struct protocol *p; if (strcmp($3, "default") == 0) { @@ -1216,7 +1233,7 @@ relayoptsl : LISTEN ON STRING port optssl { } TAILQ_INIT(&al); - if (host($3, &al, 1, &$4, NULL) <= 0) { + if (host($3, &al, 1, &$4, NULL, -1) <= 0) { yyerror("invalid listen ip: %s", $3); free($3); YYERROR; @@ -1301,7 +1318,7 @@ forwardspec : STRING port retry { } TAILQ_INIT(&al); - if (host($1, &al, 1, &$2, NULL) <= 0) { + if (host($1, &al, 1, &$2, NULL, -1) <= 0) { yyerror("invalid listen ip: %s", $1); free($1); YYERROR; @@ -1372,7 +1389,7 @@ host : STRING retry parent { fatal("out of memory"); TAILQ_INIT(&al); - if (host($1, &al, 1, NULL, NULL) <= 0) { + if (host($1, &al, 1, NULL, NULL, -1) <= 0) { yyerror("invalid host %s", $2); free($1); free($$); @@ -1945,6 +1962,7 @@ parse_config(const char *filename, int opts) popfile(); endservent(); + endprotoent(); /* Free macros and check which have not been used. */ for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) { @@ -2160,7 +2178,7 @@ host_v6(const char *s) int host_dns(const char *s, struct addresslist *al, int max, - struct portrange *port, const char *ifname) + struct portrange *port, const char *ifname, int ipproto) { struct addrinfo hints, *res0, *res; int error, cnt = 0; @@ -2196,7 +2214,10 @@ host_dns(const char *s, struct addresslist *al, int max, freeaddrinfo(res0); return (-1); } + if (ipproto != -1) + h->ipproto = ipproto; h->ss.ss_family = res->ai_family; + if (res->ai_family == AF_INET) { sain = (struct sockaddr_in *)&h->ss; sain->sin_len = sizeof(struct sockaddr_in); @@ -2222,7 +2243,7 @@ host_dns(const char *s, struct addresslist *al, int max, int host(const char *s, struct addresslist *al, int max, - struct portrange *port, const char *ifname) + struct portrange *port, const char *ifname, int ipproto) { struct address *h; @@ -2242,12 +2263,14 @@ host(const char *s, struct addresslist *al, int max, return (-1); } } + if (ipproto != -1) + h->ipproto = ipproto; TAILQ_INSERT_HEAD(al, h, entry); return (1); } - return (host_dns(s, al, max, port, ifname)); + return (host_dns(s, al, max, port, ifname, ipproto)); } struct table * diff --git a/usr.sbin/relayd/pfe_filter.c b/usr.sbin/relayd/pfe_filter.c index 86ad73a2e29..c793620f3f7 100644 --- a/usr.sbin/relayd/pfe_filter.c +++ b/usr.sbin/relayd/pfe_filter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfe_filter.c,v 1.37 2009/04/01 14:08:53 reyk Exp $ */ +/* $OpenBSD: pfe_filter.c,v 1.38 2009/04/24 14:20:24 reyk Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -425,15 +425,13 @@ sync_ruleset(struct relayd *env, struct rdr *rdr, int enable) /* NOTREACHED */ } - rio.rule.timeout[PFTM_TCP_ESTABLISHED] = - rdr->conf.timeout.tv_sec; rio.ticket = env->sc_pf->pfte[rs].ticket; if (ioctl(env->sc_pf->dev, DIOCBEGINADDRS, &pio) == -1) fatal("sync_ruleset: cannot initialise address pool"); rio.pool_ticket = pio.ticket; rio.rule.af = address->ss.ss_family; - rio.rule.proto = IPPROTO_TCP; + rio.rule.proto = address->ipproto; rio.rule.src.addr.type = PF_ADDR_ADDRMASK; rio.rule.dst.addr.type = PF_ADDR_ADDRMASK; rio.rule.dst.port_op = address->port.op; @@ -441,6 +439,10 @@ sync_ruleset(struct relayd *env, struct rdr *rdr, int enable) rio.rule.dst.port[1] = address->port.val[1]; rio.rule.rtableid = -1; /* stay in the main routing table */ + if (rio.rule.proto == IPPROTO_TCP) + rio.rule.timeout[PFTM_TCP_ESTABLISHED] = + rdr->conf.timeout.tv_sec; + if (strlen(rdr->conf.tag)) (void)strlcpy(rio.rule.tagname, rdr->conf.tag, sizeof(rio.rule.tagname)); diff --git a/usr.sbin/relayd/relayd.conf.5 b/usr.sbin/relayd/relayd.conf.5 index 1d550544e57..3078ebd4109 100644 --- a/usr.sbin/relayd/relayd.conf.5 +++ b/usr.sbin/relayd/relayd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: relayd.conf.5,v 1.103 2009/04/16 20:13:13 sobrado Exp $ +.\" $OpenBSD: relayd.conf.5,v 1.104 2009/04/24 14:20:24 reyk Exp $ .\" .\" Copyright (c) 2006, 2007 Reyk Floeter <reyk@openbsd.org> .\" Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: April 16 2009 $ +.Dd $Mdocdate: April 24 2009 $ .Dt RELAYD.CONF 5 .Os .Sh NAME @@ -430,7 +430,9 @@ This directive can be specified twice \(en the second entry will be used as the backup table if all hosts in the main table are down. At least one entry for the main table is mandatory. .It Xo -.Ic listen on Ar address Ic port Ar port +.Ic listen on Ar address +.Op ip-proto +.Ic port Ar port .Op Ic interface Ar name .Xc Specify an @@ -446,6 +448,14 @@ The argument can optionally specify a port range instead of a single port; the format is .Ar min-port : Ns Ar max-port . +The optional argument +.Ar ip-proto +can be used to specify an IP protocol like +.Ar tcp +or +.Ar udp ; +it defaults to +.Ar tcp . The rdr rule can be optionally restricted to a given interface name. .It Xo .Ic route to @@ -1048,7 +1058,7 @@ Default location of the CA bundle that can be used with .Xr relayd 8 . .El .Sh EXAMPLES -This configuration file would create a service +This configuration file would create a redirection service .Dq www which load balances four hosts and falls back to one host containing a @@ -1076,6 +1086,17 @@ redirect "www" { } .Ed .Pp +It is possible to specify multiple listen directives with different IP +protocols in a single redirection configuration: +.Bd -literal -offset indent +redirect "dns" { + listen on dns.example.com tcp port 53 + listen on dns.example.com udp port 53 + + forward to \*(Ltdnshosts\*(Gt port 53 check tcp +} +.Ed +.Pp The following configuration would add a relay to forward secure HTTPS connections to a pool of HTTP webservers using the diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h index f436f871523..c392b2ebe48 100644 --- a/usr.sbin/relayd/relayd.h +++ b/usr.sbin/relayd/relayd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: relayd.h,v 1.115 2009/04/02 14:30:51 reyk Exp $ */ +/* $OpenBSD: relayd.h,v 1.116 2009/04/24 14:20:24 reyk Exp $ */ /* * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -317,6 +317,7 @@ struct portrange { struct address { struct sockaddr_storage ss; + int ipproto; struct portrange port; char ifname[IFNAMSIZ]; TAILQ_ENTRY(address) entry; |