Add local address information to edges.
authorEtienne Dechamps <etienne@edechamps.fr>
Sun, 22 Jun 2014 15:29:30 +0000 (16:29 +0100)
committerEtienne Dechamps <etienne@edechamps.fr>
Sun, 29 Jun 2014 10:23:14 +0000 (11:23 +0100)
In addition to the remote address, each edge now stores the local address from
the point of view of the "from" node. This information is then made available
to other nodes through a backwards-compatible extension to ADD_EDGE messages.

This information can be used in future code to improve packet routing.

src/edge.c
src/edge.h
src/protocol_auth.c
src/protocol_edge.c
src/tincctl.c

index f185b4fec35329dcb8e8f482a1b28efd8ab94049..2eaae5d10c8780c59937d1dd028545c47d5fdd12 100644 (file)
@@ -110,11 +110,13 @@ bool dump_edges(connection_t *c) {
        for splay_each(node_t, n, node_tree) {
                for splay_each(edge_t, e, n->edge_tree) {
                        char *address = sockaddr2hostname(&e->address);
-                       send_request(c, "%d %d %s %s %s %x %d",
+                       char* local_address = sockaddr2hostname(&e->local_address);
+                       send_request(c, "%d %d %s %s %s %s %x %d",
                                        CONTROL, REQ_DUMP_EDGES,
                                        e->from->name, e->to->name, address,
-                                       e->options, e->weight);
+                                       local_address, e->options, e->weight);
                        free(address);
+                       free(local_address);
                }
        }
 
index cbd9e5ac0ab0ff1fe9a3a99cc31fd642bf51e10b..ed46b8a428fd65b0bf3059e368f8246033b3a505 100644 (file)
@@ -30,6 +30,7 @@ typedef struct edge_t {
        struct node_t *from;
        struct node_t *to;
        sockaddr_t address;
+       sockaddr_t local_address;
 
        uint32_t options;                       /* options turned on for this edge */
        int weight;                             /* weight of this edge */
index b8d4ee8e7a0658ff1e353fa00f36d5a0ab472fbe..778c607b2ba74f9fb9683b2df3414a375ac41e83 100644 (file)
@@ -822,6 +822,16 @@ bool ack_h(connection_t *c, const char *request) {
        sockaddr2str(&c->address, &hisaddress, NULL);
        c->edge->address = str2sockaddr(hisaddress, hisport);
        free(hisaddress);
+       sockaddr_t local_sa;
+       socklen_t local_salen = sizeof local_sa;
+       if (getsockname(c->socket, &local_sa.sa, &local_salen) < 0)
+               logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get local socket address for connection with %s", c->name);
+       else {
+               char *local_address;
+               sockaddr2str(&local_sa, &local_address, NULL);
+               c->edge->local_address = str2sockaddr(local_address, myport);
+               free(local_address);
+       }
        c->edge->weight = (weight + c->estimated_weight) / 2;
        c->edge->connection = c;
        c->edge->options = c->options;
index e285a6deaac66161a44a334436c7bfba41acf74e..4760162ccdaae1135e36a973d2b6db06d7c6a494 100644 (file)
 bool send_add_edge(connection_t *c, const edge_t *e) {
        bool x;
        char *address, *port;
+       char *local_address, *local_port;
 
        sockaddr2str(&e->address, &address, &port);
+       sockaddr2str(&e->local_address, &local_address, &local_port);
 
-       x = send_request(c, "%d %x %s %s %s %s %x %d", ADD_EDGE, rand(),
+       x = send_request(c, "%d %x %s %s %s %s %x %d %s %s", ADD_EDGE, rand(),
                                         e->from->name, e->to->name, address, port,
-                                        e->options, e->weight);
+                                        e->options, e->weight, local_address, local_port);
+
        free(address);
        free(port);
+       free(local_address);
+       free(local_port);
 
        return x;
 }
@@ -56,12 +61,15 @@ bool add_edge_h(connection_t *c, const char *request) {
        char to_name[MAX_STRING_SIZE];
        char to_address[MAX_STRING_SIZE];
        char to_port[MAX_STRING_SIZE];
-       sockaddr_t address;
+       char address_local[MAX_STRING_SIZE] = "unknown";
+       char port_local[MAX_STRING_SIZE] = "unknown";
+       sockaddr_t address, local_address;
        uint32_t options;
        int weight;
 
-       if(sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %x %d",
-                         from_name, to_name, to_address, to_port, &options, &weight) != 6) {
+       int parameter_count = sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %x %d "MAX_STRING" "MAX_STRING,
+                                             from_name, to_name, to_address, to_port, &options, &weight, address_local, port_local);
+       if (parameter_count != 6 && parameter_count != 8) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ADD_EDGE", c->name,
                           c->hostname);
                return false;
@@ -109,13 +117,14 @@ bool add_edge_h(connection_t *c, const char *request) {
        /* Convert addresses */
 
        address = str2sockaddr(to_address, to_port);
+       local_address = str2sockaddr(address_local, port_local);
 
        /* Check if edge already exists */
 
        e = lookup_edge(from, to);
 
        if(e) {
-               if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address)) {
+               if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address) || sockaddrcmp(&e->local_address, &local_address)) {
                        if(from == myself) {
                                logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry",
                                                   "ADD_EDGE", c->name, c->hostname);
@@ -145,6 +154,7 @@ bool add_edge_h(connection_t *c, const char *request) {
        e->from = from;
        e->to = to;
        e->address = address;
+       e->local_address = local_address;
        e->options = options;
        e->weight = weight;
        edge_add(e);
index da66c8ffb441d931810c643cf887613689fefc6e..18fc05ac1aa66ac87ae7e97c0c77de3004374a1d 100644 (file)
@@ -985,6 +985,8 @@ static int cmd_dump(int argc, char *argv[]) {
                char subnet[4096];
                char host[4096];
                char port[4096];
+               char local_host[4096];
+               char local_port[4096];
                char via[4096];
                char nexthop[4096];
                int cipher, digest, maclength, compression, distance, socket, weight;
@@ -1025,8 +1027,8 @@ static int cmd_dump(int argc, char *argv[]) {
                        } break;
 
                        case REQ_DUMP_EDGES: {
-                               int n = sscanf(line, "%*d %*d %s %s %s port %s %x %d", from, to, host, port, &options, &weight);
-                               if(n != 6) {
+                               int n = sscanf(line, "%*d %*d %s %s %s port %s %s port %s %x %d", from, to, host, port, local_host, local_port, &options, &weight);
+                               if(n != 8) {
                                        fprintf(stderr, "Unable to parse edge dump from tincd.\n");
                                        return 1;
                                }
@@ -1038,7 +1040,7 @@ static int cmd_dump(int argc, char *argv[]) {
                                        else if(do_graph == 2)
                                                printf(" %s -> %s [w = %f, weight = %f];\n", node1, node2, w, w);
                                } else {
-                                       printf("%s to %s at %s port %s options %x weight %d\n", from, to, host, port, options, weight);
+                                       printf("%s to %s at %s port %s local %s port %s options %x weight %d\n", from, to, host, port, local_host, local_port, options, weight);
                                }
                        } break;