X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=utcp.c;h=5eca4d3897a82eec6bbc1bca6de33c324fb73daa;hb=6cee45014dd79d59914693afad9ca3b6af7f3cb3;hp=aa1c50f79c965709276951f992fd3e681c6feb94;hpb=955836e332b42d9152f6a6b594b1cfd038e639fa;p=utcp diff --git a/utcp.c b/utcp.c index aa1c50f..5eca4d3 100644 --- a/utcp.c +++ b/utcp.c @@ -847,13 +847,7 @@ static void fast_retransmit(struct utcp_connection *c) { struct { struct hdr hdr; uint8_t data[]; - } *pkt; - - pkt = malloc(c->utcp->mtu); - - if(!pkt) { - return; - } + } *pkt = c->utcp->pkt; pkt->hdr.src = c->src; pkt->hdr.dst = c->dst; @@ -885,8 +879,6 @@ static void fast_retransmit(struct utcp_connection *c) { default: break; } - - free(pkt); } static void retransmit(struct utcp_connection *c) { @@ -898,6 +890,10 @@ static void retransmit(struct utcp_connection *c) { struct utcp *utcp = c->utcp; + if (utcp->retransmit) { + utcp->retransmit(c); + } + struct { struct hdr hdr; uint8_t data[]; @@ -1113,11 +1109,14 @@ static void handle_in_order(struct utcp_connection *c, const void *data, size_t size_t offset = len; len = c->sacks[0].offset + c->sacks[0].len; size_t remainder = len - offset; - ssize_t rxd = buffer_call(&c->rcvbuf, c->recv, c, offset, remainder); - if(rxd != (ssize_t)remainder) { - // TODO: handle the application not accepting all data. - abort(); + if(c->recv) { + ssize_t rxd = buffer_call(&c->rcvbuf, c->recv, c, offset, remainder); + + if(rxd != (ssize_t)remainder) { + // TODO: handle the application not accepting all data. + abort(); + } } } } @@ -1132,7 +1131,10 @@ static void handle_in_order(struct utcp_connection *c, const void *data, size_t static void handle_unreliable(struct utcp_connection *c, const struct hdr *hdr, const void *data, size_t len) { // Fast path for unfragmented packets if(!hdr->wnd && !(hdr->ctl & MF)) { - c->recv(c, data, len); + if(c->recv) { + c->recv(c, data, len); + } + c->rcv.nxt = hdr->seq + len; return; } @@ -1159,7 +1161,7 @@ static void handle_unreliable(struct utcp_connection *c, const struct hdr *hdr, } // Send the packet if it's the final fragment - if(!(hdr->ctl & MF)) { + if(!(hdr->ctl & MF) && c->recv) { buffer_call(&c->rcvbuf, c->recv, c, 0, hdr->wnd + len); } @@ -2167,6 +2169,13 @@ struct utcp *utcp_init(utcp_accept_t accept, utcp_pre_accept_t pre_accept, utcp_ return NULL; } + utcp_set_mtu(utcp, DEFAULT_MTU); + + if(!utcp->pkt) { + free(utcp); + return NULL; + } + if(!CLOCK_GRANULARITY) { struct timespec res; clock_getres(UTCP_CLOCK, &res); @@ -2177,7 +2186,6 @@ struct utcp *utcp_init(utcp_accept_t accept, utcp_pre_accept_t pre_accept, utcp_ utcp->pre_accept = pre_accept; utcp->send = send; utcp->priv = priv; - utcp_set_mtu(utcp, DEFAULT_MTU); utcp->timeout = DEFAULT_USER_TIMEOUT; // sec return utcp; @@ -2449,6 +2457,10 @@ void utcp_offline(struct utcp *utcp, bool offline) { } } +void utcp_set_retransmit_cb(struct utcp *utcp, utcp_retransmit_t retransmit) { + utcp->retransmit = retransmit; +} + void utcp_set_clock_granularity(long granularity) { CLOCK_GRANULARITY = granularity; }