summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2011-04-07 13:22:30 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2011-04-07 13:22:30 +0000
commit8009fc879d2991d924ed93860220e1f012cd10e5 (patch)
tree886a67b432c10a4c0a07500fc116262cdca61178
parent3b853a90fa7c3a2d4d109e5a945f43318f5400d7 (diff)
Add support for divert-to which provides some benefits over rdr-to.
ok mikeb@
-rw-r--r--usr.sbin/relayd/parse.y18
-rw-r--r--usr.sbin/relayd/relay.c36
-rw-r--r--usr.sbin/relayd/relayd.conf.517
-rw-r--r--usr.sbin/relayd/relayd.h5
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 *);