diff --git a/src/or/config.c b/src/or/config.c index 3bdb7e426d..02948a6f01 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -151,41 +151,51 @@ static void config_assign(or_options_t *options, struct config_line *list) { /* order matters here! abbreviated arguments use the first match. */ /* string options */ - config_compare(list, "LogLevel", CONFIG_TYPE_STRING, &options->LogLevel) || - config_compare(list, "LogFile", CONFIG_TYPE_STRING, &options->LogFile) || + config_compare(list, "Address", CONFIG_TYPE_STRING, &options->Address) || + + config_compare(list, "CoinWeight", CONFIG_TYPE_DOUBLE, &options->CoinWeight) || + config_compare(list, "DebugLogFile", CONFIG_TYPE_STRING, &options->DebugLogFile) || config_compare(list, "DataDirectory", CONFIG_TYPE_STRING, &options->DataDirectory) || - config_compare(list, "RouterFile", CONFIG_TYPE_STRING, &options->RouterFile) || - config_compare(list, "PidFile", CONFIG_TYPE_STRING, &options->PidFile) || - config_compare(list, "Nickname", CONFIG_TYPE_STRING, &options->Nickname) || - config_compare(list, "Address", CONFIG_TYPE_STRING, &options->Address) || + config_compare(list, "DirPort", CONFIG_TYPE_INT, &options->DirPort) || + config_compare(list, "DirBindAddress", CONFIG_TYPE_STRING, &options->DirBindAddress) || + config_compare(list, "DirFetchPostPeriod",CONFIG_TYPE_INT, &options->DirFetchPostPeriod) || + config_compare(list, "ExitPolicy", CONFIG_TYPE_STRING, &options->ExitPolicy) || - config_compare(list, "SocksBindAddress",CONFIG_TYPE_STRING,&options->SocksBindAddress) || - config_compare(list, "ORBindAddress", CONFIG_TYPE_STRING, &options->ORBindAddress) || - config_compare(list, "User", CONFIG_TYPE_STRING, &options->User) || + config_compare(list, "Group", CONFIG_TYPE_STRING, &options->Group) || - /* int options */ - config_compare(list, "MaxConn", CONFIG_TYPE_INT, &options->MaxConn) || - config_compare(list, "SocksPort", CONFIG_TYPE_INT, &options->SocksPort) || - config_compare(list, "ORPort", CONFIG_TYPE_INT, &options->ORPort) || - config_compare(list, "DirPort", CONFIG_TYPE_INT, &options->DirPort) || - config_compare(list, "DirFetchPostPeriod",CONFIG_TYPE_INT, &options->DirFetchPostPeriod) || - config_compare(list, "KeepalivePeriod", CONFIG_TYPE_INT, &options->KeepalivePeriod) || + config_compare(list, "IgnoreVersion", CONFIG_TYPE_BOOL, &options->IgnoreVersion) || + + config_compare(list, "KeepalivePeriod",CONFIG_TYPE_INT, &options->KeepalivePeriod) || + + config_compare(list, "LogLevel", CONFIG_TYPE_STRING, &options->LogLevel) || + config_compare(list, "LogFile", CONFIG_TYPE_STRING, &options->LogFile) || + config_compare(list, "LinkPadding", CONFIG_TYPE_BOOL, &options->LinkPadding) || + + config_compare(list, "MaxConn", CONFIG_TYPE_INT, &options->MaxConn) || config_compare(list, "MaxOnionsPending",CONFIG_TYPE_INT, &options->MaxOnionsPending) || + + config_compare(list, "Nickname", CONFIG_TYPE_STRING, &options->Nickname) || config_compare(list, "NewCircuitPeriod",CONFIG_TYPE_INT, &options->NewCircuitPeriod) || - config_compare(list, "TotalBandwidth", CONFIG_TYPE_INT, &options->TotalBandwidth) || - config_compare(list, "NumCpus", CONFIG_TYPE_INT, &options->NumCpus) || + config_compare(list, "NumCpus", CONFIG_TYPE_INT, &options->NumCpus) || - config_compare(list, "OnionRouter", CONFIG_TYPE_BOOL, &options->OnionRouter) || - config_compare(list, "TrafficShaping", CONFIG_TYPE_BOOL, &options->TrafficShaping) || - config_compare(list, "LinkPadding", CONFIG_TYPE_BOOL, &options->LinkPadding) || - config_compare(list, "IgnoreVersion", CONFIG_TYPE_BOOL, &options->IgnoreVersion) || - config_compare(list, "RunAsDaemon", CONFIG_TYPE_BOOL, &options->RunAsDaemon) || + config_compare(list, "ORPort", CONFIG_TYPE_INT, &options->ORPort) || + config_compare(list, "ORBindAddress", CONFIG_TYPE_STRING, &options->ORBindAddress) || + config_compare(list, "OnionRouter", CONFIG_TYPE_BOOL, &options->OnionRouter) || - /* float options */ - config_compare(list, "CoinWeight", CONFIG_TYPE_DOUBLE, &options->CoinWeight) + config_compare(list, "PidFile", CONFIG_TYPE_STRING, &options->PidFile) || + config_compare(list, "RouterFile", CONFIG_TYPE_STRING, &options->RouterFile) || + config_compare(list, "RunAsDaemon", CONFIG_TYPE_BOOL, &options->RunAsDaemon) || + + config_compare(list, "SocksPort", CONFIG_TYPE_INT, &options->SocksPort) || + config_compare(list, "SocksBindAddress",CONFIG_TYPE_STRING,&options->SocksBindAddress) || + + config_compare(list, "TotalBandwidth", CONFIG_TYPE_INT, &options->TotalBandwidth) || + config_compare(list, "TrafficShaping", CONFIG_TYPE_BOOL, &options->TrafficShaping) || + + config_compare(list, "User", CONFIG_TYPE_STRING, &options->User) ) { /* then we're ok. it matched something. */ } else { @@ -196,8 +206,22 @@ static void config_assign(or_options_t *options, struct config_line *list) { } } +/* prints the usage of tor. */ void print_usage(void) { - + printf("tor -f [args]\n" + "-d \t\tDebug file\n" + "-e \t\tExit policy\n" + "-l \t\tLog level\n" + "-m \t\tMax number of connections\n" + "-s \t\t\tAddress to bind to for Socks\n" + ); + /* split things up to be ANSI compliant */ + printf("-n \t\tNickname of router\n" + "-o \t\tOR port to bind to\n" + "-p \t\tPID file\n" + "-r \t\tRouter config file\n" + "-t \t\tTotal bandwidth\n" + ); } void free_options(or_options_t *options) { @@ -212,6 +236,7 @@ void free_options(or_options_t *options) { tor_free(options->ExitPolicy); tor_free(options->SocksBindAddress); tor_free(options->ORBindAddress); + tor_free(options->DirBindAddress); tor_free(options->User); tor_free(options->Group); } @@ -223,6 +248,7 @@ void init_options(or_options_t *options) { options->ExitPolicy = tor_strdup("reject 127.0.0.1:*"); options->SocksBindAddress = tor_strdup("127.0.0.1"); options->ORBindAddress = tor_strdup("0.0.0.0"); + options->DirBindAddress = tor_strdup("0.0.0.0"); options->loglevel = LOG_INFO; options->PidFile = tor_strdup("tor.pid"); options->DataDirectory = NULL; diff --git a/src/or/connection.c b/src/or/connection.c index d19a4b4a40..237e47f1ae 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -123,28 +123,40 @@ void connection_free(connection_t *conn) { free(conn); } -int connection_create_listener(struct sockaddr_in *bindaddr, int type) { +int connection_create_listener(char *bindaddress, uint16_t bindport, int type) { + struct sockaddr_in bindaddr; /* where to bind */ + struct hostent *rent; connection_t *conn; - int s; + int s; /* the socket we're going to make */ int one=1; + memset(&bindaddr,0,sizeof(struct sockaddr_in)); + bindaddr.sin_family = AF_INET; + bindaddr.sin_port = htons(bindport); + rent = gethostbyname(bindaddress); + if (!rent) { + log_fn(LOG_WARN,"Can't resolve BindAddress %s",bindaddress); + return -1; + } + if(rent->h_length != 4) + return -1; /* XXX complain */ + memcpy(&(bindaddr.sin_addr.s_addr),rent->h_addr,rent->h_length); + s = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); if (s < 0) { log_fn(LOG_WARN,"Socket creation failed."); return -1; } - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&one, sizeof(one)); + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); - if(bind(s,(struct sockaddr *)bindaddr,sizeof(*bindaddr)) < 0) { - log(LOG_WARN,"Could not bind to port %u: %s",ntohs(bindaddr->sin_port), - strerror(errno)); + if(bind(s,(struct sockaddr *)&bindaddr,sizeof(bindaddr)) < 0) { + log_fn(LOG_WARN,"Could not bind to port %u: %s",bindport,strerror(errno)); return -1; } if(listen(s,SOMAXCONN) < 0) { - log(LOG_WARN,"Could not listen on port %u: %s",ntohs(bindaddr->sin_port), - strerror(errno)); + log_fn(LOG_WARN,"Could not listen on port %u: %s",bindport,strerror(errno)); return -1; } @@ -159,7 +171,7 @@ int connection_create_listener(struct sockaddr_in *bindaddr, int type) { return -1; } - log_fn(LOG_DEBUG,"%s listening on port %u.",conn_type_to_string[type], ntohs(bindaddr->sin_port)); + log_fn(LOG_DEBUG,"%s listening on port %u.",conn_type_to_string[type], bindport); conn->state = LISTENER_STATE_READY; connection_start_reading(conn); @@ -275,37 +287,28 @@ int connection_connect(connection_t *conn, char *address, uint32_t addr, uint16_ } /* 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 */ +int retry_all_connections(void) { - if(or_listenport) { + if(options.ORPort) { router_retry_connections(); } - memset(&bindaddr,0,sizeof(struct sockaddr_in)); - bindaddr.sin_family = AF_INET; - bindaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* anyone can connect */ - - if(or_listenport) { - bindaddr.sin_port = htons(or_listenport); - if(!connection_get_by_type(CONN_TYPE_OR_LISTENER)) { - connection_create_listener(&bindaddr, CONN_TYPE_OR_LISTENER); - } + if(options.ORPort && !connection_get_by_type(CONN_TYPE_OR_LISTENER)) { + if(connection_create_listener(options.ORBindAddress, options.ORPort, + CONN_TYPE_OR_LISTENER) < 0) + return -1; } - if(dir_listenport) { - bindaddr.sin_port = htons(dir_listenport); - if(!connection_get_by_type(CONN_TYPE_DIR_LISTENER)) { - connection_create_listener(&bindaddr, CONN_TYPE_DIR_LISTENER); - } + if(options.DirPort && !connection_get_by_type(CONN_TYPE_DIR_LISTENER)) { + if(connection_create_listener(options.DirBindAddress, options.DirPort, + CONN_TYPE_DIR_LISTENER) < 0) + return -1; } - if(ap_listenport) { - bindaddr.sin_port = htons(ap_listenport); - bindaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* the AP listens only on localhost! */ - if(!connection_get_by_type(CONN_TYPE_AP_LISTENER)) { - connection_create_listener(&bindaddr, CONN_TYPE_AP_LISTENER); - } + if(options.SocksPort && !connection_get_by_type(CONN_TYPE_AP_LISTENER)) { + if(connection_create_listener(options.SocksBindAddress, options.SocksPort, + CONN_TYPE_AP_LISTENER) < 0) + return -1; } return 0; diff --git a/src/or/main.c b/src/or/main.c index eed0d4c481..2e48ec48ce 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -594,9 +594,10 @@ static int do_main_loop(void) { * non-zero. This is where we try to connect to all the other ORs, * and start the listeners. */ - retry_all_connections((uint16_t) options.ORPort, - (uint16_t) options.SocksPort, - (uint16_t) options.DirPort); + if(retry_all_connections() < 0) { + log_fn(LOG_ERR,"Failed to bind one of the listener ports."); + return -1; + } for(;;) { #ifndef MS_WINDOWS /* do signal stuff only on unix */ diff --git a/src/or/or.h b/src/or/or.h index b38eee1a0e..27c9740c00 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -101,7 +101,7 @@ #include "../common/log.h" #include "../common/util.h" -#define RECOMMENDED_SOFTWARE_VERSIONS "0.0.2pre8,0.0.2pre9,0.0.2pre10,0.0.2pre11,0.0.2pre12,0.0.2pre13,0.0.2pre14" +#define RECOMMENDED_SOFTWARE_VERSIONS "0.0.2pre13,0.0.2pre14" #define MAXCONNECTIONS 1000 /* upper bound on max connections. can be lowered by config file */ @@ -420,41 +420,42 @@ struct circuit_t { typedef struct circuit_t circuit_t; typedef struct { - char *LogLevel; - char *LogFile; - char *DebugLogFile; - char *DataDirectory; - char *RouterFile; - char *Nickname; - char *Address; - char *PidFile; - char *ExitPolicy; - char *SocksBindAddress; - char *ORBindAddress; - char *User; - char *Group; - double CoinWeight; - int ORPort; - int SocksPort; - int DirPort; - int MaxConn; - int OnionRouter; - int TrafficShaping; - int LinkPadding; - int IgnoreVersion; - int RunAsDaemon; - int DirRebuildPeriod; - int DirFetchPostPeriod; - int KeepalivePeriod; - int MaxOnionsPending; - int NewCircuitPeriod; - int TotalBandwidth; - int NumCpus; - int Role; - int loglevel; + char *LogLevel; + char *LogFile; + char *DebugLogFile; + char *DataDirectory; + char *RouterFile; + char *Nickname; + char *Address; + char *PidFile; + char *ExitPolicy; + char *SocksBindAddress; + char *ORBindAddress; + char *DirBindAddress; + char *User; + char *Group; + double CoinWeight; + int ORPort; + int SocksPort; + int DirPort; + int MaxConn; + int OnionRouter; + int TrafficShaping; + int LinkPadding; + int IgnoreVersion; + int RunAsDaemon; + int DirRebuildPeriod; + int DirFetchPostPeriod; + int KeepalivePeriod; + int MaxOnionsPending; + int NewCircuitPeriod; + int TotalBandwidth; + int NumCpus; + int Role; + int loglevel; } or_options_t; - /* all the function prototypes go here */ +/* all the function prototypes go here */ /********************************* buffers.c ***************************/ @@ -546,10 +547,10 @@ int getconfig(int argc, char **argv, or_options_t *options); connection_t *connection_new(int type); void connection_free(connection_t *conn); -int connection_create_listener(struct sockaddr_in *bindaddr, int type); +int connection_create_listener(char *bindaddress, uint16_t bindport, int type); 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 retry_all_connections(void); int connection_handle_read(connection_t *conn); int connection_read_to_buf(connection_t *conn);