Tor source code file analysis-Main

Source: Internet
Author: User

The main file is the file where the main execution function of the ToR system is located. The content is too large, but it is less than the file where other underlying processing functions are located. So here is a brief analysis. You can delete many uncommon and unimportant functions from the source file.

1. Global Variables

Global variables are defined in the file header. Each global variable has been analyzed and explained in more detail in English.

1) system (previous) Number of Read and Write nodes and global variable of the token bucket used for traffic control (the difference between the number of Read and Write nodes and the refill callback function)

The token bucket is used to control the traffic of the entire system. operations such as initialization, reduction, and addition (when the number of tokens for reading and writing is insufficient, the system or connection will stop reading or writing ):

// Initialize the number of token buckets/** initialize the global read bucket to options-\> bandwidthburst. */configure (void) {const or_options_t * Options = get_options ();/* start it at max traffic */global_read_bucket = (INT) options-> bandwidthburst; global_write_bucket = (INT) options-> bandwidthburst; If (options-> relaybandwidthrate) {timeout = (INT) options-> relaybandwidthburst; global_relayed_write_bucket = (INT) options-> relaybandwidthburst ;} else {global_relayed_read_bucket = (INT) options-> bandwidthburst; global_relayed_write_bucket = (INT) options-> bandwidthburst ;}}
// Reduce the number of token buckets/** we just read <B> num_read </B> and wrote <B> num_written </B> bytes * onto <B> conn </ b>. decrement buckets appropriately. */static voidconnection_buckets_decrement (connection_t * Conn, time_t now, size_t num_read, size_t num_written ){...... if (condition (Conn, now) {global_relayed_read_bucket-= (INT) num_read; global_relayed_write_bucket-= (INT) num_written;} global_read_bucket-= (INT) num_read; global_write_bucket-= (INT) num_written ;......}
// Increase the number of token buckets/** time has passed; increment buckets appropriately. */voidconnection_bucket_refill (INT milliseconds_elapsed, time_t now ){...... /* refill the global buckets */values (& bandwidth, bandwidthrate, bandwidthburst, percent, "percent"); values (& global_write_bucket, bandwidthrate, bandwidthburst, percent, "global_write_bucket "); round (& response, relayrate, relayburst, milliseconds_elapsed, "lower"); Round (& response, relayrate, relayburst, milliseconds_elapsed, "lower ");......}

The specific value of the global variable of the number of read-write segments is in the second_elapsed_callback function, which is not referenced elsewhere:

  bytes_read = (size_t)(stats_n_bytes_read - stats_prev_n_read);  bytes_written = (size_t)(stats_n_bytes_written - stats_prev_n_written);  stats_prev_n_read = stats_n_bytes_read;  stats_prev_n_written = stats_n_bytes_written;

The value of the global variable of the number of currently read write nodes is in the refill_callback function, which is not referenced elsewhere:

  bytes_written = stats_prev_global_write_bucket - global_write_bucket;  bytes_read = stats_prev_global_read_bucket - global_read_bucket;  stats_n_bytes_read += bytes_read;  stats_n_bytes_written += bytes_written;

2) system start time and run time;

The system startup time is initialized in the TOR system initialization phase and has not been modified:

tor_init(int argc, char *argv[]){  ......  time_of_process_start = time(NULL); ......}

The system running time increases with time in the second_elapsed_callback function. When important changes occur in the system, the system is reset to 0, such as hibernation and IP address change.

3) start the next DNS check time;

It is used only when the system is configured as a server. The change part is omitted here in the run_scheduled_events function.

4) newnym related variables;

The variables related to the newnym signal are changed within the signal processing function. The entry is roughly:

/** Do the work of acting on a signal received in <b>sig</b> */voidprocess_signal(uintptr_t sig){  switch (sig)  {  ....    case SIGNEWNYM: {      time_t now = time(NULL);      if (time_of_last_signewnym + MAX_SIGNEWNYM_RATE > now) {        signewnym_is_pending = 1;        log(LOG_NOTICE, LD_CONTROL,            "Rate limiting NEWNYM request: delaying by %d second(s)",            (int)(MAX_SIGNEWNYM_RATE+time_of_last_signewnym-now));      } else {        signewnym_impl(now);      }      break;    }  ......}

5) global variables of the three linked lists: Fully Connected linked lists, closed connection linked lists, and active linked connection lists. (The meaning of the linked connection is described in tor source code analysis)

Because these three linked lists have a lot of references, it is impossible to pin their main reference locations. It can be roughly said that when the system has related connections, it will be added to the relevant connection list: All, closed, and active linked. When the system deletes related connections, these connections will be deleted from the related connection list. This is the core control part of the ToR system, which is frequently encountered in system code analysis. Therefore, we will give a rough description here.

6) libevent cycle indicator variable;

The call_loop_once variable is used to indicate whether the libevent loop is blocked. If the value is 1, The libevent executes the activated event processing function without blocking. If no processing function is required, it returns. If the value is 0, libevent will block the execution of the activated event processing function, that is, when there is no processing function to be executed, blocking will not return. In the latter case, the TOR system needs to launch a loop to handle specific events. It needs to call the specific tor_event_base_loopexit function to temporarily exit the main loop:

do_main_loop{    ......    /* All active linked conns should get their read events activated. */    SMARTLIST_FOREACH(active_linked_connection_lst, connection_t *, conn,                      event_active(conn->read_event, EV_READ, 1));    called_loop_once = smartlist_len(active_linked_connection_lst) ? 1 : 0;    update_approx_time(time(NULL));    /* poll until we have an event, or the second ends, or until we have     * some active linked connections to trigger events for. */    loop_result = event_base_loop(tor_libevent_get_base(),                                  called_loop_once ? EVLOOP_ONCE : 0);    ......}

7) link availability indicator variable.

The following lists all global variables:

#ifndef USE_BUFFEREVENTSint global_read_bucket; /**< Max number of bytes I can read this second. */int global_write_bucket; /**< Max number of bytes I can write this second. *//** Max number of relayed (bandwidth class 1) bytes I can read this second. */int global_relayed_read_bucket;/** Max number of relayed (bandwidth class 1) bytes I can write this second. */int global_relayed_write_bucket;/** What was the read bucket before the last second_elapsed_callback() call? * (used to determine how many bytes we've read). */static int stats_prev_global_read_bucket;/** What was the write bucket before the last second_elapsed_callback() call? * (used to determine how many bytes we've written). */static int stats_prev_global_write_bucket;#endif/* DOCDOC stats_prev_n_read */static uint64_t stats_prev_n_read = 0;/* DOCDOC stats_prev_n_written */static uint64_t stats_prev_n_written = 0;/* XXX we might want to keep stats about global_relayed_*_bucket too. Or not.*//** How many bytes have we read since we started the process? */static uint64_t stats_n_bytes_read = 0;/** How many bytes have we written since we started the process? */static uint64_t stats_n_bytes_written = 0;/** What time did this process start up? */time_t time_of_process_start = 0;/** How many seconds have we been running? */long stats_n_seconds_working = 0;/** When do we next launch DNS wildcarding checks? */static time_t time_to_check_for_correct_dns = 0;/** How often will we honor SIGNEWNYM requests? */#define MAX_SIGNEWNYM_RATE 10/** When did we last process a SIGNEWNYM request? */static time_t time_of_last_signewnym = 0;/** Is there a signewnym request we're currently waiting to handle? */static int signewnym_is_pending = 0;/** How many times have we called newnym? */static unsigned newnym_epoch = 0;/** Smartlist of all open connections. */static smartlist_t *connection_array = NULL;/** List of connections that have been marked for close and need to be freed * and removed from connection_array. */static smartlist_t *closeable_connection_lst = NULL;/** List of linked connections that are currently reading data into their * inbuf from their partner's outbuf. */static smartlist_t *active_linked_connection_lst = NULL;/** Flag: Set to true iff we entered the current libevent main loop via * <b>loop_once</b>. If so, there's no need to trigger a loopexit in order * to handle linked connections. */static int called_loop_once = 0;/** We set this to 1 when we've opened a circuit, so we can print a log * entry to inform the user that Tor is working.  We set it to 0 when * we think the fact that we once opened a circuit doesn't mean we can do so * any longer (a big time jump happened, when we notice our directory is * heinously out-of-date, etc. */int can_complete_circuit=0;

2. function (the * sign is an extremely important function)

Dumpmemusage

Dumpstats

Records memory usage and current system status and outputs it to log;

Conn_read_callback *

Conn_write_callback *

Second_elapsed_callback *-> run_schedule_events-> run_connection_housekeeping

Refill_callback

Signal_callback-> process_signal

Read/write, second timer, token bucket filling, and signal processing callback function;

Conn_close_if_marked

Closes a connection marked as closed in the connection pool;

Connection_should_read_from_linked_conn *

Connection_start_reading_from_linked_conn *

Connection_stop_reading_from_linked_conn *

Determine the readability of the linked connection and perform read/write preparation for the connection. (the so-called read/write preparation operation is directly related to the linked list of the activities mentioned above. In fact, it is the addition or deletion operation of the linked list connected to the active linked. The active linked list is detected every time the main loop of the program is executed. All connections are activated for read/write scheduling.

Connection_add->

Connection_add_connecting-> connection_add_impl *

Add a new connection to the connection pool and generate a read/write event for the connection, but do not add the event to the scheduling pool. (-> indicates a call, the same below)

Connection_unlink-> connection_remove-> connection_unregister_events

From right to left, the read/write events of the connection are deleted from the scheduling pool, and the connection is deleted from the connection pool. The connection is released completely;

Connection_watch_events *-> connection_start_reading, connection_start_writing, connection_stop_reading, connection_stop_writing

Connection_is_reading

Connection_is_writing

Add the read/write events of a connection to the scheduling pool or call up the operation and read/write judgment of the scheduling pool. the operation of a common connection is completed by the scheduling pool, and the operation of the linked connection is completed by connecting the linked list through the activity linked.

  

Try_locking

Have_lockfile

Release_locking

Apply the global lock file and unlock control;

Tor_main-> tor_init *, do_main_loop *, do_list_fingerprint, do_hash_password

The main function of the ToR program executes the branch process.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.