Remove pull/push
This commit is contained in:
218
mud.c
218
mud.c
@@ -41,8 +41,6 @@
|
||||
#define MUD_DFRAG_OPT IP_PMTUDISC_DO
|
||||
#endif
|
||||
|
||||
#define MUD_COUNT(X) (sizeof(X)/sizeof(X[0]))
|
||||
|
||||
#define MUD_ONE_MSEC (UINT64_C(1000))
|
||||
#define MUD_ONE_SEC (1000*MUD_ONE_MSEC)
|
||||
#define MUD_ONE_MIN (60*MUD_ONE_SEC)
|
||||
@@ -53,9 +51,6 @@
|
||||
|
||||
#define MUD_PACKET_MIN_SIZE (MUD_U48_SIZE+MUD_MAC_SIZE)
|
||||
#define MUD_PACKET_MAX_SIZE (1500U)
|
||||
#define MUD_PACKET_MASK (0x3FFU)
|
||||
#define MUD_PACKET_COUNT ((MUD_PACKET_MASK)+1)
|
||||
#define MUD_PACKET_NEXT(X) (((X)+1)&(MUD_PACKET_MASK))
|
||||
#define MUD_PACKET_SIZEOF(X) ((X)+MUD_PACKET_MIN_SIZE)
|
||||
|
||||
#define MUD_PONG_SIZE MUD_PACKET_SIZEOF(MUD_U48_SIZE*3)
|
||||
@@ -108,18 +103,6 @@ struct path {
|
||||
struct path *next;
|
||||
};
|
||||
|
||||
struct packet {
|
||||
size_t size;
|
||||
int tc;
|
||||
unsigned char data[MUD_PACKET_MAX_SIZE];
|
||||
};
|
||||
|
||||
struct queue {
|
||||
struct packet *packet;
|
||||
unsigned start;
|
||||
unsigned end;
|
||||
};
|
||||
|
||||
struct public {
|
||||
unsigned char send[MUD_PKEY_SIZE];
|
||||
unsigned char recv[MUD_PKEY_SIZE];
|
||||
@@ -159,8 +142,6 @@ struct mud {
|
||||
uint64_t mtu;
|
||||
uint64_t recv_mtu;
|
||||
int send_mtu;
|
||||
struct queue tx;
|
||||
struct queue rx;
|
||||
struct path *path;
|
||||
struct crypto crypto;
|
||||
};
|
||||
@@ -688,17 +669,6 @@ int mud_create_socket (int port, int v4, int v6)
|
||||
return fd;
|
||||
}
|
||||
|
||||
static
|
||||
int mud_create_queue (struct queue *queue)
|
||||
{
|
||||
queue->packet = calloc(MUD_PACKET_COUNT, sizeof(struct packet));
|
||||
|
||||
if (!queue->packet)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void mud_keyx_init (struct mud *mud)
|
||||
{
|
||||
@@ -725,12 +695,6 @@ struct mud *mud_create (int port, int v4, int v6, int aes, int mtu)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mud_create_queue(&mud->tx) ||
|
||||
mud_create_queue(&mud->rx)) {
|
||||
mud_delete(mud);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mud->send_timeout = MUD_SEND_TIMEOUT;
|
||||
mud->time_tolerance = MUD_TIME_TOLERANCE;
|
||||
mud->mtu = mtu;
|
||||
@@ -756,9 +720,6 @@ void mud_delete (struct mud *mud)
|
||||
if (!mud)
|
||||
return;
|
||||
|
||||
free(mud->tx.packet);
|
||||
free(mud->rx.packet);
|
||||
|
||||
while (mud->path) {
|
||||
struct path *path = mud->path;
|
||||
mud->path = path->next;
|
||||
@@ -843,16 +804,6 @@ int mud_decrypt (struct mud *mud,
|
||||
return size;
|
||||
}
|
||||
|
||||
int mud_can_pull (struct mud *mud)
|
||||
{
|
||||
return (mud->rx.start != MUD_PACKET_NEXT(mud->rx.end));
|
||||
}
|
||||
|
||||
int mud_can_push (struct mud *mud)
|
||||
{
|
||||
return (mud->tx.start != mud->tx.end);
|
||||
}
|
||||
|
||||
int mud_peer_is_up (struct mud *mud, const char *name, const char *host, int port)
|
||||
{
|
||||
if (!name || !host || !port)
|
||||
@@ -1032,27 +983,18 @@ void mud_recv_keyx (struct mud *mud, struct path *path, uint64_t now,
|
||||
mud->crypto.time = now;
|
||||
}
|
||||
|
||||
int mud_pull (struct mud *mud)
|
||||
int mud_recv (struct mud *mud, void *data, size_t size)
|
||||
{
|
||||
unsigned char ctrl[256];
|
||||
|
||||
while (1) {
|
||||
unsigned next = MUD_PACKET_NEXT(mud->rx.end);
|
||||
|
||||
if (mud->rx.start == next) {
|
||||
errno = ENOBUFS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct packet *packet = &mud->rx.packet[mud->rx.end];
|
||||
|
||||
struct sockaddr_storage addr;
|
||||
unsigned char packet[MUD_PACKET_MAX_SIZE];
|
||||
|
||||
struct iovec iov = {
|
||||
.iov_base = &packet->data,
|
||||
.iov_len = sizeof(packet->data),
|
||||
.iov_base = packet,
|
||||
.iov_len = sizeof(packet),
|
||||
};
|
||||
|
||||
struct sockaddr_storage addr;
|
||||
unsigned char ctrl[256];
|
||||
|
||||
struct msghdr msg = {
|
||||
.msg_name = &addr,
|
||||
.msg_namelen = sizeof(addr),
|
||||
@@ -1062,42 +1004,42 @@ int mud_pull (struct mud *mud)
|
||||
.msg_controllen = sizeof(ctrl),
|
||||
};
|
||||
|
||||
ssize_t ret = recvmsg(mud->fd, &msg, 0);
|
||||
ssize_t packet_size = recvmsg(mud->fd, &msg, 0);
|
||||
|
||||
if (ret <= (ssize_t)MUD_PACKET_MIN_SIZE) {
|
||||
if (ret <= (ssize_t)0)
|
||||
return (int)ret;
|
||||
continue;
|
||||
if (packet_size <= (ssize_t)MUD_PACKET_MIN_SIZE) {
|
||||
if (packet_size == (ssize_t)-1)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t now = mud_now(mud);
|
||||
uint64_t send_time = mud_read48(packet->data);
|
||||
uint64_t send_time = mud_read48(packet);
|
||||
|
||||
int mud_packet = !send_time;
|
||||
|
||||
if (mud_packet) {
|
||||
if (ret < (ssize_t)MUD_PACKET_SIZEOF(MUD_U48_SIZE))
|
||||
continue;
|
||||
if (packet_size < (ssize_t)MUD_PACKET_SIZEOF(MUD_U48_SIZE))
|
||||
return 0;
|
||||
|
||||
send_time = mud_read48(&packet->data[MUD_U48_SIZE]);
|
||||
send_time = mud_read48(&packet[MUD_U48_SIZE]);
|
||||
}
|
||||
|
||||
if (mud_dt(now, send_time) >= mud->time_tolerance)
|
||||
continue;
|
||||
return 0;
|
||||
|
||||
if (mud_packet) {
|
||||
unsigned char tmp[sizeof(packet->data)];
|
||||
unsigned char tmp[sizeof(packet)];
|
||||
|
||||
struct crypto_opt opt = {
|
||||
.dst = tmp,
|
||||
.src = { .data = packet->data+ret-MUD_MAC_SIZE,
|
||||
.src = { .data = packet+packet_size-MUD_MAC_SIZE,
|
||||
.size = MUD_MAC_SIZE },
|
||||
.ad = { .data = packet->data,
|
||||
.size = ret-MUD_MAC_SIZE },
|
||||
.ad = { .data = packet,
|
||||
.size = packet_size-MUD_MAC_SIZE },
|
||||
};
|
||||
|
||||
if (mud_decrypt_opt(&mud->crypto.private, &opt))
|
||||
continue;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mud_unmapv4((struct sockaddr *)&addr);
|
||||
@@ -1105,7 +1047,7 @@ int mud_pull (struct mud *mud)
|
||||
struct ipaddr local_addr;
|
||||
|
||||
if (mud_localaddr(&local_addr, &msg, addr.ss_family))
|
||||
continue;
|
||||
return 0;
|
||||
|
||||
struct path *path = mud_path(mud, &local_addr,
|
||||
(struct sockaddr *)&addr, mud_packet);
|
||||
@@ -1124,14 +1066,14 @@ int mud_pull (struct mud *mud)
|
||||
path->recv_send_time = send_time;
|
||||
path->recv_time = now;
|
||||
|
||||
if (mud_packet && (ret == (ssize_t)MUD_PONG_SIZE)) {
|
||||
uint64_t st = mud_read48(&packet->data[MUD_U48_SIZE*2]);
|
||||
uint64_t dt = mud_read48(&packet->data[MUD_U48_SIZE*3]);
|
||||
if (mud_packet && (packet_size == (ssize_t)MUD_PONG_SIZE)) {
|
||||
uint64_t st = mud_read48(&packet[MUD_U48_SIZE*2]);
|
||||
uint64_t dt = mud_read48(&packet[MUD_U48_SIZE*3]);
|
||||
|
||||
path->dt = dt;
|
||||
path->sdt = send_time-st;
|
||||
path->rtt = now-st;
|
||||
continue;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((!path->pong_time) ||
|
||||
@@ -1141,36 +1083,18 @@ int mud_pull (struct mud *mud)
|
||||
}
|
||||
|
||||
if (mud_packet) {
|
||||
if (ret == (ssize_t)MUD_KEYX_SIZE) {
|
||||
mud_recv_keyx(mud, path, now, &packet->data[MUD_U48_SIZE*2]);
|
||||
} else if (ret == (ssize_t)MUD_MTUX_SIZE) {
|
||||
mud->recv_mtu = mud_read48(&packet->data[MUD_U48_SIZE*2]);
|
||||
if (packet_size == (ssize_t)MUD_KEYX_SIZE) {
|
||||
mud_recv_keyx(mud, path, now, &packet[MUD_U48_SIZE*2]);
|
||||
} else if (packet_size == (ssize_t)MUD_MTUX_SIZE) {
|
||||
mud->recv_mtu = mud_read48(&packet[MUD_U48_SIZE*2]);
|
||||
mud->send_mtu = 0;
|
||||
if (!path->state.active)
|
||||
mud_ctrl_path(mud, mud_mtux, path, now);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
packet->size = ret;
|
||||
mud->rx.end = next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mud_recv (struct mud *mud, void *data, size_t size)
|
||||
{
|
||||
if (mud->rx.start == mud->rx.end) {
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct packet *packet = &mud->rx.packet[mud->rx.start];
|
||||
|
||||
int ret = mud_decrypt(mud, data, size, packet->data, packet->size);
|
||||
|
||||
mud->rx.start = MUD_PACKET_NEXT(mud->rx.start);
|
||||
int ret = mud_decrypt(mud, data, size, packet, packet_size);
|
||||
|
||||
if (ret == -1) {
|
||||
mud->crypto.bad_key = 1;
|
||||
@@ -1180,7 +1104,7 @@ int mud_recv (struct mud *mud, void *data, size_t size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mud_push (struct mud *mud)
|
||||
int mud_send_ctrl (struct mud *mud)
|
||||
{
|
||||
struct path *path;
|
||||
|
||||
@@ -1221,12 +1145,23 @@ int mud_push (struct mud *mud)
|
||||
|
||||
mud_ctrl_path(mud, mud_ping, path, now);
|
||||
}
|
||||
}
|
||||
|
||||
int mud_send (struct mud *mud, const void *data, size_t size, int tc)
|
||||
{
|
||||
mud_send_ctrl(mud);
|
||||
|
||||
if (!size)
|
||||
return 0;
|
||||
|
||||
if (size > (size_t)mud_get_mtu(mud)) {
|
||||
errno = EMSGSIZE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (mud->tx.start != mud->tx.end) {
|
||||
uint64_t now = mud_now(mud);
|
||||
|
||||
struct packet *packet = &mud->tx.packet[mud->tx.start];
|
||||
|
||||
struct path *path;
|
||||
struct path *path_min = NULL;
|
||||
int64_t limit_min = INT64_MAX;
|
||||
|
||||
@@ -1250,65 +1185,24 @@ int mud_push (struct mud *mud)
|
||||
}
|
||||
|
||||
if (!path_min)
|
||||
break;
|
||||
|
||||
ssize_t ret = mud_send_path(mud, path_min, now,
|
||||
packet->data, packet->size, packet->tc);
|
||||
|
||||
if (ret == -1) {
|
||||
switch (errno) {
|
||||
case EAGAIN:
|
||||
case EINTR:
|
||||
case ENOMEM:
|
||||
case ENOBUFS:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
mud->tx.start = MUD_PACKET_NEXT(mud->tx.start);
|
||||
|
||||
// if (ret == -1 && errno == EMSGSIZE)
|
||||
// return -1;
|
||||
|
||||
if (ret == packet->size)
|
||||
path_min->limit = limit_min;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mud_send (struct mud *mud, const void *data, size_t size, int tc)
|
||||
{
|
||||
if (!size)
|
||||
return 0;
|
||||
|
||||
if (size > (size_t)mud_get_mtu(mud)) {
|
||||
errno = EMSGSIZE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned next = MUD_PACKET_NEXT(mud->tx.end);
|
||||
unsigned char packet[2048];
|
||||
|
||||
if (mud->tx.start == next) {
|
||||
errno = ENOBUFS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct packet *packet = &mud->tx.packet[mud->tx.end];
|
||||
|
||||
int ret = mud_encrypt(mud, mud_now(mud),
|
||||
packet->data, sizeof(packet->data),
|
||||
int packet_size = mud_encrypt(mud, now,
|
||||
packet, sizeof(packet),
|
||||
data, size);
|
||||
|
||||
if (!ret) {
|
||||
if (!packet_size) {
|
||||
errno = EMSGSIZE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
packet->size = ret;
|
||||
packet->tc = tc;
|
||||
ssize_t ret = mud_send_path(mud, path_min, now,
|
||||
packet, packet_size, tc);
|
||||
|
||||
mud->tx.end = next;
|
||||
if (ret == packet_size)
|
||||
path_min->limit = limit_min;
|
||||
|
||||
return size;
|
||||
return (int)ret;
|
||||
}
|
||||
|
||||
5
mud.h
5
mud.h
@@ -22,12 +22,7 @@ int mud_set_on (struct mud *, const char *, int);
|
||||
int mud_peer (struct mud *, const char *, const char *, int);
|
||||
int mud_peer_is_up (struct mud *, const char *, const char *, int);
|
||||
|
||||
int mud_can_pull (struct mud *);
|
||||
int mud_can_push (struct mud *);
|
||||
int mud_is_up (struct mud *);
|
||||
|
||||
int mud_pull (struct mud *);
|
||||
int mud_push (struct mud *);
|
||||
|
||||
int mud_recv (struct mud *, void *, size_t);
|
||||
int mud_send (struct mud *, const void *, size_t, int);
|
||||
|
||||
Reference in New Issue
Block a user