/** Do common setup for test_timely_consensus() and * test_early_consensus(). Call networkstatus_set_current_consensus() * on a constructed consensus and with an appropriately-modified * approx_time. Callers expect presence or absence of appropriate log * messages and control events. */ static int test_skew_common(void *arg, time_t now, unsigned long *offset) { char *consensus = NULL; int retval = 0; *offset = strtoul(arg, NULL, 10); /* Initialize the SRV subsystem */ MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m); mock_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1, strlen(AUTHORITY_CERT_1), NULL); sr_init(0); UNMOCK(get_my_v3_authority_cert); construct_consensus(&consensus, now); tt_assert(consensus); update_approx_time(now + *offset); mock_apparent_skew = 0; /* Caller will call UNMOCK() */ MOCK(clock_skew_warning, mock_clock_skew_warning); /* Caller will call teardown_capture_of_logs() */ setup_capture_of_logs(LOG_WARN); retval = networkstatus_set_current_consensus(consensus, strlen(consensus), "microdesc", 0, NULL); done: tor_free(consensus); return retval; }
/* * normally tor calls event_base_loopexit so control returns from the libevent * event loop back to the tor main loop. tor then activates "linked" socket * connections before returning back to the libevent event loop. * * we hijack and use the libevent loop in nonblock mode, so when tor calls * the loopexit, we basically just need to do the linked connection activation. * that is extracted to scalliontor_loopexitCallback, which we need to execute * as a callback so we don't invoke event_base_loop while it is currently being * executed. */ static void scalliontor_loopexitCallback(ScallionTor* stor) { update_approx_time(time(NULL)); scalliontor_notify(stor); while(1) { /* 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)); /* if linked conns are still active, enter libevent loop using EVLOOP_ONCE */ called_loop_once = smartlist_len(active_linked_connection_lst) ? 1 : 0; if(called_loop_once) { event_base_loop(tor_libevent_get_base(), EVLOOP_ONCE|EVLOOP_NONBLOCK); } else { /* linked conns are done */ break; } } /* make sure we handle any new events caused by the linked conns */ scalliontor_notify(stor); }
/** Test that we will use our directory guards to fetch mds even if we don't * have any dirinfo (tests bug #23862). */ static void test_directory_guard_fetch_with_no_dirinfo(void *arg) { int retval; char *consensus_text_md = NULL; or_options_t *options = get_options_mutable(); time_t now = time(NULL); (void) arg; hibernate_set_state_for_testing_(HIBERNATE_STATE_LIVE); /* Initialize the SRV subsystem */ MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m); mock_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1, strlen(AUTHORITY_CERT_1), NULL); sr_init(0); UNMOCK(get_my_v3_authority_cert); /* Initialize the entry node configuration from the ticket */ options->UseEntryGuards = 1; options->StrictNodes = 1; get_options_mutable()->EntryNodes = routerset_new(); routerset_parse(get_options_mutable()->EntryNodes, "2121212121212121212121212121212121212121", "foo"); /* Mock some functions */ dummy_state = tor_malloc_zero(sizeof(or_state_t)); MOCK(get_or_state, get_or_state_replacement); MOCK(directory_initiate_request, mock_directory_initiate_request); /* we need to mock this one to avoid memleaks */ MOCK(circuit_guard_state_new, mock_circuit_guard_state_new); /* Call guards_update_all() to simulate loading our state file (see * entry_guards_load_guards_from_state() and ticket #23989). */ guards_update_all(); /* Test logic: Simulate the arrival of a new consensus when we have no * dirinfo at all. Tor will need to fetch the mds from the consensus. Make * sure that Tor will use the specified entry guard instead of relying on the * fallback directories. */ /* Fixup the dirconn that will deliver the consensus */ dir_connection_t *conn = dir_connection_new(AF_INET); tor_addr_from_ipv4h(&conn->base_.addr, 0x7f000001); conn->base_.port = 8800; TO_CONN(conn)->address = tor_strdup("127.0.0.1"); conn->base_.purpose = DIR_PURPOSE_FETCH_CONSENSUS; conn->requested_resource = tor_strdup("ns"); /* Construct a consensus */ construct_consensus(&consensus_text_md, now); tt_assert(consensus_text_md); /* Place the consensus in the dirconn */ response_handler_args_t args; memset(&args, 0, sizeof(response_handler_args_t)); args.status_code = 200; args.body = consensus_text_md; args.body_len = strlen(consensus_text_md); /* Update approx time so that the consensus is considered live */ update_approx_time(now+1010); setup_capture_of_logs(LOG_DEBUG); /* Now handle the consensus */ retval = handle_response_fetch_consensus(conn, &args); tt_int_op(retval, OP_EQ, 0); /* Make sure that our primary guard was chosen */ expect_log_msg_containing("Selected primary guard router3"); done: tor_free(consensus_text_md); tor_free(dummy_state); connection_free_minimal(TO_CONN(conn)); entry_guards_free_all(); teardown_capture_of_logs(); }
void scalliontor_notify(ScallionTor* stor) { update_approx_time(time(NULL)); /* tell libevent to check epoll and activate the ready sockets without blocking */ event_base_loop(tor_libevent_get_base(), EVLOOP_NONBLOCK); }
gint scalliontor_start(ScallionTor* stor, gint argc, gchar *argv[]) { time_t now = time(NULL); update_approx_time(now); tor_threads_init(); init_logging(); /* tor_init() loses our logging, so set it before AND after */ scalliontor_setLogging(); if (tor_init(argc, argv) < 0) { return -1; } // scalliontor_setLogging(); /* load the private keys, if we're supposed to have them, and set up the * TLS context. */ gpointer idkey; #ifdef SCALLION_NEWIDKEYNAME idkey = client_identitykey; #else idkey = identitykey; #endif if (idkey == NULL) { if (init_keys() < 0) { log_err(LD_BUG,"Error initializing keys; exiting"); return -1; } } /* Set up the packed_cell_t memory pool. */ init_cell_pool(); /* Set up our buckets */ connection_bucket_init(); stats_prev_global_read_bucket = global_read_bucket; stats_prev_global_write_bucket = global_write_bucket; /* initialize the bootstrap status events to know we're starting up */ control_event_bootstrap(BOOTSTRAP_STATUS_STARTING, 0); if (trusted_dirs_reload_certs()) { log_warn(LD_DIR, "Couldn't load all cached v3 certificates. Starting anyway."); } #ifndef SCALLION_NOV2DIR if (router_reload_v2_networkstatus()) { return -1; } #endif if (router_reload_consensus_networkstatus()) { return -1; } /* load the routers file, or assign the defaults. */ if (router_reload_router_list()) { return -1; } /* load the networkstatuses. (This launches a download for new routers as * appropriate.) */ directory_info_has_arrived(now, 1); /* !note that scallion intercepts the cpuworker functionality (rob) */ if (server_mode(get_options())) { /* launch cpuworkers. Need to do this *after* we've read the onion key. */ cpu_init(); } /* set up once-a-second callback. */ if (! second_timer) { // struct timeval one_second; // one_second.tv_sec = 1; // one_second.tv_usec = 0; // // second_timer = periodic_timer_new(tor_libevent_get_base(), // &one_second, // second_elapsed_callback, // NULL); // tor_assert(second_timer); _scalliontor_secondCallback(stor); } #ifdef SCALLION_DOREFILLCALLBACKS #ifndef USE_BUFFEREVENTS if (!refill_timer) { int msecs = get_options()->TokenBucketRefillInterval; // struct timeval refill_interval; // // refill_interval.tv_sec = msecs/1000; // refill_interval.tv_usec = (msecs%1000)*1000; // // refill_timer = periodic_timer_new(tor_libevent_get_base(), // &refill_interval, // refill_callback, // NULL); // tor_assert(refill_timer); stor->refillmsecs = msecs; _scalliontor_refillCallback(stor); } #endif #endif /* run the startup events */ scalliontor_notify(stor); return 0; }