diff --git a/src/main.c b/src/main.c index 13ff725..9d0d39d 100644 --- a/src/main.c +++ b/src/main.c @@ -386,35 +386,16 @@ int main (int argc, char **argv) fd_set rfds; FD_ZERO(&rfds); - struct { - unsigned char *buf; - } send, recv; - - send.buf = malloc(2*mtu); - recv.buf = malloc(mtu); - - size_t send_size = 0; - size_t send_limit = 0; - int send_tc = 0; - int send_next_tc = 0; + unsigned char buf[8*1024]; while (!gt.quit) { - if (send_sizemtu) { + const ssize_t r = tun_read(tun_fd, &buf[size], sizeof(buf)-size); if (r<=0) break; struct ip_common ic; - if (ip_get_common(&ic, send.buf+send_size, mtu) || ic.size!=r) { - gt_log("packet dropped: malformed\n"); - continue; - } + if (ip_get_common(&ic, &buf[size], r) || ic.size!=r) + break; - send_size += r; - - if (send_size<=mtu) { - send_limit = send_size; - if ((ic.tc&0xFC)>(send_tc&0xFC)) - send_tc = ic.tc; - } else { - if ((ic.tc&0xFC)>(send_next_tc&0xFC)) - send_next_tc = ic.tc; - } + size += r; } - } - if (send_limit) { - int r = mud_send(mud, send.buf, send_limit, send_tc); + int p = 0; - if (r>0) { - if (send_size>send_limit) - memmove(send.buf, &send.buf[send_limit], send_size-send_limit); - send_size -= send_limit; - send_limit = send_size; - send_tc = send_next_tc; - send_next_tc = 0; - } else if (r==-1) { - if (errno==EMSGSIZE) { - long new_mtu = mud_get_mtu(mud); - if (new_mtu!=mtu) { - size_t total = send_size; + while (p(send_tc&0xFC)) - send_tc = ic.tc; - } else { - if ((ic.tc&0xFC)>(send_next_tc&0xFC)) - send_next_tc = ic.tc; - } - } + if (ip_get_common(&ic, &buf[q], size-q) || ic.size>size-q) { + size = q; + break; } - } else if (errno!=EAGAIN) { - perror("mud_send"); + + if (q+ic.size>p+mtu) + break; + + q += ic.size; + + if (tc<(ic.tc&0xFC)) + tc = ic.tc&0xFC; + } + + int r = mud_send(mud, &buf[p], q-p, tc); + + if (r==-1 && errno==EMSGSIZE) { + int new_mtu = mud_get_mtu(mud); + + if (new_mtu!=mtu) { + mtu = new_mtu; + + gt_log("MTU changed: %li\n", mtu); + + if (tun_set_mtu(tun_name, mtu)==-1) + perror("tun_set_mtu"); + } + } else { + if (r==-1 && errno!=EAGAIN) + perror("mud_send"); + + p = q; } } } if (FD_ISSET(mud_fd, &rfds)) { while (1) { - const int size = mud_recv(mud, recv.buf, mtu); + const int size = mud_recv(mud, buf, sizeof(buf)); if (size<=0) { if (size==-1 && errno!=EAGAIN) @@ -536,13 +498,10 @@ int main (int argc, char **argv) while (psize-p) + if (ip_get_common(&ic, &buf[p], size-p) || ic.size>size-p) break; - const ssize_t r = tun_write(tun_fd, recv.buf+p, ic.size); - - if (r<=0) - break; + tun_write(tun_fd, &buf[p], ic.size); p += ic.size; }