diff --git a/mud.c b/mud.c index 43536ea..b718484 100644 --- a/mud.c +++ b/mud.c @@ -150,6 +150,7 @@ struct mud { uint64_t time_tolerance; uint64_t mtu; uint64_t recv_mtu; + int send_mtu; struct queue tx; struct queue rx; struct path *path; @@ -622,6 +623,16 @@ int mud_get_mtu (struct mud *mud) return mud->recv_mtu; } +int mud_set_mtu (struct mud *mud, int mtu) +{ + if (mud->mtu != mtu) { + mud->mtu = mtu; + mud->send_mtu = 1; + } + + return 0; +} + static int mud_setup_socket (int fd, int v4, int v6) { @@ -1119,6 +1130,7 @@ int mud_pull (struct mud *mud) 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]); + mud->send_mtu = 0; if (!path->state.active) mud_ctrl_path(mud, mud_mtux, path, now); } @@ -1181,7 +1193,7 @@ int mud_push (struct mud *mud) continue; } - if (!mud->recv_mtu) { + if (!mud->recv_mtu || mud->send_mtu) { mud_ctrl_path(mud, mud_mtux, path, now); continue; } @@ -1228,11 +1240,20 @@ int mud_push (struct mud *mud) ssize_t ret = mud_send_path(mud, path_min, now, packet->data, packet->size, packet->tc); - if (ret != packet->size) - break; + if (ret == -1) { + switch (errno) { + case EAGAIN: + case EINTR: + case ENOMEM: + case ENOBUFS: + return 0; + } + } mud->tx.start = MUD_PACKET_NEXT(mud->tx.start); - path_min->limit = limit_min; + + if (ret == packet->size) + path_min->limit = limit_min; } return 0; diff --git a/mud.h b/mud.h index 8631bb6..76ad13d 100644 --- a/mud.h +++ b/mud.h @@ -12,6 +12,7 @@ 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_send_timeout_msec (struct mud *, unsigned); int mud_set_time_tolerance_sec (struct mud *, unsigned);