📄 uip.lst
字号:
647 4 /* And we are done processing options. */
648 4 break;
649 4 } else {
650 4 /* All other options have a length field, so that we easily
651 4 can skip past them. */
652 4 c += uip_buf[40 + UIP_LLH_LEN + c + 1];
653 4 }
654 3 }
655 2 }
656 1
657 1 /* Our response will be a SYNACK. */
658 1 #if UIP_ACTIVE_OPEN
tcp_send_synack:
BUF->flags = TCP_ACK;
tcp_send_syn:
BUF->flags |= TCP_SYN;
#else /* UIP_ACTIVE_OPEN */
665 1 tcp_send_synack:
666 1 BUF->flags = TCP_SYN | TCP_ACK;
667 1 #endif /* UIP_ACTIVE_OPEN */
668 1
669 1 /* We send out the TCP Maximum Segment Size option with our
670 1 SYNACK. */
671 1 BUF->optdata[0] = 2;
672 1 BUF->optdata[1] = 4;
673 1 BUF->optdata[2] = (UIP_TCP_MSS) / 256;
674 1 BUF->optdata[3] = (UIP_TCP_MSS) & 255;
675 1 uip_len = 44;
C51 COMPILER V7.10 UIP 09/03/2004 09:33:15 PAGE 12
676 1 BUF->tcpoffset = 6 << 4;
677 1 goto tcp_send;
678 1
679 1 /* This label will be jumped to if we found an active connection. */
680 1 found:
681 1 uip_flags = 0;
682 1
683 1 /* We do a very naive form of TCP reset processing; we just accept
684 1 any RST and kill our connection. We should in fact check if the
685 1 sequence number of this reset is wihtin our advertised window
686 1 before we accept the reset. */
687 1 if(BUF->flags & TCP_RST)
688 1 {
689 2 uip_conn->tcpstateflags = CLOSED;
690 2 UIP_LOG("tcp: got reset, aborting connection.");
691 2 uip_flags = UIP_ABORT;
692 2 UIP_APPCALL();
693 2 goto drop;
694 2 }
695 1 /* All segments that are come thus far should have the ACK flag set,
696 1 otherwise we drop the packet. */
697 1 if(!(BUF->flags & TCP_ACK))
698 1 {
699 2 UIP_STAT(++uip_stat.tcp.drop);
700 2 UIP_STAT(++uip_stat.tcp.ackerr);
701 2 UIP_LOG("tcp: dropped non-ack segment.");
702 2 goto drop;
703 2 }
704 1
705 1 /* Calculated the length of the data, if the application has sent
706 1 any data to us. */
707 1 c = (BUF->tcpoffset >> 4) << 2;
708 1 /* uip_len will contain the length of the actual TCP data. This is
709 1 calculated by subtracing the length of the TCP header (in
710 1 c) and the length of the IP header (20 bytes). */
711 1 uip_len = uip_len - c - 20;
712 1
713 1 /* First, check if the sequence number of the incoming packet is
714 1 what we're expecting next. If not, we send out an ACK with the
715 1 correct numbers in. */
716 1 if(uip_len > 0 &&
717 1 (BUF->seqno[0] != uip_conn->rcv_nxt[0] ||
718 1 BUF->seqno[1] != uip_conn->rcv_nxt[1] ||
719 1 BUF->seqno[2] != uip_conn->rcv_nxt[2] ||
720 1 BUF->seqno[3] != uip_conn->rcv_nxt[3])) {
721 2 goto tcp_send_ack;
722 2 }
723 1
724 1 /* Next, check if the incoming segment acknowledges any outstanding
725 1 data. If so, we also reset the retransmission timer. */
726 1 if(BUF->ackno[0] == uip_conn->ack_nxt[0] &&
727 1 BUF->ackno[1] == uip_conn->ack_nxt[1] &&
728 1 BUF->ackno[2] == uip_conn->ack_nxt[2] &&
729 1 BUF->ackno[3] == uip_conn->ack_nxt[3])
730 1 {
731 2 uip_conn->snd_nxt[0] = uip_conn->ack_nxt[0];
732 2 uip_conn->snd_nxt[1] = uip_conn->ack_nxt[1];
733 2 uip_conn->snd_nxt[2] = uip_conn->ack_nxt[2];
734 2 uip_conn->snd_nxt[3] = uip_conn->ack_nxt[3];
735 2 if(uip_conn->tcpstateflags & UIP_OUTSTANDING)
736 2 {
737 3 uip_flags = UIP_ACKDATA;
C51 COMPILER V7.10 UIP 09/03/2004 09:33:15 PAGE 13
738 3 uip_conn->tcpstateflags &= ~UIP_OUTSTANDING;
739 3 uip_conn->timer = UIP_RTO;
740 3 }
741 2 }
742 1
743 1 /* Do different things depending on in what state the connection is. */
744 1 switch(uip_conn->tcpstateflags & TS_MASK)
745 1 {
746 2 /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
747 2 implemented, since we force the application to close when the
748 2 peer sends a FIN (hence the application goes directly from
749 2 ESTABLISHED to LAST_ACK). */
750 2 case SYN_RCVD:
751 2 /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
752 2 we are waiting for an ACK that acknowledges the data we sent
753 2 out the last time. Therefore, we want to have the UIP_ACKDATA
754 2 flag set. If so, we enter the ESTABLISHED state. */
755 2 if(uip_flags & UIP_ACKDATA)
756 2 {
757 3 uip_conn->tcpstateflags = ESTABLISHED;
758 3 uip_flags = UIP_CONNECTED;
759 3 uip_len = 0;
760 3 UIP_APPCALL();
761 3 goto appsend;
762 3 }
763 2 goto drop;
764 2 #if UIP_ACTIVE_OPEN
case SYN_SENT:
/* In SYN_SENT, we wait for a SYNACK that is sent in response to
our SYN. The rcv_nxt is set to sequence number in the SYNACK
plus one, and we send an ACK. We move into the ESTABLISHED
state. */
if((uip_flags & UIP_ACKDATA) &&
BUF->flags == (TCP_SYN | TCP_ACK))
{
/* Parse the TCP MSS option, if present. */
if((BUF->tcpoffset & 0xf0) > 0x50) {
for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
opt = uip_buf[40 + UIP_LLH_LEN + c];
if(opt == 0x00) {
/* End of options. */
break;
} else if(opt == 0x01) {
++c;
/* NOP option. */
} else if(opt == 0x02 &&
uip_buf[40 + UIP_LLH_LEN + c + 1] == 0x04) {
/* An MSS option with the right option length. */
tmpport = (uip_buf[40 + UIP_LLH_LEN + c + 2] << 8) |
uip_buf[40 + UIP_LLH_LEN + c + 3];
uip_conn->mss = tmpport > UIP_TCP_MSS? UIP_TCP_MSS: tmpport;
/* And we are done processing options. */
break;
} else {
/* All other options have a length field, so that we easily
can skip past them. */
c += uip_buf[40 + UIP_LLH_LEN + c + 1];
}
}
}
C51 COMPILER V7.10 UIP 09/03/2004 09:33:15 PAGE 14
uip_conn->tcpstateflags = ESTABLISHED;
uip_conn->rcv_nxt[0] = BUF->seqno[0];
uip_conn->rcv_nxt[1] = BUF->seqno[1];
uip_conn->rcv_nxt[2] = BUF->seqno[2];
uip_conn->rcv_nxt[3] = BUF->seqno[3];
uip_add_rcv_nxt(1);
uip_flags = UIP_CONNECTED | UIP_NEWDATA;
uip_len = 0;
UIP_APPCALL();
goto appsend;
}
goto drop;
#endif /* UIP_ACTIVE_OPEN */
814 2
815 2 case ESTABLISHED:
816 2 /* In the ESTABLISHED state, we call upon the application to feed
817 2 data into the uip_buf. If the UIP_ACKDATA flag is set, the
818 2 application should put new data into the buffer, otherwise we are
819 2 retransmitting an old segment, and the application should put that
820 2 data into the buffer.
821 2
822 2 If the incoming packet is a FIN, we should close the connection on
823 2 this side as well, and we send out a FIN and enter the LAST_ACK
824 2 state. We require that the FIN will have to acknowledge all
825 2 outstanding data, otherwise we drop it. */
826 2
827 2 if(BUF->flags & TCP_FIN)
828 2 {
829 3 uip_add_rcv_nxt(1 + uip_len);
830 3 uip_flags = UIP_CLOSE;
831 3 uip_len = 0;
832 3 UIP_APPCALL();
833 3 uip_add_ack_nxt(1);
834 3 uip_conn->tcpstateflags = LAST_ACK | UIP_OUTSTANDING;
835 3 uip_conn->nrtx = 0;
836 3 tcp_send_finack:
837 3 BUF->flags = TCP_FIN | TCP_ACK;
838 3 goto tcp_send_nodata;
839 3 }
840 2
841 2 /* If uip_len > 0 we have TCP data in the packet, and we flag this
842 2 by setting the UIP_NEWDATA flag and update the sequence number
843 2 we acknowledge. If the application has stopped the dataflow
844 2 using uip_stop(), we must not accept any data packets from the
845 2 remote host. */
846 2 if(uip_len > 0 && !(uip_conn->tcpstateflags & UIP_STOPPED))
847 2 {
848 3 uip_flags |= UIP_NEWDATA;
849 3 uip_add_rcv_nxt(uip_len);
850 3 }
851 2
852 2 /* If this packet constitutes an ACK for outstanding data (flagged
853 2 by the UIP_ACKDATA flag, we should call the application since it
854 2 might want to send more data. If the incoming packet had data
855 2 from the peer (as flagged by the UIP_NEWDATA flag), the
856 2 application must also be notified.
857 2
858 2 When the application is called, the global variable uip_len
859 2 contains the length of the incoming data. The application can
860 2 access the incoming data through the global pointer
861 2 uip_appdata, which usually points 40 bytes into the uip_buf
C51 COMPILER V7.10 UIP 09/03/2004 09:33:15 PAGE 15
862 2 array.
863 2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -