|
@@ -142,8 +142,7 @@ void conn_or_init_crypto(connection_t *conn) {
|
|
|
* *result to 1 if connect() returned before completing, or to 2
|
|
|
* if it completed, and returns the new conn.
|
|
|
*/
|
|
|
-connection_t *connection_or_connect(routerinfo_t *router, struct sockaddr_in *local,
|
|
|
- uint16_t port, int *result) {
|
|
|
+connection_t *connection_or_connect(routerinfo_t *router, uint16_t port, int *result) {
|
|
|
connection_t *conn;
|
|
|
struct sockaddr_in router_addr;
|
|
|
int s;
|
|
@@ -153,11 +152,11 @@ connection_t *connection_or_connect(routerinfo_t *router, struct sockaddr_in *lo
|
|
|
return NULL;
|
|
|
|
|
|
/* set up conn so it's got all the data we need to remember */
|
|
|
- conn->addr = router->addr, conn->port = router->or_port; /* NOTE we store or_port here always */
|
|
|
+ conn->addr = router->addr;
|
|
|
+ conn->port = router->or_port; /* NOTE we store or_port here always */
|
|
|
conn->bandwidth = router->bandwidth;
|
|
|
conn->pkey = crypto_pk_dup_key(router->pkey);
|
|
|
conn->address = strdup(router->address);
|
|
|
- memcpy(&conn->local,local,sizeof(struct sockaddr_in));
|
|
|
|
|
|
s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
|
|
|
if (s < 0)
|
|
@@ -171,9 +170,9 @@ connection_t *connection_or_connect(routerinfo_t *router, struct sockaddr_in *lo
|
|
|
memset((void *)&router_addr,0,sizeof(router_addr));
|
|
|
router_addr.sin_family = AF_INET;
|
|
|
router_addr.sin_port = htons(port);
|
|
|
- router_addr.sin_addr.s_addr = router->addr;
|
|
|
+ router_addr.sin_addr.s_addr = htonl(router->addr);
|
|
|
|
|
|
- log(LOG_DEBUG,"connection_or_connect() : Trying to connect to %s:%u.",inet_ntoa(*(struct in_addr *)&router->addr),port);
|
|
|
+ log(LOG_DEBUG,"connection_or_connect() : Trying to connect to %s:%u.",router->address,port);
|
|
|
|
|
|
if(connect(s,(struct sockaddr *)&router_addr,sizeof(router_addr)) < 0){
|
|
|
if(errno != EINPROGRESS){
|
|
@@ -217,13 +216,13 @@ connection_t *connection_or_connect(routerinfo_t *router, struct sockaddr_in *lo
|
|
|
*
|
|
|
*/
|
|
|
|
|
|
-connection_t *connection_or_connect_as_op(routerinfo_t *router, struct sockaddr_in *local) {
|
|
|
+connection_t *connection_or_connect_as_op(routerinfo_t *router) {
|
|
|
connection_t *conn;
|
|
|
int result=0; /* so connection_or_connect() can tell us what happened */
|
|
|
|
|
|
- assert(router && local);
|
|
|
+ assert(router);
|
|
|
|
|
|
- if(router->addr == local->sin_addr.s_addr && router->or_port == ntohs(local->sin_port)) {
|
|
|
+ if(router_is_me(router->addr, router->or_port)) {
|
|
|
/* this is me! don't connect to me. */
|
|
|
log(LOG_WARNING,"connection_or_connect_as_op(): You just asked me to connect to myself.");
|
|
|
return NULL;
|
|
@@ -235,7 +234,7 @@ connection_t *connection_or_connect_as_op(routerinfo_t *router, struct sockaddr_
|
|
|
if(conn)
|
|
|
return conn;
|
|
|
|
|
|
- conn = connection_or_connect(router, local, router->op_port, &result);
|
|
|
+ conn = connection_or_connect(router, router->op_port, &result);
|
|
|
if(!conn)
|
|
|
return NULL;
|
|
|
|
|
@@ -340,19 +339,19 @@ int or_handshake_op_finished_sending_keys(connection_t *conn) {
|
|
|
*
|
|
|
*/
|
|
|
|
|
|
-connection_t *connection_or_connect_as_or(routerinfo_t *router, struct sockaddr_in *local) {
|
|
|
+connection_t *connection_or_connect_as_or(routerinfo_t *router) {
|
|
|
connection_t *conn;
|
|
|
int result=0; /* so connection_or_connect() can tell us what happened */
|
|
|
|
|
|
- assert(router && local);
|
|
|
+ assert(router);
|
|
|
|
|
|
- if(router->addr == local->sin_addr.s_addr && router->or_port == ntohs(local->sin_port)) {
|
|
|
+ if(router_is_me(router->addr, router->or_port)) {
|
|
|
/* this is me! don't connect to me. */
|
|
|
log(LOG_DEBUG,"connection_or_connect_as_or(): This is me. Skipping.");
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
- conn = connection_or_connect(router, local, router->or_port, &result);
|
|
|
+ conn = connection_or_connect(router, router->or_port, &result);
|
|
|
if(!conn)
|
|
|
return NULL;
|
|
|
|
|
@@ -378,9 +377,13 @@ int or_handshake_client_send_auth(connection_t *conn) {
|
|
|
int retval;
|
|
|
char buf[44];
|
|
|
char cipher[128];
|
|
|
+ struct sockaddr_in me; /* my router identity */
|
|
|
|
|
|
assert(conn);
|
|
|
|
|
|
+ if(learn_my_address(&me) < 0)
|
|
|
+ return -1;
|
|
|
+
|
|
|
/* generate random keys */
|
|
|
if(crypto_cipher_generate_key(conn->f_crypto) ||
|
|
|
crypto_cipher_generate_key(conn->b_crypto)) {
|
|
@@ -390,8 +393,8 @@ int or_handshake_client_send_auth(connection_t *conn) {
|
|
|
log(LOG_DEBUG,"or_handshake_client_send_auth() : Generated DES keys.");
|
|
|
|
|
|
/* generate first message */
|
|
|
- *(uint32_t*)buf = htonl(conn->local.sin_addr.s_addr); /* local address */
|
|
|
- *(uint16_t*)(buf+4) = conn->local.sin_port; /* local port, already network order */
|
|
|
+ *(uint32_t*)buf = me.sin_addr.s_addr; /* local address, network order */
|
|
|
+ *(uint16_t*)(buf+4) = me.sin_port; /* local port, network order */
|
|
|
*(uint32_t*)(buf+6) = htonl(conn->addr); /* remote address */
|
|
|
*(uint16_t*)(buf+10) = htons(conn->port); /* remote port */
|
|
|
memcpy(buf+12,conn->f_crypto->key,8); /* keys */
|
|
@@ -440,9 +443,13 @@ int or_handshake_client_process_auth(connection_t *conn) {
|
|
|
char cipher[128];
|
|
|
uint32_t bandwidth;
|
|
|
int retval;
|
|
|
+ struct sockaddr_in me; /* my router identity */
|
|
|
|
|
|
assert(conn);
|
|
|
|
|
|
+ if(learn_my_address(&me) < 0)
|
|
|
+ return -1;
|
|
|
+
|
|
|
if(conn->inbuf_datalen < 128) /* entire response available? */
|
|
|
return 0; /* not yet */
|
|
|
|
|
@@ -469,8 +476,8 @@ int or_handshake_client_process_auth(connection_t *conn) {
|
|
|
}
|
|
|
log(LOG_DEBUG,"or_handshake_client_process_auth() : Decrypted response.");
|
|
|
/* check validity */
|
|
|
- if ( (ntohl(*(uint32_t*)buf) != conn->local.sin_addr.s_addr) || /* local address */
|
|
|
- (*(uint16_t*)(buf+4) != conn->local.sin_port) || /* local port, keep network order */
|
|
|
+ if ( (*(uint32_t*)buf != me.sin_addr.s_addr) || /* local address, network order */
|
|
|
+ (*(uint16_t*)(buf+4) != me.sin_port) || /* local port, network order */
|
|
|
(ntohl(*(uint32_t*)(buf+6)) != conn->addr) || /* remote address */
|
|
|
(ntohs(*(uint16_t*)(buf+10)) != conn->port) || /* remote port */
|
|
|
(memcmp(conn->f_crypto->key, buf+12, 8)) || /* keys */
|
|
@@ -582,7 +589,7 @@ int or_handshake_server_process_auth(connection_t *conn) {
|
|
|
router = router_get_by_addr_port(addr,port);
|
|
|
if (!router)
|
|
|
{
|
|
|
- log(LOG_DEBUG,"or_handshake_server_process_auth() : Received a connection from an unknown router. Will drop.");
|
|
|
+ log(LOG_DEBUG,"or_handshake_server_process_auth() : Received a connection from an unknown router '%s:%d'. Will drop.", conn->address, port);
|
|
|
return -1;
|
|
|
}
|
|
|
log(LOG_DEBUG,"or_handshake_server_process_auth() : Router identified as %s:%u.",
|
|
@@ -664,9 +671,13 @@ int or_handshake_server_process_nonce(connection_t *conn) {
|
|
|
char buf[128];
|
|
|
char cipher[128];
|
|
|
int retval;
|
|
|
+ struct sockaddr_in me; /* my router identity */
|
|
|
|
|
|
assert(conn);
|
|
|
|
|
|
+ if(learn_my_address(&me) < 0)
|
|
|
+ return -1;
|
|
|
+
|
|
|
if(conn->inbuf_datalen < 128) /* entire response available? */
|
|
|
return 0; /* not yet */
|
|
|
|
|
@@ -696,8 +707,8 @@ int or_handshake_server_process_nonce(connection_t *conn) {
|
|
|
/* check validity */
|
|
|
if ((ntohl(*(uint32_t*)buf) != conn->addr) || /* remote address */
|
|
|
(ntohs(*(uint16_t*)(buf+4)) != conn->port) || /* remote port */
|
|
|
- (ntohl(*(uint32_t*)(buf+6)) != conn->local.sin_addr.s_addr) || /* local address */
|
|
|
- (*(uint16_t*)(buf+10) != conn->local.sin_port) || /* local port, network order */
|
|
|
+ (*(uint32_t*)(buf+6) != me.sin_addr.s_addr) || /* local address, network order */
|
|
|
+ (*(uint16_t*)(buf+10) != me.sin_port) || /* local port, network order */
|
|
|
(memcmp(conn->nonce,buf+12,8))) /* nonce */
|
|
|
{
|
|
|
log(LOG_ERR,"Router %s:%u failed to authenticate. Either the key I have is obsolete or they're doing something they're not supposed to.",conn->address,conn->port);
|
|
@@ -717,9 +728,9 @@ int or_handshake_server_process_nonce(connection_t *conn) {
|
|
|
/* ********************************** */
|
|
|
|
|
|
|
|
|
-int connection_or_create_listener(struct sockaddr_in *local) {
|
|
|
+int connection_or_create_listener(struct sockaddr_in *bindaddr) {
|
|
|
log(LOG_DEBUG,"connection_create_or_listener starting");
|
|
|
- return connection_create_listener(local, CONN_TYPE_OR_LISTENER);
|
|
|
+ return connection_create_listener(bindaddr, CONN_TYPE_OR_LISTENER);
|
|
|
}
|
|
|
|
|
|
int connection_or_handle_listener_read(connection_t *conn) {
|