case CELL_SENDME:
command_process_sendme_cell(cell, conn);
break;
+ case CELL_CONNECTED:
+ command_process_connected_cell(cell, conn);
+ break;
default:
log(LOG_DEBUG,"Cell of unknown type (%d) received. Dropping.", cell->command);
break;
circuit_free(circ);
}
+void command_process_connected_cell(cell_t *cell, connection_t *conn) {
+ circuit_t *circ;
+
+ circ = circuit_get_by_aci_conn(cell->aci, conn);
+
+ if(!circ) {
+ log(LOG_DEBUG,"command_process_connected_cell(): unknown circuit %d. Dropping.", cell->aci);
+ return;
+ }
+
+ if(circ->n_conn != conn) {
+ log(LOG_WARNING,"command_process_connected_cell(): cell didn't come from n_conn! (aci %d)",cell->aci);
+ return;
+ }
+
+ log(LOG_DEBUG,"command_process_connected_cell(): Received for aci %d.",cell->aci);
+ connection_send_connected(circ->p_aci, circ->p_conn);
+}
+
cell.command = CELL_DESTROY;
log(LOG_INFO,"connection_send_destroy(): Sending destroy (aci %d).",aci);
return connection_write_cell_to_buf(&cell, conn);
+}
+
+int connection_send_connected(aci_t aci, connection_t *conn) {
+ cell_t cell;
+ assert(conn);
+
+ if(!connection_speaks_cells(conn)) {
+ log(LOG_INFO,"connection_send_connected(): Aci %d: At entry point. Notifying proxy.", aci);
+ connection_ap_send_connected(conn);
+ return 0;
+ }
+
+ cell.aci = aci;
+ cell.command = CELL_CONNECTED;
+ log(LOG_INFO,"connection_send_connected(): passing back cell (aci %d).",aci);
+ return connection_write_cell_to_buf(&cell, conn);
}
int connection_write_cell_to_buf(cell_t *cellp, connection_t *conn) {
cell_t cell;
int tmpbuflen, dataleft;
char *tmpbuf;
- char zero=0;
circ->n_aci = get_unique_aci_by_addr_port(circ->n_addr, circ->n_port, ACI_TYPE_BOTH);
circ->n_conn = n_conn;
/* FIXME should set circ->expire to something here */
- /* now we want to give the AP a "0" byte, because it wants to hear
- * back from us */
- connection_write_to_buf(&zero, 1, ap_conn); /* this does connection_start_writing() too */
-
return 0;
}
+int connection_ap_send_connected(connection_t *conn) {
+ char zero=0;
+
+ 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);
+}
+
int connection_ap_process_data_cell(cell_t *cell, connection_t *conn) {
/* an incoming data cell has arrived */
if(connection_wants_to_flush(conn)) /* in case there are any queued data cells */
connection_start_writing(conn);
connection_start_reading(conn);
- return 0;
+
+ /* also, deliver a 'connected' cell back through the circuit. */
+ return connection_exit_send_connected(conn);
case EXIT_CONN_STATE_OPEN:
/* FIXME down the road, we'll clear out circuits that are pending to close */
connection_stop_writing(conn);
return 0;
}
+int connection_exit_send_connected(connection_t *conn) {
+ circuit_t *circ;
+
+ assert(conn);
+
+ circ = circuit_get_by_conn(conn);
+
+ assert(circ && circ->p_conn && circ->n_conn == conn); /* is this true? i guess i'll see if it breaks. */
+
+ return connection_send_connected(circ->p_aci, circ->p_conn);
+}
+
int connection_exit_process_data_cell(cell_t *cell, connection_t *conn) {
struct hostent *rent;
struct sockaddr_in dest_addr;
connection_set_poll_socket(conn);
conn->state = EXIT_CONN_STATE_OPEN;
connection_watch_events(conn, POLLIN);
- return 0;
+
+ /* also, deliver a 'connected' cell back through the circuit. */
+ return connection_exit_send_connected(conn);
} else {
log(LOG_DEBUG,"connection_exit_process_data_cell(): in connecting_wait, but I've already received everything. Closing.");
return -1;
#define CELL_ACK 4
#define CELL_NACK 5
#define CELL_SENDME 6
+#define CELL_CONNECTED 7
#define CELL_PAYLOAD_SIZE 120
void command_process_sendme_cell(cell_t *cell, connection_t *conn);
void command_process_data_cell(cell_t *cell, connection_t *conn);
void command_process_destroy_cell(cell_t *cell, connection_t *conn);
+void command_process_connected_cell(cell_t *cell, connection_t *conn);
/********************************* config.c ***************************/
int connection_state_is_open(connection_t *conn);
int connection_send_destroy(aci_t aci, connection_t *conn);
+int connection_send_connected(aci_t aci, connection_t *conn);
int connection_encrypt_cell(cell_t *cellp, connection_t *conn);
int connection_write_cell_to_buf(cell_t *cellp, connection_t *conn);
int ap_handshake_send_onion(connection_t *ap_conn, connection_t *or_conn, circuit_t *circ);
+int connection_ap_send_connected(connection_t *conn);
int connection_ap_process_data_cell(cell_t *cell, connection_t *conn);
int connection_ap_finished_flushing(connection_t *conn);
int connection_exit_process_inbuf(connection_t *conn);
int connection_exit_package_inbuf(connection_t *conn);
+int connection_exit_send_connected(connection_t *conn);
int connection_exit_process_data_cell(cell_t *cell, connection_t *conn);
int connection_exit_finished_flushing(connection_t *conn);