mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
refactor connects into connection_connect()
svn:r460
This commit is contained in:
parent
e4dfc3c8fe
commit
9c6343fdf8
@ -160,8 +160,7 @@ int connection_create_listener(struct sockaddr_in *bindaddr, int type) {
|
||||
int one=1;
|
||||
|
||||
s = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
|
||||
if (s < 0)
|
||||
{
|
||||
if (s < 0) {
|
||||
log_fn(LOG_ERR,"Socket creation failed.");
|
||||
return -1;
|
||||
}
|
||||
@ -386,6 +385,49 @@ static int connection_tls_finish_handshake(connection_t *conn) {
|
||||
}
|
||||
#endif
|
||||
|
||||
/* take conn, make a nonblocking socket; try to connect to
|
||||
* addr:port (they arrive in *host order*). If fail, return -1. Else
|
||||
* assign s to conn->s: if connected return 1, if eagain return 0.
|
||||
* address is used to make the logs useful.
|
||||
*/
|
||||
int connection_connect(connection_t *conn, char *address, uint32_t addr, uint16_t port) {
|
||||
int s;
|
||||
struct sockaddr_in dest_addr;
|
||||
|
||||
s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
|
||||
if (s < 0) {
|
||||
log_fn(LOG_ERR,"Error creating network socket.");
|
||||
return -1;
|
||||
}
|
||||
set_socket_nonblocking(s);
|
||||
|
||||
memset((void *)&dest_addr,0,sizeof(dest_addr));
|
||||
dest_addr.sin_family = AF_INET;
|
||||
dest_addr.sin_port = htons(port);
|
||||
dest_addr.sin_addr.s_addr = htonl(addr);
|
||||
|
||||
log_fn(LOG_DEBUG,"Connecting to %s:%u.",address,port);
|
||||
|
||||
if(connect(s,(struct sockaddr *)&dest_addr,sizeof(dest_addr)) < 0) {
|
||||
if(!ERRNO_CONN_EINPROGRESS(errno)) {
|
||||
/* yuck. kill it. */
|
||||
perror("connect");
|
||||
log_fn(LOG_DEBUG,"Connect failed.");
|
||||
return -1;
|
||||
} else {
|
||||
/* it's in progress. set state appropriately and return. */
|
||||
conn->s = s;
|
||||
log_fn(LOG_DEBUG,"connect in progress, socket %d.",s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* it succeeded. we're connected. */
|
||||
log_fn(LOG_DEBUG,"Connection to %s:%u established.",address,port);
|
||||
conn->s = s;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* start all connections that should be up but aren't */
|
||||
int retry_all_connections(uint16_t or_listenport, uint16_t ap_listenport, uint16_t dir_listenport) {
|
||||
struct sockaddr_in bindaddr; /* where to bind */
|
||||
|
@ -643,53 +643,26 @@ static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
|
||||
}
|
||||
|
||||
int connection_exit_connect(connection_t *conn) {
|
||||
int s; /* for the new socket */
|
||||
struct sockaddr_in dest_addr;
|
||||
|
||||
if(router_compare_to_exit_policy(conn) < 0) {
|
||||
log_fn(LOG_INFO,"%s:%d failed exit policy. Closing.", conn->address, conn->port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* all the necessary info is here. Start the connect() */
|
||||
s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
|
||||
if (s < 0) {
|
||||
log_fn(LOG_ERR,"Error creating network socket.");
|
||||
return -1;
|
||||
}
|
||||
set_socket_nonblocking(s);
|
||||
|
||||
memset((void *)&dest_addr,0,sizeof(dest_addr));
|
||||
dest_addr.sin_family = AF_INET;
|
||||
dest_addr.sin_port = htons(conn->port);
|
||||
dest_addr.sin_addr.s_addr = htonl(conn->addr);
|
||||
|
||||
log_fn(LOG_DEBUG,"Connecting to %s:%u.",conn->address,conn->port);
|
||||
|
||||
if(connect(s,(struct sockaddr *)&dest_addr,sizeof(dest_addr)) < 0) {
|
||||
if(!ERRNO_CONN_EINPROGRESS(errno)) {
|
||||
/* yuck. kill it. */
|
||||
perror("connect");
|
||||
log_fn(LOG_DEBUG,"Connect failed.");
|
||||
switch(connection_connect(conn, conn->address, conn->addr, conn->port)) {
|
||||
case -1:
|
||||
return -1;
|
||||
} else {
|
||||
/* it's in progress. set state appropriately and return. */
|
||||
conn->s = s;
|
||||
case 0:
|
||||
connection_set_poll_socket(conn);
|
||||
conn->state = EXIT_CONN_STATE_CONNECTING;
|
||||
|
||||
log_fn(LOG_DEBUG,"connect in progress, socket %d.",s);
|
||||
connection_watch_events(conn, POLLOUT | POLLIN | POLLERR);
|
||||
/* writable indicates finish, readable indicates broken link,
|
||||
error indicates broken link in windowsland. */
|
||||
return 0;
|
||||
}
|
||||
/* case 1: fall through */
|
||||
}
|
||||
|
||||
/* it succeeded. we're connected. */
|
||||
log_fn(LOG_DEBUG,"Connection to %s:%u established.",conn->address,conn->port);
|
||||
|
||||
conn->s = s;
|
||||
connection_set_poll_socket(conn);
|
||||
conn->state = EXIT_CONN_STATE_OPEN;
|
||||
if(connection_wants_to_flush(conn)) { /* in case there are any queued data cells */
|
||||
|
@ -73,7 +73,6 @@ int connection_or_finished_flushing(connection_t *conn) {
|
||||
#endif
|
||||
if (getsockopt(conn->s, SOL_SOCKET, SO_ERROR, (void*)&e, &len) < 0) { /* not yet */
|
||||
if(!ERRNO_CONN_EINPROGRESS(errno)){
|
||||
/* yuck. kill it. */
|
||||
log_fn(LOG_DEBUG,"in-progress connect failed. Removing.");
|
||||
return -1;
|
||||
} else {
|
||||
@ -123,8 +122,6 @@ int connection_or_finished_flushing(connection_t *conn) {
|
||||
|
||||
connection_t *connection_or_connect(routerinfo_t *router) {
|
||||
connection_t *conn;
|
||||
struct sockaddr_in router_addr;
|
||||
int s;
|
||||
|
||||
assert(router);
|
||||
|
||||
@ -152,35 +149,18 @@ connection_t *connection_or_connect(routerinfo_t *router) {
|
||||
conn->pkey = crypto_pk_dup_key(router->pkey);
|
||||
conn->address = strdup(router->address);
|
||||
|
||||
s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
|
||||
if (s < 0) {
|
||||
log(LOG_ERR,"Error creating network socket.");
|
||||
if(connection_add(conn) < 0) { /* no space, forget it */
|
||||
connection_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
set_socket_nonblocking(s);
|
||||
|
||||
memset((void *)&router_addr,0,sizeof(router_addr));
|
||||
router_addr.sin_family = AF_INET;
|
||||
router_addr.sin_port = htons(router->or_port);
|
||||
router_addr.sin_addr.s_addr = htonl(router->addr);
|
||||
|
||||
log(LOG_DEBUG,"connection_or_connect() : Trying to connect to %s:%u.",router->address,router->or_port);
|
||||
if(connect(s,(struct sockaddr *)&router_addr,sizeof(router_addr)) < 0){
|
||||
if(!ERRNO_CONN_EINPROGRESS(errno)) {
|
||||
/* yuck. kill it. */
|
||||
switch(connection_connect(conn, router->address, router->addr, router->or_port)) {
|
||||
case -1:
|
||||
connection_remove(conn);
|
||||
connection_free(conn);
|
||||
return NULL;
|
||||
} else {
|
||||
/* it's in progress. set state appropriately and return. */
|
||||
conn->s = s;
|
||||
|
||||
if(connection_add(conn) < 0) { /* no space, forget it */
|
||||
connection_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
log(LOG_DEBUG,"connection_or_connect() : connect in progress.");
|
||||
case 0:
|
||||
connection_set_poll_socket(conn);
|
||||
connection_watch_events(conn, POLLIN | POLLOUT | POLLERR);
|
||||
/* writable indicates finish, readable indicates broken link,
|
||||
error indicates broken link on windows */
|
||||
@ -190,19 +170,10 @@ connection_t *connection_or_connect(routerinfo_t *router) {
|
||||
conn->state = OR_CONN_STATE_CLIENT_CONNECTING;
|
||||
#endif
|
||||
return conn;
|
||||
}
|
||||
/* case 1: fall through */
|
||||
}
|
||||
|
||||
/* it succeeded. we're connected. */
|
||||
conn->s = s;
|
||||
|
||||
if(connection_add(conn) < 0) { /* no space, forget it */
|
||||
connection_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
log(LOG_DEBUG,"connection_or_connect() : Connection to router %s:%u established.",
|
||||
router->address, router->or_port);
|
||||
connection_set_poll_socket(conn);
|
||||
|
||||
#ifdef USE_TLS
|
||||
if(connection_tls_start_handshake(conn, 0) >= 0)
|
||||
|
@ -195,6 +195,7 @@ static int spawn_cpuworker(void) {
|
||||
conn->receiver_bucket = -1; /* non-cell connections don't do receiver buckets */
|
||||
conn->bandwidth = -1;
|
||||
conn->s = fd[0];
|
||||
conn->address = strdup("localhost");
|
||||
|
||||
if(connection_add(conn) < 0) { /* no space, forget it */
|
||||
log_fn(LOG_INFO,"connection_add failed. Giving up.");
|
||||
|
@ -22,14 +22,14 @@ static char answerstring[] = "HTTP/1.0 200 OK\r\n\r\n";
|
||||
|
||||
void directory_initiate_fetch(routerinfo_t *router) {
|
||||
connection_t *conn;
|
||||
struct sockaddr_in router_addr;
|
||||
int s;
|
||||
|
||||
if(!router) /* i guess they didn't have one in mind for me to use */
|
||||
return;
|
||||
|
||||
if(connection_get_by_type(CONN_TYPE_DIR)) /* there's already a fetch running */
|
||||
if(connection_get_by_type(CONN_TYPE_DIR)) { /* there's already a fetch running */
|
||||
log_fn(LOG_DEBUG,"Canceling fetch, dir conn already active.");
|
||||
return;
|
||||
}
|
||||
|
||||
log_fn(LOG_DEBUG,"initiating directory fetch");
|
||||
|
||||
@ -50,55 +50,27 @@ void directory_initiate_fetch(routerinfo_t *router) {
|
||||
conn->pkey = NULL;
|
||||
}
|
||||
|
||||
s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
|
||||
if(s < 0) {
|
||||
log_fn(LOG_ERR,"Error creating network socket.");
|
||||
connection_free(conn);
|
||||
return;
|
||||
}
|
||||
set_socket_nonblocking(s);
|
||||
|
||||
memset((void *)&router_addr,0,sizeof(router_addr));
|
||||
router_addr.sin_family = AF_INET;
|
||||
router_addr.sin_port = htons(router->dir_port);
|
||||
router_addr.sin_addr.s_addr = htonl(router->addr);
|
||||
|
||||
log_fn(LOG_DEBUG,"Trying to connect to %s:%u.",router->address,router->dir_port);
|
||||
|
||||
if(connect(s,(struct sockaddr *)&router_addr,sizeof(router_addr)) < 0){
|
||||
if(!ERRNO_CONN_EINPROGRESS(errno)) {
|
||||
/* yuck. kill it. */
|
||||
router_forget_router(conn->addr, conn->port); /* don't try him again */
|
||||
connection_free(conn);
|
||||
return;
|
||||
} else {
|
||||
/* it's in progress. set state appropriately and return. */
|
||||
conn->s = s;
|
||||
|
||||
if(connection_add(conn) < 0) { /* no space, forget it */
|
||||
connection_free(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
log_fn(LOG_DEBUG,"connect in progress.");
|
||||
connection_watch_events(conn, POLLIN | POLLOUT | POLLERR);
|
||||
/* writable indicates finish, readable indicates broken link,
|
||||
error indicates broken link in windowsland. */
|
||||
conn->state = DIR_CONN_STATE_CONNECTING;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* it succeeded. we're connected. */
|
||||
conn->s = s;
|
||||
|
||||
if(connection_add(conn) < 0) { /* no space, forget it */
|
||||
connection_free(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
log_fn(LOG_DEBUG,"Connection to router %s:%u established.",router->address,router->dir_port);
|
||||
switch(connection_connect(conn, router->address, router->addr, router->dir_port)) {
|
||||
case -1:
|
||||
router_forget_router(conn->addr, conn->port); /* don't try him again */
|
||||
connection_free(conn);
|
||||
return;
|
||||
case 0:
|
||||
connection_set_poll_socket(conn);
|
||||
connection_watch_events(conn, POLLIN | POLLOUT | POLLERR);
|
||||
/* writable indicates finish, readable indicates broken link,
|
||||
error indicates broken link in windowsland. */
|
||||
conn->state = DIR_CONN_STATE_CONNECTING;
|
||||
return;
|
||||
/* case 1: fall through */
|
||||
}
|
||||
|
||||
connection_set_poll_socket(conn);
|
||||
if(directory_send_command(conn) < 0) {
|
||||
connection_remove(conn);
|
||||
connection_free(conn);
|
||||
|
@ -393,6 +393,7 @@ static int spawn_dnsworker(void) {
|
||||
conn->receiver_bucket = -1; /* non-cell connections don't do receiver buckets */
|
||||
conn->bandwidth = -1;
|
||||
conn->s = fd[0];
|
||||
conn->address = strdup("localhost");
|
||||
|
||||
if(connection_add(conn) < 0) { /* no space, forget it */
|
||||
log_fn(LOG_INFO,"connection_add failed. Giving up.");
|
||||
|
10
src/or/or.h
10
src/or/or.h
@ -569,19 +569,15 @@ int getconfig(int argc, char **argv, or_options_t *options);
|
||||
|
||||
/********************************* connection.c ***************************/
|
||||
|
||||
int tv_cmp(struct timeval *a, struct timeval *b);
|
||||
|
||||
connection_t *connection_new(int type);
|
||||
|
||||
void connection_free(connection_t *conn);
|
||||
|
||||
int connection_create_listener(struct sockaddr_in *bindaddr, int type);
|
||||
|
||||
int connection_handle_listener_read(connection_t *conn, int new_type);
|
||||
|
||||
int connection_tls_start_handshake(connection_t *conn, int receiving);
|
||||
|
||||
/* start all connections that should be up but aren't */
|
||||
int connection_connect(connection_t *conn, char *address, uint32_t addr, uint16_t port);
|
||||
int retry_all_connections(uint16_t or_listenport, uint16_t ap_listenport, uint16_t dir_listenport);
|
||||
|
||||
int connection_handle_read(connection_t *conn);
|
||||
@ -596,13 +592,9 @@ int connection_flush_buf(connection_t *conn);
|
||||
int connection_handle_write(connection_t *conn);
|
||||
|
||||
int connection_write_to_buf(char *string, int len, connection_t *conn);
|
||||
void connection_send_cell(connection_t *conn);
|
||||
|
||||
int connection_receiver_bucket_should_increase(connection_t *conn);
|
||||
|
||||
void connection_increment_send_timeval(connection_t *conn);
|
||||
void connection_init_timeval(connection_t *conn);
|
||||
|
||||
#define connection_speaks_cells(conn) ((conn)->type == CONN_TYPE_OR)
|
||||
int connection_is_listener(connection_t *conn);
|
||||
int connection_state_is_open(connection_t *conn);
|
||||
|
Loading…
Reference in New Issue
Block a user