代码拉取完成,页面将自动刷新
同步操作将从 邵温财/TCP协议栈 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
#include "tcp.h"
#include "utils.h"
#include "ip.h"
#include "string.h"
#define UIP_PROTO_TCP 6
#define TCP_HEAD_LEN 20
#pragma pack(1)
struct tcp_hdr {
u16_t srcport;
u16_t destport;
u8_t seqno[4];
u8_t ackno[4];
u8_t tcpoffset;
u8_t flags;
u8_t wnd[2];
u16_t tcpchksum;
u8_t urgp[2];
u8_t optdata[4];
};
#pragma pack()
static u8_t iss[4];
static u16_t lastport = 4096;
static struct uip_tcp_conn uip_tcp_conns[UIP_TCP_CONNS] = {0};
static u16_t uip_listenports[UIP_LISTENPORTS] = {0};
static u16_t uip_tcpchksum(const u8_t *BUF,u32_t Len)
{
u16_t sum = 0;
sum = Len + UIP_PROTO_TCP;
/* Sum IP source and destination addresses. */
sum = chksum(sum, (u8_t *)(BUF - 2 * sizeof(uip_ipaddr_t)), 2 * sizeof(uip_ipaddr_t));
/* Sum TCP header and data. */
sum = chksum(sum, BUF,Len);
return (sum == 0) ? 0xffff : HTONS(sum);
}
static void uip_add_nxt(u8_t *nxt,u16_t n)
{
u8_t *op32 = nxt;
u16_t op16 = n;
u8_t uip_acc32[4];
uip_acc32[3] = op32[3] + (op16 & 0xff);
uip_acc32[2] = op32[2] + (op16 >> 8);
uip_acc32[1] = op32[1];
uip_acc32[0] = op32[0];
if(uip_acc32[2] < (op16 >> 8))
{
++uip_acc32[1];
if(uip_acc32[1] == 0)
{
++uip_acc32[0];
}
}
if(uip_acc32[3] < (op16 & 0xff))
{
++uip_acc32[2];
if(uip_acc32[2] == 0)
{
++uip_acc32[1];
if(uip_acc32[1] == 0)
{
++uip_acc32[0];
}
}
}
nxt[0] = uip_acc32[0];
nxt[1] = uip_acc32[1];
nxt[2] = uip_acc32[2];
nxt[3] = uip_acc32[3];
}
static void parse_tcp_mss_option(struct tcp_hdr *TCPBUF,struct uip_tcp_conn *uip_tcp_connr)
{
u8_t c, opt;
u16_t tmp16;
for(c = 0; c < ((TCPBUF->tcpoffset >> 4) - 5) << 2 ;)
{
opt = ((u8_t *)TCPBUF)[TCP_HEAD_LEN + c];
if(opt == TCP_OPT_END)
{
/* End of options. */
break;
}
else if(opt == TCP_OPT_NOOP)
{
++c;
/* NOP option. */
}
else if(opt == TCP_OPT_MSS && ((u8_t *)TCPBUF)[TCP_HEAD_LEN + 1 + c] == TCP_OPT_MSS_LEN)
{
/* An MSS option with the right option length. */
tmp16 = ((u16_t)((u8_t *)TCPBUF)[TCP_HEAD_LEN + 2 + c] << 8) | (u16_t)((u8_t *)TCPBUF)[TCP_HEAD_LEN + 3 + c];
uip_tcp_connr->initialmss = uip_tcp_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
/* And we are done processing options. */
break;
}
else
{
/* All other options have a length field, so that we easily
can skip past them. */
if(((u8_t *)TCPBUF)[TCP_HEAD_LEN + 1 + c] == 0)
{
/* If the length field is zero, the options are malformed
and we don't process them further. */
break;
}
c += ((u8_t *)TCPBUF)[TCP_HEAD_LEN + 1 + c];
}
}
}
static void move_data_appbuf(struct uip_tcp_conn *uip_tcp_connr,u8_t *appdata,u32_t dataLen)
{
if(dataLen >= (sizeof(uip_tcp_connr->recvBuf) - uip_tcp_connr->recvLen))
{
dataLen = (sizeof(uip_tcp_connr->recvBuf) - uip_tcp_connr->recvLen);
UIP_LOG("tcp: receive buffer overflow .\r\n");
}
memcpy(&uip_tcp_connr->recvBuf[uip_tcp_connr->recvLen],appdata,dataLen);
appdata[dataLen] = 0;
UIP_LOG("tcp: receive(%d) %s.\r\n",dataLen,appdata);
uip_tcp_connr->recvLen += dataLen;
uip_tcp_connr->recvBuf[uip_tcp_connr->recvLen] = 0;
}
static void uip_tcp_reply_rst(struct netif *netif, struct tcp_hdr *TCPBUF,uip_ipaddr_t srcipaddr)
{
u8_t c;
u32_t Len;
TCPBUF->flags = TCP_RST | TCP_ACK;
TCPBUF->tcpoffset = (TCP_HEAD_LEN / 4) << 4;
/* Flip the seqno and ackno fields in the TCP header. */
c = TCPBUF->seqno[3];
TCPBUF->seqno[3] = TCPBUF->ackno[3];
TCPBUF->ackno[3] = c;
c = TCPBUF->seqno[2];
TCPBUF->seqno[2] = TCPBUF->ackno[2];
TCPBUF->ackno[2] = c;
c = TCPBUF->seqno[1];
TCPBUF->seqno[1] = TCPBUF->ackno[1];
TCPBUF->ackno[1] = c;
c = TCPBUF->seqno[0];
TCPBUF->seqno[0] = TCPBUF->ackno[0];
TCPBUF->ackno[0] = c;
//这个期望下次的序号 不一定+1 又可能+发送的报文长度
if(++TCPBUF->ackno[3] == 0)
{
if(++TCPBUF->ackno[2] == 0)
{
if(++TCPBUF->ackno[1] == 0)
{
++TCPBUF->ackno[0];
}
}
}
Len = TCP_HEAD_LEN;
/* Swap port numbers. */
c = TCPBUF->srcport;
TCPBUF->srcport = TCPBUF->destport;
TCPBUF->destport = c;
TCPBUF->urgp[0] = TCPBUF->urgp[1] = 0;
/* Calculate TCP checksum. */
TCPBUF->tcpchksum = 0;
u16_t *BUF;
BUF = (u16_t *)((u8_t *)TCPBUF - 2 * sizeof(uip_ipaddr_t));
uip_ipaddr_copy(BUF, netif->ip_addr);
uip_ipaddr_copy(BUF+2, srcipaddr);
TCPBUF->tcpchksum = ~(uip_tcpchksum((u8_t *)TCPBUF,Len));
uip_ip_output(netif,UIP_PROTO_TCP,TCPBUF,Len,srcipaddr);
}
static void uip_tcp_output(struct netif *netif, struct tcp_hdr *TCPBUF,struct uip_tcp_conn *uip_tcp_connr,u32_t Len)
{
TCPBUF->ackno[0] = uip_tcp_connr->rcv_nxt[0];
TCPBUF->ackno[1] = uip_tcp_connr->rcv_nxt[1];
TCPBUF->ackno[2] = uip_tcp_connr->rcv_nxt[2];
TCPBUF->ackno[3] = uip_tcp_connr->rcv_nxt[3];
TCPBUF->seqno[0] = uip_tcp_connr->snd_nxt[0];
TCPBUF->seqno[1] = uip_tcp_connr->snd_nxt[1];
TCPBUF->seqno[2] = uip_tcp_connr->snd_nxt[2];
TCPBUF->seqno[3] = uip_tcp_connr->snd_nxt[3];
TCPBUF->srcport = uip_tcp_connr->lport;
TCPBUF->destport = uip_tcp_connr->rport;
if(uip_tcp_connr->tcpstateflags & UIP_STOPPED)
{
/* If the connection has issued uip_stop(), we advertise a zero
window so that the remote host will stop sending data. */
TCPBUF->wnd[0] = TCPBUF->wnd[1] = 0;
}
else
{
TCPBUF->wnd[0] = ((UIP_TCP_MSS) >> 8);
TCPBUF->wnd[1] = ((UIP_TCP_MSS) & 0xff);
}
TCPBUF->urgp[0] = TCPBUF->urgp[1] = 0;
/* Calculate TCP checksum. */
TCPBUF->tcpchksum = 0;
u16_t *BUF;
BUF = (u16_t *)((u8_t *)TCPBUF - 2 * sizeof(uip_ipaddr_t));
uip_ipaddr_copy(BUF, netif->ip_addr);
uip_ipaddr_copy(BUF+2, uip_tcp_connr->ripaddr);
TCPBUF->tcpchksum = ~(uip_tcpchksum((u8_t *)TCPBUF,Len));
uip_ip_output(netif,UIP_PROTO_TCP,TCPBUF,Len,uip_tcp_connr->ripaddr);
}
static void uip_tcp_reply_ack(struct netif *netif, struct tcp_hdr *TCPBUF,struct uip_tcp_conn *uip_tcp_connr)
{
u32_t Len;
TCPBUF->flags = TCP_ACK;
Len = TCP_HEAD_LEN;
TCPBUF->tcpoffset = (TCP_HEAD_LEN / 4) << 4;
uip_tcp_output(netif,TCPBUF,uip_tcp_connr,Len);
}
static void uip_tcp_output_rst(struct netif *netif, struct tcp_hdr *TCPBUF,struct uip_tcp_conn *uip_tcp_connr)
{
u32_t Len;
TCPBUF->flags = TCP_RST | TCP_ACK;;
Len = TCP_HEAD_LEN;
TCPBUF->tcpoffset = (TCP_HEAD_LEN / 4) << 4;
uip_tcp_output(netif,TCPBUF,uip_tcp_connr,Len);
}
static void uip_tcp_output_syn_ack(struct netif *netif, struct tcp_hdr *TCPBUF,struct uip_tcp_conn *uip_tcp_connr)
{
u32_t Len;
TCPBUF->flags = TCP_SYN | TCP_ACK;;
TCPBUF->optdata[0] = TCP_OPT_MSS;
TCPBUF->optdata[1] = TCP_OPT_MSS_LEN;
TCPBUF->optdata[2] = (UIP_TCP_MSS) / 256;
TCPBUF->optdata[3] = (UIP_TCP_MSS) & 255;
Len = TCP_HEAD_LEN + TCP_OPT_MSS_LEN;
TCPBUF->tcpoffset = ((TCP_HEAD_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
uip_tcp_output(netif,TCPBUF,uip_tcp_connr,Len);
}
static void uip_tcp_output_syn(struct netif *netif, struct tcp_hdr *TCPBUF,struct uip_tcp_conn *uip_tcp_connr)
{
u32_t Len;
TCPBUF->flags = TCP_SYN;;
TCPBUF->optdata[0] = TCP_OPT_MSS;
TCPBUF->optdata[1] = TCP_OPT_MSS_LEN;
TCPBUF->optdata[2] = (UIP_TCP_MSS) / 256;
TCPBUF->optdata[3] = (UIP_TCP_MSS) & 255;
Len = TCP_HEAD_LEN + TCP_OPT_MSS_LEN;
TCPBUF->tcpoffset = ((TCP_HEAD_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
uip_tcp_output(netif,TCPBUF,uip_tcp_connr,Len);
}
static void uip_tcp_output_fin_ack(struct netif *netif, struct tcp_hdr *TCPBUF,struct uip_tcp_conn *uip_tcp_connr)
{
u32_t Len;
TCPBUF->flags = TCP_FIN | TCP_ACK;
Len = TCP_HEAD_LEN;
TCPBUF->tcpoffset = (TCP_HEAD_LEN / 4) << 4;
uip_tcp_output(netif,TCPBUF,uip_tcp_connr,Len);
}
static void uip_tcp_output_data(struct netif *netif, struct tcp_hdr *TCPBUF,struct uip_tcp_conn *uip_tcp_connr)
{
u32_t Len;
TCPBUF->flags = TCP_ACK | TCP_PSH;
if(uip_tcp_connr->mss == 0)return;
if(uip_tcp_connr->sendLen > uip_tcp_connr->mss)
{
uip_tcp_connr->len = uip_tcp_connr->mss;
}
else
{
uip_tcp_connr->len = uip_tcp_connr->sendLen;
}
memcpy((u8_t *)TCPBUF+TCP_HEAD_LEN,uip_tcp_connr->pSendBuf,uip_tcp_connr->len);
Len = TCP_HEAD_LEN + uip_tcp_connr->len;
TCPBUF->tcpoffset = (TCP_HEAD_LEN / 4) << 4;
uip_tcp_output(netif,TCPBUF,uip_tcp_connr,Len);
}
static void uip_tcp_reply_ack_data(struct netif *netif, struct tcp_hdr *TCPBUF,struct uip_tcp_conn *uip_tcp_connr)
{
uip_tcp_output_data(netif,TCPBUF,uip_tcp_connr);
}
static void uip_tcp_reply_fin_ack(struct netif *netif, struct tcp_hdr *TCPBUF,struct uip_tcp_conn *uip_tcp_connr)
{
uip_tcp_output_fin_ack(netif,TCPBUF,uip_tcp_connr);
}
static void found_listen(struct netif *netif,struct tcp_hdr *TCPBUF,uip_ipaddr_t srcipaddr)
{
u32_t Len;
u8_t c;
register struct uip_tcp_conn *uip_tcp_connr;
uip_tcp_connr = 0;
for(c = 0; c < UIP_TCP_CONNS; ++c)
{
if(uip_tcp_conns[c].lport != 0) continue;
if(uip_tcp_conns[c].tcpstateflags == UIP_CLOSED)
{
uip_tcp_connr = &uip_tcp_conns[c];
break;
}
if(uip_tcp_conns[c].tcpstateflags == UIP_TIME_WAIT)
{
if(uip_tcp_connr == 0 || uip_tcp_conns[c].timer > uip_tcp_connr->timer)
{
uip_tcp_connr = &uip_tcp_conns[c];
}
}
}
if(uip_tcp_connr == 0)
{
/* All connections are used already, we drop packet and hope that
the remote end will retransmit the packet at a time when we
have more spare connections. */
(++netif->uip_stat.tcp.syndrop);
UIP_LOG("tcp: found no unused connections.");
return;
}
/* Fill in the necessary fields for the new connection. */
uip_tcp_connr->rto = uip_tcp_connr->timer = 3;
uip_tcp_connr->sa = 0;
uip_tcp_connr->sv = 4;
uip_tcp_connr->nrtx = 0;
uip_tcp_connr->lport = TCPBUF->destport;
uip_tcp_connr->rport = TCPBUF->srcport;
uip_ipaddr_copy(uip_tcp_connr->ripaddr, srcipaddr);
uip_tcp_connr->tcpstateflags = UIP_SYN_RCVD;
uip_tcp_connr->snd_nxt[0] = iss[0];
uip_tcp_connr->snd_nxt[1] = iss[1];
uip_tcp_connr->snd_nxt[2] = iss[2];
uip_tcp_connr->snd_nxt[3] = iss[3];
uip_tcp_connr->len = 1;
uip_tcp_connr->sendLen = 0;
/* rcv_nxt should be the seqno from the incoming packet + 1. */
uip_tcp_connr->rcv_nxt[3] = TCPBUF->seqno[3];
uip_tcp_connr->rcv_nxt[2] = TCPBUF->seqno[2];
uip_tcp_connr->rcv_nxt[1] = TCPBUF->seqno[1];
uip_tcp_connr->rcv_nxt[0] = TCPBUF->seqno[0];
uip_add_nxt(uip_tcp_connr->rcv_nxt,1);
/* Parse the TCP MSS option, if present. */
if((TCPBUF->tcpoffset & 0xf0) > 0x50)
{
//这里解析存在问题
parse_tcp_mss_option(TCPBUF,uip_tcp_connr);
}
if(uip_tcp_connr->mss == 0)
{
uip_tcp_connr->initialmss = uip_tcp_connr->mss = UIP_TCP_MSS;
}
TCPBUF->flags = TCP_ACK;
TCPBUF->flags |= TCP_SYN;
TCPBUF->optdata[0] = TCP_OPT_MSS;
TCPBUF->optdata[1] = TCP_OPT_MSS_LEN;
TCPBUF->optdata[2] = (UIP_TCP_MSS) / 256;
TCPBUF->optdata[3] = (UIP_TCP_MSS) & 255;
Len = TCP_HEAD_LEN + TCP_OPT_MSS_LEN;
TCPBUF->tcpoffset = ((TCP_HEAD_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
uip_tcp_output(netif,TCPBUF,uip_tcp_connr,Len);
}
int uip_tcp_input(struct netif *netif, void *BUF,u32_t Len,u8_t proto,uip_ipaddr_t srcipaddr)
{
u8_t c;
u16_t tmp16;
u32_t dataLen;
u8_t *appdata;
u8_t uip_acc32[4];
struct tcp_hdr *TCPBUF = BUF;
register struct uip_tcp_conn *uip_tcp_connr;
if(proto != UIP_PROTO_TCP)
{
return 0;
}
(++netif->uip_stat.tcp.recv);
if(uip_tcpchksum((u8_t *)TCPBUF,Len) != 0xffff)
{ /* Compute and check the TCP
checksum. */
(++netif->uip_stat.tcp.drop);
(++netif->uip_stat.tcp.chkerr);
UIP_LOG("tcp: bad checksum.\r\n");
return 1;
}
for(uip_tcp_connr = &uip_tcp_conns[0]; uip_tcp_connr <= &uip_tcp_conns[UIP_TCP_CONNS - 1];++uip_tcp_connr)
{
if(uip_tcp_connr->tcpstateflags != UIP_CLOSED &&
TCPBUF->destport == uip_tcp_connr->lport &&
TCPBUF->srcport == uip_tcp_connr->rport &&
uip_ipaddr_cmp(srcipaddr, uip_tcp_connr->ripaddr))
{
break;
}
}
if(uip_tcp_connr >= &uip_tcp_conns[UIP_TCP_CONNS])
{
if((TCPBUF->flags & TCP_CTL) == TCP_SYN)
{
/* Next, check listening connections. */
for(c = 0; c < UIP_LISTENPORTS; ++c)
{
if(TCPBUF->destport == uip_listenports[c])
{
found_listen(netif,TCPBUF,srcipaddr);
return 1;
}
}
}
(++netif->uip_stat.tcp.synrst);
if(TCPBUF->flags & TCP_RST)
{
return 1;
}
uip_tcp_reply_rst(netif,TCPBUF,srcipaddr);
return 1;
}
if(TCPBUF->flags & TCP_RST)
{
uip_tcp_connr->tcpstateflags = UIP_CLOSED;
uip_tcp_connr->uip_flags = UIP_ABORT;
UIP_LOG("tcp: got reset, aborting connection.\r\n");
return 1;
}
c = (TCPBUF->tcpoffset >> 4) << 2;
dataLen = Len - c; //减去TCP头部长度
appdata = (u8_t *)TCPBUF + c;
/* First, check if the sequence number of the incoming packet is
what we're expecting next. If not, we send out an ACK with the
correct numbers in. */
if(!(((uip_tcp_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && ((TCPBUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))))
{
if((dataLen > 0 || ((TCPBUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
(TCPBUF->seqno[0] != uip_tcp_connr->rcv_nxt[0] ||
TCPBUF->seqno[1] != uip_tcp_connr->rcv_nxt[1] ||
TCPBUF->seqno[2] != uip_tcp_connr->rcv_nxt[2] ||
TCPBUF->seqno[3] != uip_tcp_connr->rcv_nxt[3]))
{
//发送ack包给对端
uip_tcp_reply_ack(netif,TCPBUF,uip_tcp_connr);
return 1;
}
}
if((TCPBUF->flags & TCP_ACK) && uip_tcp_connr->len)
{
uip_acc32[0] = uip_tcp_connr->snd_nxt[0];
uip_acc32[1] = uip_tcp_connr->snd_nxt[1];
uip_acc32[2] = uip_tcp_connr->snd_nxt[2];
uip_acc32[3] = uip_tcp_connr->snd_nxt[3];
uip_add_nxt(uip_acc32,uip_tcp_connr->len);
if(TCPBUF->ackno[0] == uip_acc32[0] &&
TCPBUF->ackno[1] == uip_acc32[1] &&
TCPBUF->ackno[2] == uip_acc32[2] &&
TCPBUF->ackno[3] == uip_acc32[3]) {
/* Update sequence number. */
uip_tcp_connr->snd_nxt[0] = uip_acc32[0];
uip_tcp_connr->snd_nxt[1] = uip_acc32[1];
uip_tcp_connr->snd_nxt[2] = uip_acc32[2];
uip_tcp_connr->snd_nxt[3] = uip_acc32[3];
if(uip_tcp_connr->sendLen > 0 && (uip_tcp_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED )
{
uip_tcp_connr->sendLen -= uip_tcp_connr->len;
memcpy(uip_tcp_connr->pSendBuf,&uip_tcp_connr->pSendBuf[uip_tcp_connr->len],uip_tcp_connr->sendLen);
}
/* Do RTT estimation, unless we have done retransmissions. */
if(uip_tcp_connr->nrtx == 0)
{
signed char m;
m = uip_tcp_connr->rto - uip_tcp_connr->timer;
/* This is taken directly from VJs original code in his paper */
m = m - (uip_tcp_connr->sa >> 3);
uip_tcp_connr->sa += m;
if(m < 0) {
m = -m;
}
m = m - (uip_tcp_connr->sv >> 2);
uip_tcp_connr->sv += m;
uip_tcp_connr->rto = (uip_tcp_connr->sa >> 3) + uip_tcp_connr->sv;
}
//通知应用层 收到了应答帧
uip_tcp_connr->uip_flags = UIP_ACKDATA;
/* Reset the retransmission timer. */
uip_tcp_connr->timer = uip_tcp_connr->rto;
uip_tcp_connr->len = uip_tcp_connr->sendLen;
}
}
/* Do different things depending on in what state the connection is. */
switch(uip_tcp_connr->tcpstateflags & UIP_TS_MASK)
{
case UIP_SYN_RCVD://这里只差一个ack就可以建立连接
if(uip_tcp_connr->uip_flags & UIP_ACKDATA)
{
uip_tcp_connr->tcpstateflags = UIP_ESTABLISHED;
uip_tcp_connr->uip_flags = UIP_CONNECTED;
uip_tcp_connr->len = 0;
uip_tcp_connr->sendLen = 0;
//如果有数据
if(dataLen > 0)
{
uip_tcp_connr->uip_flags |= UIP_NEWDATA;//标记需要应答
uip_add_nxt(uip_tcp_connr->rcv_nxt,dataLen);
move_data_appbuf(uip_tcp_connr,appdata,dataLen);
}
}
return 1;
case UIP_SYN_SENT:
if((uip_tcp_connr->uip_flags & UIP_ACKDATA) && (TCPBUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))
{
/* Parse the TCP MSS option, if present. */
if((TCPBUF->tcpoffset & 0xf0) > 0x50)
{
parse_tcp_mss_option(TCPBUF,uip_tcp_connr);
}
uip_tcp_connr->tcpstateflags = UIP_ESTABLISHED;
uip_tcp_connr->rcv_nxt[0] = TCPBUF->seqno[0];
uip_tcp_connr->rcv_nxt[1] = TCPBUF->seqno[1];
uip_tcp_connr->rcv_nxt[2] = TCPBUF->seqno[2];
uip_tcp_connr->rcv_nxt[3] = TCPBUF->seqno[3];
uip_add_nxt(uip_tcp_connr->rcv_nxt,1);
uip_tcp_connr->uip_flags = UIP_CONNECTED | UIP_NEWDATA;
uip_tcp_connr->len = 0;
uip_tcp_connr->sendLen = 0;
return 1;
}
uip_tcp_connr->uip_flags = UIP_ABORT;
uip_tcp_connr->tcpstateflags = UIP_CLOSED;
//发送复位包
uip_tcp_reply_rst(netif,TCPBUF,srcipaddr);
return 1;
case UIP_ESTABLISHED:
if(TCPBUF->flags & TCP_FIN && !(uip_tcp_connr->tcpstateflags & UIP_STOPPED))
{
if(uip_tcp_connr->len)
{
return 1;
}
uip_add_nxt(uip_tcp_connr->rcv_nxt,1 + dataLen);
uip_tcp_connr->uip_flags = UIP_CLOSE;
if(dataLen > 0)
{
move_data_appbuf(uip_tcp_connr,appdata,dataLen);
}
uip_tcp_connr->len = 1;
uip_tcp_connr->tcpstateflags = UIP_LAST_ACK;
uip_tcp_connr->nrtx = 0;
//发送 FIN+ACK
uip_tcp_reply_fin_ack(netif,TCPBUF,uip_tcp_connr);
return 1;
}
if((TCPBUF->flags & TCP_URG) != 0)
{
appdata = appdata + ((TCPBUF->urgp[0] << 8) | TCPBUF->urgp[1]);
dataLen -= (TCPBUF->urgp[0] << 8) | TCPBUF->urgp[1];
}
tmp16 = ((u16_t)TCPBUF->wnd[0] << 8) + (u16_t)TCPBUF->wnd[1];
if(tmp16 > uip_tcp_connr->initialmss || tmp16 == 0)
{
tmp16 = uip_tcp_connr->initialmss;
}
uip_tcp_connr->mss = tmp16;
if(dataLen > 0 && !(uip_tcp_connr->tcpstateflags & UIP_STOPPED))
{
uip_tcp_connr->uip_flags |= UIP_NEWDATA;
uip_add_nxt(uip_tcp_connr->rcv_nxt,dataLen);
move_data_appbuf(uip_tcp_connr,appdata,dataLen);
}
if(uip_tcp_connr->sendLen > 0)
{
uip_tcp_reply_ack_data(netif,TCPBUF,uip_tcp_connr);
}
return 1;
case UIP_LAST_ACK:
if(uip_tcp_connr->uip_flags & UIP_ACKDATA)
{
uip_tcp_connr->tcpstateflags = UIP_CLOSED;
uip_tcp_connr->uip_flags = UIP_CLOSE;
}
return 1;
case UIP_FIN_WAIT_1:
if(dataLen > 0)
{
uip_add_nxt(uip_tcp_connr->rcv_nxt,dataLen);
}
if(TCPBUF->flags & TCP_FIN)
{
if(uip_tcp_connr->uip_flags & UIP_ACKDATA)
{
uip_tcp_connr->tcpstateflags = UIP_TIME_WAIT;
uip_tcp_connr->timer = 0;
uip_tcp_connr->len = 0;
uip_tcp_connr->sendLen = 0;
}
else
{
uip_tcp_connr->tcpstateflags = UIP_CLOSING;
}
uip_add_nxt(uip_tcp_connr->rcv_nxt,1);
uip_tcp_connr->uip_flags = UIP_CLOSE;
uip_tcp_reply_ack(netif,TCPBUF,uip_tcp_connr);
return 1;
}
else if(uip_tcp_connr->uip_flags & UIP_ACKDATA)
{
uip_tcp_connr->tcpstateflags = UIP_FIN_WAIT_2;
uip_tcp_connr->len = 0;
uip_tcp_connr->sendLen = 0;
return 1;
}
if(dataLen > 0)
{
uip_tcp_reply_ack(netif,TCPBUF,uip_tcp_connr);
}
return 1;
case UIP_FIN_WAIT_2:
if(dataLen > 0)
{
uip_add_nxt(uip_tcp_connr->rcv_nxt,dataLen);
}
if(TCPBUF->flags & TCP_FIN)
{
uip_tcp_connr->tcpstateflags = UIP_TIME_WAIT;
uip_tcp_connr->timer = 0;
uip_add_nxt(uip_tcp_connr->rcv_nxt,1);
uip_tcp_connr->uip_flags = UIP_CLOSE;
uip_tcp_reply_ack(netif,TCPBUF,uip_tcp_connr);
return 1;
}
if(dataLen > 0)
{
uip_tcp_reply_ack(netif,TCPBUF,uip_tcp_connr);
}
return 1;
case UIP_TIME_WAIT:
uip_tcp_reply_ack(netif,TCPBUF,uip_tcp_connr);
return 1;
case UIP_CLOSING:
if(uip_tcp_connr->uip_flags & UIP_ACKDATA)
{
uip_tcp_connr->tcpstateflags = UIP_TIME_WAIT;
uip_tcp_connr->timer = 0;
}
return 1;
}
return 1;
}
//0.5s 调用一次
void uip_tcp_timer(struct netif *netif)
{
u8_t i;
int bufLen = sizeof(netif->uip_buf);
struct tcp_hdr *TCPBUF;
struct uip_tcp_conn *uip_tcp_connr;
for(i=0; i<UIP_TCP_CONNS; i++)
{
uip_tcp_connr = &uip_tcp_conns[i];
TCPBUF = (struct tcp_hdr *)(&netif->uip_buf[bufLen-1] - TCP_HEAD_LEN - uip_tcp_connr->mss);
/* Increase the initial sequence number. */
if(++iss[3] == 0)
{
if(++iss[2] == 0)
{
if(++iss[1] == 0)
{
++iss[0];
}
}
}
if(uip_tcp_connr->tcpstateflags == UIP_TIME_WAIT || uip_tcp_connr->tcpstateflags == UIP_FIN_WAIT_2)
{
++(uip_tcp_connr->timer);
if(uip_tcp_connr->timer >= UIP_TIME_WAIT_TIMEOUT)
{
if(uip_tcp_connr->tcpstateflags == UIP_FIN_WAIT_2)
{
uip_tcp_output_rst(netif,TCPBUF,uip_tcp_connr);
}
uip_tcp_connr->timer = 0;
uip_tcp_connr->tcpstateflags = UIP_CLOSED;
continue;
}
}
else if(uip_tcp_connr->tcpstateflags != UIP_CLOSED && uip_tcp_connr->len)
{
if(uip_tcp_connr->timer-- == 0)
{
if(uip_tcp_connr->nrtx == UIP_MAXRTX ||
((uip_tcp_connr->tcpstateflags == UIP_SYN_SENT || uip_tcp_connr->tcpstateflags == UIP_SYN_RCVD) && uip_tcp_connr->nrtx == UIP_MAXSYNRTX))
{
uip_tcp_connr->tcpstateflags = UIP_CLOSED;
uip_tcp_connr->uip_flags = UIP_TIMEDOUT;
uip_tcp_connr->sendLen = -1;
//发送复位命令出去
uip_tcp_output_rst(netif,TCPBUF,uip_tcp_connr);
continue;
}
/* Exponential backoff. */
uip_tcp_connr->timer = UIP_RTO << (uip_tcp_connr->nrtx > 4? 4:uip_tcp_connr->nrtx);
++(uip_tcp_connr->nrtx);
(++netif->uip_stat.tcp.rexmit);
switch(uip_tcp_connr->tcpstateflags & UIP_TS_MASK)
{
case UIP_SYN_RCVD:
uip_tcp_output_syn_ack(netif,TCPBUF,uip_tcp_connr);
break;
case UIP_SYN_SENT:
TCPBUF->flags = 0;
uip_tcp_output_syn(netif,TCPBUF,uip_tcp_connr);
break;
case UIP_ESTABLISHED:
uip_tcp_connr->uip_flags = UIP_REXMIT;
//重传数据
uip_tcp_output_data(netif,TCPBUF,uip_tcp_connr);
break;
case UIP_FIN_WAIT_1:
case UIP_CLOSING:
case UIP_LAST_ACK:
uip_tcp_output_fin_ack(netif,TCPBUF,uip_tcp_connr);
break;
}
}
}
if(uip_tcp_connr->tcpstateflags != UIP_CLOSED && uip_tcp_connr->uip_flags & UIP_NEWDATA )
{
uip_tcp_connr->uip_flags &= ~(UIP_NEWDATA);
uip_tcp_reply_ack(netif,TCPBUF,uip_tcp_connr);
}
}
}
struct uip_tcp_conn *uip_tcp_connect(struct netif *netif,uip_ipaddr_t ripaddr, u16_t rport)
{
u16_t c;
int bufLen = sizeof(netif->uip_buf);
struct tcp_hdr *TCPBUF;
struct uip_tcp_conn *conn, *cconn;
again:
++lastport;
if(lastport >= 32000)
{
lastport = 4096;
}
lastport = HTONS(lastport);
for(c = 0; c < UIP_TCP_CONNS; ++c)
{
conn = &uip_tcp_conns[c];
if(conn->tcpstateflags != UIP_CLOSED && conn->lport == lastport)
{
goto again;
}
}
conn = 0;
for(c = 0; c < UIP_TCP_CONNS; ++c)
{
cconn = &uip_tcp_conns[c];
if(cconn->tcpstateflags == UIP_CLOSED)
{
conn = cconn;
break;
}
if(cconn->tcpstateflags == UIP_TIME_WAIT)
{
if(conn == 0 || cconn->timer > conn->timer)
{
conn = cconn;
}
}
}
if(conn == 0)
{
return 0;
}
conn->tcpstateflags = UIP_SYN_SENT;
conn->snd_nxt[0] = iss[0];
conn->snd_nxt[1] = iss[1];
conn->snd_nxt[2] = iss[2];
conn->snd_nxt[3] = iss[3];
conn->initialmss = conn->mss = UIP_TCP_MSS;
conn->len = 1; /* TCP length of the SYN is one. */
conn->nrtx = 0;
conn->timer = 1; /* Send the SYN next time around. */
conn->rto = UIP_RTO;
conn->sa = 0;
conn->sv = 16; /* Initial value of the RTT variance. */
conn->lport = lastport;
conn->rport = HTONS(rport);
uip_ipaddr_copy(&conn->ripaddr, ripaddr);
TCPBUF = (struct tcp_hdr *)(&netif->uip_buf[bufLen-1] - TCP_HEAD_LEN - conn->mss);
TCPBUF->flags = 0;
uip_tcp_output_syn(netif,TCPBUF,conn);
while(1)
{
uip_netif_periodic_handle();
if((conn->tcpstateflags & UIP_TS_MASK) == UIP_CLOSED)
{
return 0;
}
if(uip_is_tcp_connected(conn) == 1)
{
break;
}
}
return conn;
}
int uip_is_tcp_connected(struct uip_tcp_conn *conn)
{
if((conn->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED)
{
return 1;
}
else if((conn->tcpstateflags & UIP_TS_MASK) == UIP_CLOSED)
{
return 0;
}
return 2;
}
void uip_tcp_close(struct netif *netif,struct uip_tcp_conn *conn)
{
int bufLen = sizeof(netif->uip_buf);
struct tcp_hdr *TCPBUF;
UIP_LOG("tcp: app close connect.\r\n");
TCPBUF = (struct tcp_hdr *)(&netif->uip_buf[bufLen-1] - TCP_HEAD_LEN - conn->mss);
conn->len = 1;
conn->timer = 1;
conn->tcpstateflags = UIP_FIN_WAIT_1;
conn->nrtx = 0;
uip_tcp_output_fin_ack(netif,TCPBUF,conn);
conn->lport = 0;
conn->rport = 0;
conn->recvLen = 0;
}
void uip_tcp_listen(u16_t port)
{
u16_t c;
port = HTONS(port);
for(c = 0; c < UIP_LISTENPORTS; ++c)
{
if(uip_listenports[c] == port)
{
return;
}
}
for(c = 0; c < UIP_LISTENPORTS; ++c)
{
if(uip_listenports[c] == 0)
{
uip_listenports[c] = port;
return;
}
}
}
void uip_tcp_unlisten(u16_t port)
{
u16_t c;
port = HTONS(port);
for(c = 0; c < UIP_LISTENPORTS; ++c)
{
if(uip_listenports[c] == port)
{
uip_listenports[c] = 0;
return;
}
}
}
struct uip_tcp_conn *uip_tcp_accept(u16_t port)
{
static u16_t c = 0;
port = HTONS(port);
c = c % UIP_TCP_CONNS;
for(; c < UIP_TCP_CONNS; ++c)
{
if(uip_tcp_conns[c].lport == port)
{
c++;
return &uip_tcp_conns[c-1];
}
}
return 0;
}
int uip_tcp_recv(struct netif *netif,void *conn1,void *buf, int buflen,int timeout)
{
volatile int Len;
int time;
struct uip_tcp_conn *conn = (struct uip_tcp_conn *)conn1;
if(conn->recvLen == 0 && (conn->tcpstateflags & UIP_TS_MASK) == UIP_CLOSED)
{
return -1;
}
time = uip_localtime + timeout;
while(conn->recvLen == 0)
{
uip_netif_periodic_handle();
if(uip_localtime > time)
{
return 0;
}
}
if(buflen > conn->recvLen )
{
Len = conn->recvLen;
}
else
{
Len = buflen;
}
memcpy(buf,conn->recvBuf,Len);
conn->recvLen = conn->recvLen - Len;
if(conn->recvLen > 0)
{
memcpy(conn->recvBuf,&conn->recvBuf[Len],conn->recvLen);
}
return Len;
}
int is_send_ok(void *conn1)
{
struct uip_tcp_conn *conn = (struct uip_tcp_conn *)conn1;
if(conn->sendLen > 0)return 0;
return 1;
}
int set_send_block(void *conn1,u8_t flag)
{
struct uip_tcp_conn *conn = (struct uip_tcp_conn *)conn1;
if(!conn)return 0;
conn->isSendBlock = flag;
return 0;
}
int uip_tcp_send(struct netif *netif,void *conn1,void *data, int len)
{
struct uip_tcp_conn *conn = (struct uip_tcp_conn *)conn1;
int bufLen = sizeof(netif->uip_buf);
struct tcp_hdr *TCPBUF;
if(len <= 0) return 0;
if(conn->sendLen > 0)return 0;
if(len > 0)
{
conn->sendLen = len;
conn->pSendBuf = data;
TCPBUF = (struct tcp_hdr *)(&netif->uip_buf[bufLen-1] - TCP_HEAD_LEN - conn->mss);
if((conn->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED)
{
uip_tcp_output_data(netif,TCPBUF,conn);
conn->uip_flags &= ~(UIP_NEWDATA);
if(conn->isSendBlock)
{
while(conn->sendLen > 0)
{
uip_netif_periodic_handle();
if((conn->tcpstateflags & UIP_TS_MASK) != UIP_ESTABLISHED && (conn->tcpstateflags & UIP_TS_MASK) != UIP_LAST_ACK)
{
UIP_LOG("tcp: conn->tcpstateflags :%d.\r\n",conn->tcpstateflags);
return -1;
}
}
}
}
else
{
return -1;
}
}
return len;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。