diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2011-04-07 13:22:30 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2011-04-07 13:22:30 +0000 |
commit | 8009fc879d2991d924ed93860220e1f012cd10e5 (patch) | |
tree | 886a67b432c10a4c0a07500fc116262cdca61178 /usr.sbin | |
parent | 3b853a90fa7c3a2d4d109e5a945f43318f5400d7 (diff) |
Add support for divert-to which provides some benefits over rdr-to.
ok mikeb@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/relayd/parse.y | 18 | ||||
-rw-r--r-- | usr.sbin/relayd/relay.c | 36 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.conf.5 | 17 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.h | 5 |
4 files changed, 63 insertions, 13 deletions
diff --git a/usr.sbin/relayd/parse.y b/usr.sbin/relayd/parse.y index 98f881873a3..f41bd721ab3 100644 --- a/usr.sbin/relayd/parse.y +++ b/usr.sbin/relayd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.149 2010/10/26 15:04:37 reyk Exp $ */ +/* $OpenBSD: parse.y,v 1.150 2011/04/07 13:22:29 reyk Exp $ */ /* * Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org> @@ -144,7 +144,7 @@ typedef struct { %token CIPHERS CODE COOKIE DEMOTE DIGEST DISABLE ERROR EXPECT %token EXTERNAL FILENAME FILTER FORWARD FROM HASH HEADER HOST ICMP %token INCLUDE INET INET6 INTERFACE INTERVAL IP LABEL LISTEN -%token LOADBALANCE LOG LOOKUP MARK MARKED MODE NAT NO +%token LOADBALANCE LOG LOOKUP MARK MARKED MODE NAT NO DESTINATION %token NODELAY NOTHING ON PARENT PATH PORT PREFORK PROTO %token QUERYSTR REAL REDIRECT RELAY REMOVE REQUEST RESPONSE RETRY %token RETURN ROUNDROBIN ROUTE SACK SCRIPT SEND SESSION SOCKET @@ -1213,7 +1213,13 @@ relay : RELAY STRING { rlay->rl_conf.name); YYERROR; } - if ((rlay->rl_conf.flags & F_NATLOOK) == 0 && + if ((rlay->rl_conf.flags & (F_NATLOOK|F_DIVERT)) == + (F_NATLOOK|F_DIVERT)) { + yyerror("relay %s with conflicting nat lookup " + "and peer options", rlay->rl_conf.name); + YYERROR; + } + if ((rlay->rl_conf.flags & (F_NATLOOK|F_DIVERT)) == 0 && rlay->rl_conf.dstss.ss_family == AF_UNSPEC && rlay->rl_conf.dsttable == EMPTY_ID) { yyerror("relay %s has no target, rdr, " @@ -1373,6 +1379,11 @@ forwardspec : STRING port retry { rlay->rl_conf.flags |= F_NATLOOK; rlay->rl_conf.dstretry = $3; } + | DESTINATION retry { + conf->sc_flags |= F_NEEDPF; + rlay->rl_conf.flags |= F_DIVERT; + rlay->rl_conf.dstretry = $2; + } | tablespec { if (rlay->rl_backuptable) { yyerror("only one backup table is allowed"); @@ -1716,6 +1727,7 @@ lookup(char *s) { "code", CODE }, { "cookie", COOKIE }, { "demote", DEMOTE }, + { "destination", DESTINATION }, { "digest", DIGEST }, { "disable", DISABLE }, { "error", ERROR }, diff --git a/usr.sbin/relayd/relay.c b/usr.sbin/relayd/relay.c index 5510645f88f..3691a893ed5 100644 --- a/usr.sbin/relayd/relay.c +++ b/usr.sbin/relayd/relay.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relay.c,v 1.130 2011/03/12 21:06:40 bluhm Exp $ */ +/* $OpenBSD: relay.c,v 1.131 2011/04/07 13:22:29 reyk Exp $ */ /* * Copyright (c) 2006, 2007, 2008 Reyk Floeter <reyk@openbsd.org> @@ -620,6 +620,22 @@ relay_socket_af(struct sockaddr_storage *ss, in_port_t port) return (0); } +in_port_t +relay_socket_getport(struct sockaddr_storage *ss) +{ + switch (ss->ss_family) { + case AF_INET: + return (((struct sockaddr_in *)ss)->sin_port); + case AF_INET6: + return (((struct sockaddr_in6 *)ss)->sin6_port); + default: + return (0); + } + + /* NOTREACHED */ + return (0); +} + int relay_socket(struct sockaddr_storage *ss, in_port_t port, struct protocol *proto, int fd, int reuseport) @@ -2044,15 +2060,27 @@ relay_accept(int fd, short sig, void *arg) return; } - if (rlay->rl_conf.flags & F_NATLOOK) { + if (rlay->rl_conf.flags & F_DIVERT) { + slen = sizeof(con->se_out.ss); + if (getsockname(s, (struct sockaddr *)&con->se_out.ss, + &slen) == -1) { + relay_close(con, "peer lookup failed"); + return; + } + con->se_out.port = relay_socket_getport(&con->se_out.ss); + + /* Detect loop and fall back to the alternate forward target */ + if (bcmp(&rlay->rl_conf.ss, &con->se_out.ss, + sizeof(con->se_out.ss)) == 0 && + con->se_out.port == rlay->rl_conf.port) + con->se_out.ss.ss_family = AF_UNSPEC; + } else if (rlay->rl_conf.flags & F_NATLOOK) { if ((cnl = (struct ctl_natlook *) calloc(1, sizeof(struct ctl_natlook))) == NULL) { relay_close(con, "failed to allocate nat lookup"); return; } - } - if (rlay->rl_conf.flags & F_NATLOOK && cnl != NULL) { con->se_cnl = cnl; bzero(cnl, sizeof(*cnl)); cnl->in = -1; diff --git a/usr.sbin/relayd/relayd.conf.5 b/usr.sbin/relayd/relayd.conf.5 index 55f3484b1e2..f18db20514b 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.116 2010/10/26 15:26:58 jmc Exp $ +.\" $OpenBSD: relayd.conf.5,v 1.117 2011/04/07 13:22:29 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: October 26 2010 $ +.Dd $Mdocdate: April 7 2011 $ .Dt RELAYD.CONF 5 .Os .Sh NAME @@ -596,10 +596,10 @@ 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 forward to -.Ic nat lookup +.Ic destination .Ar options ... .Xc -When redirecting connections with an rdr-to rule in +When redirecting connections with an divert-to rule in .Xr pf.conf 5 to a relay listening on localhost, this directive will look up the real destination address of the intended target host, @@ -607,7 +607,14 @@ allowing the relay to be run as a transparent proxy. If an additional .Ic forward to directive to a specified address or table is present, -it will be used as a backup if the NAT lookup failed. +it will be used as a backup if the lookup failed. +.It Xo +.Ic forward to +.Ic nat lookup +.Ar options ... +.Xc +Like the previous directive, but for redirections with rdr-to in +.Xr pf.conf 5 . .It Xo .Ic listen on Ar address .Op Ic port Ar port diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h index e0cec631e45..f76572a7be6 100644 --- a/usr.sbin/relayd/relayd.h +++ b/usr.sbin/relayd/relayd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: relayd.h,v 1.140 2010/12/31 21:22:42 guenther Exp $ */ +/* $OpenBSD: relayd.h,v 1.141 2011/04/07 13:22:29 reyk Exp $ */ /* * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -249,6 +249,7 @@ TAILQ_HEAD(addresslist, address); #define F_SSLCLIENT 0x00200000 #define F_NEEDRT 0x00400000 #define F_MATCH 0x00800000 +#define F_DIVERT 0x01000000 enum forwardmode { FWD_NORMAL = 0, @@ -849,6 +850,8 @@ void relay_natlook(int, short, void *); void relay_session(struct rsession *); int relay_from_table(struct rsession *); int relay_socket_af(struct sockaddr_storage *, in_port_t); +in_port_t + relay_socket_getport(struct sockaddr_storage *); int relay_cmp_af(struct sockaddr_storage *, struct sockaddr_storage *); |