Add first draft backup

This commit is contained in:
Adrien Gallouët
2016-11-28 10:59:27 +00:00
parent 72d0573c95
commit 662fe83173
2 changed files with 47 additions and 12 deletions

52
mud.c
View File

@@ -56,6 +56,7 @@
#define MUD_PKEY_SIZE (crypto_scalarmult_BYTES+1) #define MUD_PKEY_SIZE (crypto_scalarmult_BYTES+1)
#define MUD_KEYX_SIZE MUD_PACKET_SIZEOF(MUD_U48_SIZE+2*MUD_PKEY_SIZE) #define MUD_KEYX_SIZE MUD_PACKET_SIZEOF(MUD_U48_SIZE+2*MUD_PKEY_SIZE)
#define MUD_MTUX_SIZE MUD_PACKET_SIZEOF(MUD_U48_SIZE*2) #define MUD_MTUX_SIZE MUD_PACKET_SIZEOF(MUD_U48_SIZE*2)
#define MUD_BAKX_SIZE MUD_PACKET_SIZEOF(MUD_U48_SIZE+1)
#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)
@@ -67,6 +68,7 @@ enum mud_msg {
mud_pong, mud_pong,
mud_keyx, mud_keyx,
mud_mtux, mud_mtux,
mud_bakx,
}; };
struct ipaddr { struct ipaddr {
@@ -87,6 +89,11 @@ struct path {
unsigned char data[256]; unsigned char data[256];
size_t size; size_t size;
} ctrl; } ctrl;
struct {
uint64_t send_time;
int remote;
int local;
} bak;
unsigned char *tc; unsigned char *tc;
uint64_t rdt; uint64_t rdt;
uint64_t rtt; uint64_t rtt;
@@ -224,7 +231,7 @@ uint64_t mud_abs_diff (uint64_t a, uint64_t b)
static static
int mud_timeout (uint64_t now, uint64_t last, uint64_t timeout) int mud_timeout (uint64_t now, uint64_t last, uint64_t timeout)
{ {
return ((!last) || (now-last >= timeout)); return ((!last) || ((now > last) && (now-last >= timeout)));
} }
static static
@@ -484,7 +491,7 @@ int mud_ipaddrinfo (struct ipaddr *ipaddr, const char *name)
return -1; return -1;
} }
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, int backup)
{ {
if (!name || !host || !port) { if (!name || !host || !port) {
errno = EINVAL; errno = EINVAL;
@@ -512,6 +519,7 @@ int mud_peer (struct mud *mud, const char *name, const char *host, int port)
} }
path->state.active = 1; path->state.active = 1;
path->bak.local = !!backup;
return 0; return 0;
} }
@@ -841,6 +849,10 @@ void mud_ctrl_path (struct mud *mud, enum mud_msg msg, struct path *path,
mud_write48(ctrl.data, (uint64_t)mud->mtu.local); mud_write48(ctrl.data, (uint64_t)mud->mtu.local);
size = MUD_U48_SIZE; size = MUD_U48_SIZE;
break; break;
case mud_bakx:
ctrl.data[0] = (unsigned char)path->bak.local;
size = 1;
break;
} }
struct crypto_opt opt = { struct crypto_opt opt = {
@@ -849,10 +861,9 @@ void mud_ctrl_path (struct mud *mud, enum mud_msg msg, struct path *path,
.size = size+2*MUD_U48_SIZE }, .size = size+2*MUD_U48_SIZE },
}; };
mud_encrypt_opt(&mud->crypto.private, &opt);
size += 2*MUD_U48_SIZE+MUD_MAC_SIZE; size += 2*MUD_U48_SIZE+MUD_MAC_SIZE;
mud_encrypt_opt(&mud->crypto.private, &opt);
mud_send_path(mud, path, now, &ctrl, size, 0); mud_send_path(mud, path, now, &ctrl, size, 0);
} }
@@ -997,7 +1008,7 @@ int mud_recv (struct mud *mud, void *data, size_t size)
path->rst = send_time; path->rst = send_time;
if ((path->recv_time) && if ((!path->bak.local) && (path->recv_time) &&
(mud_timeout(now, path->pong_time, MUD_PONG_TIMEOUT))) { (mud_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;
@@ -1018,6 +1029,11 @@ int mud_recv (struct mud *mud, void *data, size_t size)
path->r_rst = mud_read48(&packet[MUD_U48_SIZE*4]); path->r_rst = mud_read48(&packet[MUD_U48_SIZE*4]);
path->r_dt = send_time-path->r_rst; path->r_dt = send_time-path->r_rst;
path->rtt = now-path->r_rst; path->rtt = now-path->r_rst;
} else if (packet_size == (ssize_t)MUD_BAKX_SIZE) {
path->bak.local = 1;
path->bak.remote = (int)packet[MUD_U48_SIZE*2];
if (!path->state.active)
mud_ctrl_path(mud, mud_bakx, path, now);
} }
return 0; return 0;
} }
@@ -1058,6 +1074,13 @@ int mud_send_ctrl (struct mud *mud)
mud->mtu.send_time = now; mud->mtu.send_time = now;
continue; continue;
} }
if ((path->bak.local && !path->bak.remote) &&
(mud_timeout(now, path->bak.send_time, mud->send_timeout))) {
mud_ctrl_path(mud, mud_bakx, path, now);
path->bak.send_time = now;
continue;
}
} }
} }
} }
@@ -1089,6 +1112,9 @@ 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->bak.local)
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;
@@ -1098,8 +1124,7 @@ int mud_send (struct mud *mud, const void *data, size_t size, int tc)
limit = path->rtt/2; limit = path->rtt/2;
} }
if ((path->r_rst) && if (mud_timeout(now, path->recv_time, mud->send_timeout)) {
(now > path->r_rst+MUD_ONE_SEC)) {
mud_send_path(mud, path, now, packet, packet_size, tc); mud_send_path(mud, path, now, packet, packet_size, tc);
path->limit = limit; path->limit = limit;
continue; continue;
@@ -1111,8 +1136,17 @@ int mud_send (struct mud *mud, const void *data, size_t size, int tc)
} }
} }
if (!path_min) if (!path_min) {
return 0; for (path = mud->path; path; path = path->next) {
if (path->bak.local) {
path_min = path;
break;
}
}
if (!path_min)
return 0;
}
ssize_t ret = mud_send_path(mud, path_min, now, packet, packet_size, tc); ssize_t ret = mud_send_path(mud, path_min, now, packet, packet_size, tc);

7
mud.h
View File

@@ -7,17 +7,18 @@ struct mud;
struct mud *mud_create (int, int, int, int, int); struct mud *mud_create (int, int, int, int, int);
void mud_delete (struct mud *); void mud_delete (struct mud *);
int mud_get_fd (struct mud *);
int mud_set_key (struct mud *, unsigned char *, size_t); int mud_set_key (struct mud *, unsigned char *, size_t);
int mud_get_key (struct mud *, unsigned char *, size_t *); int mud_get_key (struct mud *, unsigned char *, size_t *);
int mud_get_fd (struct mud *);
int mud_get_mtu (struct mud *);
int mud_set_mtu (struct mud *, int mtu); int mud_set_mtu (struct mud *, int mtu);
int mud_get_mtu (struct mud *);
int mud_set_send_timeout_msec (struct mud *, unsigned); int mud_set_send_timeout_msec (struct mud *, unsigned);
int mud_set_time_tolerance_sec (struct mud *, unsigned); int mud_set_time_tolerance_sec (struct mud *, unsigned);
int mud_peer (struct mud *, const char *, const char *, int); int mud_peer (struct mud *, const char *, const char *, int, int);
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);