Add up,backup and down states

Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
Adrien Gallouët
2018-02-24 15:26:38 +00:00
parent ac1ba977f4
commit 81b279b060
2 changed files with 48 additions and 64 deletions

100
mud.c
View File

@@ -81,10 +81,7 @@
#define MUD_TIME_TOLERANCE (10 * MUD_ONE_MIN) #define MUD_TIME_TOLERANCE (10 * MUD_ONE_MIN)
struct mud_path { struct mud_path {
struct { enum mud_state state;
unsigned skip : 1;
unsigned backup : 1;
} state;
struct sockaddr_storage local_addr, addr; struct sockaddr_storage local_addr, addr;
struct { struct {
uint64_t send_time; uint64_t send_time;
@@ -147,7 +144,7 @@ struct mud_packet {
struct { struct {
unsigned char kiss[MUD_SID_SIZE]; unsigned char kiss[MUD_SID_SIZE];
unsigned char mtu[MUD_U48_SIZE]; unsigned char mtu[MUD_U48_SIZE];
unsigned char backup; unsigned char state;
struct mud_public public; struct mud_public public;
unsigned char aes; unsigned char aes;
} conf; } conf;
@@ -396,8 +393,8 @@ mud_cmp_addr(struct sockaddr_storage *a, struct sockaddr_storage *b)
} }
static struct mud_path * static struct mud_path *
mud_path(struct mud *mud, struct sockaddr_storage *local_addr, mud_get_path(struct mud *mud, struct sockaddr_storage *local_addr,
struct sockaddr_storage *addr, int create) struct sockaddr_storage *addr, int create)
{ {
struct mud_path *path; struct mud_path *path;
@@ -470,49 +467,6 @@ mud_peer(struct mud *mud, struct sockaddr *peer)
return 0; return 0;
} }
int
mud_del_path(struct mud *mud, struct sockaddr *peer)
{
struct sockaddr_storage addr;
if (mud_ss_from_sa(&addr, peer))
return -1;
struct mud_path *path;
for (path = mud->path; path; path = path->next) {
if (mud_cmp_addr(&addr, mud->peer.set ? &path->local_addr : &path->addr))
continue;
path->state.skip = 1;
}
return 0;
}
int
mud_add_path(struct mud *mud, struct sockaddr *peer)
{
if (!mud->peer.set) {
errno = EINVAL;
return -1;
}
struct sockaddr_storage addr;
if (mud_ss_from_sa(&addr, peer))
return -1;
struct mud_path *path = mud_path(mud, &addr, &mud->peer.addr, 1);
if (!path)
return -1;
path->state.skip = 0;
return 0;
}
int int
mud_get_key(struct mud *mud, unsigned char *key, size_t *size) mud_get_key(struct mud *mud, unsigned char *key, size_t *size)
{ {
@@ -607,6 +561,32 @@ mud_set_time_tolerance(struct mud *mud, unsigned long msec)
return 0; return 0;
} }
int
mud_set_state(struct mud *mud, struct sockaddr *peer, enum mud_state state)
{
if (!mud->peer.set || (state >= MUD_LAST)) {
errno = EINVAL;
return -1;
}
struct sockaddr_storage addr;
if (mud_ss_from_sa(&addr, peer))
return -1;
struct mud_path *path = mud_get_path(mud, &addr, &mud->peer.addr, state != MUD_DOWN);
if (!path)
return -1;
if (path->state != state) {
path->state = state;
path->conf.remote = 0;
}
return 0;
}
size_t size_t
mud_get_mtu(struct mud *mud) mud_get_mtu(struct mud *mud)
{ {
@@ -954,7 +934,7 @@ mud_packet_send(struct mud *mud, enum mud_packet_code code,
size = sizeof(packet.data.conf); size = sizeof(packet.data.conf);
memcpy(&packet.data.conf.kiss, &mud->kiss, size); memcpy(&packet.data.conf.kiss, &mud->kiss, size);
mud_write48(packet.data.conf.mtu, path->conf.mtu.local); mud_write48(packet.data.conf.mtu, path->conf.mtu.local);
packet.data.conf.backup = (unsigned char)path->state.backup; packet.data.conf.state = (unsigned char)path->state;
memcpy(&packet.data.conf.public.local, &mud->crypto.public.local, memcpy(&packet.data.conf.public.local, &mud->crypto.public.local,
sizeof(mud->crypto.public.local)); sizeof(mud->crypto.public.local));
memcpy(&packet.data.conf.public.remote, &mud->crypto.public.remote, memcpy(&packet.data.conf.public.remote, &mud->crypto.public.remote,
@@ -1060,7 +1040,7 @@ mud_packet_recv(struct mud *mud, struct mud_path *path,
mud_kiss_path(mud, path); mud_kiss_path(mud, path);
mud_keyx(mud, packet->data.conf.public.local, mud_keyx(mud, packet->data.conf.public.local,
packet->data.conf.aes); packet->data.conf.aes);
path->state.backup = !!packet->data.conf.backup; path->state = (enum mud_state)packet->data.conf.state;
mud_packet_send(mud, mud_conf, path, now, MSG_CONFIRM); mud_packet_send(mud, mud_conf, path, now, MSG_CONFIRM);
} }
break; break;
@@ -1138,7 +1118,7 @@ mud_recv(struct mud *mud, void *data, size_t size)
} }
} }
struct mud_path *path = mud_path(mud, &local_addr, &addr, 1); struct mud_path *path = mud_get_path(mud, &local_addr, &addr, 1);
if (!path) if (!path)
return 0; return 0;
@@ -1153,7 +1133,7 @@ mud_recv(struct mud *mud, void *data, size_t size)
path->rst = send_time; path->rst = send_time;
if ((!path->state.backup) && (path->recv_time) && if ((path->state == MUD_UP) && (path->recv_time) &&
(mud_timeout(now, path->stat_time, MUD_STAT_TIMEOUT))) { (mud_timeout(now, path->stat_time, MUD_STAT_TIMEOUT))) {
mud_packet_send(mud, mud_stat, path, now, MSG_CONFIRM); mud_packet_send(mud, mud_stat, path, now, MSG_CONFIRM);
path->stat_time = now; path->stat_time = now;
@@ -1179,7 +1159,7 @@ mud_update(struct mud *mud)
struct mud_path *path = mud->path; struct mud_path *path = mud->path;
for (; path; path = path->next) { for (; path; path = path->next) {
if (path->state.skip) if (path->state == MUD_DOWN)
continue; continue;
if (update_keyx || mud_timeout(now, path->recv_time, mud->send_timeout + MUD_ONE_SEC)) if (update_keyx || mud_timeout(now, path->recv_time, mud->send_timeout + MUD_ONE_SEC))
@@ -1223,12 +1203,10 @@ 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.skip) switch (path->state) {
continue; case MUD_BACKUP: path_backup = path; /* FALLTHRU */
case MUD_DOWN: continue;
if (path->state.backup) { default: break;
path_backup = path;
continue;
} }
int64_t limit = path->limit; int64_t limit = path->limit;

12
mud.h
View File

@@ -5,6 +5,13 @@
struct mud; struct mud;
struct sockaddr; struct sockaddr;
enum mud_state {
MUD_UP = 0,
MUD_BACKUP,
MUD_DOWN,
MUD_LAST,
};
struct mud *mud_create (struct sockaddr *); struct mud *mud_create (struct sockaddr *);
void mud_delete (struct mud *); void mud_delete (struct mud *);
@@ -21,10 +28,9 @@ int mud_set_time_tolerance (struct mud *, unsigned long);
int mud_set_tc (struct mud *, int); int mud_set_tc (struct mud *, int);
int mud_set_aes (struct mud *); int mud_set_aes (struct mud *);
int mud_peer (struct mud *, struct sockaddr *); int mud_set_state (struct mud *, struct sockaddr *, enum mud_state);
int mud_add_path (struct mud *, struct sockaddr *); int mud_peer (struct mud *, struct sockaddr *);
int mud_del_path (struct mud *, struct sockaddr *);
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);