[or-cvs] Forward-port new reasons; clean up code more; add code to c...
Nick Mathewson
nickm at seul.org
Tue Mar 1 22:16:19 UTC 2005
Update of /home/or/cvsroot/tor/src/or
In directory moria.mit.edu:/tmp/cvs-serv20853/src/or
Modified Files:
buffers.c connection.c connection_edge.c or.h relay.c
Log Message:
Forward-port new reasons; clean up code more; add code to convert new reasons to SOCKS5 reply codes; add code to convert errnos to reasons. New code still needs to get invoked.
Index: buffers.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/buffers.c,v
retrieving revision 1.126
retrieving revision 1.127
diff -u -d -r1.126 -r1.127
--- buffers.c 22 Feb 2005 08:18:34 -0000 1.126
+++ buffers.c 1 Mar 2005 22:16:15 -0000 1.127
@@ -472,7 +472,7 @@
if (!nummethods || !memchr(buf->mem+2, 0, nummethods)) {
log_fn(LOG_WARN,"socks5: offered methods don't include 'no auth'. Rejecting.");
req->replylen = 2; /* 2 bytes of response */
- req->reply[0] = 5; /* socks5 reply */
+ req->reply[0] = 5;
req->reply[1] = '\xFF'; /* reject all methods */
return -1;
}
@@ -480,7 +480,7 @@
req->replylen = 2; /* 2 bytes of response */
req->reply[0] = 5; /* socks5 reply */
- req->reply[1] = 0; /* choose the 'no auth' method */
+ req->reply[1] = SOCKS5_SUCCEEDED;
req->socks_version = 5; /* remember that we've already negotiated auth */
log_fn(LOG_DEBUG,"socks5: accepted method 0");
return 0;
Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/connection.c,v
retrieving revision 1.333
retrieving revision 1.334
diff -u -d -r1.333 -r1.334
--- connection.c 1 Mar 2005 01:15:01 -0000 1.333
+++ connection.c 1 Mar 2005 22:16:15 -0000 1.334
@@ -914,7 +914,7 @@
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_CONNECTFAILED),
+ END_STREAM_REASON_MISC : END_STREAM_REASON_CONNECTREFUSED),
conn->cpath_layer);
}
connection_mark_for_close(conn);
@@ -1092,7 +1092,7 @@
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_CONNECTFAILED,
+ connection_edge_end(conn, END_STREAM_REASON_CONNECTREFUSED,
conn->cpath_layer);
connection_close_immediate(conn);
Index: connection_edge.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/connection_edge.c,v
retrieving revision 1.285
retrieving revision 1.286
diff -u -d -r1.285 -r1.286
--- connection_edge.c 24 Feb 2005 11:44:08 -0000 1.285
+++ connection_edge.c 1 Mar 2005 22:16:15 -0000 1.286
@@ -875,21 +875,21 @@
/* SOCKS5 */
buf[0] = 0x05; /* version */
if (answer_type == RESOLVED_TYPE_IPV4 && answer_len == 4) {
- buf[1] = 0; /* succeeded */
+ buf[1] = SOCKS5_SUCCEEDED;
buf[2] = 0; /* reserved */
buf[3] = 0x01; /* IPv4 address type */
memcpy(buf+4, answer, 4); /* address */
set_uint16(buf+8, 0); /* port == 0. */
replylen = 10;
} else if (answer_type == RESOLVED_TYPE_IPV6 && answer_len == 16) {
- buf[1] = 0; /* succeeded */
+ buf[1] = SOCKS5_SUCCEEDED;
buf[2] = 0; /* reserved */
buf[3] = 0x04; /* IPv6 address type */
memcpy(buf+4, answer, 16); /* address */
set_uint16(buf+20, 0); /* port == 0. */
replylen = 22;
} else {
- buf[1] = 0x04; /* host unreachable */
+ buf[1] = SOCKS5_HOST_UNREACHABLE;
memset(buf+2, 0, 8);
replylen = 10;
}
@@ -1156,7 +1156,8 @@
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_CONNECTFAILED, conn->cpath_layer);
+ connection_edge_end(conn, END_STREAM_REASON_CONNECTREFUSED,
+ conn->cpath_layer);
circuit_detach_stream(circuit_get_by_conn(conn), conn);
connection_free(conn);
return;
Index: or.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.545
retrieving revision 1.546
diff -u -d -r1.545 -r1.546
--- or.h 1 Mar 2005 01:15:00 -0000 1.545
+++ or.h 1 Mar 2005 22:16:15 -0000 1.546
@@ -413,16 +413,18 @@
#define RELAY_COMMAND_RENDEZVOUS_ESTABLISHED 39
#define RELAY_COMMAND_INTRODUCE_ACK 40
-#define _MIN_END_STREAM_REASON 1
#define END_STREAM_REASON_MISC 1
#define END_STREAM_REASON_RESOLVEFAILED 2
-#define END_STREAM_REASON_CONNECTFAILED 3
+#define END_STREAM_REASON_CONNECTREFUSED 3
#define END_STREAM_REASON_EXITPOLICY 4
#define END_STREAM_REASON_DESTROY 5
#define END_STREAM_REASON_DONE 6
#define END_STREAM_REASON_TIMEOUT 7
-#define END_STREAM_REASON_RESOURCELIMIT 8
-#define _MAX_END_STREAM_REASON 8
+/* 8 is unallocated. */
+#define END_STREAM_REASON_HIBERNATING 9
+#define END_STREAM_REASON_INTERNAL 10
+#define END_STREAM_REASON_RESOURCELIMIT 11
+#define END_STREAM_REASON_CONNRESET 12
#define RESOLVED_TYPE_IPV4 4
#define RESOLVED_TYPE_IPV6 6
@@ -466,6 +468,18 @@
#define SOCKS4_NETWORK_LEN 8
+typedef enum {
+ SOCKS5_SUCCEEDED = 0x00,
+ SOCKS5_GENERAL_ERROR = 0x01,
+ SOCKS5_NOT_ALLOWED = 0x02,
+ SOCKS5_NET_UNREACHABLE = 0x03,
+ SOCKS5_HOST_UNREACHABLE = 0x04,
+ SOCKS5_CONNECTION_REFUSED = 0x05,
+ SOCKS5_TTL_EXPIRED = 0x06,
+ SOCKS5_COMMAND_NOT_SUPPORTED = 0x07,
+ SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED = 0x08,
+} socks5_reply_status_t;
+
/*
* Relay payload:
* Relay command [1 byte]
@@ -1512,6 +1526,10 @@
size_t payload_len, crypt_path_t *cpath_layer);
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);
+
+
extern uint64_t stats_n_data_cells_packaged;
extern uint64_t stats_n_data_bytes_packaged;
Index: relay.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/relay.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- relay.c 24 Feb 2005 11:44:08 -0000 1.41
+++ relay.c 1 Mar 2005 22:16:15 -0000 1.42
@@ -457,26 +457,105 @@
* why the stream is closing.
*/
static const char *
-connection_edge_end_reason(char *payload, uint16_t length) {
+connection_edge_end_reason_str(char *payload, uint16_t length) {
if (length < 1) {
log_fn(LOG_WARN,"End cell arrived with length 0. Should be at least 1.");
return "MALFORMED";
}
- if (*payload < _MIN_END_STREAM_REASON || *payload > _MAX_END_STREAM_REASON) {
- log_fn(LOG_WARN,"Reason for ending (%d) not recognized.",*payload);
- return "MALFORMED";
- }
switch (*payload) {
case END_STREAM_REASON_MISC: return "misc error";
case END_STREAM_REASON_RESOLVEFAILED: return "resolve failed";
- case END_STREAM_REASON_CONNECTFAILED: return "connect failed";
+ case END_STREAM_REASON_CONNECTREFUSED: return "connection refused";
case END_STREAM_REASON_EXITPOLICY: return "exit policy failed";
case END_STREAM_REASON_DESTROY: return "destroyed";
case END_STREAM_REASON_DONE: return "closed normally";
case END_STREAM_REASON_TIMEOUT: return "gave up (timeout)";
+ case END_STREAM_REASON_HIBERNATING: return "server is hibernating";
+ 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";
+ default:
+ log_fn(LOG_WARN,"Reason for ending (%d) not recognized.",*payload);
+ return "unknown";
+ }
+}
+
+socks5_reply_status_t
+connection_edge_end_reason_sock5_response(char *payload, uint16_t length) {
+ if (length < 1) {
+ log_fn(LOG_WARN,"End cell arrived with length 0. Should be at least 1.");
+ return SOCKS5_GENERAL_ERROR;
+ }
+ switch (*payload) {
+ case END_STREAM_REASON_MISC:
+ return SOCKS5_GENERAL_ERROR;
+ case END_STREAM_REASON_RESOLVEFAILED:
+ return SOCKS5_HOST_UNREACHABLE;
+ case END_STREAM_REASON_CONNECTREFUSED:
+ return SOCKS5_CONNECTION_REFUSED;
+ case END_STREAM_REASON_EXITPOLICY:
+ return SOCKS5_CONNECTION_REFUSED;
+ case END_STREAM_REASON_DESTROY:
+ return SOCKS5_GENERAL_ERROR;
+ case END_STREAM_REASON_DONE:
+ return SOCKS5_SUCCEEDED;
+ case END_STREAM_REASON_TIMEOUT:
+ return SOCKS5_TTL_EXPIRED;
+ case END_STREAM_REASON_RESOURCELIMIT:
+ return SOCKS5_GENERAL_ERROR;
+ case END_STREAM_REASON_HIBERNATING:
+ return SOCKS5_GENERAL_ERROR;
+ case END_STREAM_REASON_INTERNAL:
+ return SOCKS5_GENERAL_ERROR;
+ case END_STREAM_REASON_CONNRESET:
+ return SOCKS5_CONNECTION_REFUSED;
+ default:
+ log_fn(LOG_WARN,"Reason for ending (%d) not recognized.",*payload);
+ return SOCKS5_GENERAL_ERROR;
+ }
+}
+
+#ifdef MS_WINDOWS
+#define E_CASE(s) case s: case WSA ## s
+#define W_CASE(s) case s:
+#else
+#define E_CASE(s) case s
+#define W_CASE(s)
+#endif
+
+int
+errno_to_end_reasaon(int e)
+{
+ switch (e) {
+ E_CASE(EPIPE):
+ return END_STREAM_REASON_DONE;
+ E_CASE(EBADF):
+ E_CASE(EFAULT):
+ E_CASE(EINVAL):
+ E_CASE(EISCONN):
+ E_CASE(ENOTSOCK):
+ E_CASE(EPROTONOSUPPORT):
+ E_CASE(EAFNOSUPPORT):
+ E_CASE(EACCES):
+ E_CASE(ENOTCONN):
+ E_CASE(ENETUNREACH):
+ return END_STREAM_REASON_INTERNAL;
+ E_CASE(ECONNREFUSED):
+ return END_STREAM_REASON_CONNECTREFUSED;
+ E_CASE(ECONNRESET):
+ return END_STREAM_REASON_CONNRESET;
+ E_CASE(ETIMEDOUT):
+ return END_STREAM_REASON_TIMEOUT;
+ E_CASE(ENOBUFS):
+ E_CASE(ENOMEM):
+ E_CASE(ENFILE):
+ E_CASE(EMFILE):
+ return END_STREAM_REASON_RESOURCELIMIT;
+ default:
+ log_fn(LOG_INFO, "Didn't recognize errno %d (%s); telling the OP that we are ending a stream for 'misc' reason.",
+ e, tor_socket_strerror(e));
+ return END_STREAM_REASON_MISC;
}
- tor_assert(0);
- return "";
}
/** How many times will I retry a stream that fails due to DNS
@@ -567,7 +646,8 @@
}
}
log_fn(LOG_INFO,"Edge got end (%s) before we're connected. Marking for close.",
- connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, rh->length));
+ connection_edge_end_reason_str(cell->payload+RELAY_HEADER_SIZE,
+ rh->length));
if (CIRCUIT_IS_ORIGIN(circ))
circuit_log_path(LOG_INFO,circ);
conn->has_sent_end = 1; /* we just got an 'end', don't need to send one */
@@ -722,14 +802,16 @@
case RELAY_COMMAND_END:
if (!conn) {
log_fn(LOG_INFO,"end cell (%s) dropped, unknown stream.",
- connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, rh.length));
+ connection_edge_end_reason_str(cell->payload+RELAY_HEADER_SIZE,
+ rh.length));
return 0;
}
/* XXX add to this log_fn the exit node's nickname? */
log_fn(LOG_INFO,"%d: end cell (%s) for stream %d. Removing stream. Size %d.",
- conn->s,
- connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, rh.length),
- conn->stream_id, (int)conn->stream_size);
+ conn->s,
+ connection_edge_end_reason_str(cell->payload+RELAY_HEADER_SIZE,
+ rh.length),
+ conn->stream_id, (int)conn->stream_size);
#ifdef HALF_OPEN
conn->done_sending = 1;
More information about the tor-commits
mailing list