1 /* Copyright 2001,2002,2003 Roger Dingledine, Matej Pfajfar. */
2 /* See LICENSE for licensing information */
8 extern or_options_t options
; /* command-line and config-file options */
9 extern char *conn_state_to_string
[][_CONN_TYPE_MAX
+1];
11 static int connection_ap_handshake_process_socks(connection_t
*conn
);
12 static int connection_ap_handshake_attach_circuit(connection_t
*conn
);
13 static void connection_ap_handshake_send_begin(connection_t
*ap_conn
, circuit_t
*circ
);
14 static int connection_ap_handshake_socks_reply(connection_t
*conn
, char *reply
,
15 int replylen
, char success
);
17 static int connection_exit_begin_conn(cell_t
*cell
, circuit_t
*circ
);
18 static void connection_edge_consider_sending_sendme(connection_t
*conn
);
20 static uint32_t client_dns_lookup_entry(const char *address
);
21 static void client_dns_set_entry(const char *address
, uint32_t val
);
23 int connection_edge_process_inbuf(connection_t
*conn
) {
26 assert(conn
->type
== CONN_TYPE_AP
|| conn
->type
== CONN_TYPE_EXIT
);
28 if(conn
->inbuf_reached_eof
) {
30 /* eof reached; we're done reading, but we might want to write more. */
31 conn
->done_receiving
= 1;
32 shutdown(conn
->s
, 0); /* XXX check return, refactor NM */
33 if (conn
->done_sending
) {
34 if(connection_edge_end(conn
, END_STREAM_REASON_DONE
, conn
->cpath_layer
) < 0)
35 log_fn(LOG_WARN
,"1: I called connection_edge_end redundantly.");
37 connection_edge_send_command(conn
, circuit_get_by_conn(conn
), RELAY_COMMAND_END
,
38 NULL
, 0, conn
->cpath_layer
);
42 /* eof reached, kill it. */
43 log_fn(LOG_INFO
,"conn (fd %d) reached eof. Closing.", conn
->s
);
44 if(connection_edge_end(conn
, END_STREAM_REASON_DONE
, conn
->cpath_layer
) < 0)
45 log_fn(LOG_WARN
,"2: I called connection_edge_end redundantly.");
51 case AP_CONN_STATE_SOCKS_WAIT
:
52 if(connection_ap_handshake_process_socks(conn
) < 0) {
53 if(connection_edge_end(conn
, END_STREAM_REASON_MISC
, conn
->cpath_layer
) < 0)
54 log_fn(LOG_WARN
,"3: I called connection_edge_end redundantly.");
58 case AP_CONN_STATE_OPEN
:
59 case EXIT_CONN_STATE_OPEN
:
60 if(conn
->package_window
<= 0) {
61 log_fn(LOG_WARN
,"called with package_window %d. Tell Roger.", conn
->package_window
);
64 if(connection_edge_package_raw_inbuf(conn
) < 0) {
65 if(connection_edge_end(conn
, END_STREAM_REASON_MISC
, conn
->cpath_layer
) < 0)
66 log_fn(LOG_WARN
,"4: I called connection_edge_end redundantly.");
70 case EXIT_CONN_STATE_CONNECTING
:
71 log_fn(LOG_INFO
,"text from server while in 'connecting' state at exit. Leaving it on buffer.");
78 static char *connection_edge_end_reason(char *payload
, uint16_t length
) {
80 log_fn(LOG_WARN
,"End cell arrived with length 0. Should be at least 1.");
83 if(*payload
< END_STREAM_REASON_MISC
|| *payload
> END_STREAM_REASON_DONE
) {
84 log_fn(LOG_WARN
,"Reason for ending (%d) not recognized.",*payload
);
88 case END_STREAM_REASON_MISC
: return "misc error";
89 case END_STREAM_REASON_RESOLVEFAILED
: return "resolve failed";
90 case END_STREAM_REASON_CONNECTFAILED
: return "connect failed";
91 case END_STREAM_REASON_EXITPOLICY
: return "exit policy failed";
92 case END_STREAM_REASON_DESTROY
: return "destroyed";
93 case END_STREAM_REASON_DONE
: return "closed normally";
99 int connection_edge_end(connection_t
*conn
, char reason
, crypt_path_t
*cpath_layer
) {
104 if(conn
->has_sent_end
) {
105 log_fn(LOG_WARN
,"It appears I've already sent the end. Are you calling me twice?");
110 if(reason
== END_STREAM_REASON_EXITPOLICY
) {
111 *(uint32_t *)(payload
+1) = htonl(conn
->addr
);
115 circ
= circuit_get_by_conn(conn
);
117 log_fn(LOG_DEBUG
,"Marking conn (fd %d) and sending end.",conn
->s
);
118 connection_edge_send_command(conn
, circ
, RELAY_COMMAND_END
,
119 payload
, payload_len
, cpath_layer
);
122 conn
->marked_for_close
= 1;
123 conn
->has_sent_end
= 1;
127 int connection_edge_send_command(connection_t
*fromconn
, circuit_t
*circ
, int relay_command
,
128 void *payload
, int payload_len
, crypt_path_t
*cpath_layer
) {
131 int is_control_cell
=0;
134 log_fn(LOG_WARN
,"no circ. Closing.");
138 if(!fromconn
|| relay_command
== RELAY_COMMAND_BEGIN
) /* XXX more */
141 memset(&cell
, 0, sizeof(cell_t
));
142 if(fromconn
&& fromconn
->type
== CONN_TYPE_AP
) {
143 cell
.circ_id
= circ
->n_circ_id
;
144 cell_direction
= CELL_DIRECTION_OUT
;
146 /* NOTE: if !fromconn, we assume that it's heading towards the OP */
147 cell
.circ_id
= circ
->p_circ_id
;
148 cell_direction
= CELL_DIRECTION_IN
;
151 cell
.command
= CELL_RELAY
;
152 SET_CELL_RELAY_COMMAND(cell
, relay_command
);
154 SET_CELL_STREAM_ID(cell
, ZERO_STREAM
);
156 SET_CELL_STREAM_ID(cell
, fromconn
->stream_id
);
158 SET_CELL_RELAY_LENGTH(cell
, payload_len
);
160 memcpy(cell
.payload
+RELAY_HEADER_SIZE
,payload
,payload_len
);
162 log_fn(LOG_DEBUG
,"delivering %d cell %s.", relay_command
,
163 cell_direction
== CELL_DIRECTION_OUT
? "forward" : "backward");
165 if(circuit_deliver_relay_cell(&cell
, circ
, cell_direction
, cpath_layer
) < 0) {
166 log_fn(LOG_WARN
,"circuit_deliver_relay_cell failed. Closing.");
173 /* an incoming relay cell has arrived. return -1 if you want to tear down the
174 * circuit, else 0. */
175 int connection_edge_process_relay_cell(cell_t
*cell
, circuit_t
*circ
, connection_t
*conn
,
176 int edge_type
, crypt_path_t
*layer_hint
) {
178 static int num_seen
=0;
181 assert(cell
&& circ
);
183 relay_command
= CELL_RELAY_COMMAND(*cell
);
184 // log_fn(LOG_DEBUG,"command %d stream %d", relay_command, stream_id);
186 log_fn(LOG_DEBUG
,"Now seen %d relay cells here.", num_seen
);
188 /* either conn is NULL, in which case we've got a control cell, or else
189 * conn points to the recognized stream. */
191 if(conn
&& conn
->state
!= AP_CONN_STATE_OPEN
&& conn
->state
!= EXIT_CONN_STATE_OPEN
) {
192 if(conn
->type
== CONN_TYPE_EXIT
&& relay_command
== RELAY_COMMAND_END
) {
193 log_fn(LOG_INFO
,"Exit got end (%s) before we're connected. Marking for close.",
194 connection_edge_end_reason(cell
->payload
+RELAY_HEADER_SIZE
, CELL_RELAY_LENGTH(*cell
)));
195 if(conn
->state
== EXIT_CONN_STATE_RESOLVING
) {
196 log_fn(LOG_INFO
,"...and informing resolver we don't want the answer anymore.");
197 dns_cancel_pending_resolve(conn
->address
, conn
);
199 conn
->marked_for_close
= 1;
200 conn
->has_sent_end
= 1;
203 log_fn(LOG_WARN
,"Got an unexpected relay command %d, in state %d (%s). Closing.",
204 relay_command
, conn
->state
, conn_state_to_string
[conn
->type
][conn
->state
]);
205 if(connection_edge_end(conn
, END_STREAM_REASON_MISC
, conn
->cpath_layer
) < 0)
206 log_fn(LOG_WARN
,"1: I called connection_edge_end redundantly.");
211 switch(relay_command
) {
212 case RELAY_COMMAND_BEGIN
:
213 if(edge_type
== EDGE_AP
) {
214 log_fn(LOG_WARN
,"relay begin request unsupported at AP. Dropping.");
218 log_fn(LOG_WARN
,"begin cell for known stream. Dropping.");
221 connection_exit_begin_conn(cell
, circ
);
223 case RELAY_COMMAND_DATA
:
224 ++stats_n_data_cells_received
;
225 if((edge_type
== EDGE_AP
&& --layer_hint
->deliver_window
< 0) ||
226 (edge_type
== EDGE_EXIT
&& --circ
->deliver_window
< 0)) {
227 log_fn(LOG_WARN
,"(relay data) circ deliver_window below 0. Killing.");
228 if(connection_edge_end(conn
, END_STREAM_REASON_MISC
, conn
->cpath_layer
) < 0)
229 log_fn(LOG_WARN
,"2: I called connection_edge_end redundantly.");
232 log_fn(LOG_DEBUG
,"circ deliver_window now %d.", edge_type
== EDGE_AP
? layer_hint
->deliver_window
: circ
->deliver_window
);
234 if(circuit_consider_sending_sendme(circ
, edge_type
, layer_hint
) < 0) {
235 log_fn(LOG_WARN
,"circuit_consider_sending_sendme() failed.");
236 conn
->has_sent_end
= 1; /* we failed because conn is broken. can't send end. */
241 log_fn(LOG_INFO
,"relay cell dropped, unknown stream %d.",*(int*)conn
->stream_id
);
245 if(--conn
->deliver_window
< 0) { /* is it below 0 after decrement? */
246 log_fn(LOG_WARN
,"(relay data) conn deliver_window below 0. Killing.");
247 return -1; /* somebody's breaking protocol. kill the whole circuit. */
250 // printf("New text for buf (%d bytes): '%s'", cell->length - RELAY_HEADER_SIZE, cell->payload + RELAY_HEADER_SIZE);
251 stats_n_data_bytes_received
+= CELL_RELAY_LENGTH(*cell
);
252 connection_write_to_buf(cell
->payload
+ RELAY_HEADER_SIZE
,
253 CELL_RELAY_LENGTH(*cell
), conn
);
254 connection_edge_consider_sending_sendme(conn
);
256 case RELAY_COMMAND_END
:
258 log_fn(LOG_INFO
,"end cell (%s) dropped, unknown stream %d.",
259 connection_edge_end_reason(cell
->payload
+RELAY_HEADER_SIZE
, CELL_RELAY_LENGTH(*cell
)),
260 *(int*)conn
->stream_id
);
263 if(CELL_RELAY_LENGTH(*cell
) >= 5 &&
264 *(cell
->payload
+RELAY_HEADER_SIZE
) == END_STREAM_REASON_EXITPOLICY
) {
265 /* No need to close the connection. We'll hold it open while
266 * we try a new exit node.
267 * cell->payload+RELAY_HEADER_SIZE+1 holds the destination addr.
269 addr
= ntohl(*(uint32_t*)(cell
->payload
+RELAY_HEADER_SIZE
+1));
270 client_dns_set_entry(conn
->socks_request
->address
, addr
);
271 conn
->state
= AP_CONN_STATE_CIRCUIT_WAIT
;
272 switch(connection_ap_handshake_attach_circuit(conn
)) {
273 case -1: /* it will never work */
274 break; /* conn will get closed below */
275 case 0: /* no useful circuits available */
276 if(!circuit_get_newest(conn
, 0)) /* is one already on the way? */
277 circuit_launch_new();
279 case 1: /* it succeeded, great */
283 log_fn(LOG_INFO
,"end cell (%s) for stream %d. Removing stream.",
284 connection_edge_end_reason(cell
->payload
+RELAY_HEADER_SIZE
, CELL_RELAY_LENGTH(*cell
)),
285 *(int*)conn
->stream_id
);
288 conn
->done_sending
= 1;
289 shutdown(conn
->s
, 1); /* XXX check return; refactor NM */
290 if (conn
->done_receiving
) {
291 conn
->marked_for_close
= 1;
292 conn
->has_sent_end
= 1; /* no need to send end, we just got one! */
295 conn
->marked_for_close
= 1;
296 conn
->has_sent_end
= 1; /* no need to send end, we just got one! */
299 case RELAY_COMMAND_EXTEND
:
301 log_fn(LOG_WARN
,"'extend' for non-zero stream. Dropping.");
304 return circuit_extend(cell
, circ
);
305 case RELAY_COMMAND_EXTENDED
:
306 if(edge_type
== EDGE_EXIT
) {
307 log_fn(LOG_WARN
,"'extended' unsupported at exit. Dropping.");
310 log_fn(LOG_DEBUG
,"Got an extended cell! Yay.");
311 if(circuit_finish_handshake(circ
, cell
->payload
+RELAY_HEADER_SIZE
) < 0) {
312 log_fn(LOG_WARN
,"circuit_finish_handshake failed.");
315 if (circuit_send_next_onion_skin(circ
)<0) {
316 log_fn(LOG_INFO
,"circuit_send_next_onion_skin() failed.");
320 case RELAY_COMMAND_TRUNCATE
:
321 if(edge_type
== EDGE_AP
) {
322 log_fn(LOG_WARN
,"'truncate' unsupported at AP. Dropping.");
326 connection_send_destroy(circ
->n_circ_id
, circ
->n_conn
);
329 log_fn(LOG_DEBUG
, "Processed 'truncate', replying.");
330 connection_edge_send_command(NULL
, circ
, RELAY_COMMAND_TRUNCATED
,
333 case RELAY_COMMAND_TRUNCATED
:
334 if(edge_type
== EDGE_EXIT
) {
335 log_fn(LOG_WARN
,"'truncated' unsupported at exit. Dropping.");
338 circuit_truncated(circ
, layer_hint
);
340 case RELAY_COMMAND_CONNECTED
:
341 if(edge_type
== EDGE_EXIT
) {
342 log_fn(LOG_WARN
,"'connected' unsupported at exit. Dropping.");
346 log_fn(LOG_INFO
,"connected cell dropped, unknown stream %d.",*(int*)conn
->stream_id
);
349 log_fn(LOG_INFO
,"Connected! Notifying application.");
350 if (CELL_RELAY_LENGTH(*cell
) >= 4) {
351 addr
= ntohl(*(uint32_t*)(cell
->payload
+ RELAY_HEADER_SIZE
));
352 client_dns_set_entry(conn
->socks_request
->address
, addr
);
354 if(connection_ap_handshake_socks_reply(conn
, NULL
, 0, 1) < 0) {
355 log_fn(LOG_INFO
,"Writing to socks-speaking application failed. Closing.");
356 if(connection_edge_end(conn
, END_STREAM_REASON_MISC
, conn
->cpath_layer
) < 0)
357 log_fn(LOG_WARN
,"3: I called connection_edge_end redundantly.");
360 case RELAY_COMMAND_SENDME
:
362 if(edge_type
== EDGE_AP
) {
364 layer_hint
->package_window
+= CIRCWINDOW_INCREMENT
;
365 log_fn(LOG_DEBUG
,"circ-level sendme at AP, packagewindow %d.", layer_hint
->package_window
);
366 circuit_resume_edge_reading(circ
, EDGE_AP
, layer_hint
);
369 circ
->package_window
+= CIRCWINDOW_INCREMENT
;
370 log_fn(LOG_DEBUG
,"circ-level sendme at exit, packagewindow %d.", circ
->package_window
);
371 circuit_resume_edge_reading(circ
, EDGE_EXIT
, layer_hint
);
375 conn
->package_window
+= STREAMWINDOW_INCREMENT
;
376 log_fn(LOG_DEBUG
,"stream-level sendme, packagewindow now %d.", conn
->package_window
);
377 connection_start_reading(conn
);
378 connection_edge_package_raw_inbuf(conn
); /* handle whatever might still be on the inbuf */
381 log_fn(LOG_WARN
,"unknown relay command %d.",relay_command
);
388 int connection_edge_finished_flushing(connection_t
*conn
) {
389 unsigned char connected_payload
[4];
390 int e
, len
=sizeof(e
);
393 assert(conn
->type
== CONN_TYPE_AP
|| conn
->type
== CONN_TYPE_EXIT
);
395 switch(conn
->state
) {
396 case EXIT_CONN_STATE_CONNECTING
:
397 if (getsockopt(conn
->s
, SOL_SOCKET
, SO_ERROR
, (void*)&e
, &len
) < 0) { /* not yet */
398 if(!ERRNO_CONN_EINPROGRESS(errno
)) {
400 log_fn(LOG_DEBUG
,"in-progress exit connect failed. Removing.");
403 log_fn(LOG_DEBUG
,"in-progress exit connect still waiting.");
404 return 0; /* no change, see if next time is better */
407 /* the connect has finished. */
409 log_fn(LOG_INFO
,"Exit connection to %s:%u established.",
410 conn
->address
,conn
->port
);
412 conn
->state
= EXIT_CONN_STATE_OPEN
;
413 connection_watch_events(conn
, POLLIN
); /* stop writing, continue reading */
414 if(connection_wants_to_flush(conn
)) /* in case there are any queued relay cells */
415 connection_start_writing(conn
);
416 /* deliver a 'connected' relay cell back through the circuit. */
417 *(uint32_t*)connected_payload
= htonl(conn
->addr
);
418 if(connection_edge_send_command(conn
, circuit_get_by_conn(conn
),
419 RELAY_COMMAND_CONNECTED
, NULL
, 0, conn
->cpath_layer
) < 0)
420 return 0; /* circuit is closed, don't continue */
421 assert(conn
->package_window
> 0);
422 return connection_edge_process_inbuf(conn
); /* in case the server has written anything */
423 case AP_CONN_STATE_OPEN
:
424 case EXIT_CONN_STATE_OPEN
:
425 connection_stop_writing(conn
);
426 connection_edge_consider_sending_sendme(conn
);
428 case AP_CONN_STATE_SOCKS_WAIT
:
429 connection_stop_writing(conn
);
432 log_fn(LOG_WARN
,"BUG: called in unexpected state: %d", conn
->state
);
438 uint64_t stats_n_data_cells_packaged
= 0;
439 uint64_t stats_n_data_bytes_packaged
= 0;
440 uint64_t stats_n_data_cells_received
= 0;
441 uint64_t stats_n_data_bytes_received
= 0;
443 int connection_edge_package_raw_inbuf(connection_t
*conn
) {
444 int amount_to_process
, length
;
445 char payload
[CELL_PAYLOAD_SIZE
];
449 assert(!connection_speaks_cells(conn
));
451 repeat_connection_edge_package_raw_inbuf
:
453 circ
= circuit_get_by_conn(conn
);
455 log_fn(LOG_INFO
,"conn has no circuits! Closing.");
459 if(circuit_consider_stop_edge_reading(circ
, conn
->type
, conn
->cpath_layer
))
462 if(conn
->package_window
<= 0) {
463 log_fn(LOG_WARN
,"called with package_window %d. Tell Roger.", conn
->package_window
);
464 connection_stop_reading(conn
);
468 amount_to_process
= buf_datalen(conn
->inbuf
);
470 if(!amount_to_process
)
473 if(amount_to_process
> RELAY_PAYLOAD_SIZE
) {
474 length
= RELAY_PAYLOAD_SIZE
;
476 length
= amount_to_process
;
478 stats_n_data_bytes_packaged
+= length
;
479 stats_n_data_cells_packaged
+= 1;
481 connection_fetch_from_buf(payload
, length
, conn
);
483 log_fn(LOG_DEBUG
,"(%d) Packaging %d bytes (%d waiting).", conn
->s
, length
,
484 (int)buf_datalen(conn
->inbuf
));
486 if(connection_edge_send_command(conn
, circ
, RELAY_COMMAND_DATA
,
487 payload
, length
, conn
->cpath_layer
) < 0)
488 return 0; /* circuit is closed, don't continue */
490 if(conn
->type
== CONN_TYPE_EXIT
) {
491 assert(circ
->package_window
> 0);
492 circ
->package_window
--;
493 } else { /* we're an AP */
494 assert(conn
->type
== CONN_TYPE_AP
);
495 assert(conn
->cpath_layer
->package_window
> 0);
496 conn
->cpath_layer
->package_window
--;
499 if(--conn
->package_window
<= 0) { /* is it 0 after decrement? */
500 connection_stop_reading(conn
);
501 log_fn(LOG_DEBUG
,"conn->package_window reached 0.");
502 circuit_consider_stop_edge_reading(circ
, conn
->type
, conn
->cpath_layer
);
503 return 0; /* don't process the inbuf any more */
505 log_fn(LOG_DEBUG
,"conn->package_window is now %d",conn
->package_window
);
507 /* handle more if there's more, or return 0 if there isn't */
508 goto repeat_connection_edge_package_raw_inbuf
;
511 /* Tell any APs that are waiting for a new circuit that one is available */
512 void connection_ap_attach_pending(void)
514 connection_t
**carray
;
518 get_connection_array(&carray
, &n
);
520 for (i
= 0; i
< n
; ++i
) {
522 if (conn
->type
!= CONN_TYPE_AP
||
523 conn
->state
!= AP_CONN_STATE_CIRCUIT_WAIT
)
525 switch(connection_ap_handshake_attach_circuit(conn
)) {
526 case -1: /* it will never work */
527 conn
->marked_for_close
= 1;
528 conn
->has_sent_end
= 1;
530 case 0: /* we need to build another circuit */
531 if(!circuit_get_newest(conn
, 0)) {
532 /* if there are no acceptable clean or not-very-dirty circs on the way */
533 circuit_launch_new();
536 case 1: /* it succeeded, great */
542 static void connection_edge_consider_sending_sendme(connection_t
*conn
) {
545 if(connection_outbuf_too_full(conn
))
548 circ
= circuit_get_by_conn(conn
);
550 /* this can legitimately happen if the destroy has already
551 * arrived and torn down the circuit */
552 log_fn(LOG_INFO
,"No circuit associated with conn. Skipping.");
556 while(conn
->deliver_window
< STREAMWINDOW_START
- STREAMWINDOW_INCREMENT
) {
557 log_fn(LOG_DEBUG
,"Outbuf %d, Queueing stream sendme.", conn
->outbuf_flushlen
);
558 conn
->deliver_window
+= STREAMWINDOW_INCREMENT
;
559 if(connection_edge_send_command(conn
, circ
, RELAY_COMMAND_SENDME
,
560 NULL
, 0, conn
->cpath_layer
) < 0) {
561 log_fn(LOG_WARN
,"connection_edge_send_command failed. Returning.");
562 return; /* the circuit's closed, don't continue */
567 static int connection_ap_handshake_process_socks(connection_t
*conn
) {
568 socks_request_t
*socks
;
572 assert(conn
->type
== CONN_TYPE_AP
);
573 assert(conn
->state
== AP_CONN_STATE_SOCKS_WAIT
);
574 assert(conn
->socks_request
);
575 socks
= conn
->socks_request
;
577 log_fn(LOG_DEBUG
,"entered.");
579 sockshere
= fetch_from_buf_socks(conn
->inbuf
, socks
);
580 if(sockshere
== -1 || sockshere
== 0) {
581 if(socks
->replylen
) { /* we should send reply back */
582 log_fn(LOG_DEBUG
,"reply is already set for us. Using it.");
583 connection_ap_handshake_socks_reply(conn
, socks
->reply
, socks
->replylen
, 0);
584 } else if(sockshere
== -1) { /* send normal reject */
585 log_fn(LOG_WARN
,"Fetching socks handshake failed. Closing.");
586 connection_ap_handshake_socks_reply(conn
, NULL
, 0, 0);
588 log_fn(LOG_DEBUG
,"socks handshake not all here yet.");
591 } /* else socks handshake is done, continue processing */
593 conn
->state
= AP_CONN_STATE_CIRCUIT_WAIT
;
594 switch(connection_ap_handshake_attach_circuit(conn
)) {
595 case -1: /* it will never work */
597 case 0: /* no useful circuits available */
598 if(!circuit_get_newest(conn
, 0)) /* is one already on the way? */
599 circuit_launch_new();
601 case 1: /* it succeeded, great */
607 /* Try to find a safe live circuit for CONN_TYPE_AP connection conn. If
608 * we don't find one: if conn cannot be handled by any known nodes,
609 * warn and return -1; else tell conn to stop reading and return 0.
610 * Otherwise, associate conn with a safe live circuit, start
611 * sending a BEGIN cell down the circuit, and return 1.
613 static int connection_ap_handshake_attach_circuit(connection_t
*conn
) {
618 assert(conn
->type
== CONN_TYPE_AP
);
619 assert(conn
->state
== AP_CONN_STATE_CIRCUIT_WAIT
);
620 assert(conn
->socks_request
);
622 /* find the circuit that we should use, if there is one. */
623 circ
= circuit_get_newest(conn
, 1);
626 log_fn(LOG_INFO
,"No safe circuit ready for edge connection; delaying.");
627 addr
= client_dns_lookup_entry(conn
->socks_request
->address
);
628 if(router_exit_policy_all_routers_reject(addr
, conn
->socks_request
->port
)) {
629 log_fn(LOG_WARN
,"No node exists that will handle exit to %s:%d. Rejecting.",
630 conn
->socks_request
->address
, conn
->socks_request
->port
);
633 connection_stop_reading(conn
); /* don't read until the connected cell arrives */
637 connection_start_reading(conn
);
639 if(!circ
->timestamp_dirty
)
640 circ
->timestamp_dirty
= time(NULL
);
642 /* add it into the linked list of streams on this circuit */
643 log_fn(LOG_DEBUG
,"attaching new conn to circ. n_circ_id %d.", circ
->n_circ_id
);
644 conn
->next_stream
= circ
->p_streams
;
645 /* assert_connection_ok(conn, time(NULL)); */
646 circ
->p_streams
= conn
;
648 assert(circ
->cpath
&& circ
->cpath
->prev
);
649 assert(circ
->cpath
->prev
->state
== CPATH_STATE_OPEN
);
650 conn
->cpath_layer
= circ
->cpath
->prev
;
652 connection_ap_handshake_send_begin(conn
, circ
);
657 /* deliver the destaddr:destport in a relay cell */
658 static void connection_ap_handshake_send_begin(connection_t
*ap_conn
, circuit_t
*circ
)
660 char payload
[CELL_PAYLOAD_SIZE
];
663 const char *string_addr
;
665 assert(ap_conn
->type
== CONN_TYPE_AP
);
666 assert(ap_conn
->state
== AP_CONN_STATE_CIRCUIT_WAIT
);
667 assert(ap_conn
->socks_request
);
669 crypto_pseudo_rand(STREAM_ID_SIZE
, ap_conn
->stream_id
);
670 /* FIXME check for collisions */
672 in
.s_addr
= htonl(client_dns_lookup_entry(ap_conn
->socks_request
->address
));
673 string_addr
= in
.s_addr
? inet_ntoa(in
) : NULL
;
675 memcpy(payload
, ap_conn
->stream_id
, STREAM_ID_SIZE
);
676 payload_len
= STREAM_ID_SIZE
+ 1 +
677 snprintf(payload
+STREAM_ID_SIZE
,CELL_PAYLOAD_SIZE
-RELAY_HEADER_SIZE
-STREAM_ID_SIZE
,
679 string_addr
? string_addr
: ap_conn
->socks_request
->address
,
680 ap_conn
->socks_request
->port
);
682 log_fn(LOG_DEBUG
,"Sending relay cell to begin stream %d.",*(int *)ap_conn
->stream_id
);
684 if(connection_edge_send_command(ap_conn
, circ
, RELAY_COMMAND_BEGIN
,
685 payload
, payload_len
, ap_conn
->cpath_layer
) < 0)
686 return; /* circuit is closed, don't continue */
688 ap_conn
->package_window
= STREAMWINDOW_START
;
689 ap_conn
->deliver_window
= STREAMWINDOW_START
;
690 ap_conn
->state
= AP_CONN_STATE_OPEN
;
691 /* XXX Right now, we rely on the socks client not to send us any data
692 * XXX until we've sent back a socks reply. (If it does, we could wind
693 * XXX up packaging that data and sending it to the exit, then later having
694 * XXX the exit refuse us.)
695 * XXX Perhaps we should grow an AP_CONN_STATE_CONNECTING state.
697 log_fn(LOG_INFO
,"Address/port sent, ap socket %d, n_circ_id %d",ap_conn
->s
,circ
->n_circ_id
);
701 static int connection_ap_handshake_socks_reply(connection_t
*conn
, char *reply
,
702 int replylen
, char success
) {
705 if(replylen
) { /* we already have a reply in mind */
706 connection_write_to_buf(reply
, replylen
, conn
);
707 return flush_buf(conn
->s
, conn
->outbuf
, &conn
->outbuf_flushlen
); /* try to flush it */
709 assert(conn
->socks_request
);
710 if(conn
->socks_request
->socks_version
== 4) {
711 memset(buf
,0,SOCKS4_NETWORK_LEN
);
712 #define SOCKS4_GRANTED 90
713 #define SOCKS4_REJECT 91
714 buf
[1] = (success
? SOCKS4_GRANTED
: SOCKS4_REJECT
);
715 /* leave version, destport, destip zero */
716 connection_write_to_buf(buf
, SOCKS4_NETWORK_LEN
, conn
);
717 return flush_buf(conn
->s
, conn
->outbuf
, &conn
->outbuf_flushlen
); /* try to flush it */
719 if(conn
->socks_request
->socks_version
== 5) {
720 buf
[0] = 5; /* version 5 */
721 #define SOCKS5_SUCCESS 0
722 #define SOCKS5_GENERIC_ERROR 1
723 buf
[1] = success
? SOCKS5_SUCCESS
: SOCKS5_GENERIC_ERROR
;
725 buf
[3] = 1; /* ipv4 addr */
726 memset(buf
+4,0,6); /* Set external addr/port to 0.
727 The spec doesn't seem to say what to do here. -RD */
728 connection_write_to_buf(buf
,10,conn
);
729 return flush_buf(conn
->s
, conn
->outbuf
, &conn
->outbuf_flushlen
); /* try to flush it */
731 return 0; /* if socks_version isn't 4 or 5, don't send anything */
734 static int connection_exit_begin_conn(cell_t
*cell
, circuit_t
*circ
) {
735 connection_t
*n_stream
;
738 /* XXX currently we don't send an end cell back if we drop the
739 * begin because it's malformed.
742 if(!memchr(cell
->payload
+RELAY_HEADER_SIZE
+STREAM_ID_SIZE
,0,
743 CELL_RELAY_LENGTH(*cell
)-STREAM_ID_SIZE
)) {
744 log_fn(LOG_WARN
,"relay begin cell has no \\0. Dropping.");
747 colon
= strchr(cell
->payload
+RELAY_HEADER_SIZE
+STREAM_ID_SIZE
, ':');
749 log_fn(LOG_WARN
,"relay begin cell has no colon. Dropping.");
754 if(!atoi(colon
+1)) { /* bad port */
755 log_fn(LOG_WARN
,"relay begin cell has invalid port. Dropping.");
759 log_fn(LOG_DEBUG
,"Creating new exit connection.");
760 n_stream
= connection_new(CONN_TYPE_EXIT
);
762 memcpy(n_stream
->stream_id
, cell
->payload
+ RELAY_HEADER_SIZE
, STREAM_ID_SIZE
);
763 n_stream
->address
= tor_strdup(cell
->payload
+ RELAY_HEADER_SIZE
+ STREAM_ID_SIZE
);
764 n_stream
->port
= atoi(colon
+1);
765 n_stream
->state
= EXIT_CONN_STATE_RESOLVING
;
766 /* leave n_stream->s at -1, because it's not yet valid */
767 n_stream
->package_window
= STREAMWINDOW_START
;
768 n_stream
->deliver_window
= STREAMWINDOW_START
;
769 if(connection_add(n_stream
) < 0) { /* no space, forget it */
770 log_fn(LOG_WARN
,"connection_add failed. Dropping.");
771 connection_free(n_stream
);
775 /* add it into the linked list of streams on this circuit */
776 n_stream
->next_stream
= circ
->n_streams
;
777 circ
->n_streams
= n_stream
;
779 /* send it off to the gethostbyname farm */
780 switch(dns_resolve(n_stream
)) {
781 case 1: /* resolve worked */
782 connection_exit_connect(n_stream
);
784 case -1: /* resolve failed */
785 log_fn(LOG_INFO
,"Resolve failed (%s).", n_stream
->address
);
786 if(connection_edge_end(n_stream
, END_STREAM_REASON_RESOLVEFAILED
, NULL
) < 0)
787 log_fn(LOG_WARN
,"1: I called connection_edge_end redundantly.");
788 /* case 0, resolve added to pending list */
793 void connection_exit_connect(connection_t
*conn
) {
794 unsigned char connected_payload
[4];
796 if(router_compare_to_my_exit_policy(conn
) < 0) {
797 log_fn(LOG_INFO
,"%s:%d failed exit policy. Closing.", conn
->address
, conn
->port
);
798 if(connection_edge_end(conn
, END_STREAM_REASON_EXITPOLICY
, NULL
) < 0)
799 log_fn(LOG_WARN
,"1: I called connection_edge_end redundantly.");
803 switch(connection_connect(conn
, conn
->address
, conn
->addr
, conn
->port
)) {
805 if(connection_edge_end(conn
, END_STREAM_REASON_CONNECTFAILED
, NULL
) < 0)
806 log_fn(LOG_WARN
,"2: I called connection_edge_end redundantly.");
809 connection_set_poll_socket(conn
);
810 conn
->state
= EXIT_CONN_STATE_CONNECTING
;
812 connection_watch_events(conn
, POLLOUT
| POLLIN
| POLLERR
);
813 /* writable indicates finish, readable indicates broken link,
814 error indicates broken link in windowsland. */
816 /* case 1: fall through */
819 connection_set_poll_socket(conn
);
820 conn
->state
= EXIT_CONN_STATE_OPEN
;
821 if(connection_wants_to_flush(conn
)) { /* in case there are any queued data cells */
822 log_fn(LOG_WARN
,"tell roger: newly connected conn had data waiting!");
823 // connection_start_writing(conn);
825 // connection_process_inbuf(conn);
826 connection_watch_events(conn
, POLLIN
);
828 /* also, deliver a 'connected' cell back through the circuit. */
829 *((uint32_t*) connected_payload
) = htonl(conn
->addr
);
830 connection_edge_send_command(conn
, circuit_get_by_conn(conn
), RELAY_COMMAND_CONNECTED
,
831 connected_payload
, 4, conn
->cpath_layer
);
834 int connection_ap_can_use_exit(connection_t
*conn
, routerinfo_t
*exit
)
839 assert(conn
->type
== CONN_TYPE_AP
);
840 assert(conn
->socks_request
);
842 log_fn(LOG_DEBUG
,"considering nickname %s, for address %s / port %d:",
843 exit
->nickname
, conn
->socks_request
->address
,
844 conn
->socks_request
->port
);
845 addr
= client_dns_lookup_entry(conn
->socks_request
->address
);
846 return router_supports_exit_address(addr
, conn
->socks_request
->port
, exit
);
849 /* ***** Client DNS code ***** */
851 /* XXX Perhaps this should get merged with the dns.c code somehow. */
852 /* XXX But we can't just merge them, because then nodes that act as
853 * both OR and OP could be attacked: people could rig the dns cache
854 * by answering funny things to stream begin requests, and later
855 * other clients would reuse those funny addr's. Hm.
857 struct client_dns_entry
{
858 SPLAY_ENTRY(client_dns_entry
) node
;
863 static int client_dns_size
= 0;
864 static SPLAY_HEAD(client_dns_tree
, client_dns_entry
) client_dns_root
;
866 static int compare_client_dns_entries(struct client_dns_entry
*a
,
867 struct client_dns_entry
*b
)
869 return strcasecmp(a
->address
, b
->address
);
872 static void client_dns_entry_free(struct client_dns_entry
*ent
)
874 tor_free(ent
->address
);
878 SPLAY_PROTOTYPE(client_dns_tree
, client_dns_entry
, node
, compare_client_dns_entries
);
879 SPLAY_GENERATE(client_dns_tree
, client_dns_entry
, node
, compare_client_dns_entries
);
881 void client_dns_init(void) {
882 SPLAY_INIT(&client_dns_root
);
886 static uint32_t client_dns_lookup_entry(const char *address
)
888 struct client_dns_entry
*ent
;
889 struct client_dns_entry search
;
895 if (inet_aton(address
, &in
)) {
896 log_fn(LOG_DEBUG
, "Using static address %s (%08lX)", address
,
897 (unsigned long)ntohl(in
.s_addr
));
898 return ntohl(in
.s_addr
);
900 search
.address
= (char*)address
;
901 ent
= SPLAY_FIND(client_dns_tree
, &client_dns_root
, &search
);
903 log_fn(LOG_DEBUG
, "No entry found for address %s", address
);
907 if (ent
->expires
< now
) {
908 log_fn(LOG_DEBUG
, "Expired entry found for address %s", address
);
909 SPLAY_REMOVE(client_dns_tree
, &client_dns_root
, ent
);
910 client_dns_entry_free(ent
);
914 in
.s_addr
= htonl(ent
->addr
);
915 log_fn(LOG_DEBUG
, "Found cached entry for address %s: %s", address
,
920 static void client_dns_set_entry(const char *address
, uint32_t val
)
922 struct client_dns_entry
*ent
;
923 struct client_dns_entry search
;
930 if (inet_aton(address
, &in
))
932 search
.address
= (char*) address
;
934 ent
= SPLAY_FIND(client_dns_tree
, &client_dns_root
, &search
);
936 in
.s_addr
= htonl(val
);
937 log_fn(LOG_DEBUG
, "Updating entry for address %s: %s", address
,
940 ent
->expires
= now
+MAX_DNS_ENTRY_AGE
;
942 in
.s_addr
= htonl(val
);
943 log_fn(LOG_DEBUG
, "Caching result for address %s: %s", address
,
945 ent
= tor_malloc(sizeof(struct client_dns_entry
));
946 ent
->address
= tor_strdup(address
);
948 ent
->expires
= now
+MAX_DNS_ENTRY_AGE
;
949 SPLAY_INSERT(client_dns_tree
, &client_dns_root
, ent
);
954 void client_dns_clean(void)
956 struct client_dns_entry
**expired_entries
;
957 int n_expired_entries
= 0;
958 struct client_dns_entry
*ent
;
964 expired_entries
= tor_malloc(client_dns_size
*
965 sizeof(struct client_dns_entry
*));
968 SPLAY_FOREACH(ent
, client_dns_tree
, &client_dns_root
) {
969 if (ent
->expires
< now
) {
970 expired_entries
[n_expired_entries
++] = ent
;
973 for (i
= 0; i
< n_expired_entries
; ++i
) {
974 SPLAY_REMOVE(client_dns_tree
, &client_dns_root
, expired_entries
[i
]);
975 client_dns_entry_free(expired_entries
[i
]);
977 tor_free(expired_entries
);