Remove the internal tracker (failover)

This commit is contained in:
Adrien Gallouët
2016-11-07 15:01:51 +00:00
parent 4e6094dff9
commit c612a0772e
2 changed files with 48 additions and 132 deletions

175
mud.c
View File

@@ -60,7 +60,7 @@
#define MUD_PONG_TIMEOUT (100*MUD_ONE_MSEC) #define MUD_PONG_TIMEOUT (100*MUD_ONE_MSEC)
#define MUD_KEYX_TIMEOUT (60*MUD_ONE_MIN) #define MUD_KEYX_TIMEOUT (60*MUD_ONE_MIN)
#define MUD_SEND_TIMEOUT (10*MUD_ONE_SEC) #define MUD_SEND_TIMEOUT (MUD_ONE_SEC)
#define MUD_TIME_TOLERANCE (10*MUD_ONE_MIN) #define MUD_TIME_TOLERANCE (10*MUD_ONE_MIN)
enum mud_msg { enum mud_msg {
@@ -80,8 +80,6 @@ struct ipaddr {
struct path { struct path {
struct { struct {
unsigned up : 1;
unsigned on : 1;
unsigned active : 1; unsigned active : 1;
} state; } state;
struct ipaddr local_addr; struct ipaddr local_addr;
@@ -125,25 +123,26 @@ struct crypto_key {
int aes; int aes;
}; };
struct crypto {
uint64_t time;
unsigned char secret[crypto_scalarmult_SCALARBYTES];
struct public public;
struct crypto_key private, last, next, current;
int use_next;
int aes;
int bad_key;
};
struct mud { struct mud {
int fd; int fd;
uint64_t send_timeout; uint64_t send_timeout;
uint64_t time_tolerance; uint64_t time_tolerance;
uint64_t mtu;
uint64_t recv_mtu;
int send_mtu;
struct path *path; struct path *path;
struct crypto crypto; struct {
uint64_t recv_time;
uint64_t send_time;
unsigned char secret[crypto_scalarmult_SCALARBYTES];
struct public public;
struct crypto_key private, last, next, current;
int use_next;
int aes;
int bad_key;
} crypto;
struct {
uint64_t send_time;
int remote;
int local;
} mtu;
}; };
static static
@@ -220,6 +219,12 @@ uint64_t mud_dt (uint64_t a, uint64_t b)
return (a >= b) ? a-b : b-a; return (a >= b) ? a-b : b-a;
} }
static
int mud_timeout (uint64_t now, uint64_t last, uint64_t timeout)
{
return ((!last) || (now-last >= timeout));
}
static static
void mud_unmapv4 (struct sockaddr *addr) void mud_unmapv4 (struct sockaddr *addr)
{ {
@@ -461,8 +466,6 @@ struct path *mud_path (struct mud *mud, struct ipaddr *local_addr,
mud_set_path(path, local_addr, addr); mud_set_path(path, local_addr, addr);
path->state.on = 1;
path->next = mud->path; path->next = mud->path;
mud->path = path; mud->path = path;
@@ -490,33 +493,6 @@ int mud_ipaddrinfo (struct ipaddr *ipaddr, const char *name)
return -1; return -1;
} }
int mud_set_on (struct mud *mud, const char *name, int on)
{
if (!name) {
errno = EINVAL;
return -1;
}
struct ipaddr local_addr;
if (mud_ipaddrinfo(&local_addr, name))
return -1;
struct path *path = NULL;
for (path = mud->path; path; path = path->next) {
if (!path->state.active)
continue;
if (mud_cmp_ipaddr(&local_addr, &path->local_addr))
continue;
path->state.on = on;
}
return 0;
}
int mud_peer (struct mud *mud, const char *name, const char *host, int port) int mud_peer (struct mud *mud, const char *name, const char *host, int port)
{ {
if (!name || !host || !port) { if (!name || !host || !port) {
@@ -605,11 +581,11 @@ int mud_set_time_tolerance_sec (struct mud *mud, unsigned sec)
int mud_get_mtu (struct mud *mud) int mud_get_mtu (struct mud *mud)
{ {
if ((!mud->recv_mtu) || if ((!mud->mtu.remote) ||
(mud->mtu <= mud->recv_mtu)) (mud->mtu.local < mud->mtu.remote))
return mud->mtu; return mud->mtu.local;
return mud->recv_mtu; return mud->mtu.remote;
} }
int mud_set_mtu (struct mud *mud, int mtu) int mud_set_mtu (struct mud *mud, int mtu)
@@ -620,9 +596,9 @@ int mud_set_mtu (struct mud *mud, int mtu)
return -1; return -1;
} }
if (mud->mtu != mtu) { if (mud->mtu.local != mtu) {
mud->mtu = mtu; mud->mtu.local = mtu;
mud->send_mtu = 1; mud->mtu.send_time = UINT64_C(0);
} }
return 0; return 0;
@@ -701,7 +677,7 @@ struct mud *mud_create (int port, int v4, int v6, int aes, int mtu)
mud->send_timeout = MUD_SEND_TIMEOUT; mud->send_timeout = MUD_SEND_TIMEOUT;
mud->time_tolerance = MUD_TIME_TOLERANCE; mud->time_tolerance = MUD_TIME_TOLERANCE;
mud->mtu = mtu; mud->mtu.local = mtu;
unsigned char key[MUD_KEY_SIZE]; unsigned char key[MUD_KEY_SIZE];
@@ -808,46 +784,6 @@ int mud_decrypt (struct mud *mud,
return size; return size;
} }
int mud_peer_is_up (struct mud *mud, const char *name, const char *host, int port)
{
if (!name || !host || !port)
return 0;
struct ipaddr local_addr;
if (mud_ipaddrinfo(&local_addr, name))
return 0;
struct sockaddr_storage addr;
if (mud_addrinfo(&addr, host, port))
return 0;
mud_unmapv4((struct sockaddr *)&addr);
struct path *path = mud_path(mud, &local_addr,
(struct sockaddr *)&addr, 0);
if (!path)
return 0;
return path->state.on && path->state.up;
}
int mud_is_up (struct mud *mud)
{
struct path *path;
int up = 0;
for (path = mud->path; path; path = path->next) {
if (path->state.on)
up += path->state.up;
}
return up;
}
static static
int mud_localaddr (struct ipaddr *local_addr, struct msghdr *msg, int family) int mud_localaddr (struct ipaddr *local_addr, struct msghdr *msg, int family)
{ {
@@ -911,7 +847,7 @@ void mud_ctrl_path (struct mud *mud, enum mud_msg msg, struct path *path,
size = sizeof(mud->crypto.public); size = sizeof(mud->crypto.public);
break; break;
case mud_mtux: case mud_mtux:
mud_write48(ctrl.data, mud->mtu); mud_write48(ctrl.data, (uint64_t)mud->mtu.local);
size = MUD_U48_SIZE; size = MUD_U48_SIZE;
break; break;
default: default:
@@ -925,7 +861,10 @@ void mud_ctrl_path (struct mud *mud, enum mud_msg msg, struct path *path,
}; };
mud_encrypt_opt(&mud->crypto.private, &opt); mud_encrypt_opt(&mud->crypto.private, &opt);
mud_send_path(mud, path, now, &ctrl, size+2*MUD_U48_SIZE+MUD_MAC_SIZE, 0);
size += 2*MUD_U48_SIZE+MUD_MAC_SIZE;
mud_send_path(mud, path, now, &ctrl, size, 0);
} }
static static
@@ -987,7 +926,7 @@ void mud_recv_keyx (struct mud *mud, struct path *path, uint64_t now,
crypto_aead_aes256gcm_beforenm(&key->decrypt.state, key->decrypt.key); crypto_aead_aes256gcm_beforenm(&key->decrypt.state, key->decrypt.key);
} }
mud->crypto.time = now; mud->crypto.recv_time = now;
} }
int mud_recv (struct mud *mud, void *data, size_t size) int mud_recv (struct mud *mud, void *data, size_t size)
@@ -1059,9 +998,6 @@ int mud_recv (struct mud *mud, void *data, size_t size)
if (!path) if (!path)
return 0; return 0;
if (mud_packet)
path->state.up = 1;
int64_t dt = (now-path->recv_time)-(send_time-path->recv_send_time); int64_t dt = (now-path->recv_time)-(send_time-path->recv_send_time);
if (path->recv_time && path->recv_send_time && (dt > 0)) if (path->recv_time && path->recv_send_time && (dt > 0))
@@ -1080,8 +1016,7 @@ int mud_recv (struct mud *mud, void *data, size_t size)
return 0; return 0;
} }
if ((!path->pong_time) || if (mud_timeout(now, path->pong_time, MUD_PONG_TIMEOUT)) {
(now-path->pong_time >= MUD_PONG_TIMEOUT)) {
mud_ctrl_path(mud, mud_pong, path, now); mud_ctrl_path(mud, mud_pong, path, now);
path->pong_time = now; path->pong_time = now;
} }
@@ -1090,8 +1025,7 @@ int mud_recv (struct mud *mud, void *data, size_t size)
if (packet_size == (ssize_t)MUD_KEYX_SIZE) { if (packet_size == (ssize_t)MUD_KEYX_SIZE) {
mud_recv_keyx(mud, path, now, &packet[MUD_U48_SIZE*2]); mud_recv_keyx(mud, path, now, &packet[MUD_U48_SIZE*2]);
} else if (packet_size == (ssize_t)MUD_MTUX_SIZE) { } else if (packet_size == (ssize_t)MUD_MTUX_SIZE) {
mud->recv_mtu = mud_read48(&packet[MUD_U48_SIZE*2]); mud->mtu.remote = (int)mud_read48(&packet[MUD_U48_SIZE*2]);
mud->send_mtu = 0;
if (!path->state.active) if (!path->state.active)
mud_ctrl_path(mud, mud_mtux, path, now); mud_ctrl_path(mud, mud_mtux, path, now);
} }
@@ -1113,21 +1047,8 @@ int mud_send_ctrl (struct mud *mud)
struct path *path; struct path *path;
for (path = mud->path; path; path = path->next) { for (path = mud->path; path; path = path->next) {
if (!path->state.on)
continue;
uint64_t now = mud_now(mud); uint64_t now = mud_now(mud);
if (path->state.up) {
if ((!path->recv_time) ||
(now-path->recv_time >= mud->send_timeout))
path->state.up = 0;
}
if ((path->send_time) &&
(now-path->send_time < (mud->send_timeout>>1)))
continue;
if (!path->state.active) { if (!path->state.active) {
if (mud->crypto.bad_key) { if (mud->crypto.bad_key) {
mud_ctrl_path(mud, mud_keyx, path, now); mud_ctrl_path(mud, mud_keyx, path, now);
@@ -1136,18 +1057,19 @@ int mud_send_ctrl (struct mud *mud)
continue; continue;
} }
if (!mud->recv_mtu || mud->send_mtu) { if ((mud_timeout(now, mud->crypto.send_time, mud->send_timeout)) &&
mud_ctrl_path(mud, mud_mtux, path, now); (mud_timeout(now, mud->crypto.recv_time, MUD_KEYX_TIMEOUT))) {
continue;
}
if ((!mud->crypto.time) ||
(now-mud->crypto.time >= MUD_KEYX_TIMEOUT)) {
mud_ctrl_path(mud, mud_keyx, path, now); mud_ctrl_path(mud, mud_keyx, path, now);
mud->crypto.send_time = now;
continue; continue;
} }
mud_ctrl_path(mud, mud_ping, path, now); if ((!mud->mtu.remote) &&
(mud_timeout(now, mud->mtu.send_time, mud->send_timeout))) {
mud_ctrl_path(mud, mud_mtux, path, now);
mud->mtu.send_time = now;
continue;
}
} }
} }
@@ -1170,9 +1092,6 @@ int mud_send (struct mud *mud, const void *data, size_t size, int tc)
int64_t limit_min = INT64_MAX; int64_t limit_min = INT64_MAX;
for (path = mud->path; path; path = path->next) { for (path = mud->path; path; path = path->next) {
if (!path->state.up || !path->state.on)
continue;
int64_t limit = path->limit; int64_t limit = path->limit;
uint64_t elapsed = now-path->send_time; uint64_t elapsed = now-path->send_time;

5
mud.h
View File

@@ -19,10 +19,7 @@ int mud_set_time_tolerance_sec (struct mud *, unsigned);
int mud_set_on (struct mud *, const char *, int); int mud_set_on (struct mud *, const char *, int);
int mud_peer (struct mud *, const char *, const char *, int); int mud_peer (struct mud *, const char *, const char *, int);
int mud_peer_is_up (struct mud *, const char *, const char *, int);
int mud_is_up (struct mud *);
int mud_recv (struct mud *, void *, size_t); int mud_recv (struct mud *, void *, size_t);
int mud_send (struct mud *, const void *, size_t, int); int mud_send (struct mud *, const void *, size_t, int);