1 /* Copyright 2001,2002 Roger Dingledine, Matej Pfajfar. */
2 /* See LICENSE for licensing information */
7 int connection_exit_begin_conn(cell_t
*cell
, circuit_t
*circ
) {
8 connection_t
*n_stream
;
11 if(!memchr(cell
->payload
+RELAY_HEADER_SIZE
+STREAM_ID_SIZE
,0,cell
->length
-RELAY_HEADER_SIZE
-STREAM_ID_SIZE
)) {
12 log_fn(LOG_WARNING
,"relay begin cell has no \\0. Dropping.");
15 colon
= strchr(cell
->payload
+RELAY_HEADER_SIZE
+STREAM_ID_SIZE
, ':');
17 log_fn(LOG_WARNING
,"relay begin cell has no colon. Dropping.");
22 if(!atoi(colon
+1)) { /* bad port */
23 log_fn(LOG_DEBUG
,"relay begin cell has invalid port. Dropping.");
27 log_fn(LOG_DEBUG
,"Creating new exit connection.");
28 n_stream
= connection_new(CONN_TYPE_EXIT
);
30 log_fn(LOG_DEBUG
,"connection_new failed. Dropping.");
34 memcpy(n_stream
->stream_id
, cell
->payload
+ RELAY_HEADER_SIZE
, STREAM_ID_SIZE
);
35 n_stream
->address
= strdup(cell
->payload
+ RELAY_HEADER_SIZE
+ STREAM_ID_SIZE
);
36 n_stream
->port
= atoi(colon
+1);
37 n_stream
->state
= EXIT_CONN_STATE_RESOLVING
;
38 n_stream
->receiver_bucket
= -1; /* edge connections don't do receiver buckets */
39 n_stream
->bandwidth
= -1;
40 n_stream
->s
= -1; /* not yet valid */
41 n_stream
->package_window
= STREAMWINDOW_START
;
42 n_stream
->deliver_window
= STREAMWINDOW_START
;
43 if(connection_add(n_stream
) < 0) { /* no space, forget it */
44 log_fn(LOG_DEBUG
,"connection_add failed. Dropping.");
45 connection_free(n_stream
);
49 /* add it into the linked list of streams on this circuit */
50 n_stream
->next_stream
= circ
->n_streams
;
51 circ
->n_streams
= n_stream
;
53 /* send it off to the gethostbyname farm */
54 if(dns_resolve(n_stream
) < 0) {
55 log_fn(LOG_DEBUG
,"Couldn't queue resolve request.");
56 connection_remove(n_stream
);
57 connection_free(n_stream
);
64 int connection_exit_connect(connection_t
*conn
) {
65 int s
; /* for the new socket */
66 struct sockaddr_in dest_addr
;
68 if(router_compare_to_exit_policy(conn
) < 0) {
69 log_fn(LOG_INFO
,"%s:%d failed exit policy. Closing.", conn
->address
, conn
->port
);
73 /* all the necessary info is here. Start the connect() */
74 s
=socket(PF_INET
,SOCK_STREAM
,IPPROTO_TCP
);
76 log_fn(LOG_ERR
,"Error creating network socket.");
79 fcntl(s
, F_SETFL
, O_NONBLOCK
); /* set s to non-blocking */
81 memset((void *)&dest_addr
,0,sizeof(dest_addr
));
82 dest_addr
.sin_family
= AF_INET
;
83 dest_addr
.sin_port
= htons(conn
->port
);
84 dest_addr
.sin_addr
.s_addr
= htonl(conn
->addr
);
86 log_fn(LOG_DEBUG
,"Connecting to %s:%u.",conn
->address
,conn
->port
);
88 if(connect(s
,(struct sockaddr
*)&dest_addr
,sizeof(dest_addr
)) < 0) {
89 if(errno
!= EINPROGRESS
){
92 log_fn(LOG_DEBUG
,"Connect failed.");
95 /* it's in progress. set state appropriately and return. */
97 connection_set_poll_socket(conn
);
98 conn
->state
= EXIT_CONN_STATE_CONNECTING
;
100 log_fn(LOG_DEBUG
,"connect in progress, socket %d.",s
);
101 connection_watch_events(conn
, POLLOUT
| POLLIN
);
106 /* it succeeded. we're connected. */
107 log_fn(LOG_DEBUG
,"Connection to %s:%u established.",conn
->address
,conn
->port
);
110 connection_set_poll_socket(conn
);
111 conn
->state
= EXIT_CONN_STATE_OPEN
;
112 if(connection_wants_to_flush(conn
)) { /* in case there are any queued data cells */
113 log_fn(LOG_ERR
,"tell roger: newly connected conn had data waiting!");
114 // connection_start_writing(conn);
116 // connection_process_inbuf(conn);
117 connection_watch_events(conn
, POLLIN
);
119 /* also, deliver a 'connected' cell back through the circuit. */
120 return connection_edge_send_command(conn
, circuit_get_by_conn(conn
), RELAY_COMMAND_CONNECTED
);