X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;ds=sidebyside;f=utcp.c;h=966295a7f086a079f96a2d818cad1d8d3c90bad2;hb=365dd2877f26120742c409e62865b7e563ec87fa;hp=a65eb145a5477b860ee7c2663cfc0793a4fece92;hpb=2cc55402361be4a017d10a9641807f2bd6b4ea5c;p=utcp diff --git a/utcp.c b/utcp.c index a65eb14..966295a 100644 --- a/utcp.c +++ b/utcp.c @@ -29,101 +29,7 @@ #include #include -#define UTCP_INTERNAL -#include "utcp.h" - -#define PREP(l) char pkt[(l) + sizeof struct hdr]; struct hdr *hdr = &pkt; - -#define SYN 1 -#define ACK 2 -#define FIN 4 -#define RST 8 - -struct hdr { - uint16_t src; // Source port - uint16_t dst; // Destination port - uint32_t seq; // Sequence number - uint32_t ack; // Acknowledgement number - uint32_t wnd; // Window size - uint16_t ctl; // Flags (SYN, ACK, FIN, RST) - uint16_t aux; // other stuff -}; - -enum state { - CLOSED, - LISTEN, - SYN_SENT, - SYN_RECEIVED, - ESTABLISHED, - FIN_WAIT_1, - FIN_WAIT_2, - CLOSE_WAIT, - CLOSING, - LAST_ACK, - TIME_WAIT -}; - -const char *strstate[] = { - "CLOSED", - "LISTEN", - "SYN_SENT", - "SYN_RECEIVED", - "ESTABLISHED", - "FIN_WAIT_1", - "FIN_WAIT_2", - "CLOSE_WAIT", - "CLOSING", - "LAST_ACK", - "TIME_WAIT" -}; - -struct utcp_connection { - void *priv; - struct utcp *utcp; - bool reapable; - - uint16_t src; - uint16_t dst; - enum state state; - - // The following two structures form the TCB - - struct { - uint32_t una; - uint32_t nxt; - uint32_t wnd; - uint32_t iss; - } snd; - - struct { - uint32_t nxt; - uint32_t wnd; - uint32_t irs; - } rcv; - - utcp_recv_t recv; - - struct timeval conn_timeout; - struct timeval rtrx_timeout; - - char *sndbuf; - uint32_t sndbufsize; -}; - -struct utcp { - void *priv; - - utcp_accept_t accept; - utcp_pre_accept_t pre_accept; - utcp_send_t send; - - uint16_t mtu; - int timeout; - - struct utcp_connection **connections; - int nconnections; - int nallocated; -}; +#include "utcp_priv.h" static void set_state(struct utcp_connection *c, enum state state) { c->state = state; @@ -954,12 +860,19 @@ static void retransmit(struct utcp_connection *c) { break; case ESTABLISHED: + case FIN_WAIT_1: 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--; if(len > utcp->mtu) len = utcp->mtu; + else { + if(c->state == FIN_WAIT_1) + 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); @@ -1057,6 +970,11 @@ void utcp_exit(struct utcp *utcp) { free(utcp); } +void utcp_set_mtu(struct utcp *utcp, uint16_t mtu) { + // TODO: handle overhead of the header + utcp->mtu = mtu; +} + int utcp_set_connection_timeout(struct utcp *u, int timeout) { int prev = u->timeout; u->timeout = timeout;