X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=utcp.c;h=f48460d6f7aa6bf1686fec55cb6841139b62070f;hb=88fac696ff9e360c47e20a8fc8a397004e1ba49e;hp=75553d72567be387667b7ced7871cac32d0d6a46;hpb=5d25d40b5baf4bd60ccc1dc6db65b3e5b094e2cd;p=utcp diff --git a/utcp.c b/utcp.c index 75553d7..f48460d 100644 --- a/utcp.c +++ b/utcp.c @@ -276,21 +276,25 @@ static void ack(struct utcp_connection *c, bool sendatleastone) { struct { struct hdr hdr; - char data[c->utcp->mtu]; - } pkt; + char data[]; + } *pkt; - pkt.hdr.src = c->src; - pkt.hdr.dst = c->dst; - pkt.hdr.ack = c->rcv.nxt; - pkt.hdr.wnd = c->snd.wnd; - pkt.hdr.ctl = ACK; - pkt.hdr.aux = 0; + pkt = malloc(sizeof pkt->hdr + c->utcp->mtu); + if(!pkt->data) + return; + + pkt->hdr.src = c->src; + pkt->hdr.dst = c->dst; + pkt->hdr.ack = c->rcv.nxt; + pkt->hdr.wnd = c->snd.wnd; + pkt->hdr.ctl = ACK; + pkt->hdr.aux = 0; do { uint32_t seglen = left > c->utcp->mtu ? c->utcp->mtu : left; - pkt.hdr.seq = c->snd.nxt; + pkt->hdr.seq = c->snd.nxt; - memcpy(pkt.data, data, seglen); + memcpy(pkt->data, data, seglen); c->snd.nxt += seglen; data += seglen; @@ -301,16 +305,18 @@ static void ack(struct utcp_connection *c, bool sendatleastone) { case FIN_WAIT_1: case CLOSING: seglen--; - pkt.hdr.ctl |= FIN; + pkt->hdr.ctl |= FIN; break; default: break; } } - print_packet(c->utcp, "send", &pkt, sizeof pkt.hdr + seglen); - c->utcp->send(c->utcp, &pkt, sizeof pkt.hdr + seglen); + print_packet(c->utcp, "send", pkt, sizeof pkt->hdr + seglen); + c->utcp->send(c->utcp, pkt, sizeof pkt->hdr + seglen); } while(left); + + free(pkt); } ssize_t utcp_send(struct utcp_connection *c, const void *data, size_t len) { @@ -953,11 +959,15 @@ static void retransmit(struct utcp_connection *c) { struct { struct hdr hdr; - char data[c->utcp->mtu]; - } pkt; + char data[]; + } *pkt; - pkt.hdr.src = c->src; - pkt.hdr.dst = c->dst; + pkt = malloc(sizeof pkt->hdr + c->utcp->mtu); + if(!pkt) + return; + + pkt->hdr.src = c->src; + pkt->hdr.dst = c->dst; switch(c->state) { case LISTEN: @@ -965,27 +975,27 @@ static void retransmit(struct utcp_connection *c) { break; case SYN_SENT: - pkt.hdr.seq = c->snd.iss; - pkt.hdr.ack = 0; - pkt.hdr.wnd = c->rcv.wnd; - pkt.hdr.ctl = SYN; - print_packet(c->utcp, "rtrx", &pkt, sizeof pkt.hdr); - utcp->send(utcp, &pkt, sizeof pkt.hdr); + pkt->hdr.seq = c->snd.iss; + pkt->hdr.ack = 0; + pkt->hdr.wnd = c->rcv.wnd; + pkt->hdr.ctl = SYN; + print_packet(c->utcp, "rtrx", pkt, sizeof pkt->hdr); + utcp->send(utcp, pkt, sizeof pkt->hdr); break; case SYN_RECEIVED: - pkt.hdr.seq = c->snd.nxt; - pkt.hdr.ack = c->rcv.nxt; - pkt.hdr.ctl = SYN | ACK; - print_packet(c->utcp, "rtrx", &pkt, sizeof pkt.hdr); - utcp->send(utcp, &pkt, sizeof pkt.hdr); + pkt->hdr.seq = c->snd.nxt; + pkt->hdr.ack = c->rcv.nxt; + pkt->hdr.ctl = SYN | ACK; + print_packet(c->utcp, "rtrx", pkt, sizeof pkt->hdr); + utcp->send(utcp, pkt, sizeof pkt->hdr); break; case ESTABLISHED: case FIN_WAIT_1: - pkt.hdr.seq = c->snd.una; - pkt.hdr.ack = c->rcv.nxt; - pkt.hdr.ctl = ACK; + pkt->hdr.seq = c->snd.una; + pkt->hdr.ack = c->rcv.nxt; + pkt->hdr.ctl = ACK; uint32_t len = seqdiff(c->snd.nxt, c->snd.una); if(c->state == FIN_WAIT_1) len--; @@ -993,17 +1003,19 @@ static void retransmit(struct utcp_connection *c) { len = utcp->mtu; else { if(c->state == FIN_WAIT_1) - pkt.hdr.ctl |= FIN; + pkt->hdr.ctl |= FIN; } - memcpy(pkt.data, c->sndbuf, len); - print_packet(c->utcp, "rtrx", &pkt, sizeof pkt.hdr + len); - utcp->send(utcp, &pkt, sizeof pkt.hdr + len); + memcpy(pkt->data, c->sndbuf, len); + print_packet(c->utcp, "rtrx", pkt, sizeof pkt->hdr + len); + utcp->send(utcp, pkt, sizeof pkt->hdr + len); break; default: // TODO: implement abort(); } + + free(pkt); } /* Handle timeouts.