aboutsummaryrefslogtreecommitdiff
path: root/src/or/connection_edge.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/connection_edge.c')
-rw-r--r--src/or/connection_edge.c64
1 files changed, 51 insertions, 13 deletions
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 2ece2e44e..04e60b913 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -1391,35 +1391,43 @@ 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.
- */
-static int
-connection_ap_get_original_destination(entry_connection_t *conn,
- socks_request_t *req)
+static int
+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)
+}
+
+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;
@@ -1496,6 +1504,36 @@ connection_ap_get_original_destination(entry_connection_t *conn,
req->port = ntohs(pnl.rdport);
return 0;
+}
+
+
+/** 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;