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:
parent
b76fd968b4
commit
26283e69ba
|
@ -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
|
||||
|
|
5
doc/TODO
5
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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
168
src/or/control.c
168
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
|
||||
* <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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue