Loading src/or/circuit.c +5 −5 Original line number Diff line number Diff line Loading @@ -264,7 +264,7 @@ int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ, } log_fn(LOG_DEBUG,"Passing on unrecognized cell."); connection_write_cell_to_buf(cell, conn); connection_or_write_cell_to_buf(cell, conn); return 0; } Loading Loading @@ -409,11 +409,11 @@ void circuit_resume_edge_reading(circuit_t *circ, int edge_type, crypt_path_t *l if((edge_type == EDGE_EXIT && conn->package_window > 0) || (edge_type == EDGE_AP && conn->package_window > 0 && conn->cpath_layer == layer_hint)) { connection_start_reading(conn); connection_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */ connection_edge_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */ /* If the circuit won't accept any more data, return without looking * at any more of the streams. Any connections that should be stopped * have already been stopped by connection_package_raw_inbuf. */ * have already been stopped by connection_edge_package_raw_inbuf. */ if(circuit_consider_stop_edge_reading(circ, edge_type, layer_hint)) return; } Loading Loading @@ -733,7 +733,7 @@ int circuit_send_next_onion_skin(circuit_t *circ) { return -1; } connection_write_cell_to_buf(&cell, circ->n_conn); connection_or_write_cell_to_buf(&cell, circ->n_conn); circ->cpath->state = CPATH_STATE_AWAITING_KEYS; circ->state = CIRCUIT_STATE_BUILDING; Loading Loading @@ -837,7 +837,7 @@ int circuit_extend(cell_t *cell, circuit_t *circ) { memcpy(newcell.payload, cell->payload+RELAY_HEADER_SIZE+6, DH_ONIONSKIN_LEN); connection_write_cell_to_buf(&newcell, circ->n_conn); connection_or_write_cell_to_buf(&newcell, circ->n_conn); return 0; } Loading src/or/connection.c +3 −2 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ char *conn_state_to_string[][_CONN_TYPE_MAX+1] = { /********* END VARIABLES ************/ static int connection_init_accepted_conn(connection_t *conn); static int connection_handle_listener_read(connection_t *conn, int new_type); /**************************************************************/ Loading Loading @@ -162,7 +163,7 @@ int connection_create_listener(struct sockaddr_in *bindaddr, int type) { return 0; } int connection_handle_listener_read(connection_t *conn, int new_type) { static int connection_handle_listener_read(connection_t *conn, int new_type) { int news; /* the new socket */ connection_t *newconn; struct sockaddr_in remote; /* information about the remote peer when connecting to other routers */ Loading Loading @@ -645,7 +646,7 @@ int connection_send_destroy(aci_t aci, connection_t *conn) { cell.aci = aci; cell.command = CELL_DESTROY; log_fn(LOG_INFO,"Sending destroy (aci %d).",aci); connection_write_cell_to_buf(&cell, conn); connection_or_write_cell_to_buf(&cell, conn); return 0; } Loading src/or/connection_edge.c +10 −8 Original line number Diff line number Diff line Loading @@ -13,6 +13,8 @@ static int connection_ap_handshake_socks_reply(connection_t *conn, char *reply, int replylen, char success); static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ); static void connection_edge_consider_sending_sendme(connection_t *conn, int edge_type); int connection_edge_process_inbuf(connection_t *conn) { Loading Loading @@ -43,7 +45,7 @@ int connection_edge_process_inbuf(connection_t *conn) { /*ENDCLOSE*/ return connection_ap_handshake_process_socks(conn); case AP_CONN_STATE_OPEN: case EXIT_CONN_STATE_OPEN: if(connection_package_raw_inbuf(conn) < 0) if(connection_edge_package_raw_inbuf(conn) < 0) /*ENDCLOSE*/ return -1; return 0; case EXIT_CONN_STATE_CONNECTING: Loading Loading @@ -167,7 +169,7 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection stats_n_data_bytes_received += (cell->length - RELAY_HEADER_SIZE); connection_write_to_buf(cell->payload + RELAY_HEADER_SIZE, cell->length - RELAY_HEADER_SIZE, conn); connection_consider_sending_sendme(conn, edge_type); connection_edge_consider_sending_sendme(conn, edge_type); return 0; case RELAY_COMMAND_END: if(!conn) { Loading Loading @@ -252,7 +254,7 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection conn->package_window += STREAMWINDOW_INCREMENT; log_fn(LOG_DEBUG,"stream-level sendme, packagewindow now %d.", conn->package_window); connection_start_reading(conn); connection_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */ connection_edge_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */ break; default: log_fn(LOG_WARNING,"unknown relay command %d.",relay_command); Loading Loading @@ -295,7 +297,7 @@ int connection_edge_finished_flushing(connection_t *conn) { case AP_CONN_STATE_OPEN: case EXIT_CONN_STATE_OPEN: connection_stop_writing(conn); connection_consider_sending_sendme(conn, conn->type); connection_edge_consider_sending_sendme(conn, conn->type); return 0; case AP_CONN_STATE_SOCKS_WAIT: connection_stop_writing(conn); Loading @@ -312,7 +314,7 @@ uint64_t stats_n_data_bytes_packaged = 0; uint64_t stats_n_data_cells_received = 0; uint64_t stats_n_data_bytes_received = 0; int connection_package_raw_inbuf(connection_t *conn) { int connection_edge_package_raw_inbuf(connection_t *conn) { int amount_to_process, length; char payload[CELL_PAYLOAD_SIZE]; circuit_t *circ; Loading @@ -320,7 +322,7 @@ int connection_package_raw_inbuf(connection_t *conn) { assert(conn); assert(!connection_speaks_cells(conn)); repeat_connection_package_raw_inbuf: repeat_connection_edge_package_raw_inbuf: circ = circuit_get_by_conn(conn); if(!circ) { Loading Loading @@ -376,10 +378,10 @@ repeat_connection_package_raw_inbuf: 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; goto repeat_connection_edge_package_raw_inbuf; } void connection_consider_sending_sendme(connection_t *conn, int edge_type) { static void connection_edge_consider_sending_sendme(connection_t *conn, int edge_type) { circuit_t *circ; cell_t cell; Loading src/or/connection_or.c +9 −4 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ extern or_options_t options; /* command-line and config-file options */ static int connection_tls_finish_handshake(connection_t *conn); static int connection_or_process_cell_from_inbuf(connection_t *conn); /**************************************************************/ Loading Loading @@ -39,7 +40,7 @@ int connection_or_process_inbuf(connection_t *conn) { if(conn->state != OR_CONN_STATE_OPEN) return 0; /* don't do anything */ return connection_process_cell_from_inbuf(conn); return connection_or_process_cell_from_inbuf(conn); } int connection_or_finished_flushing(connection_t *conn) { Loading Loading @@ -252,17 +253,19 @@ static int connection_tls_finish_handshake(connection_t *conn) { /* ********************************** */ void connection_write_cell_to_buf(const cell_t *cellp, connection_t *conn) { void connection_or_write_cell_to_buf(const cell_t *cellp, connection_t *conn) { char networkcell[CELL_NETWORK_SIZE]; char *n = networkcell; assert(connection_speaks_cells(conn)); cell_pack(n, cellp); connection_write_to_buf(n, CELL_NETWORK_SIZE, conn); } /* if there's a whole cell there, pull it off and process it. */ int connection_process_cell_from_inbuf(connection_t *conn) { static int connection_or_process_cell_from_inbuf(connection_t *conn) { char buf[CELL_NETWORK_SIZE]; cell_t cell; Loading @@ -278,6 +281,8 @@ int connection_process_cell_from_inbuf(connection_t *conn) { command_process_cell(&cell, conn); /* CLEAR Shouldn't this be connection_or_process_inbuf at least? Or maybe just use a loop? If not, doc why not. */ return connection_process_inbuf(conn); /* process the remainder of the buffer */ } Loading src/or/main.c +120 −94 Original line number Diff line number Diff line Loading @@ -103,6 +103,10 @@ void connection_set_poll_socket(connection_t *conn) { poll_array[conn->poll_index].fd = conn->s; } /* Remove the current function from the global list, and remove the * corresponding poll entry. Calling this function will shift the last * connection (if any) into the position occupied by conn. */ int connection_remove(connection_t *conn) { int current_index; Loading Loading @@ -185,10 +189,8 @@ static void conn_read(int i) { /* see http://www.greenend.org.uk/rjk/2001/06/poll.html for * discussion of POLLIN vs POLLHUP */ if(!(poll_array[i].revents & (POLLIN|POLLHUP|POLLERR))) if(!connection_speaks_cells(conn) || conn->state != OR_CONN_STATE_OPEN || !connection_is_reading(conn) || !tor_tls_get_pending_bytes(conn->tls)) if(!connection_is_reading(conn) || !connection_has_pending_tls_data(conn)) return; /* this conn should not read */ log_fn(LOG_DEBUG,"socket %d wants to read.",conn->s); Loading Loading @@ -233,7 +235,7 @@ static void conn_write(int i) { } else assert_connection_ok(conn, time(NULL)); } static void check_conn_marked(int i) { static void conn_close_if_marked(int i) { connection_t *conn; conn = connection_array[i]; Loading @@ -255,28 +257,68 @@ static void check_conn_marked(int i) { connection_free(conn); if(i<nfds) { /* we just replaced the one at i with a new one. process it too. */ check_conn_marked(i); conn_close_if_marked(i); } } } static int prepare_for_poll(void) { int i; connection_t *conn; struct timeval now; static long current_second = 0; /* from previous calls to gettimeofday */ static long time_to_fetch_directory = 0; static long time_to_new_circuit = 0; /* Perform regulare maintenance tasks for a single connection. This * function gets run once per second per connection by run_housekeeping. */ static void run_connection_housekeeping(int i, time_t now) { cell_t cell; circuit_t *circ; connection_t *conn = connection_array[i]; if(connection_receiver_bucket_should_increase(conn)) { conn->receiver_bucket += conn->bandwidth; // log_fn(LOG_DEBUG,"Receiver bucket %d now %d.", i, conn->receiver_bucket); } tor_gettimeofday(&now); if(conn->wants_to_read == 1 /* it's marked to turn reading back on now */ && global_read_bucket > 0 /* and we're allowed to read */ && (!connection_speaks_cells(conn) || conn->receiver_bucket > 0)) { /* and either a non-cell conn or a cell conn with non-empty bucket */ conn->wants_to_read = 0; connection_start_reading(conn); if(conn->wants_to_write == 1) { conn->wants_to_write = 0; connection_start_writing(conn); } } if(now.tv_sec > current_second) { /* the second has rolled over. check more stuff. */ /* check connections to see whether we should send a keepalive, expire, or wait */ if(!connection_speaks_cells(conn)) return; ++stats_n_seconds_reading; if(now >= conn->timestamp_lastwritten + options.KeepalivePeriod) { if((!options.OnionRouter && !circuit_get_by_conn(conn)) || (!connection_state_is_open(conn))) { /* we're an onion proxy, with no circuits; or our handshake has expired. kill it. */ log_fn(LOG_INFO,"Expiring connection to %d (%s:%d).", i,conn->address, conn->port); conn->marked_for_close = 1; } else { /* either a full router, or we've got a circuit. send a padding cell. */ log_fn(LOG_DEBUG,"Sending keepalive to (%s:%d)", conn->address, conn->port); memset(&cell,0,sizeof(cell_t)); cell.command = CELL_PADDING; connection_or_write_cell_to_buf(&cell, conn); } } } if(time_to_fetch_directory < now.tv_sec) { /* Perform regular maintenance tasks. This function gets run once per * second by prepare_for_poll. */ static void run_scheduled_events(time_t now) { static long time_to_fetch_directory = 0; static long time_to_new_circuit = 0; circuit_t *circ; int i; /* 1. Every DirFetchPostPeriod seconds, we get a new directory and upload * our descriptor (if any). */ if(time_to_fetch_directory < now) { /* it's time to fetch a new directory and/or post our descriptor */ if(options.OnionRouter) { router_rebuild_descriptor(); Loading @@ -288,10 +330,13 @@ static int prepare_for_poll(void) { directory_initiate_command(router_pick_directory_server(), DIR_CONN_STATE_CONNECTING_FETCH); } time_to_fetch_directory = now.tv_sec + options.DirFetchPostPeriod; time_to_fetch_directory = now + options.DirFetchPostPeriod; } if(options.APPort && time_to_new_circuit < now.tv_sec) { /* 2. Every NewCircuitPeriod seconds, we expire old ciruits and make a * new one as needed. */ if(options.APPort && time_to_new_circuit < now) { circuit_expire_unused_circuits(); circuit_launch_new(-1); /* tell it to forget about previous failures */ circ = circuit_get_newest_open(); Loading @@ -299,9 +344,12 @@ static int prepare_for_poll(void) { log_fn(LOG_INFO,"Youngest circuit %s; launching replacement.", circ ? "dirty" : "missing"); circuit_launch_new(0); /* make an onion and lay the circuit */ } time_to_new_circuit = now.tv_sec + options.NewCircuitPeriod; time_to_new_circuit = now + options.NewCircuitPeriod; } /* 3. Every second, we check how much bandwidth we've consumed and * increment global_read_bucket. */ stats_n_bytes_read += stats_prev_global_read_bucket-global_read_bucket; if(global_read_bucket < 9*options.TotalBandwidth) { global_read_bucket += options.TotalBandwidth; Loading @@ -309,61 +357,39 @@ static int prepare_for_poll(void) { } stats_prev_global_read_bucket = global_read_bucket; /* do housekeeping for each connection */ for(i=0;i<nfds;i++) { conn = connection_array[i]; if(connection_receiver_bucket_should_increase(conn)) { conn->receiver_bucket += conn->bandwidth; // log_fn(LOG_DEBUG,"Receiver bucket %d now %d.", i, conn->receiver_bucket); } if(conn->wants_to_read == 1 /* it's marked to turn reading back on now */ && global_read_bucket > 0 /* and we're allowed to read */ && (!connection_speaks_cells(conn) || conn->receiver_bucket > 0)) { /* and either a non-cell conn or a cell conn with non-empty bucket */ conn->wants_to_read = 0; connection_start_reading(conn); if(conn->wants_to_write == 1) { conn->wants_to_write = 0; connection_start_writing(conn); } /* 4. We do houskeeping for each connection... */ for(i=0;i<nfds;i++) { run_connection_housekeeping(i, now); } /* check connections to see whether we should send a keepalive, expire, or wait */ if(!connection_speaks_cells(conn)) continue; /* this conn type doesn't send cells */ if(now.tv_sec >= conn->timestamp_lastwritten + options.KeepalivePeriod) { if((!options.OnionRouter && !circuit_get_by_conn(conn)) || (!connection_state_is_open(conn))) { /* we're an onion proxy, with no circuits; or our handshake has expired. kill it. */ log_fn(LOG_INFO,"Expiring connection to %d (%s:%d).", i,conn->address, conn->port); conn->marked_for_close = 1; } else { /* either a full router, or we've got a circuit. send a padding cell. */ log_fn(LOG_DEBUG,"Sending keepalive to (%s:%d)", conn->address, conn->port); memset(&cell,0,sizeof(cell_t)); cell.command = CELL_PADDING; connection_write_cell_to_buf(&cell, conn); } } } /* blow away any connections that need to die. can't do this later /* 5. and blow away any connections that need to die. can't do this later * because we might open up a circuit and not realize we're about to cull * the connection it's running over. */ for(i=0;i<nfds;i++) check_conn_marked(i); conn_close_if_marked(i); } static int prepare_for_poll(void) { static long current_second = 0; /* from previous calls to gettimeofday */ connection_t *conn; struct timeval now; int i; tor_gettimeofday(&now); if(now.tv_sec > current_second) { /* the second has rolled over. check more stuff. */ ++stats_n_seconds_reading; run_scheduled_events(now.tv_sec); current_second = now.tv_sec; /* remember which second it is, for next time */ } for(i=0;i<nfds;i++) { conn = connection_array[i]; if(connection_speaks_cells(conn) && connection_state_is_open(conn) && tor_tls_get_pending_bytes(conn->tls)) { if(connection_has_pending_tls_data(conn)) { log_fn(LOG_DEBUG,"sock %d has pending bytes.",conn->s); return 0; /* has pending bytes to read; don't let poll wait. */ } Loading Loading @@ -621,7 +647,7 @@ static int do_main_loop(void) { /* any of the conns need to be closed now? */ for(i=0;i<nfds;i++) check_conn_marked(i); conn_close_if_marked(i); /* refilling buckets and sending cells happens at the beginning of the * next iteration of the loop, inside prepare_for_poll() Loading Loading
src/or/circuit.c +5 −5 Original line number Diff line number Diff line Loading @@ -264,7 +264,7 @@ int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ, } log_fn(LOG_DEBUG,"Passing on unrecognized cell."); connection_write_cell_to_buf(cell, conn); connection_or_write_cell_to_buf(cell, conn); return 0; } Loading Loading @@ -409,11 +409,11 @@ void circuit_resume_edge_reading(circuit_t *circ, int edge_type, crypt_path_t *l if((edge_type == EDGE_EXIT && conn->package_window > 0) || (edge_type == EDGE_AP && conn->package_window > 0 && conn->cpath_layer == layer_hint)) { connection_start_reading(conn); connection_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */ connection_edge_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */ /* If the circuit won't accept any more data, return without looking * at any more of the streams. Any connections that should be stopped * have already been stopped by connection_package_raw_inbuf. */ * have already been stopped by connection_edge_package_raw_inbuf. */ if(circuit_consider_stop_edge_reading(circ, edge_type, layer_hint)) return; } Loading Loading @@ -733,7 +733,7 @@ int circuit_send_next_onion_skin(circuit_t *circ) { return -1; } connection_write_cell_to_buf(&cell, circ->n_conn); connection_or_write_cell_to_buf(&cell, circ->n_conn); circ->cpath->state = CPATH_STATE_AWAITING_KEYS; circ->state = CIRCUIT_STATE_BUILDING; Loading Loading @@ -837,7 +837,7 @@ int circuit_extend(cell_t *cell, circuit_t *circ) { memcpy(newcell.payload, cell->payload+RELAY_HEADER_SIZE+6, DH_ONIONSKIN_LEN); connection_write_cell_to_buf(&newcell, circ->n_conn); connection_or_write_cell_to_buf(&newcell, circ->n_conn); return 0; } Loading
src/or/connection.c +3 −2 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ char *conn_state_to_string[][_CONN_TYPE_MAX+1] = { /********* END VARIABLES ************/ static int connection_init_accepted_conn(connection_t *conn); static int connection_handle_listener_read(connection_t *conn, int new_type); /**************************************************************/ Loading Loading @@ -162,7 +163,7 @@ int connection_create_listener(struct sockaddr_in *bindaddr, int type) { return 0; } int connection_handle_listener_read(connection_t *conn, int new_type) { static int connection_handle_listener_read(connection_t *conn, int new_type) { int news; /* the new socket */ connection_t *newconn; struct sockaddr_in remote; /* information about the remote peer when connecting to other routers */ Loading Loading @@ -645,7 +646,7 @@ int connection_send_destroy(aci_t aci, connection_t *conn) { cell.aci = aci; cell.command = CELL_DESTROY; log_fn(LOG_INFO,"Sending destroy (aci %d).",aci); connection_write_cell_to_buf(&cell, conn); connection_or_write_cell_to_buf(&cell, conn); return 0; } Loading
src/or/connection_edge.c +10 −8 Original line number Diff line number Diff line Loading @@ -13,6 +13,8 @@ static int connection_ap_handshake_socks_reply(connection_t *conn, char *reply, int replylen, char success); static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ); static void connection_edge_consider_sending_sendme(connection_t *conn, int edge_type); int connection_edge_process_inbuf(connection_t *conn) { Loading Loading @@ -43,7 +45,7 @@ int connection_edge_process_inbuf(connection_t *conn) { /*ENDCLOSE*/ return connection_ap_handshake_process_socks(conn); case AP_CONN_STATE_OPEN: case EXIT_CONN_STATE_OPEN: if(connection_package_raw_inbuf(conn) < 0) if(connection_edge_package_raw_inbuf(conn) < 0) /*ENDCLOSE*/ return -1; return 0; case EXIT_CONN_STATE_CONNECTING: Loading Loading @@ -167,7 +169,7 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection stats_n_data_bytes_received += (cell->length - RELAY_HEADER_SIZE); connection_write_to_buf(cell->payload + RELAY_HEADER_SIZE, cell->length - RELAY_HEADER_SIZE, conn); connection_consider_sending_sendme(conn, edge_type); connection_edge_consider_sending_sendme(conn, edge_type); return 0; case RELAY_COMMAND_END: if(!conn) { Loading Loading @@ -252,7 +254,7 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection conn->package_window += STREAMWINDOW_INCREMENT; log_fn(LOG_DEBUG,"stream-level sendme, packagewindow now %d.", conn->package_window); connection_start_reading(conn); connection_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */ connection_edge_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */ break; default: log_fn(LOG_WARNING,"unknown relay command %d.",relay_command); Loading Loading @@ -295,7 +297,7 @@ int connection_edge_finished_flushing(connection_t *conn) { case AP_CONN_STATE_OPEN: case EXIT_CONN_STATE_OPEN: connection_stop_writing(conn); connection_consider_sending_sendme(conn, conn->type); connection_edge_consider_sending_sendme(conn, conn->type); return 0; case AP_CONN_STATE_SOCKS_WAIT: connection_stop_writing(conn); Loading @@ -312,7 +314,7 @@ uint64_t stats_n_data_bytes_packaged = 0; uint64_t stats_n_data_cells_received = 0; uint64_t stats_n_data_bytes_received = 0; int connection_package_raw_inbuf(connection_t *conn) { int connection_edge_package_raw_inbuf(connection_t *conn) { int amount_to_process, length; char payload[CELL_PAYLOAD_SIZE]; circuit_t *circ; Loading @@ -320,7 +322,7 @@ int connection_package_raw_inbuf(connection_t *conn) { assert(conn); assert(!connection_speaks_cells(conn)); repeat_connection_package_raw_inbuf: repeat_connection_edge_package_raw_inbuf: circ = circuit_get_by_conn(conn); if(!circ) { Loading Loading @@ -376,10 +378,10 @@ repeat_connection_package_raw_inbuf: 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; goto repeat_connection_edge_package_raw_inbuf; } void connection_consider_sending_sendme(connection_t *conn, int edge_type) { static void connection_edge_consider_sending_sendme(connection_t *conn, int edge_type) { circuit_t *circ; cell_t cell; Loading
src/or/connection_or.c +9 −4 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ extern or_options_t options; /* command-line and config-file options */ static int connection_tls_finish_handshake(connection_t *conn); static int connection_or_process_cell_from_inbuf(connection_t *conn); /**************************************************************/ Loading Loading @@ -39,7 +40,7 @@ int connection_or_process_inbuf(connection_t *conn) { if(conn->state != OR_CONN_STATE_OPEN) return 0; /* don't do anything */ return connection_process_cell_from_inbuf(conn); return connection_or_process_cell_from_inbuf(conn); } int connection_or_finished_flushing(connection_t *conn) { Loading Loading @@ -252,17 +253,19 @@ static int connection_tls_finish_handshake(connection_t *conn) { /* ********************************** */ void connection_write_cell_to_buf(const cell_t *cellp, connection_t *conn) { void connection_or_write_cell_to_buf(const cell_t *cellp, connection_t *conn) { char networkcell[CELL_NETWORK_SIZE]; char *n = networkcell; assert(connection_speaks_cells(conn)); cell_pack(n, cellp); connection_write_to_buf(n, CELL_NETWORK_SIZE, conn); } /* if there's a whole cell there, pull it off and process it. */ int connection_process_cell_from_inbuf(connection_t *conn) { static int connection_or_process_cell_from_inbuf(connection_t *conn) { char buf[CELL_NETWORK_SIZE]; cell_t cell; Loading @@ -278,6 +281,8 @@ int connection_process_cell_from_inbuf(connection_t *conn) { command_process_cell(&cell, conn); /* CLEAR Shouldn't this be connection_or_process_inbuf at least? Or maybe just use a loop? If not, doc why not. */ return connection_process_inbuf(conn); /* process the remainder of the buffer */ } Loading
src/or/main.c +120 −94 Original line number Diff line number Diff line Loading @@ -103,6 +103,10 @@ void connection_set_poll_socket(connection_t *conn) { poll_array[conn->poll_index].fd = conn->s; } /* Remove the current function from the global list, and remove the * corresponding poll entry. Calling this function will shift the last * connection (if any) into the position occupied by conn. */ int connection_remove(connection_t *conn) { int current_index; Loading Loading @@ -185,10 +189,8 @@ static void conn_read(int i) { /* see http://www.greenend.org.uk/rjk/2001/06/poll.html for * discussion of POLLIN vs POLLHUP */ if(!(poll_array[i].revents & (POLLIN|POLLHUP|POLLERR))) if(!connection_speaks_cells(conn) || conn->state != OR_CONN_STATE_OPEN || !connection_is_reading(conn) || !tor_tls_get_pending_bytes(conn->tls)) if(!connection_is_reading(conn) || !connection_has_pending_tls_data(conn)) return; /* this conn should not read */ log_fn(LOG_DEBUG,"socket %d wants to read.",conn->s); Loading Loading @@ -233,7 +235,7 @@ static void conn_write(int i) { } else assert_connection_ok(conn, time(NULL)); } static void check_conn_marked(int i) { static void conn_close_if_marked(int i) { connection_t *conn; conn = connection_array[i]; Loading @@ -255,28 +257,68 @@ static void check_conn_marked(int i) { connection_free(conn); if(i<nfds) { /* we just replaced the one at i with a new one. process it too. */ check_conn_marked(i); conn_close_if_marked(i); } } } static int prepare_for_poll(void) { int i; connection_t *conn; struct timeval now; static long current_second = 0; /* from previous calls to gettimeofday */ static long time_to_fetch_directory = 0; static long time_to_new_circuit = 0; /* Perform regulare maintenance tasks for a single connection. This * function gets run once per second per connection by run_housekeeping. */ static void run_connection_housekeeping(int i, time_t now) { cell_t cell; circuit_t *circ; connection_t *conn = connection_array[i]; if(connection_receiver_bucket_should_increase(conn)) { conn->receiver_bucket += conn->bandwidth; // log_fn(LOG_DEBUG,"Receiver bucket %d now %d.", i, conn->receiver_bucket); } tor_gettimeofday(&now); if(conn->wants_to_read == 1 /* it's marked to turn reading back on now */ && global_read_bucket > 0 /* and we're allowed to read */ && (!connection_speaks_cells(conn) || conn->receiver_bucket > 0)) { /* and either a non-cell conn or a cell conn with non-empty bucket */ conn->wants_to_read = 0; connection_start_reading(conn); if(conn->wants_to_write == 1) { conn->wants_to_write = 0; connection_start_writing(conn); } } if(now.tv_sec > current_second) { /* the second has rolled over. check more stuff. */ /* check connections to see whether we should send a keepalive, expire, or wait */ if(!connection_speaks_cells(conn)) return; ++stats_n_seconds_reading; if(now >= conn->timestamp_lastwritten + options.KeepalivePeriod) { if((!options.OnionRouter && !circuit_get_by_conn(conn)) || (!connection_state_is_open(conn))) { /* we're an onion proxy, with no circuits; or our handshake has expired. kill it. */ log_fn(LOG_INFO,"Expiring connection to %d (%s:%d).", i,conn->address, conn->port); conn->marked_for_close = 1; } else { /* either a full router, or we've got a circuit. send a padding cell. */ log_fn(LOG_DEBUG,"Sending keepalive to (%s:%d)", conn->address, conn->port); memset(&cell,0,sizeof(cell_t)); cell.command = CELL_PADDING; connection_or_write_cell_to_buf(&cell, conn); } } } if(time_to_fetch_directory < now.tv_sec) { /* Perform regular maintenance tasks. This function gets run once per * second by prepare_for_poll. */ static void run_scheduled_events(time_t now) { static long time_to_fetch_directory = 0; static long time_to_new_circuit = 0; circuit_t *circ; int i; /* 1. Every DirFetchPostPeriod seconds, we get a new directory and upload * our descriptor (if any). */ if(time_to_fetch_directory < now) { /* it's time to fetch a new directory and/or post our descriptor */ if(options.OnionRouter) { router_rebuild_descriptor(); Loading @@ -288,10 +330,13 @@ static int prepare_for_poll(void) { directory_initiate_command(router_pick_directory_server(), DIR_CONN_STATE_CONNECTING_FETCH); } time_to_fetch_directory = now.tv_sec + options.DirFetchPostPeriod; time_to_fetch_directory = now + options.DirFetchPostPeriod; } if(options.APPort && time_to_new_circuit < now.tv_sec) { /* 2. Every NewCircuitPeriod seconds, we expire old ciruits and make a * new one as needed. */ if(options.APPort && time_to_new_circuit < now) { circuit_expire_unused_circuits(); circuit_launch_new(-1); /* tell it to forget about previous failures */ circ = circuit_get_newest_open(); Loading @@ -299,9 +344,12 @@ static int prepare_for_poll(void) { log_fn(LOG_INFO,"Youngest circuit %s; launching replacement.", circ ? "dirty" : "missing"); circuit_launch_new(0); /* make an onion and lay the circuit */ } time_to_new_circuit = now.tv_sec + options.NewCircuitPeriod; time_to_new_circuit = now + options.NewCircuitPeriod; } /* 3. Every second, we check how much bandwidth we've consumed and * increment global_read_bucket. */ stats_n_bytes_read += stats_prev_global_read_bucket-global_read_bucket; if(global_read_bucket < 9*options.TotalBandwidth) { global_read_bucket += options.TotalBandwidth; Loading @@ -309,61 +357,39 @@ static int prepare_for_poll(void) { } stats_prev_global_read_bucket = global_read_bucket; /* do housekeeping for each connection */ for(i=0;i<nfds;i++) { conn = connection_array[i]; if(connection_receiver_bucket_should_increase(conn)) { conn->receiver_bucket += conn->bandwidth; // log_fn(LOG_DEBUG,"Receiver bucket %d now %d.", i, conn->receiver_bucket); } if(conn->wants_to_read == 1 /* it's marked to turn reading back on now */ && global_read_bucket > 0 /* and we're allowed to read */ && (!connection_speaks_cells(conn) || conn->receiver_bucket > 0)) { /* and either a non-cell conn or a cell conn with non-empty bucket */ conn->wants_to_read = 0; connection_start_reading(conn); if(conn->wants_to_write == 1) { conn->wants_to_write = 0; connection_start_writing(conn); } /* 4. We do houskeeping for each connection... */ for(i=0;i<nfds;i++) { run_connection_housekeeping(i, now); } /* check connections to see whether we should send a keepalive, expire, or wait */ if(!connection_speaks_cells(conn)) continue; /* this conn type doesn't send cells */ if(now.tv_sec >= conn->timestamp_lastwritten + options.KeepalivePeriod) { if((!options.OnionRouter && !circuit_get_by_conn(conn)) || (!connection_state_is_open(conn))) { /* we're an onion proxy, with no circuits; or our handshake has expired. kill it. */ log_fn(LOG_INFO,"Expiring connection to %d (%s:%d).", i,conn->address, conn->port); conn->marked_for_close = 1; } else { /* either a full router, or we've got a circuit. send a padding cell. */ log_fn(LOG_DEBUG,"Sending keepalive to (%s:%d)", conn->address, conn->port); memset(&cell,0,sizeof(cell_t)); cell.command = CELL_PADDING; connection_write_cell_to_buf(&cell, conn); } } } /* blow away any connections that need to die. can't do this later /* 5. and blow away any connections that need to die. can't do this later * because we might open up a circuit and not realize we're about to cull * the connection it's running over. */ for(i=0;i<nfds;i++) check_conn_marked(i); conn_close_if_marked(i); } static int prepare_for_poll(void) { static long current_second = 0; /* from previous calls to gettimeofday */ connection_t *conn; struct timeval now; int i; tor_gettimeofday(&now); if(now.tv_sec > current_second) { /* the second has rolled over. check more stuff. */ ++stats_n_seconds_reading; run_scheduled_events(now.tv_sec); current_second = now.tv_sec; /* remember which second it is, for next time */ } for(i=0;i<nfds;i++) { conn = connection_array[i]; if(connection_speaks_cells(conn) && connection_state_is_open(conn) && tor_tls_get_pending_bytes(conn->tls)) { if(connection_has_pending_tls_data(conn)) { log_fn(LOG_DEBUG,"sock %d has pending bytes.",conn->s); return 0; /* has pending bytes to read; don't let poll wait. */ } Loading Loading @@ -621,7 +647,7 @@ static int do_main_loop(void) { /* any of the conns need to be closed now? */ for(i=0;i<nfds;i++) check_conn_marked(i); conn_close_if_marked(i); /* refilling buckets and sending cells happens at the beginning of the * next iteration of the loop, inside prepare_for_poll() Loading