Only in tor-0.2.4.21/src/common: .dirstamp
Only in tor-0.2.4.21/src/config: torrc.sample
Only in tor-0.2.4.21/src/ext/curve25519_donna: .dirstamp
Only in tor-0.2.4.21/src/ext: .dirstamp
diff -ur tor-0.2.4.21-orig/src/or/connection.c tor-0.2.4.21/src/or/connection.c
--- tor-0.2.4.21-orig/src/or/connection.c	2014-02-25 20:04:22.000000000 +0000
+++ tor-0.2.4.21/src/or/connection.c	2014-03-19 17:46:35.624154811 +0000
@@ -1474,6 +1474,24 @@
 connection_connect(connection_t *conn, const char *address,
                    const tor_addr_t *addr, uint16_t port, int *socket_error)
 {
+    return connection_connect_withbind(conn, address, addr, port, socket_error,
+        (in_addr_t) 0 );
+
+}
+
+/**
+ * 
+ * like connection_connect, except: 
+ * 
+ * If the connection is to localhost, an optionally supplied in_addr 
+ * will be used to bind (instead of the configured bind addr). Connections
+ * to other destinations unaffected. local_bind_addr arrives in network order.
+ */
+int
+connection_connect_withbind(connection_t *conn, const char *address,
+                   const tor_addr_t *addr, uint16_t port, int *socket_error,
+                    in_addr_t local_bind_addr )
+{
   tor_socket_t s;
   int inprogress = 0;
   struct sockaddr_storage addrbuf;
@@ -1544,6 +1562,21 @@
         }
       }
     }
+  } else {
+      if (local_bind_addr != 0) {
+          // tor_addr_is_loopback.
+          // DO IPv4 bind
+          struct sockaddr_in bindaddr_in;
+          bindaddr_in.sin_family = AF_INET;
+          bindaddr_in.sin_port = 0;
+          bindaddr_in.sin_addr.s_addr = local_bind_addr;
+          if (bind(s, (struct sockaddr *) &bindaddr_in, sizeof(bindaddr_in)) < 0)
+          {
+              log_warn(LD_NET,
+                "XXX: Unable to bind to the desired loopback bind address.");
+              // Then continue and work anyway..
+          }
+      }
   }
 
   if (set_socket_nonblocking(s) == -1) {
diff -ur tor-0.2.4.21-orig/src/or/connection_edge.c tor-0.2.4.21/src/or/connection_edge.c
--- tor-0.2.4.21-orig/src/or/connection_edge.c	2014-02-25 20:04:22.000000000 +0000
+++ tor-0.2.4.21/src/or/connection_edge.c	2014-03-19 17:46:25.764278795 +0000
@@ -2641,8 +2641,9 @@
   uint16_t port;
   connection_t *conn = TO_CONN(edge_conn);
   int socket_error = 0;
+  int is_rendezvous = connection_edge_is_rendezvous_stream(edge_conn);
 
-  if ( (!connection_edge_is_rendezvous_stream(edge_conn) &&
+  if ( (!is_rendezvous &&
         router_compare_to_my_exit_policy(&edge_conn->base_.addr,
                                          edge_conn->base_.port)) ||
        (tor_addr_family(&conn->addr) == AF_INET6 &&
@@ -2662,7 +2663,39 @@
     conn->socket_family = AF_INET6;
 
   log_debug(LD_EXIT,"about to try connecting");
-  switch (connection_connect(conn, conn->address, addr, port, &socket_error)) {
+  // XXX POI
+  // This is where it actually connects, either to a HS or origin
+  // server, in the case of a Tor exit node.
+
+  in_addr_t local_bind_addr = 0;
+  if (is_rendezvous) {
+      // About to make the inbound HS connection.
+      // edge_conn->on_circuit - struct circuit_t *on_circuit
+      // on_circuit - circid_t n_circ_id
+      log_notice(LD_REND, "XXX: rv incoming circuit ID=%08x", edge_conn->on_circuit->n_circ_id);
+      {
+          // Convert the circuit ID (u_int32_t) into an IPv4
+          // Bind address in the 127.x.x.x range.
+          // Calculate what address we want to bind to.
+          uint32_t mybindaddr = edge_conn->on_circuit->n_circ_id; // circuit ID
+          // The top byte needs to be 0x7f (127.x.x.x)
+          uint32_t topbyte = mybindaddr & 0xff000000;
+          // XOR the top byte into the next byte.
+          topbyte = topbyte >> 8; // Move it down.
+          mybindaddr = mybindaddr & 0x00ffffff; // Mask out the previous top byte
+          // XOR it in.
+          mybindaddr = mybindaddr ^ topbyte;
+          // Put 0x7f into the new top byte (which should now be 0)
+          mybindaddr = mybindaddr | 0x7f000000;
+          struct in_addr mybindaddr_in;
+          mybindaddr_in.s_addr = htonl(mybindaddr);
+          log_notice(LD_REND, "XXX: will bind from %s", inet_ntoa(mybindaddr_in));
+          local_bind_addr = mybindaddr_in.s_addr; // used below.
+      }      
+  }
+  
+  switch (connection_connect_withbind(conn, conn->address, addr, port, &socket_error,
+        local_bind_addr)) {
     case -1: {
       int reason = errno_to_stream_end_reason(socket_error);
       connection_edge_end(edge_conn, reason);
@@ -2671,6 +2704,7 @@
       return;
     }
     case 0:
+      
       conn->state = EXIT_CONN_STATE_CONNECTING;
 
       connection_watch_events(conn, READ_EVENT | WRITE_EVENT);
diff -ur tor-0.2.4.21-orig/src/or/connection.h tor-0.2.4.21/src/or/connection.h
--- tor-0.2.4.21-orig/src/or/connection.h	2014-02-25 20:04:22.000000000 +0000
+++ tor-0.2.4.21/src/or/connection.h	2014-03-19 15:07:59.939908235 +0000
@@ -85,6 +85,10 @@
 
 void connection_expire_held_open(void);
 
+int connection_connect_withbind(connection_t *conn, const char *address,
+                   const tor_addr_t *addr, uint16_t port, int *socket_error,
+                    in_addr_t local_bind_addr );
+
 int connection_connect(connection_t *conn, const char *address,
                        const tor_addr_t *addr,
                        uint16_t port, int *socket_error);
Only in tor-0.2.4.21/src/or: .dirstamp
Only in tor-0.2.4.21-orig/src/or: or_sha1.i
Only in tor-0.2.4.21/src/tools: .dirstamp
