| 
					
				 | 
			
			
				@@ -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; 
			 |