📄 uip.lst
字号:
801 1 BUF->tcpoffset = 5 << 4;
802 1
803 1 /* Flip the seqno and ackno fields in the TCP header. */
804 1 c = BUF->seqno[3];
805 1 BUF->seqno[3] = BUF->ackno[3];
806 1 BUF->ackno[3] = c;
807 1
808 1 c = BUF->seqno[2];
809 1 BUF->seqno[2] = BUF->ackno[2];
810 1 BUF->ackno[2] = c;
811 1
812 1 c = BUF->seqno[1];
813 1 BUF->seqno[1] = BUF->ackno[1];
814 1 BUF->ackno[1] = c;
815 1
816 1 c = BUF->seqno[0];
817 1 BUF->seqno[0] = BUF->ackno[0];
818 1 BUF->ackno[0] = c;
819 1
820 1 /* We also have to increase the sequence number we are
821 1 acknowledging. If the least significant byte overflowed, we need
822 1 to propagate the carry to the other bytes as well. */
823 1 if(++BUF->ackno[3] == 0) {
824 2 if(++BUF->ackno[2] == 0) {
825 3 if(++BUF->ackno[1] == 0) {
826 4 ++BUF->ackno[0];
827 4 }
828 3 }
829 2 }
830 1
831 1 /* Swap port numbers. */
832 1 tmp16 = BUF->srcport;
833 1 BUF->srcport = BUF->destport;
834 1 BUF->destport = tmp16;
835 1
836 1 /* Swap IP addresses. */
837 1 tmp16 = BUF->destipaddr[0];
838 1 BUF->destipaddr[0] = BUF->srcipaddr[0];
839 1 BUF->srcipaddr[0] = tmp16;
840 1 tmp16 = BUF->destipaddr[1];
841 1 BUF->destipaddr[1] = BUF->srcipaddr[1];
842 1 BUF->srcipaddr[1] = tmp16;
843 1
844 1
845 1 /* And send out the RST packet! */
846 1 goto tcp_send_noconn;
847 1
848 1 /* This label will be jumped to if we matched the incoming packet
849 1 with a connection in LISTEN. In that case, we should create a new
850 1 connection and send a SYNACK in return. */
851 1 found_listen:
852 1 /* First we check if there are any connections avaliable. Unused
853 1 connections are kept in the same table as used connections, but
854 1 unused ones have the tcpstate set to CLOSED. Also, connections in
855 1 TIME_WAIT are kept track of and we'll use the oldest one if no
856 1 CLOSED connections are found. Thanks to Eddie C. Dost for a very
857 1 nice algorithm for the TIME_WAIT search. */
858 1 uip_connr = -1; // 8051 starts at 0x0000
859 1 for(c = 0; c < UIP_CONNS; ++c) {
C51 COMPILER V8.02 UIP 10/28/2008 15:31:45 PAGE 15
860 2 if(uip_conns[c].tcpstateflags == CLOSED) {
861 3 uip_connr = &uip_conns[c];
862 3 break;
863 3 }
864 2 if(uip_conns[c].tcpstateflags == TIME_WAIT) {
865 3 if(uip_connr == 0 ||
866 3 uip_conns[c].timer > uip_connr->timer) {
867 4 uip_connr = &uip_conns[c];
868 4 }
869 3 }
870 2 }
871 1
872 1 if(uip_connr == -1) { // 8051 starts at 0x0000
873 2 /* All connections are used already, we drop packet and hope that
874 2 the remote end will retransmit the packet at a time when we
875 2 have more spare connections. */
876 2 UIP_STAT(++uip_stat.tcp.syndrop);
877 2 UIP_LOG("tcp: found no unused connections.");
878 2 goto drop;
879 2 }
880 1 uip_conn = uip_connr;
881 1
882 1 /* Fill in the necessary fields for the new connection. */
883 1 uip_connr->rto = uip_connr->timer = UIP_RTO;
884 1 uip_connr->sa = 0;
885 1 uip_connr->sv = 4;
886 1 uip_connr->nrtx = 0;
887 1 uip_connr->lport = BUF->destport;
888 1 uip_connr->rport = BUF->srcport;
889 1 uip_connr->ripaddr[0] = BUF->srcipaddr[0];
890 1 uip_connr->ripaddr[1] = BUF->srcipaddr[1];
891 1 uip_connr->tcpstateflags = SYN_RCVD;
892 1
893 1 uip_connr->snd_nxt[0] = iss[0];
894 1 uip_connr->snd_nxt[1] = iss[1];
895 1 uip_connr->snd_nxt[2] = iss[2];
896 1 uip_connr->snd_nxt[3] = iss[3];
897 1 uip_connr->len = 1;
898 1
899 1 /* rcv_nxt should be the seqno from the incoming packet + 1. */
900 1 uip_connr->rcv_nxt[3] = BUF->seqno[3];
901 1 uip_connr->rcv_nxt[2] = BUF->seqno[2];
902 1 uip_connr->rcv_nxt[1] = BUF->seqno[1];
903 1 uip_connr->rcv_nxt[0] = BUF->seqno[0];
904 1 uip_add_rcv_nxt(1);
905 1
906 1 /* Parse the TCP MSS option, if present. */
907 1 if((BUF->tcpoffset & 0xf0) > 0x50) {
908 2 for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
909 3 opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
910 3 if(opt == 0x00) {
911 4 /* End of options. */
912 4 break;
913 4 } else if(opt == 0x01) {
914 4 ++c;
915 4 /* NOP option. */
916 4 } else if(opt == 0x02 &&
917 3 uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
918 4 /* An MSS option with the right option length. */
919 4 tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
920 4 (u16_t)uip_buf[40 + UIP_LLH_LEN + 3 + c];
921 4 uip_connr->initialmss = uip_connr->mss =
C51 COMPILER V8.02 UIP 10/28/2008 15:31:45 PAGE 16
922 4 tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
923 4
924 4 /* And we are done processing options. */
925 4 break;
926 4 } else {
927 4 /* All other options have a length field, so that we easily
928 4 can skip past them. */
929 4 if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
930 5 /* If the length field is zero, the options are malformed
931 5 and we don't process them further. */
932 5 break;
933 5 }
934 4 c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
935 4 }
936 3 }
937 2 }
938 1
939 1 /* Our response will be a SYNACK. */
940 1 #if UIP_ACTIVE_OPEN
tcp_send_synack:
BUF->flags = TCP_ACK;
tcp_send_syn:
BUF->flags |= TCP_SYN;
#else /* UIP_ACTIVE_OPEN */
947 1 tcp_send_synack:
948 1 BUF->flags = TCP_SYN | TCP_ACK;
949 1 #endif /* UIP_ACTIVE_OPEN */
950 1
951 1 /* We send out the TCP Maximum Segment Size option with our
952 1 SYNACK. */
953 1 BUF->optdata[0] = 2;
954 1 BUF->optdata[1] = 4;
955 1 BUF->optdata[2] = (UIP_TCP_MSS) / 256;
956 1 BUF->optdata[3] = (UIP_TCP_MSS) & 255;
957 1 uip_len = 44;
958 1 BUF->tcpoffset = 6 << 4;
959 1 goto tcp_send;
960 1
961 1 /* This label will be jumped to if we found an active connection. */
962 1 found:
963 1 uip_conn = uip_connr;
964 1 uip_flags = 0;
965 1
966 1 /* We do a very naive form of TCP reset processing; we just accept
967 1 any RST and kill our connection. We should in fact check if the
968 1 sequence number of this reset is wihtin our advertised window
969 1 before we accept the reset. */
970 1 if(BUF->flags & TCP_RST) {
971 2 uip_connr->tcpstateflags = CLOSED;
972 2 UIP_LOG("tcp: got reset, aborting connection.");
973 2 uip_flags = UIP_ABORT;
974 2 UIP_APPCALL();
975 2 goto drop;
976 2 }
977 1 /* Calculated the length of the data, if the application has sent
978 1 any data to us. */
979 1 c = (BUF->tcpoffset >> 4) << 2;
980 1 /* uip_len will contain the length of the actual TCP data. This is
981 1 calculated by subtracing the length of the TCP header (in
982 1 c) and the length of the IP header (20 bytes). */
983 1 uip_len = uip_len - c - 20;
C51 COMPILER V8.02 UIP 10/28/2008 15:31:45 PAGE 17
984 1
985 1 /* First, check if the sequence number of the incoming packet is
986 1 what we're expecting next. If not, we send out an ACK with the
987 1 correct numbers in. */
988 1 if(uip_len > 0 &&
989 1 (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
990 1 BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
991 1 BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
992 1 BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
993 2 goto tcp_send_ack;
994 2 }
995 1
996 1 /* Next, check if the incoming segment acknowledges any outstanding
997 1 data. If so, we update the sequence number, reset the length of
998 1 the outstanding data, calculate RTT estimations, and reset the
999 1 retransmission timer. */
1000 1 if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
1001 2 uip_add32(uip_connr->snd_nxt, uip_connr->len);
1002 2 if(BUF->ackno[0] == uip_acc32[0] &&
1003 2 BUF->ackno[1] == uip_acc32[1] &&
1004 2 BUF->ackno[2] == uip_acc32[2] &&
1005 2 BUF->ackno[3] == uip_acc32[3]) {
1006 3 /* Update sequence number. */
1007 3 uip_connr->snd_nxt[0] = uip_acc32[0];
1008 3 uip_connr->snd_nxt[1] = uip_acc32[1];
1009 3 uip_connr->snd_nxt[2] = uip_acc32[2];
1010 3 uip_connr->snd_nxt[3] = uip_acc32[3];
1011 3
1012 3
1013 3 /* Do RTT estimation, unless we have done retransmissions. */
1014 3 if(uip_connr->nrtx == 0) {
1015 4 signed char m;
1016 4 m = uip_connr->rto - uip_connr->timer;
1017 4 /* This is taken directly from VJs original code in his paper */
1018 4 m = m - (uip_connr->sa >> 3);
1019 4 uip_connr->sa += m;
1020 4 if(m < 0) {
1021 5 m = -m;
1022 5 }
1023 4 m = m - (uip_connr->sv >> 2);
1024 4 uip_connr->sv += m;
1025 4 uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
1026 4
1027 4 }
1028 3 /* Set the acknowledged flag. */
1029 3 uip_flags = UIP_ACKDATA;
1030 3 /* Reset the retransmission timer. */
1031 3 uip_connr->timer = uip_connr->rto;
1032 3 }
1033 2
1034 2 }
1035 1
1036 1 /* Do different things depending on in what state the connection is. */
1037 1 switch(uip_connr->tcpstateflags & TS_MASK) {
1038 2 /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
1039 2 implemented, since we force the application to close when the
1040 2 peer sends a FIN (hence the application goes directly from
1041 2 ESTABLISHED to LAST_ACK). */
1042 2 case SYN_RCVD:
1043 2 /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
1044 2 we are waiting for an ACK that acknowledges the data we sent
1045 2 out the last time. Therefore, we want to have the UIP_ACKDATA
C51 COMPILER V8.02 UIP 10/28/2008 15:31:45 PAGE 18
1046 2 flag set. If so, we enter the ESTABLISHED state. */
1047 2 if(uip_flags & UIP_ACKDATA) {
1048 3 uip_connr->tcpstateflags = ESTABLISHED;
1049 3 uip_flags = UIP_CONNECTED;
1050 3 uip_connr->len = 0;
1051 3 if(uip_len > 0) {
1052 4 uip_flags |= UIP_NEWDATA;
1053 4 uip_add_rcv_nxt(uip_len);
1054 4 }
1055 3 uip_slen = 0;
1056 3 UIP_APPCALL();
1057 3 goto appsend;
1058 3 }
1059 2 goto drop;
1060 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 ;) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -