r8973@totoro: nickm | 2006-10-09 11:45:47 -0400

Touch up last patch (to add REASON to CIRC events): make some reasons
 more sensible, send reasons only to controllers that have enabled
 extended events, and clean up whitespace.
 
 


svn:r8672
This commit is contained in:
Nick Mathewson 2006-10-09 15:47:50 +00:00
parent b76fd968b4
commit 26283e69ba
9 changed files with 168 additions and 62 deletions

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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
* <b>event</b>. The event's body is given by <b>msg</b>. */
* <b>event</b>. The event's body is given by <b>msg</b>.
*
* 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)) {
@ -645,24 +662,17 @@ send_control1_event_string(uint16_t event, name_type_t which, const char *msg)
}
}
/* Send an event to all v1 controllers that are listening for code
* <b>event</b>. The event's body is created by the printf-style format in
* <b>format</b>, 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
* <b>event</b>. The event's body is created by the printf-style format in
* <b>format</b>, 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
* <b>event</b>. The event's body is created by the printf-style format in
* <b>format</b>, 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 <b>id</b>, 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 <b>circ</b>: 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);

View File

@ -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,

View File

@ -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);
}
/*