struct utcp *utcp = c->utcp;
+ if(utcp->retransmit) {
+ utcp->retransmit(c);
+ }
+
struct {
struct hdr hdr;
uint8_t data[];
print_packet(c, "send", &pkt, sizeof(hdr));
utcp->send(utcp, &pkt, sizeof(hdr));
}
+
+ start_retransmit_timer(c);
} else {
// No, we don't want your packets, send a RST back
len = 1;
}
c->rcv.irs = hdr.seq;
- c->rcv.nxt = hdr.seq;
+ c->rcv.nxt = hdr.seq + 1;
if(c->shut_wr) {
c->snd.last++;
set_state(c, ESTABLISHED);
}
- // TODO: notify application of this somehow.
break;
case SYN_RECEIVED:
case CLOSING:
case LAST_ACK:
case TIME_WAIT:
- // Ehm, no. We should never receive a second SYN.
- return 0;
+ // This could be a retransmission. Ignore the SYN flag, but send an ACK back.
+ break;
default:
#ifdef UTCP_DEBUG
#endif
return 0;
}
-
- // SYN counts as one sequence number
- c->rcv.nxt++;
}
// 6. Process new data
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);
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;
}
}
+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;
}