return 0;
}
-/** Find circuits that are waiting on <b>or_conn</b> to become open,
- * if any, and get them to send their create cells forward.
+/** Find any circuits that are waiting on <b>or_conn</b> to become
+ * open and get them to send their create cells forward.
*
* Status is 1 if connect succeeded, or 0 if connect failed.
*/
changed = 1;
if (changed) {
- log_fn(severity, LD_CIRC, " (%d/%d helpers are usable)",
+ log_fn(severity, LD_CIRC, " (%d/%d helpers are usable/new)",
num_live_helpers(), smartlist_len(helper_nodes));
helper_nodes_changed();
}
/** Called when a connection to an OR with the identity digest <b>digest</b>
* is established (<b>succeeded</b>==1) or has failed (<b>succeeded</b>==0).
* If the OR is a helper, change that helper's up/down status.
+ * Return 0 normally, or -1 if we want to tear down the new connection.
*/
-void
+int
helper_node_set_status(const char *digest, int succeeded)
{
int changed = 0;
+ int refuse_conn = 0;
if (! helper_nodes)
- return;
+ return 0;
SMARTLIST_FOREACH(helper_nodes, helper_node_t *, helper,
{
if (!memcmp(helper->identity, digest, DIGEST_LEN)) {
if (succeeded) {
if (!helper->made_contact) {
+ /* We've just added a new long-term helper node. Perhaps
+ * the network just came back? We should give our earlier
+ * helpers another try too, and close this connection so
+ * we don't use it before we've given the others a shot. */
helper->made_contact = 1;
- /* We've just added a new long-term helper node.
- * Perhaps the network just came back? We should
- * give our earlier helpers another try too. */
+ refuse_conn = 1;
SMARTLIST_FOREACH(helper_nodes, helper_node_t *, h,
{
routerinfo_t *r = router_get_by_digest(h->identity);
- h->down_since = 0;
- if (r) r->is_running = 1;
+ if (h->made_contact) {
+ h->down_since = 0;
+ if (r) r->is_running = 1;
+ }
if (h == helper)
break;
});
+ notice(LD_CIRC,
+ "Connected to new helper node '%s'. Marking earlier "
+ "helpers up. %d/%d helpers usable/new.", helper->nickname,
+ num_live_helpers(), smartlist_len(helper_nodes));
changed = 1;
}
if (helper->down_since) {
/*XXXX shouldn't be so loud. NM */
notice(LD_CIRC,
"Connection to formerly down helper node '%s' succeeded. "
- "%d/%d helpers usable.", helper->nickname,
+ "%d/%d helpers usable/new.", helper->nickname,
num_live_helpers(), smartlist_len(helper_nodes));
helper->down_since = 0;
changed = 1;
if (!helper->made_contact) { /* dump him */
notice(LD_CIRC,
"Connection to never-contacted helper node '%s' failed. "
- "Removing from the list. %d/%d helpers usable.",
+ "Removing from the list. %d/%d helpers usable/new.",
helper->nickname,
num_live_helpers()-1, smartlist_len(helper_nodes)-1);
tor_free(helper);
} else if (!helper->down_since) {
helper->down_since = time(NULL);
warn(LD_CIRC, "Connection to helper node '%s' failed."
- " %d/%d helpers usable.",
+ " %d/%d helpers usable/new.",
helper->nickname,
num_live_helpers(), smartlist_len(helper_nodes));
changed = 1;
if (changed)
helper_nodes_changed();
+ return refuse_conn ? -1 : 0;
}
/** Pick a live (up and listed) helper node from the list of helpers, and
connection_tls_finish_handshake(connection_t *conn)
{
char digest_rcvd[DIGEST_LEN];
+ int started_here = connection_or_nonopen_was_started_here(conn);
debug(LD_OR,"tls handshake done. verifying.");
if (connection_or_check_valid_handshake(conn, digest_rcvd) < 0)
return -1;
- if (!connection_or_nonopen_was_started_here(conn)) {
+ if (!started_here) {
#if 0
connection_t *c;
if ((c=connection_or_get_by_identity_digest(digest_rcvd))) {
directory_set_dirty();
conn->state = OR_CONN_STATE_OPEN;
+ control_event_or_conn_status(conn, OR_CONN_EVENT_CONNECTED);
+ if (started_here) {
+ rep_hist_note_connect_succeeded(conn->identity_digest, time(NULL));
+ if (helper_node_set_status(conn->identity_digest, 1) < 0) {
+ /* pending circs get closed in circuit_about_to_close_connection() */
+ return -1;
+ }
+ }
connection_watch_events(conn, EV_READ);
circuit_n_conn_done(conn, 1); /* send the pending creates, if any. */
- rep_hist_note_connect_succeeded(conn->identity_digest, time(NULL));
- helper_node_set_status(conn->identity_digest, 1);
- control_event_or_conn_status(conn, OR_CONN_EVENT_CONNECTED);
return 0;
}
/** Pack <b>cell</b> into wire-format, and write it onto <b>conn</b>'s
* outbuf.
*
- * (Commented out) If it's an OR conn, and an entire TLS record is
+ * If it's an OR conn, and an entire TLS record is
* ready, then try to flush the record now.
*/
void