[or-cvs] reshuffle functions for cleaner organization

Roger Dingledine arma at seul.org
Fri Sep 12 22:45:34 UTC 2003


Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/home2/arma/work/onion/cvs/src/or

Modified Files:
	Makefile.am config.c connection.c connection_edge.c 
	connection_or.c or.h 
Removed Files:
	connection_ap.c connection_exit.c 
Log Message:
reshuffle functions for cleaner organization


Index: Makefile.am
===================================================================
RCS file: /home/or/cvsroot/src/or/Makefile.am,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- Makefile.am	20 Aug 2003 23:05:22 -0000	1.19
+++ Makefile.am	12 Sep 2003 22:45:31 -0000	1.20
@@ -5,14 +5,14 @@
 bin_PROGRAMS = or
 
 or_SOURCES = buffers.c circuit.c command.c connection.c \
-             connection_exit.c connection_ap.c connection_or.c config.c \
+             connection_or.c config.c \
              onion.c routers.c directory.c dns.c connection_edge.c \
              cpuworker.c main.c tor_main.c
 
 or_LDADD = ../common/libor.a
 
 test_SOURCES = buffers.c circuit.c command.c connection.c \
-             connection_exit.c connection_ap.c connection_or.c config.c \
+             connection_or.c config.c \
              onion.c routers.c directory.c dns.c connection_edge.c \
              cpuworker.c main.c test.c
 

Index: config.c
===================================================================
RCS file: /home/or/cvsroot/src/or/config.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- config.c	8 Sep 2003 06:26:37 -0000	1.41
+++ config.c	12 Sep 2003 22:45:31 -0000	1.42
@@ -287,29 +287,6 @@
   config_assign(options,cl);
   config_free_lines(cl);
 
-/* print config */
-/* XXX this section is rotting. Should maybe remove it sometime. */
-  if (options->loglevel == LOG_DEBUG) {
-    printf("LogLevel=%s\n",
-           options->LogLevel);
-    printf("RouterFile=%s, PrivateKeyFile=%s, SigningPrivateKeyFile=%s\n",
-           options->RouterFile ? options->RouterFile : "(undefined)",
-           options->PrivateKeyFile ? options->PrivateKeyFile : "(undefined)",
-           options->SigningPrivateKeyFile ? options->SigningPrivateKeyFile : "(undefined)");
-    printf("ORPort=%d, APPort=%d DirPort=%d\n",
-           options->ORPort,
-           options->APPort,options->DirPort);
-    printf("CoinWeight=%6.4f, MaxConn=%d, TrafficShaping=%d, LinkPadding=%d\n",
-           options->CoinWeight,
-           options->MaxConn,
-           options->TrafficShaping,
-           options->LinkPadding);
-    printf("DirFetchPeriod=%d KeepalivePeriod=%d\n",
-           options->DirFetchPeriod,
-           options->KeepalivePeriod);
-    printf("Daemon=%d\n", options->Daemon);
-  }
-
 /* Validate options */
 
   if(options->LogLevel) {

Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection.c,v
retrieving revision 1.87
retrieving revision 1.88
diff -u -d -r1.87 -r1.88
--- connection.c	12 Sep 2003 06:50:21 -0000	1.87
+++ connection.c	12 Sep 2003 22:45:31 -0000	1.88
@@ -75,8 +75,10 @@
 /********* END VARIABLES ************/
 
 static int connection_init_accepted_conn(connection_t *conn);
+#ifdef USE_TLS
 static int connection_tls_continue_handshake(connection_t *conn);
 static int connection_tls_finish_handshake(connection_t *conn);
+#endif
 
 /**************************************************************/
 
@@ -673,56 +675,6 @@
   return connection_write_cell_to_buf(&cell, conn);
 }
 
-int connection_write_cell_to_buf(const cell_t *cellp, connection_t *conn) {
-  char networkcell[CELL_NETWORK_SIZE];
-  char *n = networkcell;
- 
-  cell_pack(n, cellp);
-
-#ifndef USE_TLS
-  if(connection_encrypt_cell(n,conn)<0) {
-    return -1;
-  }
-#endif
-
-  return connection_write_to_buf(n, CELL_NETWORK_SIZE, conn);
-}
-
-#ifndef USE_TLS
-int connection_encrypt_cell(char *cellp, connection_t *conn) {
-  char cryptcell[CELL_NETWORK_SIZE];
-#if 0
-  int x;
-  char *px;
-
-  printf("Sending: Cell header plaintext: ");
-  px = (char *)cellp;
-  for(x=0;x<8;x++) {
-    printf("%u ",px[x]);
-  } 
-  printf("\n");
-#endif
-
-  assert(conn);
-
-  if(crypto_cipher_encrypt(conn->f_crypto, cellp, CELL_NETWORK_SIZE, cryptcell)) {
-    log(LOG_ERR,"Could not encrypt cell for connection %s:%u.",conn->address,conn->port);
-    return -1;
-  }
-#if 0
-  printf("Sending: Cell header crypttext: ");
-  px = (char *)&newcell;
-  for(x=0;x<8;x++) {
-    printf("%u ",px[x]);
-  }
-  printf("\n");
-#endif
-
-  memcpy(cellp,cryptcell,CELL_NETWORK_SIZE);
-  return 0;
-}
-#endif
-
 int connection_process_inbuf(connection_t *conn) {
 
   assert(conn);
@@ -745,127 +697,6 @@
   }
 }
 
-int connection_package_raw_inbuf(connection_t *conn) {
-  int amount_to_process;
-  cell_t cell;
-  circuit_t *circ;
-
-  assert(conn);
-  assert(!connection_speaks_cells(conn));
-
-repeat_connection_package_raw_inbuf:
-
-  circ = circuit_get_by_conn(conn);
-  if(!circ) {
-    log_fn(LOG_DEBUG,"conn has no circuits!");
-    return -1;
-  }
-
-  if(circuit_consider_stop_edge_reading(circ, conn->type, conn->cpath_layer))
-    return 0;
-
-  if(conn->package_window <= 0) {
-    log_fn(LOG_ERR,"called with package_window 0. Tell Roger.");
-    connection_stop_reading(conn);
-    return 0;
-  }
-
-  amount_to_process = conn->inbuf_datalen;
-
-  if(!amount_to_process)
-    return 0;
-
-  /* Initialize the cell with 0's */
-  memset(&cell, 0, sizeof(cell_t));
-
-  if(amount_to_process > CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE) {
-    cell.length = CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE;
-  } else {
-    cell.length = amount_to_process;
-  }
-
-  connection_fetch_from_buf(cell.payload+RELAY_HEADER_SIZE, cell.length, conn);
-
-  log_fn(LOG_DEBUG,"(%d) Packaging %d bytes (%d waiting).",conn->s,cell.length, conn->inbuf_datalen);
-
-
-  cell.command = CELL_RELAY;
-  SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_DATA);
-  SET_CELL_STREAM_ID(cell, conn->stream_id);
-  cell.length += RELAY_HEADER_SIZE;
-
-  if(conn->type == CONN_TYPE_EXIT) {
-    cell.aci = circ->p_aci;
-    if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_IN, NULL) < 0) {
-      log_fn(LOG_DEBUG,"circuit_deliver_relay_cell (backward) failed. Closing.");
-      circuit_close(circ);
-      return 0;
-    }
-    assert(circ->package_window > 0);
-    circ->package_window--;
-  } else { /* send it forward. we're an AP */
-    assert(conn->type == CONN_TYPE_AP);
-    cell.aci = circ->n_aci;
-    if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, conn->cpath_layer) < 0) {
-      log_fn(LOG_DEBUG,"circuit_deliver_relay_cell (forward) failed. Closing.");
-      circuit_close(circ);
-      return 0;
-    }
-    assert(conn->cpath_layer->package_window > 0);
-    conn->cpath_layer->package_window--;
-  }
-
-  assert(conn->package_window > 0);
-  if(--conn->package_window <= 0) { /* is it 0 after decrement? */
-    connection_stop_reading(conn);
-    log_fn(LOG_DEBUG,"conn->package_window reached 0.");
-    circuit_consider_stop_edge_reading(circ, conn->type, conn->cpath_layer);
-    return 0; /* don't process the inbuf any more */
-  }
-  log_fn(LOG_DEBUG,"conn->package_window is now %d",conn->package_window);
-
-  /* handle more if there's more, or return 0 if there isn't */
-  goto repeat_connection_package_raw_inbuf;
-}
-
-int connection_consider_sending_sendme(connection_t *conn, int edge_type) {
-  circuit_t *circ;
-  cell_t cell;
-
-  if(connection_outbuf_too_full(conn))
-    return 0;
-
-  circ = circuit_get_by_conn(conn);
-  if(!circ) {
-    /* this can legitimately happen if the destroy has already arrived and torn down the circuit */
-    log_fn(LOG_DEBUG,"No circuit associated with conn. Skipping.");
-    return 0;
-  }
-
-  memset(&cell, 0, sizeof(cell_t));
-  cell.command = CELL_RELAY;
-  SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_SENDME);
-  SET_CELL_STREAM_ID(cell, conn->stream_id);
-  cell.length += RELAY_HEADER_SIZE;
-
-  if(edge_type == EDGE_EXIT)
-    cell.aci = circ->p_aci;
-  else
-    cell.aci = circ->n_aci;
-
-  while(conn->deliver_window < STREAMWINDOW_START - STREAMWINDOW_INCREMENT) {
-    log_fn(LOG_DEBUG,"Outbuf %d, Queueing stream sendme.", conn->outbuf_flushlen);
-    conn->deliver_window += STREAMWINDOW_INCREMENT;
-    if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION(edge_type), conn->cpath_layer) < 0) {
-      log_fn(LOG_DEBUG,"circuit_deliver_relay_cell failed. Closing.");
-      circuit_close(circ);
-      return 0;
-    }
-  }
-
-  return 0;
-}
-
 int connection_finished_flushing(connection_t *conn) {
 
   assert(conn);
@@ -890,55 +721,6 @@
   }
 }
 
-int connection_process_cell_from_inbuf(connection_t *conn) {
-  /* check if there's a whole cell there.
-   * if yes, pull it off, decrypt it if we're not doing TLS, and process it.
-   */
-#ifndef USE_TLS
-  char networkcell[CELL_NETWORK_SIZE];
-#endif
-  char buf[CELL_NETWORK_SIZE];
-//  int x;
-  cell_t cell;
-
-  if(conn->inbuf_datalen < CELL_NETWORK_SIZE) /* entire response available? */
-    return 0; /* not yet */
-
-#ifdef USE_TLS
-  connection_fetch_from_buf(buf, CELL_NETWORK_SIZE, conn);
-#else
-  connection_fetch_from_buf(networkcell, CELL_NETWORK_SIZE, conn);
-#if 0
-  printf("Cell header crypttext: ");
-  for(x=0;x<8;x++) {
-    printf("%u ",crypted[x]);
-  }
-  printf("\n");
-#endif
-  /* decrypt */
-  if(crypto_cipher_decrypt(conn->b_crypto, networkcell, CELL_NETWORK_SIZE, buf)) {
-    log_fn(LOG_ERR,"Decryption failed, dropping.");
-    return connection_process_inbuf(conn); /* process the remainder of the buffer */
-  }
-//  log_fn(LOG_DEBUG,"Cell decrypted (%d bytes).",outlen);
-#if 0
-  printf("Cell header plaintext: ");
-  for(x=0;x<8;x++) {
-    printf("%u ",outbuf[x]);
-  }
-  printf("\n");
-#endif
-#endif
-
-  /* retrieve cell info from buf (create the host-order struct from the network-order string) */
-  cell_unpack(&cell, buf);
-
-//  log_fn(LOG_DEBUG,"Decrypted cell is of type %u (ACI %u).",cellp->command,cellp->aci);
-  command_process_cell(&cell, conn);
-
-  return connection_process_inbuf(conn); /* process the remainder of the buffer */
-}
-
 void
 cell_pack(char *dest, const cell_t *src)
 {
@@ -966,3 +748,4 @@
   c-basic-offset:2
   End:
 */
+

Index: connection_edge.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_edge.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- connection_edge.c	14 Aug 2003 17:13:51 -0000	1.17
+++ connection_edge.c	12 Sep 2003 22:45:31 -0000	1.18
@@ -6,6 +6,12 @@
 
 extern or_options_t options; /* command-line and config-file options */
 
+static int connection_ap_handshake_process_socks(connection_t *conn);
+static int connection_ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ);
+static int connection_ap_handshake_socks_reply(connection_t *conn, char result);
+
+static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ);
+
 int connection_edge_process_inbuf(connection_t *conn) {
 
   assert(conn);
@@ -45,7 +51,7 @@
 
   switch(conn->state) {
     case AP_CONN_STATE_SOCKS_WAIT:
-      return ap_handshake_process_socks(conn);
+      return connection_ap_handshake_process_socks(conn);
     case AP_CONN_STATE_OPEN:
     case EXIT_CONN_STATE_OPEN:
       if(connection_package_raw_inbuf(conn) < 0)
@@ -226,7 +232,7 @@
         break;
       }
       log_fn(LOG_DEBUG,"Connected! Notifying application.");
-      if(ap_handshake_socks_reply(conn, SOCKS4_REQUEST_GRANTED) < 0) {
+      if(connection_ap_handshake_socks_reply(conn, SOCKS4_REQUEST_GRANTED) < 0) {
         conn->marked_for_close = 1;
       }
       break;
@@ -298,6 +304,404 @@
   return 0;
 }
 
+int connection_package_raw_inbuf(connection_t *conn) {
+  int amount_to_process;
+  cell_t cell;
+  circuit_t *circ;
+ 
+  assert(conn);
+  assert(!connection_speaks_cells(conn));
+ 
+repeat_connection_package_raw_inbuf:
+ 
+  circ = circuit_get_by_conn(conn);
+  if(!circ) {
+    log_fn(LOG_DEBUG,"conn has no circuits!");
+    return -1;
+  }
+ 
+  if(circuit_consider_stop_edge_reading(circ, conn->type, conn->cpath_layer))
+    return 0;
+ 
+  if(conn->package_window <= 0) {
+    log_fn(LOG_ERR,"called with package_window 0. Tell Roger.");
+    connection_stop_reading(conn);
+    return 0;
+  }
+ 
+  amount_to_process = conn->inbuf_datalen;
+ 
+  if(!amount_to_process)
+    return 0;
+ 
+  /* Initialize the cell with 0's */
+  memset(&cell, 0, sizeof(cell_t));
+ 
+  if(amount_to_process > CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE) {
+    cell.length = CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE;
+  } else {
+    cell.length = amount_to_process;
+  }
+ 
+  connection_fetch_from_buf(cell.payload+RELAY_HEADER_SIZE, cell.length, conn);
+ 
+  log_fn(LOG_DEBUG,"(%d) Packaging %d bytes (%d waiting).",conn->s,cell.length, conn->inbuf_datalen);
+ 
+  cell.command = CELL_RELAY;
+  SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_DATA);
+  SET_CELL_STREAM_ID(cell, conn->stream_id);
+  cell.length += RELAY_HEADER_SIZE;
+ 
+  if(conn->type == CONN_TYPE_EXIT) {
+    cell.aci = circ->p_aci;
+    if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_IN, NULL) < 0) {
+      log_fn(LOG_DEBUG,"circuit_deliver_relay_cell (backward) failed. Closing.");
+      circuit_close(circ);
+      return 0;
+    }
+    assert(circ->package_window > 0);
+    circ->package_window--;
+  } else { /* send it forward. we're an AP */
+    assert(conn->type == CONN_TYPE_AP);
+    cell.aci = circ->n_aci;
+    if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, conn->cpath_layer) < 0) {
+      log_fn(LOG_DEBUG,"circuit_deliver_relay_cell (forward) failed. Closing.");
+      circuit_close(circ);
+      return 0;
+    }
+    assert(conn->cpath_layer->package_window > 0);
+    conn->cpath_layer->package_window--;
+  }
+ 
+  assert(conn->package_window > 0);
+  if(--conn->package_window <= 0) { /* is it 0 after decrement? */
+    connection_stop_reading(conn);
+    log_fn(LOG_DEBUG,"conn->package_window reached 0.");
+    circuit_consider_stop_edge_reading(circ, conn->type, conn->cpath_layer);
+    return 0; /* don't process the inbuf any more */
+  }
+  log_fn(LOG_DEBUG,"conn->package_window is now %d",conn->package_window);
+ 
+  /* handle more if there's more, or return 0 if there isn't */
+  goto repeat_connection_package_raw_inbuf;
+}
+
+int connection_consider_sending_sendme(connection_t *conn, int edge_type) {
+  circuit_t *circ;
+  cell_t cell;
+ 
+  if(connection_outbuf_too_full(conn))
+    return 0;
+ 
+  circ = circuit_get_by_conn(conn);
+  if(!circ) {
+    /* this can legitimately happen if the destroy has already arrived and torn down the circuit */
+    log_fn(LOG_DEBUG,"No circuit associated with conn. Skipping.");
+    return 0;
+  }
+ 
+  memset(&cell, 0, sizeof(cell_t));
+  cell.command = CELL_RELAY;
+  SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_SENDME);
+  SET_CELL_STREAM_ID(cell, conn->stream_id);
+  cell.length += RELAY_HEADER_SIZE;
+ 
+  if(edge_type == EDGE_EXIT)
+    cell.aci = circ->p_aci;
+  else
+    cell.aci = circ->n_aci;
+ 
+  while(conn->deliver_window < STREAMWINDOW_START - STREAMWINDOW_INCREMENT) {
+    log_fn(LOG_DEBUG,"Outbuf %d, Queueing stream sendme.", conn->outbuf_flushlen);
+    conn->deliver_window += STREAMWINDOW_INCREMENT;
+    if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION(edge_type), conn->cpath_layer) < 0) {
+      log_fn(LOG_DEBUG,"circuit_deliver_relay_cell failed. Closing.");
+      circuit_close(circ);
+      return 0;
+    }
+  }
+ 
+  return 0;
+}
+
+static int connection_ap_handshake_process_socks(connection_t *conn) {
+  socks4_t socks4_info; 
+  circuit_t *circ;
+  char tmpbuf[512];
+  int amt;
+
+  assert(conn);
+
+  log_fn(LOG_DEBUG,"entered.");
+
+  if(!conn->socks_version) { /* try to pull it in */
+
+    if(conn->inbuf_datalen < sizeof(socks4_t)) /* basic info available? */
+      return 0; /* not yet */
+
+    connection_fetch_from_buf((char *)&socks4_info,sizeof(socks4_t),conn);
+
+    log_fn(LOG_DEBUG,"Successfully read socks info.");
+
+    if(socks4_info.version != 4) {
+      log_fn(LOG_NOTICE,"Unrecognized version %d.",socks4_info.version);
+      connection_ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
+      return -1;
+    }
+    conn->socks_version = socks4_info.version;
+
+    if(socks4_info.command != 1) { /* not a connect? we don't support it. */
+      log_fn(LOG_NOTICE,"command %d not '1'.",socks4_info.command);
+      connection_ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
+      return -1;
+    }
+
+    conn->dest_port = ntohs(*(uint16_t*)&socks4_info.destport);
+    if(!conn->dest_port) {
+      log_fn(LOG_NOTICE,"Port is zero.");
+      connection_ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
+      return -1;
+    }
+    log_fn(LOG_NOTICE,"Dest port is %d.",conn->dest_port);
+
+    if(socks4_info.destip[0] || 
+       socks4_info.destip[1] ||
+       socks4_info.destip[2] ||
+       !socks4_info.destip[3]) { /* not 0.0.0.x */
+      log_fn(LOG_NOTICE,"destip not in form 0.0.0.x.");
+      sprintf(tmpbuf, "%d.%d.%d.%d", socks4_info.destip[0],
+        socks4_info.destip[1], socks4_info.destip[2], socks4_info.destip[3]);
+      conn->dest_addr = strdup(tmpbuf);
+      log_fn(LOG_DEBUG,"Successfully read destip (%s)", conn->dest_addr);
+    }
+
+  }
+
+  if(!conn->read_username) { /* the socks spec says we've got to read stuff until we get a null */
+    amt = connection_find_on_inbuf("\0", 1, conn);
+    if(amt < 0) /* not there yet */
+      return 0;
+    if(amt > 500) {
+      log_fn(LOG_NOTICE,"username too long.");    
+      connection_ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
+      return -1;
+    }
+    connection_fetch_from_buf(tmpbuf,amt,conn);
+    conn->read_username = 1;
+    log_fn(LOG_DEBUG,"Successfully read username.");
+  }
+
+  if(!conn->dest_addr) { /* no dest_addr found yet */
+    amt = connection_find_on_inbuf("\0", 1, conn);
+    if(amt < 0) /* not there yet */
+      return 0;
+    if(amt > 500) {
+      log_fn(LOG_NOTICE,"dest_addr too long.");    
+      connection_ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
+      return -1;
+    }
+    connection_fetch_from_buf(tmpbuf,amt,conn);
+
+    conn->dest_addr = strdup(tmpbuf);
+    log_fn(LOG_NOTICE,"successfully read dest addr '%s'",
+      conn->dest_addr);
+  }
+
+  /* find the circuit that we should use, if there is one. */
+  circ = circuit_get_newest_ap();
+
+  if(!circ) {
+    log_fn(LOG_INFO,"No circuit ready. Closing.");
+    return -1;
+  }
+
+  circ->dirty = 1;
+
+  /* add it into the linked list of streams on this circuit */
+  log_fn(LOG_DEBUG,"attaching new conn to circ. n_aci %d.", circ->n_aci);
+  conn->next_stream = circ->p_streams;
+  circ->p_streams = conn;
+
+  assert(circ->cpath && circ->cpath->prev);
+  assert(circ->cpath->prev->state == CPATH_STATE_OPEN);
+  conn->cpath_layer = circ->cpath->prev;
+
+  if(connection_ap_handshake_send_begin(conn, circ) < 0) {
+    circuit_close(circ);
+    return -1;
+  }
+
+  return 0;
+}
+
+int connection_ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ) {
+  cell_t cell;
+
+  memset(&cell, 0, sizeof(cell_t));
+  /* deliver the dest_addr in a relay cell */
+  cell.command = CELL_RELAY;
+  cell.aci = circ->n_aci;
+  SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_BEGIN);
+  if(crypto_pseudo_rand(STREAM_ID_SIZE, ap_conn->stream_id) < 0)
+    return -1;
+  /* FIXME check for collisions */
+  SET_CELL_STREAM_ID(cell, ZERO_STREAM);
+
+  memcpy(cell.payload+RELAY_HEADER_SIZE, ap_conn->stream_id, STREAM_ID_SIZE);
+  cell.length = 
+    snprintf(cell.payload+RELAY_HEADER_SIZE+STREAM_ID_SIZE, CELL_PAYLOAD_SIZE-RELAY_HEADER_SIZE-STREAM_ID_SIZE,
+             "%s:%d", ap_conn->dest_addr, ap_conn->dest_port) + 
+    1 + STREAM_ID_SIZE + RELAY_HEADER_SIZE;
+  log_fn(LOG_DEBUG,"Sending relay cell (id %d) to begin stream %d.", *(int *)(cell.payload+1),*(int *)ap_conn->stream_id);
+  if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, ap_conn->cpath_layer) < 0) {
+    log_fn(LOG_DEBUG,"failed to deliver begin cell. Closing.");
+    return -1;
+  }
+  ap_conn->package_window = STREAMWINDOW_START;
+  ap_conn->deliver_window = STREAMWINDOW_START;
+  ap_conn->state = AP_CONN_STATE_OPEN;
+  log_fn(LOG_INFO,"Address/port sent, ap socket %d, n_aci %d",ap_conn->s,circ->n_aci);
+  return 0;
+}
+
+int connection_ap_handshake_socks_reply(connection_t *conn, char result) {
+  socks4_t socks4_info; 
+
+  assert(conn);
+
+  socks4_info.version = 0;
+  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;
+
+  if(connection_write_to_buf((char *)&socks4_info, sizeof(socks4_t), conn) < 0)
+    return -1;
+  return connection_flush_buf(conn); /* try to flush it, in case we're about to close the conn */
+}
+
+static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
+  connection_t *n_stream;
+  char *colon;
+
+  if(!memchr(cell->payload+RELAY_HEADER_SIZE+STREAM_ID_SIZE,0,cell->length-RELAY_HEADER_SIZE-STREAM_ID_SIZE)) {
+    log_fn(LOG_WARNING,"relay begin cell has no \\0. Dropping.");
+    return 0;
+  }
+  colon = strchr(cell->payload+RELAY_HEADER_SIZE+STREAM_ID_SIZE, ':');
+  if(!colon) {
+    log_fn(LOG_WARNING,"relay begin cell has no colon. Dropping.");
+    return 0;
+  }
+  *colon = 0;
+
+  if(!atoi(colon+1)) { /* bad port */
+    log_fn(LOG_DEBUG,"relay begin cell has invalid port. Dropping.");
+    return 0;
+  }
+
+  log_fn(LOG_DEBUG,"Creating new exit connection.");
+  n_stream = connection_new(CONN_TYPE_EXIT);
+  if(!n_stream) {
+    log_fn(LOG_DEBUG,"connection_new failed. Dropping.");
+    return 0;
+  }
+
+  memcpy(n_stream->stream_id, cell->payload + RELAY_HEADER_SIZE, STREAM_ID_SIZE);
+  n_stream->address = strdup(cell->payload + RELAY_HEADER_SIZE + STREAM_ID_SIZE);
+  n_stream->port = atoi(colon+1);
+  n_stream->state = EXIT_CONN_STATE_RESOLVING;
+  n_stream->receiver_bucket = -1; /* edge connections don't do receiver buckets */
+  n_stream->bandwidth = -1;
+  n_stream->s = -1; /* not yet valid */
+  n_stream->package_window = STREAMWINDOW_START;
+  n_stream->deliver_window = STREAMWINDOW_START;
+  if(connection_add(n_stream) < 0) { /* no space, forget it */
+    log_fn(LOG_DEBUG,"connection_add failed. Dropping.");
+    connection_free(n_stream);
+    return 0;
+  }
+
+  /* add it into the linked list of streams on this circuit */
+  n_stream->next_stream = circ->n_streams;
+  circ->n_streams = n_stream;
+
+  /* send it off to the gethostbyname farm */
+  switch(dns_resolve(n_stream)) {
+    case 1: /* resolve worked */
+      if(connection_exit_connect(n_stream) >= 0)
+        return 0;
+      /* else fall through */
+    case -1: /* resolve failed */
+      log_fn(LOG_DEBUG,"Couldn't queue resolve request.");
+      connection_remove(n_stream);
+      connection_free(n_stream);
+    case 0: /* resolve added to pending list */
+      ;
+  }
+  return 0;
+}
+
+int connection_exit_connect(connection_t *conn) {
+  int s; /* for the new socket */
+  struct sockaddr_in dest_addr;
+
+  if(router_compare_to_exit_policy(conn) < 0) {
+    log_fn(LOG_INFO,"%s:%d failed exit policy. Closing.", conn->address, conn->port);
+    return -1;
+  }
+
+  /* all the necessary info is here. Start the connect() */
+  s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
+  if (s < 0) {
+    log_fn(LOG_ERR,"Error creating network socket.");
+    return -1;
+  }
+  set_socket_nonblocking(s);
+
+  memset((void *)&dest_addr,0,sizeof(dest_addr));
+  dest_addr.sin_family = AF_INET;
+  dest_addr.sin_port = htons(conn->port);
+  dest_addr.sin_addr.s_addr = htonl(conn->addr);
+
+  log_fn(LOG_DEBUG,"Connecting to %s:%u.",conn->address,conn->port); 
+
+  if(connect(s,(struct sockaddr *)&dest_addr,sizeof(dest_addr)) < 0) {
+    if(!ERRNO_CONN_EINPROGRESS(errno)) {
+      /* yuck. kill it. */
+      perror("connect");
+      log_fn(LOG_DEBUG,"Connect failed.");
+      return -1;
+    } else {
+      /* it's in progress. set state appropriately and return. */
+      conn->s = s;
+      connection_set_poll_socket(conn);
+      conn->state = EXIT_CONN_STATE_CONNECTING;
+
+      log_fn(LOG_DEBUG,"connect in progress, socket %d.",s);
+      connection_watch_events(conn, POLLOUT | POLLIN | POLLERR);
+      /* writable indicates finish, readable indicates broken link,
+         error indicates broken link in windowsland. */
+      return 0;
+    }
+  }
+
+  /* it succeeded. we're connected. */
+  log_fn(LOG_DEBUG,"Connection to %s:%u established.",conn->address,conn->port);
+
+  conn->s = s;
+  connection_set_poll_socket(conn);
+  conn->state = EXIT_CONN_STATE_OPEN;
+  if(connection_wants_to_flush(conn)) { /* in case there are any queued data cells */
+    log_fn(LOG_ERR,"tell roger: newly connected conn had data waiting!");
+//    connection_start_writing(conn);
+  }
+//   connection_process_inbuf(conn);
+  connection_watch_events(conn, POLLIN);
+
+  /* also, deliver a 'connected' cell back through the circuit. */
+  return connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_CONNECTED);
+}
+
 /*
   Local Variables:
   mode:c
@@ -305,3 +709,4 @@
   c-basic-offset:2
   End:
 */
+

Index: connection_or.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_or.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -d -r1.47 -r1.48
--- connection_or.c	12 Sep 2003 06:50:21 -0000	1.47
+++ connection_or.c	12 Sep 2003 22:45:31 -0000	1.48
@@ -683,6 +683,106 @@
 }
 #endif
 
+int connection_write_cell_to_buf(const cell_t *cellp, connection_t *conn) {
+  char networkcell[CELL_NETWORK_SIZE];
+  char *n = networkcell;
+
+  cell_pack(n, cellp);
+ 
+#ifndef USE_TLS
+  if(connection_encrypt_cell(n,conn)<0) {
+    return -1;
+  }
+#endif
+ 
+  return connection_write_to_buf(n, CELL_NETWORK_SIZE, conn);
+}
+
+int connection_process_cell_from_inbuf(connection_t *conn) {
+  /* check if there's a whole cell there.
+   *    * if yes, pull it off, decrypt it if we're not doing TLS, and process it.
+   *       */
+#ifndef USE_TLS
+  char networkcell[CELL_NETWORK_SIZE];
+#endif
+  char buf[CELL_NETWORK_SIZE];
+//  int x;
+  cell_t cell;
+ 
+  if(conn->inbuf_datalen < CELL_NETWORK_SIZE) /* entire response available? */
+    return 0; /* not yet */
+ 
+#ifdef USE_TLS
+  connection_fetch_from_buf(buf, CELL_NETWORK_SIZE, conn);
+#else
+  connection_fetch_from_buf(networkcell, CELL_NETWORK_SIZE, conn);
+#if 0
+  printf("Cell header crypttext: ");
+  for(x=0;x<8;x++) {
+    printf("%u ",crypted[x]);
+  }
+  printf("\n");
+#endif
+  /* decrypt */
+  if(crypto_cipher_decrypt(conn->b_crypto, networkcell, CELL_NETWORK_SIZE, buf)) {
+    log_fn(LOG_ERR,"Decryption failed, dropping.");
+    return connection_process_inbuf(conn); /* process the remainder of the buffer */
+  }
+//  log_fn(LOG_DEBUG,"Cell decrypted (%d bytes).",outlen);
+#if 0
+  printf("Cell header plaintext: ");
+  for(x=0;x<8;x++) {
+    printf("%u ",outbuf[x]);
+  }
+  printf("\n");
+#endif
+#endif
+ 
+  /* retrieve cell info from buf (create the host-order struct from the network-order string) */
+  cell_unpack(&cell, buf);
+ 
+//  log_fn(LOG_DEBUG,"Decrypted cell is of type %u (ACI %u).",cellp->command,cellp->aci);
+  command_process_cell(&cell, conn);
+ 
+  return connection_process_inbuf(conn); /* process the remainder of the buffer */
+}
+
+
+#ifndef USE_TLS
+int connection_encrypt_cell(char *cellp, connection_t *conn) {
+  char cryptcell[CELL_NETWORK_SIZE];
+#if 0
+  int x;
+  char *px;
+ 
+  printf("Sending: Cell header plaintext: ");
+  px = (char *)cellp;
+  for(x=0;x<8;x++) {
+    printf("%u ",px[x]);
+  }#
+  printf("\n");
+#endif
+ 
+  assert(conn);
+ 
+  if(crypto_cipher_encrypt(conn->f_crypto, cellp, CELL_NETWORK_SIZE, cryptcell)) {
+    log(LOG_ERR,"Could not encrypt cell for connection %s:%u.",conn->address,conn->port);
+    return -1;
+  }
+#if 0
+  printf("Sending: Cell header crypttext: ");
+  px = (char *)&newcell;
+  for(x=0;x<8;x++) {
+    printf("%u ",px[x]);
+  }
+  printf("\n");
+#endif
+
+  memcpy(cellp,cryptcell,CELL_NETWORK_SIZE);
+  return 0;
+}
+#endif
+
 
 
 /*

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.121
retrieving revision 1.122
diff -u -d -r1.121 -r1.122
--- or.h	12 Sep 2003 06:50:21 -0000	1.121
+++ or.h	12 Sep 2003 22:45:31 -0000	1.122
@@ -7,7 +7,7 @@
 
 #include "orconfig.h"
 
-#define USE_TLS
+//#define USE_TLS
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -613,29 +613,14 @@
 
 int connection_send_destroy(aci_t aci, connection_t *conn);
 int connection_send_connected(aci_t aci, connection_t *conn);
-#ifndef USE_TLS
-int connection_encrypt_cell(char *cellp, connection_t *conn);
-#endif
-int connection_write_cell_to_buf(const cell_t *cellp, connection_t *conn);
 
 int connection_process_inbuf(connection_t *conn);
-int connection_package_raw_inbuf(connection_t *conn);
-int connection_process_cell_from_inbuf(connection_t *conn);
 
-int connection_consider_sending_sendme(connection_t *conn, int edge_type);
 int connection_finished_flushing(connection_t *conn);
 
 void cell_pack(char *dest, const cell_t *src);
 void cell_unpack(cell_t *dest, const char *src);
 
-/********************************* connection_ap.c ****************************/
-
-int ap_handshake_process_socks(connection_t *conn);
-
-int ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ);
-
-int ap_handshake_socks_reply(connection_t *conn, char result);
-
 /********************************* connection_edge.c ***************************/
 
 int connection_edge_process_inbuf(connection_t *conn);
@@ -643,10 +628,8 @@
 int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection_t *conn, int edge_type, crypt_path_t *layer_hint);
 int connection_edge_finished_flushing(connection_t *conn);
 
-/********************************* connection_exit.c ***************************/
-
-int connection_exit_send_connected(connection_t *conn);
-int connection_exit_begin_conn(cell_t *cell, circuit_t *circ);
+int connection_package_raw_inbuf(connection_t *conn);
+int connection_consider_sending_sendme(connection_t *conn, int edge_type);
 
 int connection_exit_connect(connection_t *conn);
 
@@ -656,6 +639,12 @@
 int connection_or_finished_flushing(connection_t *conn);
 
 connection_t *connection_or_connect(routerinfo_t *router);
+
+int connection_write_cell_to_buf(const cell_t *cellp, connection_t *conn);
+int connection_process_cell_from_inbuf(connection_t *conn);
+#ifndef USE_TLS
+int connection_encrypt_cell(char *cellp, connection_t *conn);
+#endif
 
 /********************************* cpuworker.c *****************************/
 

--- connection_ap.c DELETED ---

--- connection_exit.c DELETED ---



More information about the tor-commits mailing list