Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Tor
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Container Registry
Model registry
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
The Tor Project
Core
Tor
Commits
dc79504e
Commit
dc79504e
authored
8 years ago
by
Nick Mathewson
Browse files
Options
Downloads
Patches
Plain Diff
Document main.c a lot better
parent
172b1240
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/or/main.c
+144
-21
144 additions, 21 deletions
src/or/main.c
with
144 additions
and
21 deletions
src/or/main.c
+
144
−
21
View file @
dc79504e
...
...
@@ -8,6 +8,42 @@
* \file main.c
* \brief Toplevel module. Handles signals, multiplexes between
* connections, implements main loop, and drives scheduled events.
*
* For the main loop itself; see run_main_loop_once(). It invokes the rest of
* Tor mostly through Libevent callbacks. Libevent callbacks can happen when
* a timer elapses, a signal is received, a socket is ready to read or write,
* or an event is manually activated.
*
* Most events in Tor are driven from these callbacks:
* <ul>
* <li>conn_read_callback() and conn_write_callback() here, which are
* invoked when a socket is ready to read or write respectively.
* <li>signal_callback(), which handles incoming signals.
* </ul>
* Other events are used for specific purposes, or for building more complex
* control structures. If you search for usage of tor_libevent_new(), you
* will find all the events that we construct in Tor.
*
* Tor has numerous housekeeping operations that need to happen
* regularly. They are handled in different ways:
* <ul>
* <li>The most frequent operations are handled after every read or write
* event, at the end of connection_handle_read() and
* connection_handle_write().
*
* <li>The next most frequent operations happen after each invocation of the
* main loop, in run_main_loop_once().
*
* <li>Once per second, we run all of the operations listed in
* second_elapsed_callback(), and in its child, run_scheduled_events().
*
* <li>Once-a-second operations are handled in second_elapsed_callback().
*
* <li>More infrequent operations take place based on the periodic event
* driver in periodic.c . These are stored in the periodic_events[]
* table.
* </ul>
*
**/
#define MAIN_PRIVATE
...
...
@@ -1408,13 +1444,13 @@ run_scheduled_events(time_t now)
pt_configure_remaining_proxies
();
}
/* Periodic callback: Every MIN_ONION_KEY_LIFETIME seconds, rotate the onion
* keys, shut down and restart all cpuworkers, and update our descriptor if
* necessary.
*/
static
int
rotate_onion_key_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
/* 1a. Every MIN_ONION_KEY_LIFETIME seconds, rotate the onion keys,
* shut down and restart all cpuworkers, and update the directory if
* necessary.
*/
if
(
server_mode
(
options
))
{
time_t
rotation_time
=
get_onion_key_set_at
()
+
MIN_ONION_KEY_LIFETIME
;
if
(
rotation_time
>
now
)
{
...
...
@@ -1434,6 +1470,9 @@ rotate_onion_key_callback(time_t now, const or_options_t *options)
return
PERIODIC_EVENT_NO_UPDATE
;
}
/* Periodic callback: Every 30 seconds, check whether it's time to make new
* Ed25519 subkeys.
*/
static
int
check_ed_keys_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1451,6 +1490,11 @@ check_ed_keys_callback(time_t now, const or_options_t *options)
return
PERIODIC_EVENT_NO_UPDATE
;
}
/**
* Periodic callback: Every {LAZY,GREEDY}_DESCRIPTOR_RETRY_INTERVAL,
* see about fetching descriptors, microdescriptors, and extrainfo
* documents.
*/
static
int
launch_descriptor_fetches_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1465,6 +1509,10 @@ launch_descriptor_fetches_callback(time_t now, const or_options_t *options)
return
GREEDY_DESCRIPTOR_RETRY_INTERVAL
;
}
/**
* Periodic event: Rotate our X.509 certificates and TLS keys once every
* MAX_SSL_KEY_LIFETIME_INTERNAL.
*/
static
int
rotate_x509_certificate_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1490,6 +1538,10 @@ rotate_x509_certificate_callback(time_t now, const or_options_t *options)
return
MAX_SSL_KEY_LIFETIME_INTERNAL
;
}
/**
* Periodic callback: once an hour, grab some more entropy from the
* kernel and feed it to our CSPRNG.
**/
static
int
add_entropy_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1506,6 +1558,10 @@ add_entropy_callback(time_t now, const or_options_t *options)
return
ENTROPY_INTERVAL
;
}
/**
* Periodic callback: if we're an authority, make sure we test
* the routers on the network for reachability.
*/
static
int
launch_reachability_tests_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1517,6 +1573,10 @@ launch_reachability_tests_callback(time_t now, const or_options_t *options)
return
REACHABILITY_TEST_INTERVAL
;
}
/**
* Periodic callback: if we're an authority, discount the stability
* information (and other rephist information) that's older.
*/
static
int
downrate_stability_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1528,6 +1588,10 @@ downrate_stability_callback(time_t now, const or_options_t *options)
return
safe_timer_diff
(
now
,
next
);
}
/**
* Periodic callback: if we're an authority, record our measured stability
* information from rephist in an mtbf file.
*/
static
int
save_stability_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1540,6 +1604,10 @@ save_stability_callback(time_t now, const or_options_t *options)
return
SAVE_STABILITY_INTERVAL
;
}
/**
* Periodic callback: if we're an authority, check on our authority
* certificate (the one that authenticates our authority signing key).
*/
static
int
check_authority_cert_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1552,6 +1620,10 @@ check_authority_cert_callback(time_t now, const or_options_t *options)
return
CHECK_V3_CERTIFICATE_INTERVAL
;
}
/**
* Periodic callback: If our consensus is too old, recalculate whether
* we can actually use it.
*/
static
int
check_expired_networkstatus_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1571,6 +1643,9 @@ check_expired_networkstatus_callback(time_t now, const or_options_t *options)
return
CHECK_EXPIRED_NS_INTERVAL
;
}
/**
* Periodic callback: Write statistics to disk if appropriate.
*/
static
int
write_stats_file_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1618,6 +1693,9 @@ write_stats_file_callback(time_t now, const or_options_t *options)
return
safe_timer_diff
(
now
,
next_time_to_write_stats_files
);
}
/**
* Periodic callback: Write bridge statistics to disk if appropriate.
*/
static
int
record_bridge_stats_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1645,6 +1723,9 @@ record_bridge_stats_callback(time_t now, const or_options_t *options)
return
PERIODIC_EVENT_NO_UPDATE
;
}
/**
* Periodic callback: Clean in-memory caches every once in a while
*/
static
int
clean_caches_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1658,6 +1739,10 @@ clean_caches_callback(time_t now, const or_options_t *options)
return
CLEAN_CACHES_INTERVAL
;
}
/**
* Periodic callback: Clean the cache of failed hidden service lookups
* frequently frequently.
*/
static
int
rend_cache_failure_clean_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1669,20 +1754,21 @@ rend_cache_failure_clean_callback(time_t now, const or_options_t *options)
return
30
;
}
/**
* Periodic callback: If we're a server and initializing dns failed, retry.
*/
static
int
retry_dns_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
(
void
)
now
;
#define RETRY_DNS_INTERVAL (10*60)
/* If we're a server and initializing dns failed, retry periodically. */
if
(
server_mode
(
options
)
&&
has_dns_init_failed
())
dns_init
();
return
RETRY_DNS_INTERVAL
;
}
/* 2. Periodically, we consider force-uploading our descriptor
* (if we've passed our internal checks). */
/** Periodic callback: consider rebuilding or and re-uploading our descriptor
* (if we've passed our internal checks). */
static
int
check_descriptor_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1709,6 +1795,11 @@ check_descriptor_callback(time_t now, const or_options_t *options)
return
CHECK_DESCRIPTOR_INTERVAL
;
}
/**
* Periodic callback: check whether we're reachable (as a relay), and
* whether our bandwidth has changed enough that we need to
* publish a new descriptor.
*/
static
int
check_for_reachability_bw_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1745,13 +1836,13 @@ check_for_reachability_bw_callback(time_t now, const or_options_t *options)
return
CHECK_DESCRIPTOR_INTERVAL
;
}
/**
* Periodic event: once a minute, (or every second if TestingTorNetwork, or
* during client bootstrap), check whether we want to download any
* networkstatus documents. */
static
int
fetch_networkstatus_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
/* 2c. Every minute (or every second if TestingTorNetwork, or during
* client bootstrap), check whether we want to download any networkstatus
* documents. */
/* How often do we check whether we should download network status
* documents? */
const
int
we_are_bootstrapping
=
networkstatus_consensus_is_bootstrapping
(
...
...
@@ -1773,12 +1864,13 @@ fetch_networkstatus_callback(time_t now, const or_options_t *options)
return
networkstatus_dl_check_interval
;
}
/**
* Periodic callback: Every 60 seconds, we relaunch listeners if any died. */
static
int
retry_listeners_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
(
void
)
now
;
(
void
)
options
;
/* 3d. And every 60 seconds, we relaunch listeners if any died. */
if
(
!
net_is_disabled
())
{
retry_all_listeners
(
NULL
,
NULL
,
0
);
return
60
;
...
...
@@ -1786,6 +1878,9 @@ retry_listeners_callback(time_t now, const or_options_t *options)
return
PERIODIC_EVENT_NO_UPDATE
;
}
/**
* Periodic callback: as a server, see if we have any old unused circuits
* that should be expired */
static
int
expire_old_ciruits_serverside_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1795,6 +1890,10 @@ expire_old_ciruits_serverside_callback(time_t now, const or_options_t *options)
return
11
;
}
/**
* Periodic event: if we're an exit, see if our DNS server is telling us
* obvious lies.
*/
static
int
check_dns_honesty_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1817,6 +1916,10 @@ check_dns_honesty_callback(time_t now, const or_options_t *options)
return
12
*
3600
+
crypto_rand_int
(
12
*
3600
);
}
/**
* Periodic callback: if we're the bridge authority, write a networkstatus
* file to disk.
*/
static
int
write_bridge_ns_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1829,6 +1932,9 @@ write_bridge_ns_callback(time_t now, const or_options_t *options)
return
PERIODIC_EVENT_NO_UPDATE
;
}
/**
* Periodic callback: poke the tor-fw-helper app if we're using one.
*/
static
int
check_fw_helper_app_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -1852,7 +1958,9 @@ check_fw_helper_app_callback(time_t now, const or_options_t *options)
return
PORT_FORWARDING_CHECK_INTERVAL
;
}
/** Callback to write heartbeat message in the logs. */
/**
* Periodic callback: write the heartbeat message in the logs.
*/
static
int
heartbeat_callback
(
time_t
now
,
const
or_options_t
*
options
)
{
...
...
@@ -2358,19 +2466,26 @@ run_main_loop_once(void)
/* Make it easier to tell whether libevent failure is our fault or not. */
errno
=
0
;
#endif
/* All active linked conns should get their read events activated. */
/* All active linked conns should get their read events activated,
* so that libevent knows to run their callbacks. */
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
;
/* Make sure we know (about) what time it is. */
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. */
/* Here it is: the main loop. Here we tell Libevent to poll until we have
* an event, or the second ends, or until we have some active linked
* connections to trigger events for. Libevent will wait till one
* of these happens, then run all the appropriate callbacks. */
loop_result
=
event_base_loop
(
tor_libevent_get_base
(),
called_loop_once
?
EVLOOP_ONCE
:
0
);
/* let catch() handle things like ^c, and otherwise don't worry about it */
/* Oh, the loop failed. That might be an error that we need to
* catch, but more likely, it's just an interrupted poll() call or something,
* and we should try again. */
if
(
loop_result
<
0
)
{
int
e
=
tor_socket_errno
(
-
1
);
/* let the program survive things like ^z */
...
...
@@ -2393,9 +2508,17 @@ run_main_loop_once(void)
}
}
/* This will be pretty fast if nothing new is pending. Note that this gets
* called once per libevent loop, which will make it happen once per group
* of events that fire, or once per second. */
/* And here is where we put callbacks that happen "every time the event loop
* runs." They must be very fast, or else the whole Tor process will get
* slowed down.
*
* Note that this gets called once per libevent loop, which will make it
* happen once per group of events that fire, or once per second. */
/* If there are any pending client connections, try attaching them to
* circuits (if we can.) This will be pretty fast if nothing new is
* pending.
*/
connection_ap_attach_pending
(
0
);
return
1
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment