Add first draft backup
This commit is contained in:
52
mud.c
52
mud.c
@@ -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
7
mud.h
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user