1 /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
2 * Copyright (c) 2007-2010, The Tor Project, Inc. */
3 /* See LICENSE for licensing information */
7 * \brief Convert circuit, stream, and orconn error reasons to and/or from
8 * strings and errno values.
13 /***************************** Edge (stream) reasons **********************/
15 /** Convert the reason for ending a stream <b>reason</b> into the format used
16 * in STREAM events. Return NULL if the reason is unrecognized. */
18 stream_end_reason_to_control_string(int reason
)
20 reason
&= END_STREAM_REASON_MASK
;
22 case END_STREAM_REASON_MISC
: return "MISC";
23 case END_STREAM_REASON_RESOLVEFAILED
: return "RESOLVEFAILED";
24 case END_STREAM_REASON_CONNECTREFUSED
: return "CONNECTREFUSED";
25 case END_STREAM_REASON_EXITPOLICY
: return "EXITPOLICY";
26 case END_STREAM_REASON_DESTROY
: return "DESTROY";
27 case END_STREAM_REASON_DONE
: return "DONE";
28 case END_STREAM_REASON_TIMEOUT
: return "TIMEOUT";
29 case END_STREAM_REASON_HIBERNATING
: return "HIBERNATING";
30 case END_STREAM_REASON_INTERNAL
: return "INTERNAL";
31 case END_STREAM_REASON_RESOURCELIMIT
: return "RESOURCELIMIT";
32 case END_STREAM_REASON_CONNRESET
: return "CONNRESET";
33 case END_STREAM_REASON_TORPROTOCOL
: return "TORPROTOCOL";
34 case END_STREAM_REASON_NOTDIRECTORY
: return "NOTDIRECTORY";
36 case END_STREAM_REASON_CANT_ATTACH
: return "CANT_ATTACH";
37 case END_STREAM_REASON_NET_UNREACHABLE
: return "NET_UNREACHABLE";
38 case END_STREAM_REASON_SOCKSPROTOCOL
: return "SOCKS_PROTOCOL";
44 /** Translate <b>reason</b>, which came from a relay 'end' cell,
45 * into a static const string describing why the stream is closing.
46 * <b>reason</b> is -1 if no reason was provided.
49 stream_end_reason_to_string(int reason
)
53 log_fn(LOG_PROTOCOL_WARN
, LD_PROTOCOL
,
54 "End cell arrived with length 0. Should be at least 1.");
56 case END_STREAM_REASON_MISC
: return "misc error";
57 case END_STREAM_REASON_RESOLVEFAILED
: return "resolve failed";
58 case END_STREAM_REASON_CONNECTREFUSED
: return "connection refused";
59 case END_STREAM_REASON_EXITPOLICY
: return "exit policy failed";
60 case END_STREAM_REASON_DESTROY
: return "destroyed";
61 case END_STREAM_REASON_DONE
: return "closed normally";
62 case END_STREAM_REASON_TIMEOUT
: return "gave up (timeout)";
63 case END_STREAM_REASON_HIBERNATING
: return "server is hibernating";
64 case END_STREAM_REASON_INTERNAL
: return "internal error at server";
65 case END_STREAM_REASON_RESOURCELIMIT
: return "server out of resources";
66 case END_STREAM_REASON_CONNRESET
: return "connection reset";
67 case END_STREAM_REASON_TORPROTOCOL
: return "Tor protocol error";
68 case END_STREAM_REASON_NOTDIRECTORY
: return "not a directory";
70 log_fn(LOG_PROTOCOL_WARN
, LD_PROTOCOL
,
71 "Reason for ending (%d) not recognized.",reason
);
76 /** Translate <b>reason</b> (as from a relay 'end' cell) into an
77 * appropriate SOCKS5 reply code.
79 * A reason of 0 means that we're not actually expecting to send
80 * this code back to the socks client; we just call it 'succeeded'
81 * to keep things simple.
84 stream_end_reason_to_socks5_response(int reason
)
86 switch (reason
& END_STREAM_REASON_MASK
) {
88 return SOCKS5_SUCCEEDED
;
89 case END_STREAM_REASON_MISC
:
90 return SOCKS5_GENERAL_ERROR
;
91 case END_STREAM_REASON_RESOLVEFAILED
:
92 return SOCKS5_HOST_UNREACHABLE
;
93 case END_STREAM_REASON_CONNECTREFUSED
:
94 return SOCKS5_CONNECTION_REFUSED
;
95 case END_STREAM_REASON_ENTRYPOLICY
:
96 return SOCKS5_NOT_ALLOWED
;
97 case END_STREAM_REASON_EXITPOLICY
:
98 return SOCKS5_NOT_ALLOWED
;
99 case END_STREAM_REASON_DESTROY
:
100 return SOCKS5_GENERAL_ERROR
;
101 case END_STREAM_REASON_DONE
:
102 return SOCKS5_SUCCEEDED
;
103 case END_STREAM_REASON_TIMEOUT
:
104 return SOCKS5_TTL_EXPIRED
;
105 case END_STREAM_REASON_RESOURCELIMIT
:
106 return SOCKS5_GENERAL_ERROR
;
107 case END_STREAM_REASON_HIBERNATING
:
108 return SOCKS5_GENERAL_ERROR
;
109 case END_STREAM_REASON_INTERNAL
:
110 return SOCKS5_GENERAL_ERROR
;
111 case END_STREAM_REASON_CONNRESET
:
112 return SOCKS5_CONNECTION_REFUSED
;
113 case END_STREAM_REASON_TORPROTOCOL
:
114 return SOCKS5_GENERAL_ERROR
;
116 case END_STREAM_REASON_CANT_ATTACH
:
117 return SOCKS5_GENERAL_ERROR
;
118 case END_STREAM_REASON_NET_UNREACHABLE
:
119 return SOCKS5_NET_UNREACHABLE
;
120 case END_STREAM_REASON_SOCKSPROTOCOL
:
121 return SOCKS5_GENERAL_ERROR
;
123 log_fn(LOG_PROTOCOL_WARN
, LD_PROTOCOL
,
124 "Reason for ending (%d) not recognized; "
125 "sending generic socks error.", reason
);
126 return SOCKS5_GENERAL_ERROR
;
130 /* We need to use a few macros to deal with the fact that Windows
131 * decided that their sockets interface should be a permakludge.
132 * E_CASE is for errors where windows has both a EFOO and a WSAEFOO
133 * version, and S_CASE is for errors where windows has only a WSAEFOO
134 * version. (The E is for 'error', the S is for 'socket'). */
136 #define E_CASE(s) case s: case WSA ## s
137 #define S_CASE(s) case WSA ## s
139 #define E_CASE(s) case s
140 #define S_CASE(s) case s
143 /** Given an errno from a failed exit connection, return a reason code
144 * appropriate for use in a RELAY END cell. */
146 errno_to_stream_end_reason(int e
)
148 /* To add new errors here, find out if they exist on Windows, and if a WSA*
149 * equivalent exists on windows. Add a case, an S_CASE, or an E_CASE as
153 return END_STREAM_REASON_DONE
;
159 S_CASE(EPROTONOSUPPORT
):
160 S_CASE(EAFNOSUPPORT
):
164 return END_STREAM_REASON_INTERNAL
;
165 S_CASE(ECONNREFUSED
):
166 return END_STREAM_REASON_CONNECTREFUSED
;
168 return END_STREAM_REASON_CONNRESET
;
170 return END_STREAM_REASON_TIMEOUT
;
175 return END_STREAM_REASON_RESOURCELIMIT
;
177 log_info(LD_EXIT
, "Didn't recognize errno %d (%s); telling the client "
178 "that we are ending a stream for 'misc' reason.",
179 e
, tor_socket_strerror(e
));
180 return END_STREAM_REASON_MISC
;
184 /***************************** ORConn reasons *****************************/
186 /** Convert the reason for ending an OR connection <b>r</b> into the format
187 * used in ORCONN events. Return "UNKNOWN" if the reason is unrecognized. */
189 orconn_end_reason_to_control_string(int r
)
191 /* To add new errors here, find out if they exist on Windows, and if a WSA*
192 * equivalent exists on windows. Add a case, an S_CASE, or an E_CASE as
195 case END_OR_CONN_REASON_DONE
:
197 case END_OR_CONN_REASON_REFUSED
:
198 return "CONNECTREFUSED";
199 case END_OR_CONN_REASON_OR_IDENTITY
:
201 case END_OR_CONN_REASON_CONNRESET
:
202 return "CONNECTRESET";
203 case END_OR_CONN_REASON_TIMEOUT
:
205 case END_OR_CONN_REASON_NO_ROUTE
:
207 case END_OR_CONN_REASON_IO_ERROR
:
209 case END_OR_CONN_REASON_RESOURCE_LIMIT
:
210 return "RESOURCELIMIT";
211 case END_OR_CONN_REASON_MISC
:
216 log_warn(LD_BUG
, "Unrecognized or_conn reason code %d", r
);
221 /** Convert a TOR_TLS_* error code into an END_OR_CONN_* reason. */
223 tls_error_to_orconn_end_reason(int e
)
226 case TOR_TLS_ERROR_IO
:
227 return END_OR_CONN_REASON_IO_ERROR
;
228 case TOR_TLS_ERROR_CONNREFUSED
:
229 return END_OR_CONN_REASON_REFUSED
;
230 case TOR_TLS_ERROR_CONNRESET
:
231 return END_OR_CONN_REASON_CONNRESET
;
232 case TOR_TLS_ERROR_NO_ROUTE
:
233 return END_OR_CONN_REASON_NO_ROUTE
;
234 case TOR_TLS_ERROR_TIMEOUT
:
235 return END_OR_CONN_REASON_TIMEOUT
;
236 case TOR_TLS_WANTREAD
:
237 case TOR_TLS_WANTWRITE
:
240 return END_OR_CONN_REASON_DONE
;
242 return END_OR_CONN_REASON_MISC
;
246 /** Given an errno from a failed ORConn connection, return a reason code
247 * appropriate for use in the controller orconn events. */
249 errno_to_orconn_end_reason(int e
)
253 return END_OR_CONN_REASON_DONE
;
257 S_CASE(EHOSTUNREACH
):
258 return END_OR_CONN_REASON_NO_ROUTE
;
259 S_CASE(ECONNREFUSED
):
260 return END_OR_CONN_REASON_REFUSED
;
262 return END_OR_CONN_REASON_CONNRESET
;
264 return END_OR_CONN_REASON_TIMEOUT
;
273 return END_OR_CONN_REASON_RESOURCE_LIMIT
;
275 log_info(LD_OR
, "Didn't recognize errno %d (%s).",
276 e
, tor_socket_strerror(e
));
277 return END_OR_CONN_REASON_MISC
;
281 /***************************** Circuit reasons *****************************/
283 /** Convert a numeric reason for destroying a circuit into a string for a
286 circuit_end_reason_to_control_string(int reason
)
288 if (reason
>= 0 && reason
& END_CIRC_REASON_FLAG_REMOTE
)
289 reason
&= ~END_CIRC_REASON_FLAG_REMOTE
;
291 case END_CIRC_AT_ORIGIN
:
292 /* This shouldn't get passed here; it's a catch-all reason. */
294 case END_CIRC_REASON_NONE
:
295 /* This shouldn't get passed here; it's a catch-all reason. */
297 case END_CIRC_REASON_TORPROTOCOL
:
298 return "TORPROTOCOL";
299 case END_CIRC_REASON_INTERNAL
:
301 case END_CIRC_REASON_REQUESTED
:
303 case END_CIRC_REASON_HIBERNATING
:
304 return "HIBERNATING";
305 case END_CIRC_REASON_RESOURCELIMIT
:
306 return "RESOURCELIMIT";
307 case END_CIRC_REASON_CONNECTFAILED
:
308 return "CONNECTFAILED";
309 case END_CIRC_REASON_OR_IDENTITY
:
310 return "OR_IDENTITY";
311 case END_CIRC_REASON_OR_CONN_CLOSED
:
312 return "OR_CONN_CLOSED";
313 case END_CIRC_REASON_FINISHED
:
315 case END_CIRC_REASON_TIMEOUT
:
317 case END_CIRC_REASON_DESTROYED
:
319 case END_CIRC_REASON_NOPATH
:
321 case END_CIRC_REASON_NOSUCHSERVICE
:
322 return "NOSUCHSERVICE";
324 log_warn(LD_BUG
, "Unrecognized reason code %d", (int)reason
);
329 /** Return a string corresponding to a SOCKS4 reponse code. */
331 socks4_response_code_to_string(uint8_t code
)
335 return "connection accepted";
337 return "server rejected connection";
339 return "server cannot connect to identd on this client";
341 return "user id does not match identd";
343 return "invalid SOCKS 4 response code";
347 /** Return a string corresponding to a SOCKS5 reponse code. */
349 socks5_response_code_to_string(uint8_t code
)
353 return "connection accepted";
355 return "general SOCKS server failure";
357 return "connection not allowed by ruleset";
359 return "Network unreachable";
361 return "Host unreachable";
363 return "Connection refused";
365 return "TTL expired";
367 return "Command not supported";
369 return "Address type not supported";
371 return "unknown reason";
375 /** Return a string corresponding to a bandwidht_weight_rule_t */
377 bandwidth_weight_rule_to_string(bandwidth_weight_rule_t rule
)
382 return "no weighting";
383 case WEIGHT_FOR_EXIT
:
384 return "weight as exit";
386 return "weight as middle node";
387 case WEIGHT_FOR_GUARD
:
388 return "weight as guard";
390 return "weight as directory";
392 return "unknown rule";