Add up,backup and down states
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
100
mud.c
100
mud.c
@@ -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
12
mud.h
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user