log_fn(LOG_INFO,"circuit built!");
circuit_reset_failure_count(0);
if (!has_completed_circuit) {
+ or_options_t *options = get_options();
has_completed_circuit=1;
log_fn(LOG_NOTICE,"Tor has successfully opened a circuit. Looks like it's working.");
/* XXX009 Log a count of known routers here */
+ if (server_mode(options) && !check_whether_ports_reachable())
+ log_fn(LOG_NOTICE,"Now checking whether ORPort %s %s reachable...",
+ options->DirPort ? "and DirPort" : "",
+ options->DirPort ? "are" : "is");
}
circuit_rep_hist_note_result(circ);
circuit_has_opened(circ); /* do other actions as necessary */
connection_edge_end_errno(conn, conn->cpath_layer);
connection_close_immediate(conn); /* Don't flush; connection is dead. */
- conn->has_sent_end = 1;
connection_mark_for_close(conn);
return -1;
}
size_t bytes_written;
size_t bytes_read;
int seconds_elapsed;
+ or_options_t *options = get_options();
if (!timeout_event) {
timeout_event = tor_malloc_zero(sizeof(struct event));
evtimer_set(timeout_event, second_elapsed_callback, NULL);
seconds_elapsed = current_second ? (now.tv_sec - current_second) : 0;
stats_n_bytes_read += bytes_read;
stats_n_bytes_written += bytes_written;
- if (accounting_is_enabled(get_options()))
+ if (accounting_is_enabled(options))
accounting_add_bytes(bytes_read, bytes_written, seconds_elapsed);
control_event_bandwidth_used((uint32_t)bytes_read,(uint32_t)bytes_written);
stats_prev_global_read_bucket = global_read_bucket;
stats_prev_global_write_bucket = global_write_bucket;
+#define TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT (20*60) /* 20 minutes */
+ if (server_mode(options) &&
+ stats_n_seconds_working < TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT &&
+ stats_n_seconds_working+seconds_elapsed >=
+ TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT &&
+ !check_whether_ports_reachable()) {
+ routerinfo_t *me = router_get_my_routerinfo();
+ tor_assert(me);
+ log_fn(LOG_WARN,"Your server (%s:%d) has not managed to confirm that it is reachable. Please check your firewalls, ports, address, etc.", me->address, me->or_port);
+ }
+
/* if more than 10s have elapsed, probably the clock jumped: doesn't count. */
if (seconds_elapsed < 100)
stats_n_seconds_working += seconds_elapsed;
int e = errno;
/* let the program survive things like ^z */
if (e != EINTR) {
- log_fn(LOG_ERR,"poll failed: %s [%d]",
+ log_fn(LOG_ERR,"event poll failed: %s [%d]",
tor_socket_strerror(e), e);
return -1;
} else {
- log_fn(LOG_DEBUG,"poll interrupted.");
+ log_fn(LOG_DEBUG,"event poll interrupted.");
/* You can't trust the results of this poll(). Go back to the
* top of the big for loop. */
continue;
crypto_pk_env_t *init_key_from_file(const char *fname);
int init_keys(void);
+int check_whether_ports_reachable(void);
void consider_testing_reachability(void);
void router_orport_found_reachable(void);
void router_dirport_found_reachable(void);
/** Whether we can reach our DirPort from the outside. */
static int can_reach_dir_port = 0;
+/** Return 1 if all open ports are known reachable; else return 0. */
+int check_whether_ports_reachable(void) {
+ if (!can_reach_or_port)
+ return 0;
+ if (get_options()->DirPort && !can_reach_dir_port)
+ return 0;
+ return 1;
+}
+
void consider_testing_reachability(void) {
routerinfo_t *me = router_get_my_routerinfo();
}
}
+static void ports_now_reachable(void) {
+ log_fn(LOG_NOTICE,"Your server is reachable. Publishing server descriptor.");
+}
+
/** Annotate that we found our ORPort reachable. */
void router_orport_found_reachable(void) {
if (!can_reach_or_port) {
log_fn(LOG_NOTICE,"Your ORPort is reachable from the outside. Excellent.");
can_reach_or_port = 1;
+ if (check_whether_ports_reachable())
+ ports_now_reachable();
}
}
if (!can_reach_dir_port) {
log_fn(LOG_NOTICE,"Your DirPort is reachable from the outside. Excellent.");
can_reach_dir_port = 1;
+ if (check_whether_ports_reachable())
+ ports_now_reachable();
}
}
if (options->AuthoritativeDir)
return 1;
- if (!can_reach_or_port)
- return 0;
- if (options->DirPort && !can_reach_dir_port)
- return 0;
-
- return 1;
+ return check_whether_ports_reachable();
}
void consider_publishable_server(time_t now, int force) {