|
@@ -1391,35 +1391,48 @@ get_pf_socket(void)
|
|
|
}
|
|
|
#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.
|
|
|
- *
|
|
|
- * Return -1 if an error prevents fetching the destination,
|
|
|
- * else return 0.
|
|
|
- */
|
|
|
+#if defined(TRANS_NETFILTER) || defined(TRANS_PF)
|
|
|
+/** Try fill in the address of <b>req</b> from the socket configured
|
|
|
+ * with <b>conn</b>. */
|
|
|
static int
|
|
|
-connection_ap_get_original_destination(entry_connection_t *conn,
|
|
|
- socks_request_t *req)
|
|
|
+destination_from_socket(entry_connection_t *conn, socks_request_t *req)
|
|
|
{
|
|
|
-#ifdef TRANS_NETFILTER
|
|
|
- /* Linux 2.4+ */
|
|
|
struct sockaddr_storage orig_dst;
|
|
|
socklen_t orig_dst_len = sizeof(orig_dst);
|
|
|
tor_addr_t addr;
|
|
|
|
|
|
+#ifdef TRANS_NETFILTER
|
|
|
if (getsockopt(ENTRY_TO_CONN(conn)->s, SOL_IP, SO_ORIGINAL_DST,
|
|
|
(struct sockaddr*)&orig_dst, &orig_dst_len) < 0) {
|
|
|
int e = tor_socket_errno(ENTRY_TO_CONN(conn)->s);
|
|
|
log_warn(LD_NET, "getsockopt() failed: %s", tor_socket_strerror(e));
|
|
|
return -1;
|
|
|
}
|
|
|
+#elif defined(TRANS_PF)
|
|
|
+ if (getsockname(ENTRY_TO_CONN(conn)->s, (struct sockaddr*)&orig_dst,
|
|
|
+ &orig_dst_len) < 0) {
|
|
|
+ int e = tor_socket_errno(ENTRY_TO_CONN(conn)->s);
|
|
|
+ log_warn(LD_NET, "getsockname() failed: %s", tor_socket_strerror(e));
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+#else
|
|
|
+ (void)conn;
|
|
|
+ (void)req;
|
|
|
+ log_warn(LD_BUG, "Unable to determine destination from socket.");
|
|
|
+ return -1;
|
|
|
+#endif
|
|
|
|
|
|
tor_addr_from_sockaddr(&addr, (struct sockaddr*)&orig_dst, &req->port);
|
|
|
tor_addr_to_str(req->address, &addr, sizeof(req->address), 1);
|
|
|
|
|
|
return 0;
|
|
|
-#elif defined(TRANS_PF)
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef TRANS_PF
|
|
|
+static int
|
|
|
+destination_from_pf(entry_connection_t *conn, socks_request_t *req)
|
|
|
+{
|
|
|
struct sockaddr_storage proxy_addr;
|
|
|
socklen_t proxy_addr_len = sizeof(proxy_addr);
|
|
|
struct sockaddr *proxy_sa = (struct sockaddr*) &proxy_addr;
|
|
@@ -1435,6 +1448,21 @@ connection_ap_get_original_destination(entry_connection_t *conn,
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
+#ifdef __FreeBSD__
|
|
|
+ if (get_options()->TransProxyType_parsed == TPT_IPFW) {
|
|
|
+ /* ipfw(8) is used and in this case getsockname returned the original
|
|
|
+ destination */
|
|
|
+ if (tor_addr_from_sockaddr(&addr, proxy_sa, &req->port) < 0) {
|
|
|
+ tor_fragile_assert();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ tor_addr_to_str(req->address, &addr, sizeof(req->address), 0);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
memset(&pnl, 0, sizeof(pnl));
|
|
|
pnl.proto = IPPROTO_TCP;
|
|
|
pnl.direction = PF_OUT;
|
|
@@ -1481,6 +1509,36 @@ connection_ap_get_original_destination(entry_connection_t *conn,
|
|
|
req->port = ntohs(pnl.rdport);
|
|
|
|
|
|
return 0;
|
|
|
+}
|
|
|
+#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.
|
|
|
+ *
|
|
|
+ * Return -1 if an error prevents fetching the destination,
|
|
|
+ * else return 0.
|
|
|
+ */
|
|
|
+static int
|
|
|
+connection_ap_get_original_destination(entry_connection_t *conn,
|
|
|
+ socks_request_t *req)
|
|
|
+{
|
|
|
+#ifdef TRANS_NETFILTER
|
|
|
+ return destination_from_socket(conn, req);
|
|
|
+#elif defined(TRANS_PF)
|
|
|
+ const or_options_t *options = get_options();
|
|
|
+
|
|
|
+ if (options->TransProxyType_parsed == TPT_PF_DIVERT)
|
|
|
+ return destination_from_socket(conn, req);
|
|
|
+
|
|
|
+ if (options->TransProxyType_parsed == TPT_DEFAULT)
|
|
|
+ return destination_from_pf(conn, req);
|
|
|
+
|
|
|
+ (void)conn;
|
|
|
+ (void)req;
|
|
|
+ log_warn(LD_BUG, "Proxy destination determination mechanism %s unknown.",
|
|
|
+ options->TransProxyType);
|
|
|
+ return -1;
|
|
|
#else
|
|
|
(void)conn;
|
|
|
(void)req;
|