summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/or/connection.c15
-rw-r--r--src/or/connection_edge.c19
-rw-r--r--src/or/dns.c2
-rw-r--r--src/or/hibernate.c3
-rw-r--r--src/or/or.h6
-rw-r--r--src/or/relay.c12
6 files changed, 34 insertions, 23 deletions
diff --git a/src/or/connection.c b/src/or/connection.c
index 79c98fd280..75c61b4daa 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -913,9 +913,7 @@ loop_again:
/* There's a read error; kill the connection.*/
connection_close_immediate(conn); /* Don't flush; connection is dead. */
if (CONN_IS_EDGE(conn)) {
- connection_edge_end(conn, (char)(connection_state_is_open(conn) ?
- END_STREAM_REASON_MISC : END_STREAM_REASON_CONNECTREFUSED),
- conn->cpath_layer);
+ connection_edge_end_errno(conn, conn->cpath_layer);
}
connection_mark_for_close(conn);
return -1;
@@ -1083,7 +1081,7 @@ int connection_handle_write(connection_t *conn) {
if (getsockopt(conn->s, SOL_SOCKET, SO_ERROR, (void*)&e, &len) < 0) {
log_fn(LOG_WARN,"getsockopt() syscall failed?! Please report to tor-ops.");
if (CONN_IS_EDGE(conn))
- connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
+ connection_edge_end_errno(conn, conn->cpath_layer);
connection_mark_for_close(conn);
return -1;
}
@@ -1092,8 +1090,7 @@ int connection_handle_write(connection_t *conn) {
if (!ERRNO_IS_CONN_EINPROGRESS(e)) {
log_fn(LOG_INFO,"in-progress connect failed. Removing.");
if (CONN_IS_EDGE(conn))
- connection_edge_end(conn, END_STREAM_REASON_CONNECTREFUSED,
- conn->cpath_layer);
+ connection_edge_end_errno(conn, conn->cpath_layer);
connection_close_immediate(conn);
connection_mark_for_close(conn);
@@ -1157,11 +1154,9 @@ int connection_handle_write(connection_t *conn) {
} else {
result = flush_buf(conn->s, conn->outbuf, &conn->outbuf_flushlen);
if (result < 0) {
- /* XXXX Is this right? -NM
if (CONN_IS_EDGE(conn))
- connection_edge_end(conn, END_STREAM_REASON_MISC,
- conn->cpath_layer);
- */
+ connection_edge_end_errno(conn, conn->cpath_layer);
+
connection_close_immediate(conn); /* Don't flush; connection is dead. */
conn->has_sent_end = 1;
connection_mark_for_close(conn);
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 937b282e10..c30fd5285c 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -78,6 +78,7 @@ int connection_edge_process_inbuf(connection_t *conn, int package_partial) {
case AP_CONN_STATE_OPEN:
case EXIT_CONN_STATE_OPEN:
if (connection_edge_package_raw_inbuf(conn, package_partial) < 0) {
+ /* XXXX We can't tell *why* package failed. -NM */
connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
connection_mark_for_close(conn);
return -1;
@@ -96,7 +97,7 @@ int connection_edge_process_inbuf(connection_t *conn, int package_partial) {
#ifdef TOR_FRAGILE
tor_assert(0);
#endif
- connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
+ connection_edge_end(conn, END_STREAM_REASON_INTERNAL, conn->cpath_layer);
connection_mark_for_close(conn);
return -1;
}
@@ -161,6 +162,17 @@ connection_edge_end(connection_t *conn, char reason, crypt_path_t *cpath_layer)
return 0;
}
+/** DOCDOC **/
+int
+connection_edge_end_errno(connection_t *conn, crypt_path_t *cpath_layer)
+{
+ uint8_t reason;
+ tor_assert(conn);
+ reason = (uint8_t)errno_to_end_reason(tor_socket_errno(conn->s));
+ return connection_edge_end(conn, reason, cpath_layer);
+}
+
+
/** Connection <b>conn</b> has finished writing and has no bytes left on
* its outbuf.
*
@@ -1036,7 +1048,7 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
/* default to failed, change in dns_resolve if it turns out not to fail */
if (we_are_hibernating()) {
- connection_edge_end(n_stream, END_STREAM_REASON_EXITPOLICY, n_stream->cpath_layer);
+ connection_edge_end(n_stream, END_STREAM_REASON_HIBERNATING, n_stream->cpath_layer);
connection_free(n_stream);
return 0;
}
@@ -1156,8 +1168,7 @@ connection_exit_connect(connection_t *conn) {
log_fn(LOG_DEBUG,"about to try connecting");
switch (connection_connect(conn, conn->address, addr, port)) {
case -1:
- connection_edge_end(conn, END_STREAM_REASON_CONNECTREFUSED,
- conn->cpath_layer);
+ connection_edge_end_errno(conn, conn->cpath_layer);
circuit_detach_stream(circuit_get_by_conn(conn), conn);
connection_free(conn);
return;
diff --git a/src/or/dns.c b/src/or/dns.c
index 71dff34009..1c0310ef65 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -154,7 +154,7 @@ static void purge_expired_resolves(uint32_t now) {
/* Connections should only be pending if they have no socket. */
tor_assert(pend->conn->s == -1);
pendconn = pend->conn;
- connection_edge_end(pendconn, END_STREAM_REASON_MISC,
+ connection_edge_end(pendconn, END_STREAM_REASON_TIMEOUT,
pendconn->cpath_layer);
circuit_detach_stream(circuit_get_by_conn(pendconn), pendconn);
connection_free(pendconn);
diff --git a/src/or/hibernate.c b/src/or/hibernate.c
index 1867aec0d9..cb96bf39d6 100644
--- a/src/or/hibernate.c
+++ b/src/or/hibernate.c
@@ -739,7 +739,8 @@ hibernate_go_dormant(time_t now) {
(conn = connection_get_by_type(CONN_TYPE_AP)) ||
(conn = connection_get_by_type(CONN_TYPE_EXIT))) {
if (CONN_IS_EDGE(conn))
- connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
+ connection_edge_end(conn, END_STREAM_REASON_HIBERNATING,
+ conn->cpath_layer);
log_fn(LOG_INFO,"Closing conn type %d", conn->type);
connection_mark_for_close(conn);
}
diff --git a/src/or/or.h b/src/or/or.h
index 821d4e08a5..90a3245321 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -425,6 +425,7 @@ typedef enum {
#define END_STREAM_REASON_INTERNAL 10
#define END_STREAM_REASON_RESOURCELIMIT 11
#define END_STREAM_REASON_CONNRESET 12
+#define END_STREAM_REASON_TORPROTOCOL 13
#define RESOLVED_TYPE_IPV4 4
#define RESOLVED_TYPE_IPV6 6
@@ -1286,6 +1287,7 @@ int connection_edge_reached_eof(connection_t *conn);
int connection_edge_process_inbuf(connection_t *conn, int package_partial);
int connection_edge_destroy(uint16_t circ_id, connection_t *conn);
int connection_edge_end(connection_t *conn, char reason, crypt_path_t *cpath_layer);
+int connection_edge_end_errno(connection_t *conn, crypt_path_t *cpath_layer);
int connection_edge_finished_flushing(connection_t *conn);
int connection_edge_finished_connecting(connection_t *conn);
@@ -1527,9 +1529,7 @@ int connection_edge_send_command(connection_t *fromconn, circuit_t *circ,
int connection_edge_package_raw_inbuf(connection_t *conn, int package_partial);
void connection_edge_consider_sending_sendme(connection_t *conn);
socks5_reply_status_t connection_edge_end_reason_sock5_response(char *payload, uint16_t length);
-int errno_to_end_reasaon(int e);
-
-
+int errno_to_end_reason(int e);
extern uint64_t stats_n_data_cells_packaged;
extern uint64_t stats_n_data_bytes_packaged;
diff --git a/src/or/relay.c b/src/or/relay.c
index 10be51228b..8a6ba88057 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -474,6 +474,7 @@ connection_edge_end_reason_str(char *payload, uint16_t length) {
case END_STREAM_REASON_INTERNAL: return "internal error at server";
case END_STREAM_REASON_RESOURCELIMIT: return "server out of resources";
case END_STREAM_REASON_CONNRESET: return "connection reset";
+ case END_STREAM_REASON_TORPROTOCOL: return "Tor protocol error";
default:
log_fn(LOG_WARN,"Reason for ending (%d) not recognized.",*payload);
return "unknown";
@@ -509,6 +510,8 @@ connection_edge_end_reason_sock5_response(char *payload, uint16_t length) {
return SOCKS5_GENERAL_ERROR;
case END_STREAM_REASON_CONNRESET:
return SOCKS5_CONNECTION_REFUSED;
+ case END_STREAM_REASON_TORPROTOCOL:
+ return SOCKS5_GENERAL_ERROR;
default:
log_fn(LOG_WARN,"Reason for ending (%d) not recognized.",*payload);
return SOCKS5_GENERAL_ERROR;
@@ -524,7 +527,7 @@ connection_edge_end_reason_sock5_response(char *payload, uint16_t length) {
#endif
int
-errno_to_end_reasaon(int e)
+errno_to_end_reason(int e)
{
switch (e) {
E_CASE(EPIPE):
@@ -668,7 +671,7 @@ connection_edge_process_relay_cell_not_open(
addr = ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE));
if (!addr) {
log_fn(LOG_INFO,"...but it claims the IP address was 0.0.0.0. Closing.");
- connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
+ connection_edge_end(conn, END_STREAM_REASON_TORPROTOCOL, conn->cpath_layer);
connection_mark_for_close(conn);
return 0;
}
@@ -680,6 +683,7 @@ connection_edge_process_relay_cell_not_open(
conn->socks_request->has_finished = 1;
/* handle anything that might have queued */
if (connection_edge_package_raw_inbuf(conn, 1) < 0) {
+ /* XXXX we can't tell why package failed. -NM */
connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
connection_mark_for_close(conn);
return 0;
@@ -710,7 +714,7 @@ connection_edge_process_relay_cell_not_open(
log_fn(LOG_WARN,"Got an unexpected relay command %d, in state %d (%s). Closing.",
rh->command, conn->state, conn_state_to_string[conn->type][conn->state]);
- connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
+ connection_edge_end(conn, END_STREAM_REASON_TORPROTOCOL, conn->cpath_layer);
connection_mark_for_close(conn);
return -1;
}
@@ -771,7 +775,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
if (( layer_hint && --layer_hint->deliver_window < 0) ||
(!layer_hint && --circ->deliver_window < 0)) {
log_fn(LOG_WARN,"(relay data) circ deliver_window below 0. Killing.");
- connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer);
+ connection_edge_end(conn, END_STREAM_REASON_TORPROTOCOL, conn->cpath_layer);
connection_mark_for_close(conn);
return -1;
}