Skip to content

Commit

Permalink
Improve recently seen address cache
Browse files Browse the repository at this point in the history
- create cache directory on init
- only remember addresses for TCP connections
- update cache in more situations
- add tests
  • Loading branch information
hg committed May 29, 2022
1 parent 1695d88 commit c6a15e2
Show file tree
Hide file tree
Showing 21 changed files with 263 additions and 98 deletions.
12 changes: 5 additions & 7 deletions src/address_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include "netutl.h"
#include "xalloc.h"

static const unsigned int NOT_CACHED = -1;
static const unsigned int NOT_CACHED = UINT_MAX;

// Find edges pointing to this node, and use them to build a list of unique, known addresses.
static struct addrinfo *get_known_addresses(node_t *n) {
Expand Down Expand Up @@ -90,6 +90,8 @@ void add_recent_address(address_cache_t *cache, const sockaddr_t *sa) {
return;
}

logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Caching recent address for %s", cache->node->name);

// Shift everything, move/add the address to the first slot
if(pos == NOT_CACHED) {
if(cache->data.used < MAX_CACHED_ADDRESSES) {
Expand Down Expand Up @@ -216,7 +218,7 @@ const sockaddr_t *get_recent_address(address_cache_t *cache) {
exit_configuration(cache->config_tree);
cache->config_tree = NULL;

return false;
return NULL;
}

address_cache_t *open_address_cache(node_t *node) {
Expand Down Expand Up @@ -251,11 +253,7 @@ address_cache_t *open_address_cache(node_t *node) {
return cache;
}

void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa) {
if(sa) {
add_recent_address(cache, sa);
}

void reset_address_cache(address_cache_t *cache) {
if(cache->config_tree) {
exit_configuration(cache->config_tree);
cache->config_tree = NULL;
Expand Down
2 changes: 1 addition & 1 deletion src/address_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ const sockaddr_t *get_recent_address(address_cache_t *cache);

void close_address_cache(address_cache_t *cache);
address_cache_t *open_address_cache(node_t *node) ATTR_DEALLOCATOR(close_address_cache);
void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa);
void reset_address_cache(address_cache_t *cache);

#endif
9 changes: 9 additions & 0 deletions src/graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#include "script.h"
#include "subnet.h"
#include "xalloc.h"
#include "address_cache.h"

/* Implementation of Kruskal's algorithm.
Running time: O(EN)
Expand Down Expand Up @@ -226,6 +227,14 @@ static void check_reachability(void) {

if(n != myself) {
became_reachable_count++;

if(n->connection && n->connection->outgoing) {
if(!n->address_cache) {
n->address_cache = open_address_cache(n);
}

add_recent_address(n->address_cache, &n->connection->address);
}
}
} else {
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became unreachable",
Expand Down
27 changes: 7 additions & 20 deletions src/invitation.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,13 +384,12 @@ int cmd_invite(int argc, char *argv[]) {
}
}

snprintf(filename, sizeof(filename), "%s" SLASH "invitations", confbase);

if(mkdir(filename, 0700) && errno != EEXIST) {
fprintf(stderr, "Could not create directory %s: %s\n", filename, strerror(errno));
return 1;
if(!makedirs(DIR_INVITATIONS)) {
return false;
}

snprintf(filename, sizeof(filename), "%s" SLASH "invitations", confbase);

// Count the number of valid invitations, clean up old ones
DIR *dir = opendir(filename);

Expand Down Expand Up @@ -779,13 +778,7 @@ static bool finalize_join(void) {
goto make_names;
}

if(mkdir(confbase, 0777) && errno != EEXIST) {
fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno));
return false;
}

if(mkdir(hosts_dir, 0777) && errno != EEXIST) {
fprintf(stderr, "Could not create directory %s: %s\n", hosts_dir, strerror(errno));
if(!makedirs(DIR_HOSTS | DIR_CONFBASE | DIR_CACHE)) {
return false;
}

Expand Down Expand Up @@ -1213,14 +1206,8 @@ int cmd_join(int argc, char *argv[]) {
}

// Make sure confbase exists and is accessible.
if(!confbase_given && mkdir(confdir, 0755) && errno != EEXIST) {
fprintf(stderr, "Could not create directory %s: %s\n", confdir, strerror(errno));
return 1;
}

if(mkdir(confbase, 0777) && errno != EEXIST) {
fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno));
return 1;
if(!makedirs(DIR_CONFDIR | DIR_CONFBASE)) {
return false;
}

if(access(confbase, R_OK | W_OK | X_OK)) {
Expand Down
5 changes: 4 additions & 1 deletion src/net_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,10 @@ static void udp_probe_h(node_t *n, vpn_packet_t *packet, length_t len) {
n->address_cache = open_address_cache(n);
}

reset_address_cache(n->address_cache, &n->address);
if(n->connection && n->connection->edge) {
reset_address_cache(n->address_cache);
add_recent_address(n->address_cache, &n->connection->edge->address);
}
}

// Reset the UDP ping timer.
Expand Down
8 changes: 3 additions & 5 deletions src/net_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,7 @@ void load_all_nodes(void) {
read_host_config(&config, ent->d_name, true);

if(!n) {
n = new_node();
n->name = xstrdup(ent->d_name);
n = new_node(ent->d_name);
node_add(n);
}

Expand Down Expand Up @@ -764,10 +763,9 @@ static bool setup_myself(void) {
}

myname = xstrdup(name);
myself = new_node();
myself = new_node(name);
myself->connection = new_connection();
myself->name = name;
myself->connection->name = xstrdup(name);
myself->connection->name = name;
read_host_config(&config_tree, name, true);

if(!get_config_string(lookup_config(&config_tree, "Port"), &myport.tcp)) {
Expand Down
25 changes: 10 additions & 15 deletions src/net_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -671,22 +671,18 @@ void setup_outgoing_connection(outgoing_t *outgoing, bool verbose) {
n->address_cache = open_address_cache(n);
}

if(n->connection) {
logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", n->name);

if(!n->connection->outgoing) {
n->connection->outgoing = outgoing;
return;
} else {
goto remove;
}
if(!n->connection) {
do_outgoing_connection(outgoing);
return;
}

do_outgoing_connection(outgoing);
return;
logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", n->name);

remove:
list_delete(&outgoing_list, outgoing);
if(n->connection->outgoing) {
list_delete(&outgoing_list, outgoing);
} else {
n->connection->outgoing = outgoing;
}
}

static bool check_tarpit(const sockaddr_t *sa, int fd) {
Expand Down Expand Up @@ -864,8 +860,7 @@ void try_outgoing_connections(void) {
node_t *n = lookup_node(name);

if(!n) {
n = new_node();
n->name = xstrdup(name);
n = new_node(name);
node_add(n);
}

Expand Down
3 changes: 2 additions & 1 deletion src/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ void exit_nodes(void) {
splay_empty_tree(&node_tree);
}

node_t *new_node(void) {
node_t *new_node(const char *name) {
node_t *n = xzalloc(sizeof(*n));

if(replaywin) {
Expand All @@ -84,6 +84,7 @@ node_t *new_node(void) {
n->mtu = MTU;
n->maxmtu = MTU;
n->udp_ping_rtt = -1;
n->name = xstrdup(name);

return n;
}
Expand Down
2 changes: 1 addition & 1 deletion src/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ extern splay_tree_t node_tree;

extern void exit_nodes(void);
extern void free_node(node_t *n);
extern node_t *new_node(void) ATTR_MALLOC ATTR_DEALLOCATOR(free_node);
extern node_t *new_node(const char *name) ATTR_MALLOC ATTR_DEALLOCATOR(free_node);
extern void node_add(node_t *n);
extern void node_del(node_t *n);
extern node_t *lookup_node(char *name);
Expand Down
20 changes: 18 additions & 2 deletions src/protocol_auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "random.h"
#include "compression.h"
#include "proxy.h"
#include "address_cache.h"

#include "ed25519/sha512.h"
#include "keys.h"
Expand Down Expand Up @@ -139,6 +140,22 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len)

logger(DEBUG_CONNECTIONS, LOG_INFO, "Key successfully received from %s (%s)", c->name, c->hostname);

if(!c->node) {
c->node = lookup_node(c->name);
}

if(!c->node) {
c->node = new_node(c->name);
c->node->connection = c;
node_add(c->node);
}

if(!c->node->address_cache) {
c->node->address_cache = open_address_cache(c->node);
}

add_recent_address(c->node->address_cache, &c->address);

// Call invitation-accepted script
environment_t env;
char *address, *port;
Expand Down Expand Up @@ -936,8 +953,7 @@ bool ack_h(connection_t *c, const char *request) {
n = lookup_node(c->name);

if(!n) {
n = new_node();
n->name = xstrdup(c->name);
n = new_node(c->name);
node_add(n);
} else {
if(n->connection) {
Expand Down
6 changes: 2 additions & 4 deletions src/protocol_edge.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,12 @@ bool add_edge_h(connection_t *c, const char *request) {
}

if(!from) {
from = new_node();
from->name = xstrdup(from_name);
from = new_node(from_name);
node_add(from);
}

if(!to) {
to = new_node();
to->name = xstrdup(to_name);
to = new_node(to_name);
node_add(to);
}

Expand Down
3 changes: 2 additions & 1 deletion src/protocol_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ bool pong_h(connection_t *c, const char *request) {

if(c->outgoing && c->outgoing->timeout) {
c->outgoing->timeout = 0;
reset_address_cache(c->outgoing->node->address_cache, &c->address);
reset_address_cache(c->node->address_cache);
add_recent_address(c->node->address_cache, &c->address);
}

return true;
Expand Down
4 changes: 1 addition & 3 deletions src/protocol_subnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#include "protocol.h"
#include "subnet.h"
#include "utils.h"
#include "xalloc.h"

bool send_add_subnet(connection_t *c, const subnet_t *subnet) {
char netstr[MAXNETSTR];
Expand Down Expand Up @@ -85,8 +84,7 @@ bool add_subnet_h(connection_t *c, const char *request) {
}

if(!owner) {
owner = new_node();
owner->name = xstrdup(name);
owner = new_node(name);
node_add(owner);
}

Expand Down
58 changes: 45 additions & 13 deletions src/tincctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2189,6 +2189,49 @@ int check_port(const char *name) {
return 0;
}

static bool makedir(const char *path, mode_t mode) {
if(mkdir(path, mode) && errno != EEXIST) {
fprintf(stderr, "Could not create directory %s: %s\n", path, strerror(errno));
return false;
}

return true;
}

bool makedirs(tincd_dir_t dirs) {
if(dirs & DIR_CONFBASE && !makedir(confbase, 0777)) {
return false;
}

if(dirs & DIR_CONFDIR && !confbase_given && !makedir(confdir, 0755)) {
return false;
}

if(dirs & DIR_HOSTS && !makedir(hosts_dir, 0777)) {
return false;
}

char path[PATH_MAX];

if(dirs & DIR_INVITATIONS) {
snprintf(path, sizeof(path), "%s" SLASH "invitations", confbase);

if(!makedir(path, 0700)) {
return false;
}
}

if(dirs & DIR_CACHE) {
snprintf(path, sizeof(path), "%s" SLASH "%s", confbase, "cache");

if(!makedir(path, 0755)) {
return false;
}
}

return true;
}

static int cmd_init(int argc, char *argv[]) {
if(!access(tinc_conf, F_OK)) {
fprintf(stderr, "Configuration file %s already exists!\n", tinc_conf);
Expand Down Expand Up @@ -2234,19 +2277,8 @@ static int cmd_init(int argc, char *argv[]) {
return 1;
}

if(!confbase_given && mkdir(confdir, 0755) && errno != EEXIST) {
fprintf(stderr, "Could not create directory %s: %s\n", confdir, strerror(errno));
return 1;
}

if(mkdir(confbase, 0777) && errno != EEXIST) {
fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno));
return 1;
}

if(mkdir(hosts_dir, 0777) && errno != EEXIST) {
fprintf(stderr, "Could not create directory %s: %s\n", hosts_dir, strerror(errno));
return 1;
if(!makedirs(DIR_HOSTS | DIR_CONFBASE | DIR_CONFDIR | DIR_CACHE)) {
return false;
}

FILE *f = fopen(tinc_conf, "w");
Expand Down
Loading

0 comments on commit c6a15e2

Please sign in to comment.