瀏覽代碼

onion proxy now speaks socks4a

httpap is obsolete; we support privoxy directly now!

smtpap is obsolete; need to find a good socks4a-enabled smtp proxy/client

I dub thee 0.0.1.


svn:r107
Roger Dingledine 21 年之前
父節點
當前提交
155c9b80ca
共有 9 個文件被更改,包括 149 次插入129 次删除
  1. 1 1
      HACKING
  2. 23 22
      README
  3. 2 2
      configure.in
  4. 2 2
      src/Makefile.am
  5. 0 2
      src/or/connection.c
  6. 85 87
      src/or/connection_ap.c
  7. 10 3
      src/or/connection_exit.c
  8. 0 2
      src/or/main.c
  9. 26 8
      src/or/or.h

+ 1 - 1
HACKING

@@ -45,7 +45,7 @@ a type, or "command", which indicates what it's for.
 3.1. Role.
 3.1. Role.
 
 
 
 
-3. Robustness features.
+4. Robustness features.
 
 
 4.1. Bandwidth throttling. Each cell-speaking connection has a maximum
 4.1. Bandwidth throttling. Each cell-speaking connection has a maximum
 bandwidth it can use, as specified in the routers.or file. Bandwidth
 bandwidth it can use, as specified in the routers.or file. Bandwidth

+ 23 - 22
README

@@ -1,10 +1,13 @@
 
 
 Dependencies:
 Dependencies:
 
 
-  You're going to need openssl (0.9.5 or later) and popt (1.6 or later).
-  If you're on Linux, everything will probably work fine. OS X and BSD
-  (but see below under troubleshooting) now work too. Let us know if
-  you get it working elsewhere.
+  You're going to need Privoxy (www.privoxy.org) installed, and configured
+  to point at a socks4a proxy -- see below.
+
+  For tor itself, you're going to need openssl (0.9.5 or later) and popt
+  (1.6 or later). If you're on Linux, everything will probably work
+  fine. OS X and BSD (but see below under troubleshooting) now work
+  too. Let us know if you get it working elsewhere.
 
 
 If you got the source from cvs:
 If you got the source from cvs:
 
 
@@ -31,11 +34,9 @@ If this doesn't work for you / troubleshooting:
 
 
 Once you've got it compiled:
 Once you've got it compiled:
 
 
-  It's a bit hard to figure out what to do with the binaries. If you
-  want to run a local onion proxy (that is, you're a user, not a node
-  operator), go into src/config and look at the oprc file. You can run an
-  onion proxy by "../or/or -f oprc". In another window, run something like
-  "../httpap/httpap -f httpaprc2 -p 9051". See below for how to use it.
+  If you want to run a local onion proxy (that is, you're a user, not a
+  node operator), go into src/config and look at the oprc file. You can
+  run an onion proxy by "../or/or -f oprc". See below for how to use it.
 
 
   If you want to set up your own test network (that is, act like you're
   If you want to set up your own test network (that is, act like you're
   a full set of node operators), go into src/config/ and look at the
   a full set of node operators), go into src/config/ and look at the
@@ -48,24 +49,24 @@ Once you've got it compiled:
   network. I recommend using a screen session (man screen), or some
   network. I recommend using a screen session (man screen), or some
   other way to handle many windows at once. I open a window for each
   other way to handle many windows at once. I open a window for each
   onion router, go into the src/config directory, and run something like
   onion router, go into the src/config directory, and run something like
-  "../or/or -f moria2-orrc". In yet another window, I run something like
-  "../httpap/httpap -f httpaprc -p 9051". 
+  "../or/or -f moria2-orrc".
 
 
 How to use it:
 How to use it:
 
 
-  From here, you can point your browser/etc at localhost:9051 and treat
-  it as a web proxy. As a first test, you might telnet to it and enter
-  "GET http://seul.org/ HTTP/1.0" (without the quotes), followed by a pair
-  of carriage returns (one to separate your request from the headers,
-  and another to indicate that you're providing no headers). For more
-  convenient command-line use, I recommend making a ~/.wgetrc with
-  the line
-    http_proxy=localhost:9051
+  Download privoxy (www.privoxy.org). Install it. Add the following
+  line to your 'config' file:
+    forward-socks4a / localhost:9050 .
+  Don't forget the . at the end.
+
+  From here, you can point your browser/etc at localhost:8118 and your
+  traffic will go through Privoxy, then through the onion proxy, to the
+  onion routing network.
+
+  For more convenient command-line use, I recommend making a ~/.wgetrc
+  with the line
+    http_proxy=localhost:8118
   Then you can do things like "wget seul.org" and watch as it downloads
   Then you can do things like "wget seul.org" and watch as it downloads
   from the onion routing network.
   from the onion routing network.
-  (You can set your Mozilla/etc to use localhost:9051 as a proxy, and it
-  will work -- but it will work even better if you tell your Mozilla to
-  speak only HTTP 1.0 (the http proxy we include doesn't do 1.1 yet.))
 
 
   For fun, you can wget a very large file (a megabyte or more), and
   For fun, you can wget a very large file (a megabyte or more), and
   then ^z the wget a little bit in. The onion routers will continue
   then ^z the wget a little bit in. The onion routers will continue

+ 2 - 2
configure.in

@@ -1,6 +1,6 @@
 
 
 AC_INIT
 AC_INIT
-AM_INIT_AUTOMAKE(tor, 0.0.0)
+AM_INIT_AUTOMAKE(tor, 0.0.1)
 AM_CONFIG_HEADER(orconfig.h)
 AM_CONFIG_HEADER(orconfig.h)
 
 
 CFLAGS="-Wall -O2"
 CFLAGS="-Wall -O2"
@@ -143,5 +143,5 @@ dnl The warning message here is no longer strictly accurate.
 
 
 AC_CHECK_HEADERS(unistd.h string.h signal.h netdb.h ctype.h poll.h sys/poll.h sys/types.h sys/fcntl.h sys/ioctl.h sys/socket.h sys/time.h netinet/in.h arpa/inet.h errno.h assert.h stdint.h, , AC_MSG_WARN(some headers were not found, compilation may fail))
 AC_CHECK_HEADERS(unistd.h string.h signal.h netdb.h ctype.h poll.h sys/poll.h sys/types.h sys/fcntl.h sys/ioctl.h sys/socket.h sys/time.h netinet/in.h arpa/inet.h errno.h assert.h stdint.h, , AC_MSG_WARN(some headers were not found, compilation may fail))
 
 
-AC_OUTPUT(Makefile src/Makefile src/common/Makefile src/smtpap/Makefile src/orkeygen/Makefile src/httpap/Makefile src/or/Makefile)
+AC_OUTPUT(Makefile src/Makefile src/common/Makefile src/orkeygen/Makefile src/or/Makefile)
 
 

+ 2 - 2
src/Makefile.am

@@ -1,7 +1,7 @@
 
 
 # leave in dependency order, since common must be built first
 # leave in dependency order, since common must be built first
 
 
-SUBDIRS =      common smtpap orkeygen httpap or
-DIST_SUBDIRS = common smtpap orkeygen httpap or
+SUBDIRS =      common orkeygen or
+DIST_SUBDIRS = common orkeygen or
 EXTRA_DIST = config
 EXTRA_DIST = config
 
 

+ 0 - 2
src/or/connection.c

@@ -117,8 +117,6 @@ void connection_free(connection_t *conn) {
     free(conn->address);
     free(conn->address);
   if(conn->dest_addr)
   if(conn->dest_addr)
     free(conn->dest_addr);
     free(conn->dest_addr);
-  if(conn->dest_port)
-    free(conn->dest_port);
 
 
   if(connection_speaks_cells(conn)) {
   if(connection_speaks_cells(conn)) {
     if (conn->f_crypto)
     if (conn->f_crypto)

+ 85 - 87
src/or/connection_ap.c

@@ -5,6 +5,7 @@
 #include "or.h"
 #include "or.h"
 
 
 extern int global_role; /* from main.c */
 extern int global_role; /* from main.c */
+static const char socks_userid[] = "anonymous";
 
 
 int connection_ap_process_inbuf(connection_t *conn) {
 int connection_ap_process_inbuf(connection_t *conn) {
 
 
@@ -19,8 +20,8 @@ int connection_ap_process_inbuf(connection_t *conn) {
 //  log(LOG_DEBUG,"connection_ap_process_inbuf(): state %d.",conn->state);
 //  log(LOG_DEBUG,"connection_ap_process_inbuf(): state %d.",conn->state);
 
 
   switch(conn->state) {
   switch(conn->state) {
-    case AP_CONN_STATE_SS_WAIT:
-      return ap_handshake_process_ss(conn);
+    case AP_CONN_STATE_SOCKS_WAIT:
+      return ap_handshake_process_socks(conn);
     case AP_CONN_STATE_OPEN:
     case AP_CONN_STATE_OPEN:
       return connection_package_raw_inbuf(conn);
       return connection_package_raw_inbuf(conn);
     default:
     default:
@@ -30,107 +31,91 @@ int connection_ap_process_inbuf(connection_t *conn) {
   return 0;
   return 0;
 }
 }
 
 
-int ap_handshake_process_ss(connection_t *conn) {
-  uint16_t len;
+int ap_handshake_process_socks(connection_t *conn) {
+  char c;
+  socks4_t socks4_info; 
+  static char destaddr[512]; /* XXX there's a race condition waiting to happen here */
+  static int destlen=0;
 
 
   assert(conn);
   assert(conn);
 
 
-  log(LOG_DEBUG,"ap_handshake_process_ss() entered.");
+  log(LOG_DEBUG,"ap_handshake_process_socks() entered.");
 
 
-  if(!conn->ss_received) { /* try to pull it in */
+  if(!conn->socks_version) { /* try to pull it in */
 
 
-    if(conn->inbuf_datalen < sizeof(ss_t)) /* entire ss available? */
+    if(conn->inbuf_datalen < sizeof(socks4_t)) /* basic info available? */
       return 0; /* not yet */
       return 0; /* not yet */
 
 
-    if(connection_fetch_from_buf((char *)&conn->ss,sizeof(ss_t),conn) < 0)
+    if(connection_fetch_from_buf((char *)&socks4_info,sizeof(socks4_t),conn) < 0)
       return -1;
       return -1;
 
 
-    conn->ss_received = sizeof(ss_t);
-    log(LOG_DEBUG,"ap_handshake_process_ss(): Successfully read ss.");
+    log(LOG_DEBUG,"ap_handshake_process_socks(): Successfully read socks info.");
 
 
-    if ((conn->ss.version == 0) || (conn->ss.version != OR_VERSION)) { /* unsupported version */
-      log(LOG_NOTICE,"ap_handshake_process_ss(): ss: Unsupported version '%c'.",conn->ss.version);
-      if(tolower(conn->ss.version) == 'g') {
-        log(LOG_NOTICE,"ap_handshake_process_ss(): are you using the onion proxy as a web proxy?");
-      }
-      return -1;
-    }
-    if (conn->ss.addr_fmt != SS_ADDR_FMT_ASCII_HOST_PORT) { /* unrecognized address format */
-      log(LOG_DEBUG,"ap_handshake_process_ss(): ss: Unrecognized address format.");
+    if(socks4_info.version != 4) {
+      log(LOG_NOTICE,"ap_handshake_process_socks(): Unrecognized version %d.",socks4_info.version);
+      ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
       return -1;
       return -1;
     }
     }
-  }
-
-  if(!conn->dest_addr) { /* no dest_addr found yet */
+    conn->socks_version = socks4_info.version;
 
 
-    if(conn->inbuf_datalen < sizeof(uint16_t))
-      return 0; /* not yet */
-
-    if(connection_fetch_from_buf((char *)&len,sizeof(uint16_t),conn) < 0)
-      return -1;
-
-    len = ntohs(len);
-    if(len > 512) {
-      log(LOG_DEBUG,"ap_handshake_process_ss(): Addr length %d too high.",len);
+    if(socks4_info.command != 1) { /* not a connect? we don't support it. */
+      log(LOG_NOTICE,"ap_handshake_process_socks(): command %d not '1'.",socks4_info.command);
+      ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
       return -1;
       return -1;
     }
     }
 
 
-    conn->dest_addr = malloc(len+1);
-    if(!conn->dest_addr) {
-      log(LOG_DEBUG,"ap_handshake_process_ss(): Addr malloc failed");
+    conn->dest_port = ntohs(*(uint16_t*)&socks4_info.destport);
+    if(!conn->dest_port) {
+      log(LOG_NOTICE,"ap_handshake_process_socks(): Port is zero.");
+      ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
       return -1;
       return -1;
     }
     }
-
-    conn->dest_addr[len] = 0; /* null terminate it */
-    conn->dest_addr_len = len;
-    log(LOG_DEBUG,"Preparing a dest_addr of %d+1 bytes.",len);
-  }
-  if(conn->dest_addr_len != conn->dest_addr_received) { /* try to fetch it all in */
-
-    if(conn->inbuf_datalen < conn->dest_addr_len)
-      return 0; /* not yet */
-
-    if(connection_fetch_from_buf(conn->dest_addr,conn->dest_addr_len,conn) < 0)
+    log(LOG_NOTICE,"ap_handshake_process_socks(): Dest port is %d.",conn->dest_port);
+
+    if(socks4_info.destip[0] || 
+       socks4_info.destip[1] ||
+       socks4_info.destip[2] ||
+       !socks4_info.destip[3]) { /* must be in form 0.0.0.x, at least for now */
+      log(LOG_NOTICE,"ap_handshake_process_socks(): destip not in form 0.0.0.x.");
+      ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
       return -1;
       return -1;
-    log(LOG_DEBUG,"ap_handshake_process_ss(): Read dest_addr '%s'.",conn->dest_addr);
+    }
+    log(LOG_DEBUG,"ap_handshake_process_socks(): Successfully read destip (0.0.0.x.)");
 
 
-    conn->dest_addr_received = conn->dest_addr_len;
   }
   }
-  /* now do the same thing for port */
-  if(!conn->dest_port) { /* no dest_port found yet */
-
-    if(conn->inbuf_datalen < sizeof(uint16_t))
-      return 0; /* not yet */
-
-    if(connection_fetch_from_buf((char *)&len,sizeof(uint16_t),conn) < 0)
-      return -1;
-
-    len = ntohs(len);
-    if(len > 10) {
-      log(LOG_DEBUG,"ap_handshake_process_ss(): Port length %d too high.",len);
-      return -1;
-    }
 
 
-    conn->dest_port = malloc(len+1);
-    if(!conn->dest_port) {
-      log(LOG_DEBUG,"ap_handshake_process_ss(): Port malloc failed");
-      return -1;
+  if(!conn->read_username) { /* the socks spec says we've got to read stuff until we get a null */
+    while(conn->inbuf_datalen) {
+      if(connection_fetch_from_buf((char *)&c,1,conn) < 0)
+        return -1;
+      if(!c) {
+        conn->read_username = 1;
+        log(LOG_DEBUG,"ap_handshake_process_socks(): Successfully read username.");
+        break;
+      }
     }
     }
-
-    conn->dest_port[len] = 0; /* null terminate it */
-    conn->dest_port_len = len;
-    log(LOG_DEBUG,"Preparing a dest_port of %d+1 bytes.",len);
   }
   }
-  if(conn->dest_port_len != conn->dest_port_received) { /* try to fetch it all in */
 
 
-    if(conn->inbuf_datalen < conn->dest_port_len)
-      return 0; /* not yet */
-
-    if(connection_fetch_from_buf(conn->dest_port,conn->dest_port_len,conn) < 0)
-      return -1;
-    log(LOG_DEBUG,"ap_handshake_process_ss(): Read dest_port '%s'.",conn->dest_port);
+  if(!conn->dest_addr) { /* no dest_addr found yet */
 
 
-    conn->dest_port_received = conn->dest_port_len;
+    while(conn->inbuf_datalen) {
+      if(connection_fetch_from_buf((char *)&c,1,conn) < 0)
+        return -1;
+      destaddr[destlen++] = c;
+      if(destlen > 500) {
+        log(LOG_NOTICE,"ap_handshake_process_socks(): dest_addr too long!");
+        ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
+        destlen = 0;
+        return -1;
+      }
+      if(!c) { /* we found the null; we're done */
+        conn->dest_addr = strdup(destaddr);
+        destlen = 0;
+        log(LOG_NOTICE,"ap_handshake_process_socks(): successfully read dest addr '%s'",
+          conn->dest_addr);
+        break;
+      }
+    }
   }
   }
 
 
   /* now we're all ready to make an onion, etc */
   /* now we're all ready to make an onion, etc */
@@ -291,6 +276,7 @@ int ap_handshake_send_onion(connection_t *ap_conn, connection_t *n_conn, circuit
   }
   }
   free(tmpbuf);
   free(tmpbuf);
 
 
+#if 0
   /* deliver the ss in a data cell */
   /* deliver the ss in a data cell */
   cell.command = CELL_DATA;
   cell.command = CELL_DATA;
   cell.aci = circ->n_aci;
   cell.aci = circ->n_aci;
@@ -302,12 +288,13 @@ int ap_handshake_send_onion(connection_t *ap_conn, connection_t *n_conn, circuit
     circuit_close(circ);
     circuit_close(circ);
     return -1;
     return -1;
   }
   }
+#endif
 
 
   /* deliver the dest_addr in a data cell */
   /* deliver the dest_addr in a data cell */
   cell.command = CELL_DATA;
   cell.command = CELL_DATA;
   cell.aci = circ->n_aci;
   cell.aci = circ->n_aci;
-  cell.length = ap_conn->dest_addr_len+1;
-  strncpy(cell.payload, ap_conn->dest_addr, ap_conn->dest_addr_len+1);
+  strncpy(cell.payload, ap_conn->dest_addr, CELL_PAYLOAD_SIZE);
+  cell.length = strlen(cell.payload)+1;
   log(LOG_DEBUG,"ap_handshake_send_onion(): Sending a data cell for addr...");
   log(LOG_DEBUG,"ap_handshake_send_onion(): Sending a data cell for addr...");
   if(circuit_deliver_data_cell(&cell, circ, circ->n_conn, 'e') < 0) {
   if(circuit_deliver_data_cell(&cell, circ, circ->n_conn, 'e') < 0) {
     log(LOG_DEBUG,"ap_handshake_send_onion(): failed to deliver addr cell. Closing.");
     log(LOG_DEBUG,"ap_handshake_send_onion(): failed to deliver addr cell. Closing.");
@@ -318,8 +305,8 @@ int ap_handshake_send_onion(connection_t *ap_conn, connection_t *n_conn, circuit
   /* deliver the dest_port in a data cell */
   /* deliver the dest_port in a data cell */
   cell.command = CELL_DATA;
   cell.command = CELL_DATA;
   cell.aci = circ->n_aci;
   cell.aci = circ->n_aci;
-  cell.length = ap_conn->dest_port_len+1;
-  strncpy(cell.payload, ap_conn->dest_port, ap_conn->dest_port_len+1);
+  snprintf(cell.payload, CELL_PAYLOAD_SIZE, "%d", ap_conn->dest_port);
+  cell.length = strlen(cell.payload)+1;
   log(LOG_DEBUG,"ap_handshake_send_onion(): Sending a data cell for port...");
   log(LOG_DEBUG,"ap_handshake_send_onion(): Sending a data cell for port...");
   if(circuit_deliver_data_cell(&cell, circ, circ->n_conn, 'e') < 0) {
   if(circuit_deliver_data_cell(&cell, circ, circ->n_conn, 'e') < 0) {
     log(LOG_DEBUG,"ap_handshake_send_onion(): failed to deliver port cell. Closing.");
     log(LOG_DEBUG,"ap_handshake_send_onion(): failed to deliver port cell. Closing.");
@@ -336,13 +323,24 @@ int ap_handshake_send_onion(connection_t *ap_conn, connection_t *n_conn, circuit
   return 0;
   return 0;
 }
 }
 
 
-int connection_ap_send_connected(connection_t *conn) {
-  char zero=0;
+int ap_handshake_socks_reply(connection_t *conn, char result) {
+  socks4_t socks4_info; 
 
 
   assert(conn);
   assert(conn);
 
 
-  /* give the AP a "0" byte, because it wants to hear that we've connected */
-  return connection_write_to_buf(&zero, 1, conn);
+  socks4_info.version = 4;
+  socks4_info.command = result;
+  socks4_info.destport[0] = socks4_info.destport[1] = 0;
+  socks4_info.destip[0] = socks4_info.destip[1] = socks4_info.destip[2] = socks4_info.destip[3] = 0;
+
+  connection_write_to_buf((char *)&socks4_info, sizeof(socks4_t), conn); 
+  return connection_flush_buf(conn); /* try to flush it, in case we're about to close the conn */
+}
+
+int connection_ap_send_connected(connection_t *conn) {
+  assert(conn);
+
+  return ap_handshake_socks_reply(conn, SOCKS4_REQUEST_GRANTED);
 }
 }
 
 
 int connection_ap_process_data_cell(cell_t *cell, connection_t *conn) {
 int connection_ap_process_data_cell(cell_t *cell, connection_t *conn) {
@@ -388,7 +386,7 @@ int connection_ap_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *lo
 }
 }
 
 
 int connection_ap_handle_listener_read(connection_t *conn) {
 int connection_ap_handle_listener_read(connection_t *conn) {
-  log(LOG_NOTICE,"AP: Received a connection request. Waiting for SS.");
-  return connection_handle_listener_read(conn, CONN_TYPE_AP, AP_CONN_STATE_SS_WAIT);
+  log(LOG_NOTICE,"AP: Received a connection request. Waiting for socksinfo.");
+  return connection_handle_listener_read(conn, CONN_TYPE_AP, AP_CONN_STATE_SOCKS_WAIT);
 } 
 } 
 
 

+ 10 - 3
src/or/connection_exit.c

@@ -93,6 +93,7 @@ int connection_exit_process_data_cell(cell_t *cell, connection_t *conn) {
   switch(conn->state) {
   switch(conn->state) {
     case EXIT_CONN_STATE_CONNECTING_WAIT:
     case EXIT_CONN_STATE_CONNECTING_WAIT:
       log(LOG_DEBUG,"connection_exit_process_data_cell(): state is connecting_wait. cell length %d.", cell->length);
       log(LOG_DEBUG,"connection_exit_process_data_cell(): state is connecting_wait. cell length %d.", cell->length);
+#if 0
       if(!conn->ss_received) { /* this cell contains the ss */
       if(!conn->ss_received) { /* this cell contains the ss */
         if(cell->length != sizeof(ss_t)) {
         if(cell->length != sizeof(ss_t)) {
           log(LOG_DEBUG,"connection_exit_process_data_cell(): Supposed to contain SS but wrong size. Closing.");
           log(LOG_DEBUG,"connection_exit_process_data_cell(): Supposed to contain SS but wrong size. Closing.");
@@ -104,8 +105,10 @@ int connection_exit_process_data_cell(cell_t *cell, connection_t *conn) {
           return -1;
           return -1;
         }
         }
         conn->ss_received = 1;
         conn->ss_received = 1;
-	log(LOG_DEBUG,"connection_exit_process_data_cell(): SS received.");
-      } else if (!conn->addr) { /* this cell contains the dest addr */
+        log(LOG_DEBUG,"connection_exit_process_data_cell(): SS received.");
+      } else 
+#endif
+      if (!conn->addr) { /* this cell contains the dest addr */
         if(!memchr(cell->payload,0,cell->length)) {
         if(!memchr(cell->payload,0,cell->length)) {
           log(LOG_DEBUG,"connection_exit_process_data_cell(): dest_addr cell has no \\0. Closing.");
           log(LOG_DEBUG,"connection_exit_process_data_cell(): dest_addr cell has no \\0. Closing.");
           return -1;
           return -1;
@@ -117,7 +120,7 @@ int connection_exit_process_data_cell(cell_t *cell, connection_t *conn) {
           return -1;
           return -1;
         }
         }
         memcpy(&conn->addr, rent->h_addr,rent->h_length); 
         memcpy(&conn->addr, rent->h_addr,rent->h_length); 
-	log(LOG_DEBUG,"connection_exit_process_data_cell(): addr is %s.",cell->payload);
+        log(LOG_DEBUG,"connection_exit_process_data_cell(): addr is %s.",cell->payload);
       } else if (!conn->port) { /* this cell contains the dest port */
       } else if (!conn->port) { /* this cell contains the dest port */
         if(!memchr(cell->payload,'\0',cell->length)) {
         if(!memchr(cell->payload,'\0',cell->length)) {
           log(LOG_DEBUG,"connection_exit_process_data_cell(): dest_port cell has no \\0. Closing.");
           log(LOG_DEBUG,"connection_exit_process_data_cell(): dest_port cell has no \\0. Closing.");
@@ -167,6 +170,10 @@ int connection_exit_process_data_cell(cell_t *cell, connection_t *conn) {
         conn->s = s;
         conn->s = s;
         connection_set_poll_socket(conn);
         connection_set_poll_socket(conn);
         conn->state = EXIT_CONN_STATE_OPEN;
         conn->state = EXIT_CONN_STATE_OPEN;
+        if(connection_wants_to_flush(conn)) { /* in case there are any queued data cells */
+          log(LOG_NOTICE,"connection_exit_process_data_cell(): tell roger: newly connected conn had data waiting!");
+//          connection_start_writing(conn);
+        }
         connection_watch_events(conn, POLLIN);
         connection_watch_events(conn, POLLIN);
 
 
         /* also, deliver a 'connected' cell back through the circuit. */
         /* also, deliver a 'connected' cell back through the circuit. */

+ 0 - 2
src/or/main.c

@@ -13,8 +13,6 @@ static connection_t *connection_array[MAXCONNECTIONS] =
         { NULL };
         { NULL };
 
 
 static struct pollfd poll_array[MAXCONNECTIONS];
 static struct pollfd poll_array[MAXCONNECTIONS];
-/*  =       { [0 ... MAXCONNECTIONS-1] = { -1, 0, 0 } };
- */
 
 
 static int nfds=0; /* number of connections currently active */
 static int nfds=0; /* number of connections currently active */
 
 

+ 26 - 8
src/or/or.h

@@ -46,7 +46,7 @@
 			      can be overridden by config file */
 			      can be overridden by config file */
 
 
 #define MAX_BUF_SIZE (640*1024)
 #define MAX_BUF_SIZE (640*1024)
-#define DEFAULT_BANDWIDTH_OP 1024
+#define DEFAULT_BANDWIDTH_OP 102400
 
 
 #define ACI_TYPE_LOWER 0
 #define ACI_TYPE_LOWER 0
 #define ACI_TYPE_HIGHER 1
 #define ACI_TYPE_HIGHER 1
@@ -100,7 +100,7 @@
 #define EXIT_CONN_STATE_CLOSE_WAIT 4 /* have sent a destroy, awaiting a confirmation */
 #define EXIT_CONN_STATE_CLOSE_WAIT 4 /* have sent a destroy, awaiting a confirmation */
 #endif
 #endif
 
 
-#define AP_CONN_STATE_SS_WAIT 0
+#define AP_CONN_STATE_SOCKS_WAIT 0
 #define AP_CONN_STATE_OR_WAIT 1
 #define AP_CONN_STATE_OR_WAIT 1
 #define AP_CONN_STATE_OPEN 2
 #define AP_CONN_STATE_OPEN 2
 
 
@@ -147,6 +147,21 @@ typedef struct
   unsigned char payload[120];
   unsigned char payload[120];
 } cell_t;
 } cell_t;
 
 
+#define SOCKS4_REQUEST_GRANTED          90
+#define SOCKS4_REQUEST_REJECT           91
+#define SOCKS4_REQUEST_IDENT_FAILED     92
+#define SOCKS4_REQUEST_IDENT_CONFLICT   93
+
+/* structure of a socks client operation */
+typedef struct {
+   unsigned char version;     /* socks version number */
+   unsigned char command;     /* command code */
+   unsigned char destport[2]; /* destination port, network order */
+   unsigned char destip[4];   /* destination address */
+   /* userid follows, terminated by a NULL */
+   /* dest host follows, terminated by a NULL */
+} socks4_t;
+
 typedef struct
 typedef struct
 { 
 { 
 
 
@@ -190,12 +205,14 @@ typedef struct
 
 
 /* used by exit and ap: */
 /* used by exit and ap: */
 
 
-  ss_t ss; /* standard structure */
-  int ss_received; /* size of ss, received so far */
+//  ss_t ss; /* standard structure */
+//  int ss_received; /* size of ss, received so far */
+
+  char socks_version; 
+  char read_username;
 
 
-  char *dest_addr, *dest_port;
-  uint16_t dest_addr_len, dest_port_len;
-  uint16_t dest_addr_received, dest_port_received;
+  char *dest_addr;
+  uint16_t dest_port;
   
   
 /* used by OR, to keep state while connect()ing: Kludge. */
 /* used by OR, to keep state while connect()ing: Kludge. */
 
 
@@ -460,7 +477,7 @@ int connection_finished_flushing(connection_t *conn);
 
 
 int connection_ap_process_inbuf(connection_t *conn);
 int connection_ap_process_inbuf(connection_t *conn);
 
 
-int ap_handshake_process_ss(connection_t *conn);
+int ap_handshake_process_socks(connection_t *conn);
 
 
 int ap_handshake_create_onion(connection_t *conn);
 int ap_handshake_create_onion(connection_t *conn);
 
 
@@ -472,6 +489,7 @@ int ap_handshake_n_conn_open(connection_t *or_conn);
 
 
 int ap_handshake_send_onion(connection_t *ap_conn, connection_t *or_conn, circuit_t *circ);
 int ap_handshake_send_onion(connection_t *ap_conn, connection_t *or_conn, circuit_t *circ);
 
 
+int ap_handshake_socks_reply(connection_t *conn, char result);
 int connection_ap_send_connected(connection_t *conn);
 int connection_ap_send_connected(connection_t *conn);
 int connection_ap_process_data_cell(cell_t *cell, connection_t *conn);
 int connection_ap_process_data_cell(cell_t *cell, connection_t *conn);