diff --git a/ChangeLog b/ChangeLog index 67d56e4fb..4409bdcc0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,8 @@ Changes in version 0.1.2.3-alpha - 2006-10-?? o Minor features, controller: - - Add a REASON field to CIRC events. (Patch from Mike Perry) + - Add a REASON field to CIRC events; for backward compatibility, this + field is sent only to controllers that have enabled the extended + event format. (Patch from Mike Perry) o Minor bugfixes: - Change NT service functions to be loaded on demand. This lets us diff --git a/doc/TODO b/doc/TODO index 17c080580..a15fff2aa 100644 --- a/doc/TODO +++ b/doc/TODO @@ -58,6 +58,11 @@ N . Have (and document) a BEGIN_DIR relay cell that means "Connect to your N - Send back RELAY_END cells on malformed RELAY_BEGIN. +N - Change the circuit end reason display a little for reasons from + destroyed/truncated circuits. We want to indicate both that we're + closing because somebody told us to, and why they told us they wanted to + close. + x - We should ship with a list of stable dir mirrors -- they're not trusted like the authorities, but they'll provide more robustness and diversity for bootstrapping clients. diff --git a/doc/control-spec.txt b/doc/control-spec.txt index 003f9ef23..a10774ae6 100644 --- a/doc/control-spec.txt +++ b/doc/control-spec.txt @@ -751,7 +751,7 @@ $Id$ The syntax is: - "650" SP "CIRC" SP CircuitID SP CircStatus [SP Path] + "650" SP "CIRC" SP CircuitID SP CircStatus [SP Path] [SP "REASON=" Reason] CRLF CircStatus = @@ -763,14 +763,18 @@ $Id$ Path = ServerID *("," ServerID) - Reason = "NONE" / "TORPROTOCOL" / "INTERNAL" / "REQUESTED" / + Reason = "NONE" / "TORPROTOCOL" / "INTERNAL" / "REQUESTED" / "HIBERNATING" / "RESOURCELIMIT" / "CONNECTFAILED" / "OR_IDENTITY" / "OR_CONN_CLOSED" The path is provided only when the circuit has been extended at least one hop. - Reason is provided only for FAILED and CLOSED events. + The "REASON" field is provided only for FAILED and CLOSED events, and only + if extended events are enabled (see 3.19). Clients MUST accept reasons + not listed above. + + [XXXX Explain what the reasons mean.] 4.1.2. Stream status changed diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 5acb4b93d..9a9ca59b1 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -305,6 +305,7 @@ circuit_establish_circuit(uint8_t purpose, extend_info_t *info, if (onion_pick_cpath_exit(circ, info) < 0 || onion_populate_cpath(circ) < 0) { + /* XXX should there be a 'couldn't build a path' reason? */ circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL); return NULL; } @@ -425,7 +426,8 @@ circuit_n_conn_done(or_connection_t *or_conn, int status) * set_circid_orconn here. */ circ->n_conn = or_conn; if (CIRCUIT_IS_ORIGIN(circ)) { - if ((err_reason = circuit_send_next_onion_skin(TO_ORIGIN_CIRCUIT(circ))) < 0) { + if ((err_reason = + circuit_send_next_onion_skin(TO_ORIGIN_CIRCUIT(circ))) < 0) { log_info(LD_CIRC, "send_next_onion_skin failed; circuit marked for closing."); circuit_mark_for_close(circ, -err_reason); @@ -892,7 +894,7 @@ circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer) * means that a connection broke or an extend failed. For now, * just give up. */ - circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_TORPROTOCOL); + circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_OR_CONN_CLOSED); return 0; #if 0 diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index 65e08a44e..35514e378 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -824,7 +824,7 @@ void _circuit_mark_for_close(circuit_t *circ, int reason, int line, const char *file) { - int orig_reason = reason; + int orig_reason = reason; /* Passed to the controller */ assert_circuit_ok(circ); tor_assert(line); tor_assert(file); @@ -844,10 +844,8 @@ _circuit_mark_for_close(circuit_t *circ, int reason, int line, } reason = END_CIRC_REASON_NONE; } else if (CIRCUIT_IS_ORIGIN(circ) && reason != END_CIRC_REASON_NONE) { - /* Don't warn about this; there are plenty of places where our code - * is origin-agnostic. */ - /* In fact, due to the desire to export reason information to the - * controller, it has been made even more "origin-agnostic" than before */ + /* We don't send reasons when closing circuits at the origin, but we want + * to track them anyway so we can give them to the controller. */ reason = END_CIRC_REASON_NONE; } if (reason < _END_CIRC_REASON_MIN || reason > _END_CIRC_REASON_MAX) { diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 65bf2f9e6..487692607 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -265,6 +265,7 @@ circuit_expire_building(time_t now) circuit_state_to_string(victim->state), victim->purpose); circuit_log_path(LOG_INFO,LD_CIRC,TO_ORIGIN_CIRCUIT(victim)); + /* XXXX Should there be a timeout reason? CONNECTFAILED isn't right. */ circuit_mark_for_close(victim, END_CIRC_REASON_CONNECTFAILED); } } @@ -583,6 +584,7 @@ circuit_expire_old_circuits(time_t now) log_debug(LD_CIRC, "Closing n_circ_id %d (dirty %d secs ago, purp %d)", circ->n_circ_id, (int)(now - circ->timestamp_dirty), circ->purpose); + /* XXXX Should there be a timeout reason? REQUESTED isn't right. */ circuit_mark_for_close(circ, END_CIRC_REASON_REQUESTED); } else if (!circ->timestamp_dirty && circ->state == CIRCUIT_STATE_OPEN && @@ -591,6 +593,7 @@ circuit_expire_old_circuits(time_t now) log_debug(LD_CIRC, "Closing circuit that has been unused for %d seconds.", (int)(now - circ->timestamp_created)); + /* XXXX Should there be a timeout reason? REQUESTED isn't right. */ circuit_mark_for_close(circ, END_CIRC_REASON_REQUESTED); } } diff --git a/src/or/control.c b/src/or/control.c index 64439d3b4..e839cea62 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -144,9 +144,13 @@ static int disable_log_messages = 0; static int authentication_cookie_is_set = 0; static char authentication_cookie[AUTHENTICATION_COOKIE_LEN]; -typedef enum { - SHORT_NAMES,LONG_NAMES,ALL_NAMES -} name_type_t; +#define SHORT_NAMES 1 +#define LONG_NAMES 2 +#define ALL_NAMES (SHORT_NAMES|LONG_NAMES) +#define EXTENDED_FORMAT 4 +#define NONEXTENDED_FORMAT 8 +#define ALL_FORMATS (EXTENDED_FORMAT|NONEXTENDED_FORMAT) +typedef int event_format_t; static void connection_printf_to_buf(control_connection_t *conn, const char *format, ...) @@ -164,9 +168,12 @@ static void send_control0_error(control_connection_t *conn, uint16_t error, const char *message); static void send_control0_event(uint16_t event, uint32_t len, const char *body); -static void send_control1_event(uint16_t event, name_type_t which, +static void send_control1_event(uint16_t event, event_format_t which, const char *format, ...) CHECK_PRINTF(3,4); +static void send_control1_event_extended(uint16_t event, event_format_t which, + const char *format, ...) + CHECK_PRINTF(3,4); static int handle_control_setconf(control_connection_t *conn, uint32_t len, char *body); static int handle_control_resetconf(control_connection_t *conn, uint32_t len, @@ -614,9 +621,12 @@ send_control0_event(uint16_t event, uint32_t len, const char *body) } /* Send an event to all v1 controllers that are listening for code - * event. The event's body is given by msg. */ + * event. The event's body is given by msg. + * + * docdoc which, is_extended */ static void -send_control1_event_string(uint16_t event, name_type_t which, const char *msg) +send_control1_event_string(uint16_t event, event_format_t which, + const char *msg) { connection_t **conns; int n_conns, i; @@ -629,11 +639,18 @@ send_control1_event_string(uint16_t event, name_type_t which, const char *msg) !conns[i]->marked_for_close && conns[i]->state == CONTROL_CONN_STATE_OPEN_V1) { control_connection_t *control_conn = TO_CONTROL_CONN(conns[i]); - if (which == SHORT_NAMES) { - if (control_conn->use_long_names) + if (control_conn->use_long_names) { + if (!(which & LONG_NAMES)) continue; - } else if (which == LONG_NAMES) { - if (! control_conn->use_long_names) + } else { + if (!(which & SHORT_NAMES)) + continue; + } + if (control_conn->use_extended_events) { + if (!(which & EXTENDED_FORMAT)) + continue; + } else { + if (!(which & NONEXTENDED_FORMAT)) continue; } if (control_conn->event_mask & (1<event. The event's body is created by the printf-style format in - * format, and other arguments as provided. - * - * Currently the length of the message is limited to 1024 (including the - * ending \n\r\0. */ static void -send_control1_event(uint16_t event, name_type_t which, const char *format, ...) +send_control1_event_impl(uint16_t event, event_format_t which, int extended, + const char *format, va_list ap) { #define SEND_CONTROL1_EVENT_BUFFERSIZE 1024 int r; char buf[SEND_CONTROL1_EVENT_BUFFERSIZE]; /* XXXX Length */ - va_list ap; size_t len; + char *cp; - va_start(ap, format); r = tor_vsnprintf(buf, sizeof(buf), format, ap); - va_end(ap); if (r<0) { log_warn(LD_BUG, "Unable to format event for controller."); return; @@ -676,7 +686,51 @@ send_control1_event(uint16_t event, name_type_t which, const char *format, ...) buf[SEND_CONTROL1_EVENT_BUFFERSIZE-3] = '\r'; } - send_control1_event_string(event, which, buf); + if (extended && (cp = strchr(buf, '@'))) { + which &= ~ALL_FORMATS; + *cp = ' '; + send_control1_event_string(event, which|EXTENDED_FORMAT, buf); + memcpy(cp, "\r\n\0", 3); + send_control1_event_string(event, which|NONEXTENDED_FORMAT, buf); + } else { + send_control1_event_string(event, which|ALL_FORMATS, buf); + } +} + +/* Send an event to all v1 controllers that are listening for code + * event. The event's body is created by the printf-style format in + * format, and other arguments as provided. + * + * Currently the length of the message is limited to 1024 (including the + * ending \n\r\0. */ +static void +send_control1_event(uint16_t event, event_format_t which, + const char *format, ...) +{ + va_list ap; + va_start(ap, format); + send_control1_event_impl(event, which, 0, format, ap); + va_end(ap); +} + +/* Send an event to all v1 controllers that are listening for code + * event. The event's body is created by the printf-style format in + * format, and other arguments as provided. + * + * If the format contains a single '@' character, it will be replaced with a + * space and all text after that character will be sent only to controllers + * that have enabled extended events. + * + * Currently the length of the message is limited to 1024 (including the + * ending \n\r\0. */ +static void +send_control1_event_extended(uint16_t event, event_format_t which, + const char *format, ...) +{ + va_list ap; + va_start(ap, format); + send_control1_event_impl(event, which, 1, format, ap); + va_end(ap); } /** Given a text circuit id, return the corresponding circuit. */ @@ -1009,7 +1063,8 @@ handle_control_setevents(control_connection_t *conn, uint32_t len, smartlist_free(events); } conn->event_mask = event_mask; - conn->use_extended_events = extended; + if (extended) + conn->use_extended_events = 1; control_update_global_event_mask(); send_control_done(conn); @@ -2338,7 +2393,7 @@ handle_control_usefeature(control_connection_t *conn, SMARTLIST_FOREACH(args, const char *, arg, { if (!strcasecmp(arg, "VERBOSE_NAMES")) verbose_names = 1; - else if (!strcasecmp(arg, "EXTENDED_EVENTS")) + else if (!strcasecmp(arg, "EXTENDED_FORMAT")) extended_events = 1; else { connection_printf_to_buf(conn, "552 Unrecognized feature \"%s\"\r\n", @@ -2744,11 +2799,43 @@ connection_control_process_inbuf(control_connection_t *conn) return connection_control_process_inbuf_v1(conn); } +static const char * +circuit_end_reason_to_string(int reason) +{ + switch (reason) { + case END_CIRC_AT_ORIGIN: + /* This shouldn't get passed here; it's a catch-all reason. */ + return "REASON=ORIGIN"; + case END_CIRC_REASON_NONE: + /* This shouldn't get passed here; it's a catch-all reason. */ + return "REASON=NONE"; + case END_CIRC_REASON_TORPROTOCOL: + return "REASON=TORPROTOCOL"; + case END_CIRC_REASON_INTERNAL: + return "REASON=INTERNAL"; + case END_CIRC_REASON_REQUESTED: + return "REASON=REQUESTED"; + case END_CIRC_REASON_HIBERNATING: + return "REASON=HIBERNATING"; + case END_CIRC_REASON_RESOURCELIMIT: + return "REASON=RESOURCELIMIT"; + case END_CIRC_REASON_CONNECTFAILED: + return "REASON=CONNECTFAILED"; + case END_CIRC_REASON_OR_IDENTITY: + return "REASON=OR_IDENTITY"; + case END_CIRC_REASON_OR_CONN_CLOSED: + return "REASON=OR_CONN_CLOSED"; + default: + log_warn(LD_BUG, "Unrecognized reason code %d", (int)reason); + return NULL; + } +} + /** Something has happened to circuit circ: tell any interested * control connections. */ int control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp, - int rsn) + int reason_code) { char *path=NULL, *msg; if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS)) @@ -2783,34 +2870,20 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp, return 0; } - if(tp == CIRC_EVENT_FAILED || tp == CIRC_EVENT_CLOSED) { - switch (rsn) - { - case END_CIRC_AT_ORIGIN: reason = " REASON=ORIGIN"; break; - case END_CIRC_REASON_NONE: reason = " REASON=NONE"; break; - case END_CIRC_REASON_TORPROTOCOL: reason = " REASON=TORPROTOCOL"; break; - case END_CIRC_REASON_INTERNAL: reason = " REASON=INTERNAL"; break; - case END_CIRC_REASON_REQUESTED: reason = " REASON=REQUESTED"; break; - case END_CIRC_REASON_HIBERNATING: reason = " REASON=HIBERNATING"; break; - case END_CIRC_REASON_RESOURCELIMIT: reason = " REASON=RESOURCELIMIT"; break; - case END_CIRC_REASON_CONNECTFAILED: reason = " REASON=CONNECTFAILED"; break; - case END_CIRC_REASON_OR_IDENTITY: reason = " REASON=OR_IDENTITY"; break; - case END_CIRC_REASON_OR_CONN_CLOSED: reason = " REASON=OR_CONN_CLOSED"; break; - default: - log_warn(LD_BUG, "Unrecognized reason code %d", (int)rsn); - } + if (tp == CIRC_EVENT_FAILED || tp == CIRC_EVENT_CLOSED) { + reason = circuit_end_reason_to_string(reason_code); } if (EVENT_IS_INTERESTING1S(EVENT_CIRCUIT_STATUS)) { - send_control1_event(EVENT_CIRCUIT_STATUS, SHORT_NAMES, - "650 CIRC %lu %s %s%s\r\n", + send_control1_event_extended(EVENT_CIRCUIT_STATUS, SHORT_NAMES, + "650 CIRC %lu %s %s@%s\r\n", (unsigned long)circ->global_identifier, status, path, reason); } if (EVENT_IS_INTERESTING1L(EVENT_CIRCUIT_STATUS)) { char *vpath = circuit_list_path_for_controller(circ); - send_control1_event(EVENT_CIRCUIT_STATUS, LONG_NAMES, - "650 CIRC %lu %s %s%s\r\n", + send_control1_event_extended(EVENT_CIRCUIT_STATUS, LONG_NAMES, + "650 CIRC %lu %s %s@%s\r\n", (unsigned long)circ->global_identifier, status, vpath, reason); tor_free(vpath); @@ -3097,7 +3170,7 @@ control_event_descriptors_changed(smartlist_t *routers) size_t len = strlen(ids)+32; msg = tor_malloc(len); tor_snprintf(msg, len, "650 NEWDESC %s\r\n", ids); - send_control1_event_string(EVENT_NEW_DESC, SHORT_NAMES, msg); + send_control1_event_string(EVENT_NEW_DESC, SHORT_NAMES|ALL_FORMATS, msg); tor_free(ids); tor_free(msg); } @@ -3114,7 +3187,7 @@ control_event_descriptors_changed(smartlist_t *routers) len = strlen(ids)+32; msg = tor_malloc(len); tor_snprintf(msg, len, "650 NEWDESC %s\r\n", ids); - send_control1_event_string(EVENT_NEW_DESC, LONG_NAMES, msg); + send_control1_event_string(EVENT_NEW_DESC, LONG_NAMES|ALL_FORMATS, msg); tor_free(ids); tor_free(msg); SMARTLIST_FOREACH(names, char *, cp, tor_free(cp)); @@ -3180,7 +3253,8 @@ control_event_or_authdir_new_descriptor(const char *action, buf = tor_malloc(totallen); strlcpy(buf, firstline, totallen); strlcpy(buf+strlen(firstline), esc, totallen); - send_control1_event_string(EVENT_AUTHDIR_NEWDESCS, ALL_NAMES, buf); + send_control1_event_string(EVENT_AUTHDIR_NEWDESCS, ALL_NAMES|ALL_FORMATS, + buf); tor_free(esc); tor_free(buf); diff --git a/src/or/or.h b/src/or/or.h index 913bf3d47..d3304cd69 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2069,7 +2069,7 @@ int connection_control_reached_eof(control_connection_t *conn); int connection_control_process_inbuf(control_connection_t *conn); int control_event_circuit_status(origin_circuit_t *circ, - circuit_status_event_t e, int rsn); + circuit_status_event_t e, int reason); int control_event_stream_status(edge_connection_t *conn, stream_status_event_t e); int control_event_or_conn_status(or_connection_t *conn, diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 408c1e8bf..773b25eac 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -428,6 +428,7 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request, char serviceid[REND_SERVICE_ID_LEN+1]; char hexcookie[9]; int circ_needs_uptime; + int reason = END_CIRC_REASON_TORPROTOCOL; base32_encode(serviceid, REND_SERVICE_ID_LEN+1, circuit->rend_pk_digest,10); @@ -493,12 +494,14 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request, if ((int)len != 7+DIGEST_LEN+2+klen+20+128) { log_warn(LD_PROTOCOL, "Bad length %u for version 2 INTRODUCE2 cell.", (int)len); + reason = END_CIRC_REASON_TORPROTOCOL; goto err; } extend_info->onion_key = crypto_pk_asn1_decode(buf+7+DIGEST_LEN+2, klen); if (!extend_info->onion_key) { log_warn(LD_PROTOCOL, "Error decoding onion key in version 2 INTRODUCE2 cell."); + reason = END_CIRC_REASON_TORPROTOCOL; goto err; } ptr = buf+7+DIGEST_LEN+2+klen; @@ -537,6 +540,8 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request, if (!router) { log_info(LD_REND, "Couldn't find router %s named in rendezvous cell.", escaped(rp_nickname)); + /* XXXX Add a no-such-router reason? */ + reason = END_CIRC_REASON_TORPROTOCOL; goto err; } @@ -545,6 +550,7 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request, if (len != REND_COOKIE_LEN+DH_KEY_LEN) { log_warn(LD_PROTOCOL, "Bad length %u for INTRODUCE2 cell.", (int)len); + reason = END_CIRC_REASON_TORPROTOCOL; return -1; } @@ -556,11 +562,13 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request, if (!dh || crypto_dh_generate_public(dh)<0) { log_warn(LD_BUG,"Internal error: couldn't build DH state " "or generate public key."); + reason = END_CIRC_REASON_INTERNAL; goto err; } if (crypto_dh_compute_secret(dh, ptr+REND_COOKIE_LEN, DH_KEY_LEN, keys, DIGEST_LEN+CPATH_KEY_MATERIAL_LEN)<0) { log_warn(LD_BUG, "Internal error: couldn't complete DH handshake"); + reason = END_CIRC_REASON_INTERNAL; goto err; } @@ -583,6 +591,7 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request, log_warn(LD_REND, "Giving up launching first hop of circuit to rendezvous " "point '%s' for service %s.", extend_info->nickname, serviceid); + reason = END_CIRC_REASON_CONNECTFAILED; goto err; } log_info(LD_REND, @@ -612,7 +621,7 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request, err: if (dh) crypto_dh_free(dh); if (launched) - circuit_mark_for_close(TO_CIRCUIT(launched), END_CIRC_REASON_TORPROTOCOL); + circuit_mark_for_close(TO_CIRCUIT(launched), reason); if (extend_info) extend_info_free(extend_info); return -1; } @@ -717,6 +726,7 @@ rend_service_intro_has_opened(origin_circuit_t *circuit) char buf[RELAY_PAYLOAD_SIZE]; char auth[DIGEST_LEN + 9]; char serviceid[REND_SERVICE_ID_LEN+1]; + int reason = END_CIRC_REASON_TORPROTOCOL; tor_assert(circuit->_base.purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO); tor_assert(circuit->cpath); @@ -728,6 +738,8 @@ rend_service_intro_has_opened(origin_circuit_t *circuit) if (!service) { log_warn(LD_REND, "Unrecognized service ID %s on introduction circuit %d.", serviceid, circuit->_base.n_circ_id); + /* XXXX Add a no-such-servicer reason? */ + reason = END_CIRC_REASON_CONNECTFAILED; goto err; } @@ -748,6 +760,7 @@ rend_service_intro_has_opened(origin_circuit_t *circuit) r = crypto_pk_private_sign_digest(service->private_key, buf+len, buf, len); if (r<0) { log_warn(LD_BUG, "Internal error: couldn't sign introduction request."); + reason = END_CIRC_REASON_INTERNAL; goto err; } len += r; @@ -758,12 +771,13 @@ rend_service_intro_has_opened(origin_circuit_t *circuit) log_info(LD_GENERAL, "Couldn't send introduction request for service %s on circuit %d", serviceid, circuit->_base.n_circ_id); + reason = END_CIRC_REASON_INTERNAL; goto err; } return; err: - circuit_mark_for_close(TO_CIRCUIT(circuit), END_CIRC_REASON_TORPROTOCOL); + circuit_mark_for_close(TO_CIRCUIT(circuit), reason); } /** Called when we get an INTRO_ESTABLISHED cell; mark the circuit as a @@ -808,6 +822,7 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit) crypt_path_t *hop; char serviceid[REND_SERVICE_ID_LEN+1]; char hexcookie[9]; + int reason; tor_assert(circuit->_base.purpose == CIRCUIT_PURPOSE_S_CONNECT_REND); tor_assert(circuit->cpath); @@ -828,6 +843,7 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit) if (!service) { log_warn(LD_GENERAL, "Internal error: unrecognized service ID on " "introduction circuit."); + reason = END_CIRC_REASON_INTERNAL; goto err; } @@ -836,6 +852,7 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit) if (crypto_dh_get_public(hop->dh_handshake_state, buf+REND_COOKIE_LEN, DH_KEY_LEN)<0) { log_warn(LD_GENERAL,"Couldn't get DH public key."); + reason = END_CIRC_REASON_INTERNAL; goto err; } memcpy(buf+REND_COOKIE_LEN+DH_KEY_LEN, hop->handshake_digest, @@ -847,6 +864,7 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit) buf, REND_COOKIE_LEN+DH_KEY_LEN+DIGEST_LEN, circuit->cpath->prev)<0) { log_warn(LD_GENERAL, "Couldn't send RENDEZVOUS1 cell."); + reason = END_CIRC_REASON_INTERNAL; goto err; } @@ -869,7 +887,7 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit) return; err: - circuit_mark_for_close(TO_CIRCUIT(circuit), END_CIRC_REASON_TORPROTOCOL); + circuit_mark_for_close(TO_CIRCUIT(circuit), reason); } /*