📄 uip.lst
字号:
675 1 uip_connr->rcv_nxt[2] = BUF->seqno[2];
676 1 uip_connr->rcv_nxt[1] = BUF->seqno[1];
677 1 uip_connr->rcv_nxt[0] = BUF->seqno[0];
678 1
679 1 uip_add_rcv_nxt(1); //在上面的函数中可知
680 1
681 1 /* Parse the TCP MSS option, if present. */
682 1 if((BUF->tcpoffset & 0xf0) > 0x50) { //对偏移量的处理
683 2 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
684 3 opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
685 3 if(opt == 0x00) {
686 4 /* End of options. */
687 4 break;
688 4 } else if(opt == 0x01) {
689 4 ++c;
690 4 /* NOP option. */
691 4 } else if(opt == 0x02 &&
692 3 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
693 4 /* An MSS option with the right option length. */
694 4 tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
695 4 (u16_t)uip_buf[40 + UIP_LLH_LEN + 3 + c];
696 4
697 4 uip_connr->initialmss = uip_connr->mss =
698 4 tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
699 4
700 4 /* And we are done processing options. */
701 4 break;
702 4 } else {
703 4 /* All other options have a length field, so that we easily
704 4 can skip past them. */
705 4 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
706 5 /* If the length field is zero, the options are malformed 畸形
707 5 and we don't process them further. */
708 5 break;
709 5 }
710 4 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
711 4 }
712 3 }
713 2 }
714 1
715 1 /* Our response will be a SYNACK. */
716 1 #if UIP_ACTIVE_OPEN
717 1 tcp_send_synack:
718 1 BUF->flags = TCP_ACK;
719 1
720 1 tcp_send_syn:
721 1 BUF->flags |= TCP_SYN;
722 1 #else /* UIP_ACTIVE_OPEN */
tcp_send_synack: //发送SYNACK包
BUF->flags = TCP_SYN | TCP_ACK; //0x12
#endif /* UIP_ACTIVE_OPEN */
726 1
727 1 /* We send out the TCP Maximum Segment Size option with our
728 1 SYNACK. *///将TCP最大段的大小选项作为我们的回应信号
729 1 BUF->optdata[0] = 2;
730 1 BUF->optdata[1] = 4;
731 1 BUF->optdata[2] = (UIP_TCP_MSS) / 256;
732 1 BUF->optdata[3] = (UIP_TCP_MSS) & 255;
733 1 uip_len = 40;
734 1 BUF->tcpoffset = 5 << 4; //正确,24
735 1 goto tcp_send;
736 1
C51 COMPILER V8.08 UIP 08/22/2008 14:32:51 PAGE 13
737 1
738 1 /* This label will be jumped to if we found an active connection. */
739 1 found:
740 1 uip_conn = uip_connr;
741 1
742 1 uip_flags = 0;
743 1
744 1 /* We do a very naive form of TCP reset processing; we just accept
745 1 any RST and kill our connection. We should in fact check if the
746 1 sequence number of this reset is wihtin our advertised window
747 1 before we accept the reset. */
748 1 if(BUF->flags & TCP_RST) {
749 2 uip_connr->tcpstateflags = CLOSED;
750 2 UIP_LOG("tcp: got reset, aborting connection.");
751 2 uip_flags = UIP_ABORT;
752 2 UIP_APPCALL();
753 2 goto drop;
754 2 }
755 1 /* Calculated the length of the data, if the application has sent
756 1 any data to us. */
757 1 c = (BUF->tcpoffset >> 4) << 2;
758 1 /* uip_len will contain the length of the actual TCP data. This is
759 1 calculated by subtracing the length of the TCP header (in
760 1 c) and the length of the IP header (20 bytes). */
761 1 uip_len = uip_len - c - 20; //除去报头的具体数据的长度
762 1
763 1 /* First, check if the sequence number of the incoming packet is
764 1 what we're expecting next. If not, we send out an ACK with the
765 1 correct numbers in. */
766 1 if(uip_len > 0 &&
767 1 (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
768 1 BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
769 1 BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
770 1 BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
771 2 goto tcp_send_ack;
772 2 }
773 1
774 1 /* Next, check if the incoming segment acknowledges any outstanding
775 1 data. If so, we update the sequence number, reset the length of
776 1 the outstanding data, calculate RTT estimations, and reset the
777 1 retransmission timer. */
778 1 if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr))
779 1 {
780 2 uip_add32(uip_connr->snd_nxt, uip_connr->len);
781 2 //无数据ACK包在这里丢失?
782 2 if(BUF->ackno[0] == uip_acc32[0] &&
783 2 BUF->ackno[1] == uip_acc32[1] &&
784 2 BUF->ackno[2] == uip_acc32[2] &&
785 2 BUF->ackno[3] == uip_acc32[3])
786 2 {
787 3 /* Update sequence number. */
788 3 uip_connr->snd_nxt[0] = uip_acc32[0];
789 3 uip_connr->snd_nxt[1] = uip_acc32[1];
790 3 uip_connr->snd_nxt[2] = uip_acc32[2];
791 3 uip_connr->snd_nxt[3] = uip_acc32[3];
792 3
793 3
794 3 /* Do RTT estimation, unless we have done retransmissions. */
795 3 if(uip_connr->nrtx == 0) {
796 4 signed char m;
797 4 m = uip_connr->rto - uip_connr->timer;
798 4 /* This is taken directly from VJs original code in his paper */
C51 COMPILER V8.08 UIP 08/22/2008 14:32:51 PAGE 14
799 4 m = m - (uip_connr->sa >> 3);
800 4 uip_connr->sa += m;
801 4
802 4 if(m < 0) {
803 5 m = -m;
804 5 }
805 4 m = m - (uip_connr->sv >> 2);
806 4 uip_connr->sv += m;
807 4 uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
808 4
809 4 }
810 3 /* Set the acknowledged flag. */
811 3 uip_flags = UIP_ACKDATA;
812 3 /* Reset the retransmission timer. */
813 3 uip_connr->timer = uip_connr->rto;
814 3 }
815 2
816 2 }
817 1
818 1 /* Do different things depending on in what state the connection is. */
819 1 switch(uip_connr->tcpstateflags & TS_MASK) { //掩盖上面的4位
820 2 /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
821 2 implemented, since we force the application to close when the
822 2 peer sends a FIN (hence the application goes directly from
823 2 ESTABLISHED to LAST_ACK). */
824 2 case SYN_RCVD:
825 2 /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
826 2 we are waiting for an ACK that acknowledges the data we sent
827 2 out the last time. Therefore, we want to have the UIP_ACKDATA
828 2 flag set. If so, we enter the ESTABLISHED state. */
829 2 if(uip_flags & UIP_ACKDATA) {
830 3 uip_connr->tcpstateflags = ESTABLISHED;
831 3
832 3 uip_flags = UIP_CONNECTED;
833 3 uip_connr->len = 0; //前面为1
834 3 if(uip_len > 0) { //先接数据然后在发送,优先权
835 4 uip_flags |= UIP_NEWDATA;
836 4
837 4 uip_add_rcv_nxt(uip_len); //序列号加上接收数据的多少,作为下次接收的序列号
838 4 }
839 3 uip_slen = 0;
840 3 UIP_APPCALL();
841 3 goto appsend;
842 3 }
843 2 goto drop;
844 2 #if UIP_ACTIVE_OPEN
845 2 case SYN_SENT:
846 2 /* In SYN_SENT, we wait for a SYNACK that is sent in response to
847 2 our SYN. The rcv_nxt is set to sequence number in the SYNACK
848 2 plus one, and we send an ACK. We move into the ESTABLISHED
849 2 state. */
850 2 if((uip_flags & UIP_ACKDATA) &&
851 2 BUF->flags == (TCP_SYN | TCP_ACK)) {
852 3
853 3 /* Parse the TCP MSS option, if present. */
854 3 if((BUF->tcpoffset & 0xf0) > 0x50) {
855 4 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
856 5 opt = uip_buf[40 + UIP_LLH_LEN + c];
857 5 if(opt == 0x00) {
858 6 /* End of options. */
859 6 break;
860 6 } else if(opt == 0x01) {
C51 COMPILER V8.08 UIP 08/22/2008 14:32:51 PAGE 15
861 6 ++c;
862 6 /* NOP option. */
863 6 } else if(opt == 0x02 &&
864 5 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
865 6 /* An MSS option with the right option length. */
866 6 tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
867 6 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
868 6 uip_connr->initialmss =
869 6 uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
870 6
871 6 /* And we are done processing options. */
872 6 break;
873 6 } else {
874 6 /* All other options have a length field, so that we easily
875 6 can skip past them. */
876 6 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
877 7 /* If the length field is zero, the options are malformed
878 7 and we don't process them further. */
879 7 break;
880 7 }
881 6 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
882 6 }
883 5 }
884 4 }
885 3 uip_connr->tcpstateflags = ESTABLISHED;
886 3 uip_connr->rcv_nxt[0] = BUF->seqno[0];
887 3 uip_connr->rcv_nxt[1] = BUF->seqno[1];
888 3 uip_connr->rcv_nxt[2] = BUF->seqno[2];
889 3 uip_connr->rcv_nxt[3] = BUF->seqno[3];
890 3 uip_add_rcv_nxt(1);
891 3 uip_flags = UIP_CONNECTED | UIP_NEWDATA;
892 3 uip_connr->len = 0;
893 3 uip_len = 0;
894 3 uip_slen = 0;
895 3 UIP_APPCALL();
896 3 goto appsend;
897 3 }
898 2 goto reset;
899 2 #endif /* UIP_ACTIVE_OPEN */
900 2
901 2 case ESTABLISHED:
902 2 /* In the ESTABLISHED state, we call upon the application to feed
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -