As the most important connection in the connection type, the or connection is fully responsible for the communication between op and or. That is to say, the existence of or connections is a necessary condition for communication between the two underlying machines. Therefore, it is necessary to conduct an in-depth analysis of the source code file connected to or and give a brief introduction to the or connection. Later, we will introduce all the connections of the ToR system in more detail and their functions.
Or connection, that is, Onion Router connection, is used to connect two nodes in the TOR system. The main functions of this connection include managing TLS connections between nodes, managing activity links, and managing sending and receiving of cells. Or the connection is at the lowest layer of the ToR system, and the lower layer is the TLS layer. Therefore, the or connection is responsible for reliable cell transmission and interaction with the upper-layer connection layer.
Dir connection ...... Application Layer
------------------------
AP connection, exit connection ......
------------------
Circuit link ...... Tor protocol layer
------------------
Or connection ......
------------------------
TLS connection Transport Layer
At the same time, it is worth noting that the TOR system applications connect to the AP, link circuit, or connection, and the reuse between the three: (Multi-AP connection reuse circuit, multi-circuit reuse or connection)
AP stream 1 -->
AP stream 2 --> circuit 1->
... 3 -->
Circuit 2-> or connection 1
Circuit 3->
0. global variable 1) orconn_identity_map
/** Map from identity digest of connected OR or desired OR to a connection_t * with that identity digest. If there is more than one such connection_t, * they form a linked list, with next_with_same_id as the next pointer. */static digestmap_t *orconn_identity_map = NULL;
The global variable is a hash table that uses the link address method to handle conflicts. The key of the hash table is the or ID digest, the hash table value is or connected to the Linked List (multiple or connections may be connected to the same or, or different or tables may have the same ID abstract ). This hash table provides the ability to insert or delete key-value pairs. It is mainly used to establish the first hop and or next hop services for the op. The following code is detailed:
// Use the local or connection to reuse the service when the op establishes the first hop of The Link/** start establishing the first hop of our circuit. figure out what * Or we shoshould connect to, and if necessary start the connection to * It. if we're already connected, then sends the 'create' cell. * return 0 for OK,-reason If CIRC shoshould be marked-for-close. */intcircuit_handle_first_hop (origin_circuit_t * CIRC ){...... /* Now see if we're re already connected to the first Or in 'route '*/log_debug (ld_circ, "Looking for firsthop' % s: % U'", fmt_addr (& firsthop-> extend_info-> ADDR ), firsthop-> extend_info-> port); n_conn = quit (firsthop-> extend_info-> identity_digest, & firsthop-> extend_info-> ADDR, & MSG, & should_launch); If (! N_conn) {/* it's not open. create one */......} else {/* It's already open. use it. */......} return 0 ;}
// Or use the local or connection to reuse the service when extending the link/** take the 'extend' <B> cell </B>, pull out ADDR/port plus the onion * skin and identity digest for the next hop. if we're re already connected, * pass the onion skin to the next hop using a create cell; otherwise * launch a new or connection, and <B> CIRC </B> will notice when the * connection succeeds or fails. ** return-1 if we want to warn and tear down the circuit, else retu Rn 0. */intcircuit_extend (cell_t * cell, circuit_t * CIRC ){...... n_conn = connection_or_get_for_extend (id_digest, & n_addr, & MSG, & should_launch); If (! N_conn) {/* it's not open. create one */...... if (should_launch) {/* We shoshould try to open a connection */n_conn = connection_or_connect (& n_addr, n_port, id_digest );......} /* return success. the Onion/circuit/etc will be taken care of * automatically (may already have been) Whenever n_conn reaches * or_conn_state_open. */return 0;} tor_assert (! Circ-> n_hop);/* connection is already established. */Circ-> n_conn = n_conn; log_debug (ld_circ, "n_conn is % s: % u", n_conn-> _ base. address, n_conn-> _ base. port); If (circuit_deliver_create_cell (CIRC, cell_create, onionskin) <0) Return-1; return 0 ;}
2) broken_connection_counts
/** Map from a string describing what a non-open OR connection was doing when * failed, to an intptr_t describing the count of connections that failed that * way. Note that the count is stored _as_ the pointer. */static strmap_t *broken_connection_counts;/** If true, do not record information in <b>broken_connection_counts</b>. */static int disable_broken_connection_counts = 0;
This global variable is used to record Tor system error information. It is a string-to-integer Hash table (corresponding table, no need for a linked list to resolve conflicts ). By adding or deleting a hash table, you can record or erase the status information related to connection errors in the system. The final report location is connection_or_report_broken_states. The main processing functions of variables are as follows:
/** Record that an OR connection failed in <b>state</b>. */static voidnote_broken_connection(const char *state){ void *ptr; intptr_t val; if (disable_broken_connection_counts) return; if (!broken_connection_counts) broken_connection_counts = strmap_new(); ptr = strmap_get(broken_connection_counts, state); val = (intptr_t)ptr; val++; ptr = (void*)val; strmap_set(broken_connection_counts, state, ptr);}/** Forget all recorded states for failed connections. If * <b>stop_recording</b> is true, don't record any more. */voidclear_broken_connection_map(int stop_recording){ if (broken_connection_counts) strmap_free(broken_connection_counts, NULL); broken_connection_counts = NULL; if (stop_recording) disable_broken_connection_counts = 1;}
3) version
/** Array of recognized link protocol versions. */static const uint16_t or_protocol_versions[] = { 1, 2, 3 };/** Number of versions in <b>or_protocol_versions</b>. */static const int n_or_protocol_versions = (int)( sizeof(or_protocol_versions)/sizeof(uint16_t) );
This global variable is used to store the Protocol version number and number of protocol versions used by the system. It is basically a fixed value and will only change when a new version is added. The reference is small and simple, so it is skipped temporarily.
1. Global variable control functions
Connection_or_set_identity_digest
Connection_or_remove_from_identity_map
Connection_or_clear_identity_map
Add, delete, and clear hash table entries connected to or by ID Summarization;
Note_broken_connection <-- 2 connection_or_note_state_when_broken 1 --> connection_or_get_state_description
Clear_broken_connection_map
Connection_or_report_broken_states
Increase, clear, and output the number of entries in the hash table (corresponding to the table) from the error status string to the number of error connections;
2. Or connection Cell Control
Cell_pack
Cell_unpack
The cell in the Local Machine differs from the cell transmitted in the network in the byte order. Therefore, we need to use two separate struct structures for representation and conversion, which are simply called package and package. (Network: packed_cell_t; local Machine: cell_t)
Var_cell_pack_header
Var_cell_new
Var_cell_free
Variable-length cell related operations;
3. or connection read/write control
Connection_or_process_inbuf --> connection_or_process_cells_from_inbuf
Connection_or_reached_eof
Or connection to process the data in the input buffer. Different data processing methods are different, generally cell data or EOF data;
Connection_or_flushed_some // objective: to obtain more data to be written from the activity Link
Connection_or_finished_flushing
Connection_or_finished_connecting // objective: to call this function for the next TLS connection after the normal socket connection is complete
Or connects to function operations called when some operations are completed. operations include outputting part of the data, outputting the data, and completing the connection;
Connection_or_write_cell_to_buf
Connection_or_write_var_cell_to_buf
Write the cell or variable-length cell into the or output buffer and wait for the output;
4. or connection management
Connection_or_about_to_close
Scanning and closing the or connection before closing the connection;
Connection_or_update_token_buckets
Reset the or connection token bucket;
Connection_or_digest_is_known_relay
Determine whether the selected or is a known relay server that can be used;
Connection_or_set_state_open
After the TLS handshake and or handshake are completed, set the connection status to enabled and notify all other subsystems;
5. Or connection usage
Connection_or_connect
Initiate the or connection to the specified or, and return the newly created or connection struct. The content includes creating a connection, enabling a socket connection, and then enabling a TLS connection;
Connection_tls_start_handshake
Connection_tls_continue_handshake
After the non-blocking socket connection is enabled for the or connection, the system will enable the TLS handshake process for the or connection at the appropriate time according to the read/write rules;
Connection_init_or_handshake_state
Or_handshake_state_free
Or_handshake_state_record_cell
Or_handshake_state_record_var_cell
During or layer handshake, handshake_state is used to record the digest information of the handshake packet throughout the process to ensure that the handshake is correct. (handshake layers: Socket handshake, TLS handshake, or handshake)
Connection_or_send_destroy
Connection_or_send_versions
Connection_or_send_versions
Connection_or_send_certs_cell
Connection_or_send_auth_challenge_cell
Connection_or_send_authenticate_cell --> connection_or_compute_authenticate_cell_body
Construct a handshake package related to or handshake, and use the connection_or_write_cell_to_buf function or connection_or_write_var_cell_to_buf function to write or connection buffer to wait for output;
You can see from the usage functions of the above or connections that the entire or connection creation process is as follows:
1) Establish or connections;
2) Establish a socket connection and perform a socket handshake. (three handshakes)
3) Establish a TLS connection and perform a TLS handshake)
4. In the hands-on process, you must ensure that all the hand-held packages are used to calculate the optimized features (see tor_spec.txt)