Use lowbw scheduler and clean old unused stuff

Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
Adrien Gallouët
2018-11-29 22:21:07 +00:00
parent b5289a8472
commit 79688de09e
2 changed files with 227 additions and 197 deletions

392
mud.c
View File

@@ -65,19 +65,19 @@
#define MUD_PACKET_MARK(X) ((X) | UINT64_C(1)) #define MUD_PACKET_MARK(X) ((X) | UINT64_C(1))
#define MUD_PACKET_MIN_SIZE (MUD_U48_SIZE + MUD_MAC_SIZE) #define MUD_PACKET_MIN_SIZE (MUD_U48_SIZE + MUD_MAC_SIZE)
#define MUD_PACKET_MAX_SIZE (9000U) #define MUD_PACKET_MAX_SIZE (1500U)
#define MUD_PACKET_TC (192) // CS6 #define MUD_PACKET_TC (192) // CS6
#define MUD_MTU (1280U + MUD_PACKET_MIN_SIZE) #define MUD_MTU_MIN (1280U + MUD_PACKET_MIN_SIZE)
#define MUD_MTU_MAX (1450U + MUD_PACKET_MIN_SIZE)
#define MUD_TIME_BITS (48) #define MUD_TIME_BITS (48)
#define MUD_TIME_MASK(X) ((X) & ((UINT64_C(1) << MUD_TIME_BITS) - 2)) #define MUD_TIME_MASK(X) ((X) & ((UINT64_C(1) << MUD_TIME_BITS) - 2))
#define MUD_STAT_TIMEOUT (100 * MUD_ONE_MSEC) #define MUD_SEND_TIMEOUT (100 * MUD_ONE_MSEC)
#define MUD_KEYX_TIMEOUT (60 * MUD_ONE_MIN) #define MUD_KEYX_TIMEOUT (60 * MUD_ONE_MIN)
#define MUD_KEYX_RESET_TIMEOUT (2 * MUD_STAT_TIMEOUT) #define MUD_KEYX_RESET_TIMEOUT (200 * MUD_ONE_MSEC)
#define MUD_SEND_TIMEOUT (MUD_ONE_SEC)
#define MUD_TIME_TOLERANCE (10 * MUD_ONE_MIN) #define MUD_TIME_TOLERANCE (10 * MUD_ONE_MIN)
#define MUD_CTRL_SIZE (CMSG_SPACE(MUD_PKTINFO_SIZE) + \ #define MUD_CTRL_SIZE (CMSG_SPACE(MUD_PKTINFO_SIZE) + \
@@ -122,8 +122,6 @@ struct mud_packet {
unsigned char latmin[MUD_U48_SIZE]; unsigned char latmin[MUD_U48_SIZE];
unsigned char rate[MUD_U48_SIZE]; unsigned char rate[MUD_U48_SIZE];
unsigned char ratemax[MUD_U48_SIZE]; unsigned char ratemax[MUD_U48_SIZE];
unsigned char max[MUD_U48_SIZE];
unsigned char max_time[MUD_U48_SIZE];
}; };
struct mud { struct mud {
@@ -156,6 +154,7 @@ struct mud {
uint64_t time; uint64_t time;
} decrypt, difftime, keyx; } decrypt, difftime, keyx;
} bad; } bad;
unsigned long long window;
}; };
static int static int
@@ -170,7 +169,8 @@ mud_addr_is_v6(struct mud_addr *addr)
} }
static int static int
mud_encrypt_opt(const struct mud_crypto_key *k, const struct mud_crypto_opt *c) mud_encrypt_opt(const struct mud_crypto_key *k,
const struct mud_crypto_opt *c)
{ {
if (k->aes) { if (k->aes) {
unsigned char npub[crypto_aead_aes256gcm_NPUBBYTES] = {0}; unsigned char npub[crypto_aead_aes256gcm_NPUBBYTES] = {0};
@@ -208,7 +208,8 @@ mud_encrypt_opt(const struct mud_crypto_key *k, const struct mud_crypto_opt *c)
} }
static int static int
mud_decrypt_opt(const struct mud_crypto_key *k, const struct mud_crypto_opt *c) mud_decrypt_opt(const struct mud_crypto_key *k,
const struct mud_crypto_opt *c)
{ {
if (k->aes) { if (k->aes) {
unsigned char npub[crypto_aead_aes256gcm_NPUBBYTES] = {0}; unsigned char npub[crypto_aead_aes256gcm_NPUBBYTES] = {0};
@@ -317,74 +318,19 @@ mud_unmapv4(struct sockaddr_storage *addr)
memcpy(addr, &sin, sizeof(sin)); memcpy(addr, &sin, sizeof(sin));
} }
static void
mud_update_mtu(struct mud *mud)
{
size_t mtu = MUD_PACKET_MAX_SIZE;
size_t count = 0;
for (unsigned i = 0; i < mud->count; i++) {
struct mud_path *path = &mud->paths[i];
if (path->state <= MUD_DOWN)
continue;
count++;
if (mtu > path->mtu.ok)
mtu = path->mtu.ok;
}
mud->mtu = count ? mtu : MUD_MTU;
}
static struct mud_path * static struct mud_path *
mud_select_path(struct mud *mud, unsigned k) mud_select_path(struct mud *mud, unsigned k)
{ {
unsigned long long n = 0;
for (unsigned i = 0; i < mud->count; i++) {
struct mud_path *path = &mud->paths[i];
path->prob = 0;
if (!path->ok || path->state <= MUD_DOWN)
continue;
unsigned long long coef = 18;
uint64_t dt = (path->r_lat - path->r_latmin) / MUD_ONE_MSEC;
if (dt >= 300) {
coef = 0;
} else if (dt >= 50) {
coef = (16 - ((dt - 50) * 16)/(300 - 50)) + 1;
}
unsigned long long r = (path->r_ratemax * coef) / 16;
if (r == 0)
r = 10000;
if (path->send.bytes >= r)
continue;
path->prob = r - path->send.bytes;
n += path->prob;
}
if (!n)
return NULL;
unsigned w = 0; unsigned w = 0;
struct mud_path *last = NULL; struct mud_path *last = NULL;
for (unsigned i = 0; i < mud->count; i++) { for (unsigned i = 0; i < mud->count; i++) {
struct mud_path *path = &mud->paths[i]; struct mud_path *path = &mud->paths[i];
if (!path->prob) if (!path->window)
continue; continue;
w += ((path->prob << 16) + (n >> 1)) / n; w += ((path->window << 16) + (mud->window >> 1)) / mud->window;
last = path; last = path;
if (k <= w) if (k <= w)
@@ -469,11 +415,6 @@ mud_send_path(struct mud *mud, struct mud_path *path, uint64_t now,
path->send.bytes += size; path->send.bytes += size;
path->send.time = now; path->send.time = now;
if (path->send.max <= size) {
path->send.max = size;
path->send.max_time = now;
}
return ret; return ret;
} }
@@ -513,16 +454,6 @@ mud_cmp_addr(struct sockaddr_storage *a, struct sockaddr_storage *b)
return 1; return 1;
} }
unsigned long
mud_sync(struct mud *mud)
{
const uint64_t last = mud->last_recv_time;
mud_send(mud, NULL, 0, 0);
return last ? MUD_TIME_MASK(mud_now() - last) / MUD_ONE_MSEC : ~0UL;
}
struct mud_path * struct mud_path *
mud_get_paths(struct mud *mud, unsigned *ret_count) mud_get_paths(struct mud *mud, unsigned *ret_count)
{ {
@@ -593,10 +524,14 @@ mud_copy_port(struct sockaddr_storage *d, struct sockaddr_storage *s)
static void static void
mud_reset_path(struct mud *mud, struct mud_path *path) mud_reset_path(struct mud *mud, struct mud_path *path)
{ {
path->state = MUD_UP; path->mtu.ok = MUD_MTU_MIN;
path->mtu.ok = MUD_MTU; path->mtu.min = MUD_MTU_MIN;
path->mtu.probe = mud->mtu; path->mtu.max = MUD_MTU_MAX;
path->mtu.count = 0;
path->send.ratemax = 0;
path->window = 0;
path->ok = 0; path->ok = 0;
path->stat_count = 0;
} }
static struct mud_path * static struct mud_path *
@@ -656,8 +591,8 @@ mud_get_path(struct mud *mud, struct sockaddr_storage *local_addr,
memcpy(&path->local_addr, local_addr, sizeof(*local_addr)); memcpy(&path->local_addr, local_addr, sizeof(*local_addr));
memcpy(&path->addr, addr, sizeof(*addr)); memcpy(&path->addr, addr, sizeof(*addr));
path->state = MUD_UP;
mud_reset_path(mud, path); mud_reset_path(mud, path);
mud_update_mtu(mud);
return path; return path;
} }
@@ -815,8 +750,7 @@ mud_set_state(struct mud *mud, struct sockaddr *addr, enum mud_state state)
return 0; return 0;
path->state = state; path->state = state;
mud_reset_path(mud, path);
mud_update_mtu(mud);
return 0; return 0;
} }
@@ -1002,7 +936,7 @@ mud_create(struct sockaddr *addr)
mud->time_tolerance = MUD_TIME_TOLERANCE; mud->time_tolerance = MUD_TIME_TOLERANCE;
mud->keyx_timeout = MUD_KEYX_TIMEOUT; mud->keyx_timeout = MUD_KEYX_TIMEOUT;
mud->tc = MUD_PACKET_TC; mud->tc = MUD_PACKET_TC;
mud->mtu = MUD_MTU; mud->mtu = MUD_MTU_MIN;
memcpy(&mud->addr, addr, addrlen); memcpy(&mud->addr, addr, addrlen);
@@ -1130,13 +1064,14 @@ mud_localaddr(struct sockaddr_storage *addr, struct msghdr *msg)
static int static int
mud_packet_send(struct mud *mud, struct mud_path *path, mud_packet_send(struct mud *mud, struct mud_path *path,
uint64_t now, uint64_t sent, int probe) uint64_t now, uint64_t sent, size_t size)
{ {
unsigned char dst[MUD_PACKET_MAX_SIZE]; unsigned char dst[MUD_PACKET_MAX_SIZE];
unsigned char src[MUD_PACKET_MAX_SIZE] = {0}; unsigned char src[MUD_PACKET_MAX_SIZE] = {0};
struct mud_packet *packet = (struct mud_packet *)src; struct mud_packet *packet = (struct mud_packet *)src;
size_t size = sizeof(struct mud_packet);
if (size < MUD_PACKET_MIN_SIZE + sizeof(struct mud_packet))
size = MUD_PACKET_MIN_SIZE + sizeof(struct mud_packet);
mud_write48(dst, MUD_PACKET_MARK(now)); mud_write48(dst, MUD_PACKET_MARK(now));
mud_write48(packet->sent, sent); mud_write48(packet->sent, sent);
@@ -1166,26 +1101,20 @@ mud_packet_send(struct mud *mud, struct mud_path *path,
packet->aes = (unsigned char)mud->crypto.aes; packet->aes = (unsigned char)mud->crypto.aes;
mud_write48(packet->lat, path->lat); mud_write48(packet->lat, path->lat.val);
mud_write48(packet->latmin, path->latmin); mud_write48(packet->latmin, path->latmin);
mud_write48(packet->max, path->recv.max); mud_write48(packet->rate, path->rate.val);
mud_write48(packet->max_time, path->recv.max_time);
mud_write48(packet->rate, path->recv.rate);
mud_write48(packet->ratemax, path->recv.ratemax); mud_write48(packet->ratemax, path->recv.ratemax);
if (probe)
size = path->mtu.probe - MUD_PACKET_MIN_SIZE;
const struct mud_crypto_opt opt = { const struct mud_crypto_opt opt = {
.dst = dst, .dst = dst,
.src = src, .src = src,
.size = size, .size = size - MUD_PACKET_MIN_SIZE,
}; };
mud_encrypt_opt(&mud->crypto.private, &opt); mud_encrypt_opt(&mud->crypto.private, &opt);
return mud_send_path(mud, path, now, return mud_send_path(mud, path, now, dst, size,
dst, size + MUD_PACKET_MIN_SIZE,
mud->tc, sent ? MSG_CONFIRM : 0); mud->tc, sent ? MSG_CONFIRM : 0);
} }
@@ -1212,15 +1141,16 @@ mud_packet_decrypt(struct mud *mud,
} }
static void static void
mud_compute_rtt(struct mud_path *path, const uint64_t rtt) mud_value_update(struct mud_value *value, const uint64_t val)
{ {
if (path->rtt) { if (value->setup) {
path->rttvar = ((path->rttvar << 1) + path->rttvar const uint64_t var = mud_abs_diff(value->val, val);
+ mud_abs_diff(path->rtt, rtt)) >> 2; value->var = ((value->var << 1) + value->var + var) >> 2;
path->rtt = ((path->rtt << 3) - path->rtt + rtt) >> 3; value->val = ((value->val << 3) - value->val + val) >> 3;
} else { } else {
path->rttvar = rtt >> 1; value->setup = 1;
path->rtt = rtt; value->var = val >> 1;
value->val = val;
} }
} }
@@ -1238,7 +1168,7 @@ mud_ss_from_packet(struct sockaddr_storage *ss, struct mud_packet *pkt)
} }
} }
static void static int
mud_packet_recv(struct mud *mud, struct mud_path *path, mud_packet_recv(struct mud *mud, struct mud_path *path,
uint64_t now, uint64_t sent, uint64_t now, uint64_t sent,
unsigned char *data, size_t size) unsigned char *data, size_t size)
@@ -1253,7 +1183,12 @@ mud_packet_recv(struct mud *mud, struct mud_path *path,
const uint64_t peer_sent = mud_read48(packet->sent); const uint64_t peer_sent = mud_read48(packet->sent);
if (peer_sent) { if (peer_sent) {
mud_compute_rtt(path, MUD_TIME_MASK(now - peer_sent)); mud_value_update(&path->rtt, MUD_TIME_MASK(now - peer_sent));
if (path->mtu.ok < size) {
path->mtu.ok = size;
path->mtu.min = size + 1;
path->mtu.count = 0;
}
} else { } else {
mud_keyx_init(mud, now); mud_keyx_init(mud, now);
} }
@@ -1270,7 +1205,7 @@ mud_packet_recv(struct mud *mud, struct mud_path *path,
if (mud_keyx(mud, packet->pub, packet->aes)) { if (mud_keyx(mud, packet->pub, packet->aes)) {
mud->bad.keyx.addr = path->addr; mud->bad.keyx.addr = path->addr;
mud->bad.keyx.time = now; mud->bad.keyx.time = now;
return; return -1;
} }
if (!mud->peer.set) { if (!mud->peer.set) {
@@ -1286,8 +1221,6 @@ mud_packet_recv(struct mud *mud, struct mud_path *path,
MUD_PUB_SIZE)) MUD_PUB_SIZE))
mud->paths[i].state = MUD_EMPTY; mud->paths[i].state = MUD_EMPTY;
} }
mud_packet_send(mud, path, now, sent, 0);
} }
path->pub = mud->crypto.pub; path->pub = mud->crypto.pub;
@@ -1297,16 +1230,31 @@ mud_packet_recv(struct mud *mud, struct mud_path *path,
path->r_lat = mud_read48(packet->lat); path->r_lat = mud_read48(packet->lat);
path->r_latmin = mud_read48(packet->latmin); path->r_latmin = mud_read48(packet->latmin);
path->r_max = mud_read48(packet->max);
path->r_max_time = mud_read48(packet->max_time);
path->r_rate = mud_read48(packet->rate); path->r_rate = mud_read48(packet->rate);
path->r_ratemax = mud_read48(packet->ratemax); path->r_ratemax = mud_read48(packet->ratemax);
if (path->mtu.ok < path->r_max) // TODO
path->mtu.ok = path->r_max;
mud_update_mtu(mud); const uint64_t dt = MUD_TIME_MASK(path->r_lat - path->r_latmin);
path->ok = 1; const uint64_t target = 15 * MUD_ONE_MSEC;
const uint64_t a = (path->r_ratemax * 1500) >> 1;
const uint64_t b = (path->send.ratemax ?: 5000) * target;
if (dt < target) {
uint64_t delta = ((target - dt) * a) / b;
path->send.ratemax += delta;
} else if (dt > target) {
uint64_t delta = ((dt - target) * a) / b;
if (path->send.ratemax > delta) {
path->send.ratemax -= delta;
} else {
path->send.ratemax = 5000;
}
if (path->send.ratemax < 5000)
path->send.ratemax = 5000;
}
return !!peer_sent;
} }
int int
@@ -1372,83 +1320,87 @@ mud_recv(struct mud *mud, void *data, size_t size)
if (!path) if (!path)
return 0; return 0;
path->ok = 1;
path->stat_count = 0;
path->recv.total++; path->recv.total++;
path->recv.time = now; path->recv.time = now;
mud->last_recv_time = now; mud->last_recv_time = now;
if (path->recv.max <= packet_size) { const uint64_t lat = MUD_TIME_MASK(now - send_time + mud->time_tolerance);
path->recv.max = packet_size; mud_value_update(&path->lat, lat);
path->recv.max_time = send_time;
if (path->mtu.ok < path->recv.max) { if (!path->latmin)
path->mtu.ok = path->recv.max; path->latmin = path->lat.val;
mud_update_mtu(mud);
} size_t reply_size = 0;
}
if (MUD_PACKET(send_time)) if (MUD_PACKET(send_time))
mud_packet_recv(mud, path, now, send_time, data, ret); if (!mud_packet_recv(mud, path, now, send_time, data, packet_size))
reply_size = packet_size;
if (mud_timeout(now, path->recv.stat_time, MUD_STAT_TIMEOUT)) { if (mud_timeout(now, path->recv.stat_time, mud->send_timeout)) {
const uint64_t rate = path->recv.bytes; const uint64_t rate = path->recv.bytes;
mud_value_update(&path->rate, rate);
path->lat = MUD_TIME_MASK(now - send_time + mud->time_tolerance); if (path->recv.ratemax < path->rate.val) {
path->recv.ratemax = path->rate.val;
if (path->latmin) {
if (path->latmin > path->lat)
path->latmin = path->lat;
if (path->latmax < path->lat)
path->latmax = path->lat;
} else { } else {
path->latmin = path->lat; if (path->lat.val > path->latmin + 4 * path->lat.var) {
path->latmax = path->lat; path->recv.ratemax = (rate + 7 * path->recv.ratemax) / 8;
}
if (path->recv.ratemax > rate) {
if (rate < (7 * path->recv.ratemax) / 8)
path->latmin = (7 * path->latmin + path->lat) / 8;
if (path->latmin < path->lat) {
const uint64_t a = path->lat - path->latmin;
const uint64_t b = path->latmax - path->lat;
const uint64_t r = path->latmax - path->latmin;
path->recv.ratemax = (a * rate + (b + r) * path->recv.ratemax) / (r << 1);
}
} else { } else {
path->recv.ratemax = rate; // TODO
}
} }
path->recv.rate = rate; if (path->latmin > path->lat.val) {
path->latmin = path->lat.val;
} else {
if (path->rate.val + 4 * path->rate.var < path->recv.ratemax) {
path->latmin = (lat + 7 * path->latmin) / 8;
} else {
// TODO
}
}
if (!reply_size)
reply_size = path->mtu.ok;
path->recv.bytes = packet_size; path->recv.bytes = packet_size;
mud_packet_send(mud, path, now, send_time, 0);
path->recv.stat_time = now; path->recv.stat_time = now;
} else { } else {
path->recv.bytes += packet_size; path->recv.bytes += packet_size;
} }
if (reply_size)
mud_packet_send(mud, path, now, send_time, reply_size);
return MUD_PACKET(send_time) ? 0 : ret; return MUD_PACKET(send_time) ? 0 : ret;
} }
static void static void
mud_probe_mtu(struct mud *mud, struct mud_path *path, uint64_t now) mud_probe_mtu(struct mud *mud, struct mud_path *path, uint64_t now)
{ {
if ((!path->rtt) || if (path->mtu.min > path->mtu.max)
(!mud_timeout(now, path->mtu.time, path->rtt)))
return; return;
while ((path->mtu.probe != path->r_max + 1) && if (path->mtu.count && path->rtt.setup &&
(path->r_max != MUD_PACKET_MAX_SIZE)) { !mud_timeout(now, path->mtu.time, path->rtt.val + 4 * path->rtt.var))
return;
if (path->mtu.probe > path->mtu.ok) {
path->mtu.probe = (path->mtu.probe + path->mtu.ok) >> 1;
} else {
path->mtu.probe = (MUD_PACKET_MAX_SIZE + path->mtu.ok + 1) >> 1;
}
path->mtu.time = now; path->mtu.time = now;
if ((path->mtu.probe == MUD_MTU) || while (1) {
(mud_packet_send(mud, path, now, 0, 1) != -1) || const size_t probe = (path->mtu.min + path->mtu.max) >> 1;
if (path->mtu.count == 2) {
path->mtu.max = probe - 1;
path->mtu.count = 0;
continue;
}
path->mtu.count++;
if ((mud_packet_send(mud, path, now, 0, probe) != -1) ||
(errno != EMSGSIZE)) (errno != EMSGSIZE))
break; break;
} }
@@ -1464,41 +1416,121 @@ mud_update(struct mud *mud, uint64_t now)
mud_keyx_reset(mud); mud_keyx_reset(mud);
} }
unsigned long long window = 0;
size_t mtu = 0;
for (unsigned i = 0; i < mud->count; i++) { for (unsigned i = 0; i < mud->count; i++) {
struct mud_path *path = &mud->paths[i]; struct mud_path *path = &mud->paths[i];
if (path->state < MUD_DOWN) if (path->state < MUD_DOWN)
continue; continue;
if (path->send.bytes && path->recv.time && path->window = 0;
mud_timeout(now, path->recv.time, mud->send_timeout))
if (path->ok) {
if (path->stat_count >= 10) {
mud_reset_path(mud, path); mud_reset_path(mud, path);
} else {
if (!mtu || mtu > path->mtu.ok)
mtu = path->mtu.ok;
}
}
int reset = mud_timeout(now, path->send.stat_time, mud->send_timeout / 2);
if (reset) {
if (path->send.bytes > path->send.ratemax) {
path->send.bytes -= path->send.ratemax;
} else {
path->send.bytes = 0;
}
}
if (path->ok && path->send.ratemax > path->send.bytes) {
path->window = path->send.ratemax - path->send.bytes;
window += path->window;
}
if (!reset)
continue;
path->send.stat_time = now;
if (mud->peer.set) { if (mud->peer.set) {
if (mud->crypto.ready) if (path->ok)
mud_packet_send(mud, path, now, 0, 0);
mud_probe_mtu(mud, path, now); mud_probe_mtu(mud, path, now);
if (mud_timeout(now, path->send.time, mud->send_timeout))
mud_packet_send(mud, path, now, 0, 0); //path->mtu.ok);
} }
if (mud_timeout(now, path->send.stat_time, MUD_STAT_TIMEOUT)) { if (path->ok)
path->send.bytes = 0; path->stat_count++;
path->send.stat_time = now;
} }
mud->window = window;
mud->mtu = mtu ?: MUD_MTU_MIN;
} }
unsigned long
mud_send_wait(struct mud *mud)
{
const uint64_t now = mud_now();
mud_update(mud, now);
if (mud->window)
return 0;
unsigned long dt = MUD_ONE_SEC - 1;
for (unsigned i = 0; i < mud->count; i++) {
struct mud_path *path = &mud->paths[i];
if (path->state < MUD_DOWN || !path->ok)
continue;
if (!path->send.stat_time) // TODO
continue;
uint64_t elapsed = MUD_TIME_MASK(now - path->send.stat_time);
if (elapsed >= mud->send_timeout / 2)
continue; // TODO
uint64_t new_dt = (mud->send_timeout / 2) - elapsed;
if ((uint64_t)dt > new_dt)
dt = (unsigned long)new_dt;
}
return dt;
}
unsigned long
mud_sync(struct mud *mud)
{
const uint64_t last = mud->last_recv_time;
const uint64_t now = mud_now();
mud_update(mud, now);
return last ? MUD_TIME_MASK(now - last) / MUD_ONE_MSEC : ~0UL;
} }
int int
mud_send(struct mud *mud, const void *data, size_t size, unsigned tc) mud_send(struct mud *mud, const void *data, size_t size, unsigned tc)
{ {
unsigned char packet[MUD_PACKET_MAX_SIZE]; if (!size)
const uint64_t now = mud_now();
mud_update(mud, now);
if (!size || !mud->count)
return 0; return 0;
if (!mud->window) {
errno = EAGAIN;
return -1;
}
unsigned char packet[MUD_PACKET_MAX_SIZE];
const uint64_t now = mud_now();
const int packet_size = mud_encrypt(mud, now, packet, sizeof(packet), data, size); const int packet_size = mud_encrypt(mud, now, packet, sizeof(packet), data, size);
if (!packet_size) { if (!packet_size) {

28
mud.h
View File

@@ -20,35 +20,31 @@ struct mud_public {
unsigned char local[MUD_PUB_SIZE]; unsigned char local[MUD_PUB_SIZE];
}; };
struct mud_value {
uint64_t val;
uint64_t var;
int setup;
};
struct mud_path { struct mud_path {
enum mud_state state; enum mud_state state;
struct sockaddr_storage local_addr, addr, r_addr; struct sockaddr_storage local_addr, addr, r_addr;
struct { struct mud_value rtt, lat, rate;
uint64_t send_time;
int remote;
} conf;
uint64_t rtt;
uint64_t rttvar;
uint64_t lat;
uint64_t latmin; uint64_t latmin;
uint64_t latmax;
uint64_t r_lat; uint64_t r_lat;
uint64_t r_latmin; uint64_t r_latmin;
uint64_t r_rate; uint64_t r_rate;
uint64_t r_ratemax; uint64_t r_ratemax;
uint64_t r_max; uint64_t window;
uint64_t r_max_time;
uint64_t prob;
struct { struct {
size_t min;
size_t max;
size_t ok; size_t ok;
size_t probe;
uint64_t time; uint64_t time;
unsigned char count;
} mtu; } mtu;
struct { struct {
uint64_t max;
uint64_t max_time;
uint64_t total; uint64_t total;
uint64_t rate;
uint64_t ratemax; uint64_t ratemax;
uint64_t bytes; uint64_t bytes;
uint64_t stat_time; uint64_t stat_time;
@@ -56,6 +52,7 @@ struct mud_path {
} send, recv; } send, recv;
struct mud_public pub; struct mud_public pub;
unsigned char ok; unsigned char ok;
unsigned char stat_count;
}; };
struct mud *mud_create (struct sockaddr *); struct mud *mud_create (struct sockaddr *);
@@ -69,6 +66,7 @@ int mud_get_key (struct mud *, unsigned char *, size_t *);
void mud_set_mtu (struct mud *, size_t); void mud_set_mtu (struct mud *, size_t);
size_t mud_get_mtu (struct mud *); size_t mud_get_mtu (struct mud *);
unsigned long mud_send_wait (struct mud *);
unsigned long mud_sync (struct mud *); unsigned long mud_sync (struct mud *);
int mud_set_send_timeout (struct mud *, unsigned long); int mud_set_send_timeout (struct mud *, unsigned long);