diff options
author | Nick Mathewson <nickm@torproject.org> | 2006-08-10 09:01:54 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2006-08-10 09:01:54 +0000 |
commit | cd560d85284f27f25a676dbc40849cfa97b9e662 (patch) | |
tree | de3ee7fce796aa6c9c476b9a2f6845cb45b2aa0e /src | |
parent | d893d8c52ed7a66eaea630cffe94cdaf82fbc99d (diff) | |
download | tor-cd560d85284f27f25a676dbc40849cfa97b9e662.tar tor-cd560d85284f27f25a676dbc40849cfa97b9e662.tar.gz |
r7301@Kushana: nickm | 2006-08-10 01:41:27 -0700
Only open /dev/pf once.
svn:r7009
Diffstat (limited to 'src')
-rw-r--r-- | src/or/connection_edge.c | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 62fa699e0..12ffb3fa2 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -1236,6 +1236,33 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn, return 0; /* unreached but keeps the compiler happy */ } +#ifdef TRANS_PF +static int pf_socket = -1; +static int +get_pf_socket(void) +{ + int pf; + /* Ideally, this should be opened before dropping privs. */ + if (pf_socket >= 0) + return pf_socket; + +#ifdef OPENBSD + /* only works on OpenBSD */ + pf = open("/dev/pf", O_RDONLY); +#else + /* works on NetBSD and FreeBSD */ + pf = open("/dev/pf", O_RDWR); +#endif + + if (pf < 0) { + log_warn(LD_NET, "open(\"/dev/pf\") failed: %s", strerror(errno)); + return -1; + } + + pf_socket = pf; +} +#endif + /** Fetch the original destination address and port from a * system-specific interface and put them into a * socks_request_t as if they came from a socks request. @@ -1287,29 +1314,15 @@ connection_ap_get_original_destination(edge_connection_t *conn, pnl.sport = htons(conn->_base.port); pnl.daddr.v4.s_addr = proxy_addr.sin_addr.s_addr; pnl.dport = proxy_addr.sin_port; - - /* XXX We should open the /dev/pf device once and close it at cleanup time - * instead of reopening it for every connection. Ideally, it should be - * opened before dropping privs. */ -#ifdef OPENBSD - /* only works on OpenBSD */ - pf = open("/dev/pf", O_RDONLY); -#else - /* works on NetBSD and FreeBSD */ - pf = open("/dev/pf", O_RDWR); -#endif - - if (pf < 0) { - log_warn(LD_NET, "open(\"/dev/pf\") failed: %s", strerror(errno)); + + pf = get_pf_socket(); + if (pf<0) return -1; - } if (ioctl(pf, DIOCNATLOOK, &pnl) < 0) { log_warn(LD_NET, "ioctl(DIOCNATLOOK) failed: %s", strerror(errno)); - close(pf); return -1; } - close(pf); tor_inet_ntoa(&pnl.rdaddr.v4, tmpbuf, sizeof(tmpbuf)); strlcpy(req->address, tmpbuf, sizeof(req->address)); |