r9303@Kushana: nickm | 2006-10-20 12:07:34 -0400

Start implementing reason extension for stream events to match the one one used by circuit events. (Not a complete implementation yet; actual reasons are not passed to control.c)


svn:r8777
This commit is contained in:
Nick Mathewson 2006-10-20 17:54:36 +00:00
parent c8c36dd227
commit 12af87539b
5 changed files with 88 additions and 14 deletions

View File

@ -835,6 +835,7 @@ $Id$
The syntax is:
"650" SP "STREAM" SP StreamID SP StreamStatus SP CircID SP Target
[SP "REASON=" Reason [ SP "REMOTE_REASON=" Reason ]] CRLF
StreamStatus =
"NEW" / ; New request to connect
@ -851,6 +852,24 @@ $Id$
The circuit ID designates which circuit this stream is attached to. If
the stream is unattached, the circuit ID "0" is given.
Reason = "MISC" / "RESOLVEFAILED" / "CONNECTREFUSED" /
"EXITPOLICY" / "DESTROY" / "DONE" / "TIMEOUT" /
"HIBERNATING" / "INTERNAL"/ "RESOURCELIMIT" /
"CONNRESET" / "TORPROTOCOL" / "NOTDIRECTORY" / "END"
The "REASON" field is provided only for FAILED, CLOSED, and DETACHED
events, and only if extended events are enabled (see 3.19). Clients MUST
accept reasons not listed above. Reasons are as given in tor-spec.txt,
except for:
END (We received a RELAY_END cell from the other side of thise
stream.)
The "REMOTE_REASON" field is provided only when we receive a RELAY_END
cell, and only if extended events are enabled. It contains the actual
reason given by the remote OR for closing the stream. Clients MUST accept
reasons not listed above. Reasons are as listed in tor-spec.txt.
4.1.3. OR Connection status changed
The syntax is:

View File

@ -458,9 +458,9 @@ connection_about_to_close_connection(connection_t *conn)
log_warn(LD_BUG,"Bug: Closing stream (marked at %s:%d) without sending"
" back a socks reply.",
conn->marked_for_close_file, conn->marked_for_close);
} else {
control_event_stream_status(edge_conn, STREAM_EVENT_CLOSED);
}
control_event_stream_status(edge_conn, STREAM_EVENT_CLOSED,
END_STREAM_REASON_FIXME_XXXX);
break;
case CONN_TYPE_EXIT:
edge_conn = TO_EDGE_CONN(conn);

View File

@ -498,7 +498,8 @@ circuit_discard_optional_exit_enclaves(extend_info_t *info)
int
connection_ap_detach_retriable(edge_connection_t *conn, origin_circuit_t *circ)
{
control_event_stream_status(conn, STREAM_EVENT_FAILED_RETRIABLE);
control_event_stream_status(conn, STREAM_EVENT_FAILED_RETRIABLE,
END_STREAM_REASON_FIXME_XXXX);
conn->_base.timestamp_lastread = time(NULL);
if (! get_options()->LeaveStreamsUnattached) {
conn->_base.state = AP_CONN_STATE_CIRCUIT_WAIT;
@ -1436,9 +1437,9 @@ connection_ap_handshake_process_socks(edge_connection_t *conn)
} /* else socks handshake is done, continue processing */
if (socks->command == SOCKS_COMMAND_CONNECT)
control_event_stream_status(conn, STREAM_EVENT_NEW);
control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
else
control_event_stream_status(conn, STREAM_EVENT_NEW_RESOLVE);
control_event_stream_status(conn, STREAM_EVENT_NEW_RESOLVE, 0);
if (options->LeaveStreamsUnattached) {
conn->_base.state = AP_CONN_STATE_CONTROLLER_WAIT;
@ -1480,7 +1481,7 @@ connection_ap_process_transparent(edge_connection_t *conn)
}
/* we have the original destination */
control_event_stream_status(conn, STREAM_EVENT_NEW);
control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
if (options->LeaveStreamsUnattached) {
conn->_base.state = AP_CONN_STATE_CONTROLLER_WAIT;
@ -1557,7 +1558,7 @@ connection_ap_handshake_send_begin(edge_connection_t *ap_conn,
ap_conn->_base.state = AP_CONN_STATE_CONNECT_WAIT;
log_info(LD_APP,"Address/port sent, ap socket %d, n_circ_id %d",
ap_conn->_base.s, circ->_base.n_circ_id);
control_event_stream_status(ap_conn, STREAM_EVENT_SENT_CONNECT);
control_event_stream_status(ap_conn, STREAM_EVENT_SENT_CONNECT, 0);
return 0;
}
@ -1623,7 +1624,7 @@ connection_ap_handshake_send_resolve(edge_connection_t *ap_conn,
ap_conn->_base.state = AP_CONN_STATE_RESOLVE_WAIT;
log_info(LD_APP,"Address sent for resolve, ap socket %d, n_circ_id %d",
ap_conn->_base.s, circ->_base.n_circ_id);
control_event_stream_status(ap_conn, STREAM_EVENT_SENT_RESOLVE);
control_event_stream_status(ap_conn, STREAM_EVENT_SENT_RESOLVE, 0);
return 0;
}
@ -1781,7 +1782,8 @@ connection_ap_handshake_socks_reply(edge_connection_t *conn, char *reply,
tor_assert(conn->socks_request); /* make sure it's an AP stream */
control_event_stream_status(conn,
status==SOCKS5_SUCCEEDED ? STREAM_EVENT_SUCCEEDED : STREAM_EVENT_FAILED);
status==SOCKS5_SUCCEEDED ? STREAM_EVENT_SUCCEEDED : STREAM_EVENT_FAILED,
END_STREAM_REASON_FIXME_XXXX);
if (conn->socks_request->has_finished) {
log_warn(LD_BUG, "Harmless bug: duplicate calls to "

View File

@ -2946,10 +2946,34 @@ write_stream_target_to_buf(edge_connection_t *conn, char *buf, size_t len)
return 0;
}
/* DOCDOC */
static const char *
stream_end_reason_to_string(int reason)
{
reason &= ~END_CIRC_REASON_FLAG_REMOTE;
switch (reason) {
case END_STREAM_REASON_MISC: return "MISC";
case END_STREAM_REASON_RESOLVEFAILED: return "RESOLVEFAILED";
case END_STREAM_REASON_CONNECTREFUSED: return "CONNECTREFUSED";
case END_STREAM_REASON_EXITPOLICY: return "EXITPOLICY";
case END_STREAM_REASON_DESTROY: return "DESTROY";
case END_STREAM_REASON_DONE: return "DONE";
case END_STREAM_REASON_TIMEOUT: return "TIMEOUT";
case END_STREAM_REASON_HIBERNATING: return "HIBERNATING";
case END_STREAM_REASON_INTERNAL: return "INTERNAL";
case END_STREAM_REASON_RESOURCELIMIT: return "RESOURCELIMIT";
case END_STREAM_REASON_CONNRESET: return "CONNRESET";
case END_STREAM_REASON_TORPROTOCOL: return "TORPROTOCOL";
case END_STREAM_REASON_NOTDIRECTORY: return "NOTDIRECTORY";
default: return NULL;
}
}
/** Something has happened to the stream associated with AP connection
* <b>conn</b>: tell any interested control connections. */
int
control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp)
control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp,
int reason_code)
{
char *msg;
size_t len;
@ -2971,9 +2995,11 @@ control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp)
tor_free(msg);
}
if (EVENT_IS_INTERESTING1(EVENT_STREAM_STATUS)) {
char reason_buf[64];
const char *status;
circuit_t *circ;
origin_circuit_t *origin_circ = NULL;
reason_buf[0] = '\0';
switch (tp)
{
case STREAM_EVENT_SENT_CONNECT: status = "SENTCONNECT"; break;
@ -2988,15 +3014,33 @@ control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp)
log_warn(LD_BUG, "Unrecognized status code %d", (int)tp);
return 0;
}
if (reason_code && (tp == STREAM_EVENT_FAILED ||
tp == STREAM_EVENT_CLOSED ||
tp == STREAM_EVENT_FAILED_RETRIABLE)) {
const char *reason_str = stream_end_reason_to_string(reason_code);
char *r = NULL;
if (!reason_str) {
r = tor_malloc(16);
tor_snprintf(r, 16, "UNKNOWN_%d", reason_code);
reason_str = r;
}
if (reason_code & END_STREAM_REASON_FLAG_REMOTE)
tor_snprintf(reason_buf, sizeof(reason_buf),
"REASON=END REMOTE_REASON=%s", reason_str);
else
tor_snprintf(reason_buf, sizeof(reason_buf),
"REASON=%s", reason_str);
tor_free(r);
}
circ = circuit_get_by_edge_conn(conn);
if (circ && CIRCUIT_IS_ORIGIN(circ))
origin_circ = TO_ORIGIN_CIRCUIT(circ);
send_control1_event(EVENT_STREAM_STATUS, ALL_NAMES,
"650 STREAM %lu %s %lu %s\r\n",
send_control1_event_extended(EVENT_STREAM_STATUS, ALL_NAMES,
"650 STREAM %lu %s %lu %s@%s\r\n",
(unsigned long)conn->global_identifier, status,
origin_circ?
(unsigned long)origin_circ->global_identifier : 0ul,
buf);
buf, reason_buf);
/* XXX need to specify its intended exit, etc? */
}
return 0;

View File

@ -464,6 +464,10 @@ typedef enum {
#define RELAY_COMMAND_RENDEZVOUS_ESTABLISHED 39
#define RELAY_COMMAND_INTRODUCE_ACK 40
/* XXXX Placeholder: remove me as soon as we have correct reasons sent
* everywhere. */
#define END_STREAM_REASON_FIXME_XXXX 0
#define END_STREAM_REASON_MISC 1
#define END_STREAM_REASON_RESOLVEFAILED 2
#define END_STREAM_REASON_CONNECTREFUSED 3
@ -479,6 +483,10 @@ typedef enum {
#define END_STREAM_REASON_TORPROTOCOL 13
#define END_STREAM_REASON_NOTDIRECTORY 14
/* OR this with the argument to control_event_stream_status to indicate that
* the reason came from an END cell. */
#define END_STREAM_REASON_FLAG_REMOTE 512
/* These high-numbered end reasons are not part of the official spec,
* and are not intended to be put in relay end cells. They are here
* to be more informative when sending back socks replies to the
@ -2089,7 +2097,8 @@ int connection_control_process_inbuf(control_connection_t *conn);
int control_event_circuit_status(origin_circuit_t *circ,
circuit_status_event_t e, int reason);
int control_event_stream_status(edge_connection_t *conn,
stream_status_event_t e);
stream_status_event_t e,
int reason);
int control_event_or_conn_status(or_connection_t *conn,
or_conn_status_event_t e);
int control_event_bandwidth_used(uint32_t n_read, uint32_t n_written);