📄 uip.lst
字号:
1064 1 /* Calculated the length of the data, if the application has sent
1065 1 any data to us. */
1066 1 c = (BUF->tcpoffset >> 4) << 2;
1067 1 /* uip_len will contain the length of the actual TCP data. This is
1068 1 calculated by subtracing the length of the TCP header (in
1069 1 c) and the length of the IP header (20 bytes). */
1070 1 uip_len = uip_len - c - 20;
1071 1
1072 1 /* First, check if the sequence number of the incoming packet is
1073 1 what we're expecting next. If not, we send out an ACK with the
1074 1 correct numbers in. */
1075 1 if(uip_len > 0 &&
1076 1 (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
1077 1 BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
1078 1 BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
1079 1 BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
1080 2 goto tcp_send_ack;
1081 2 }
1082 1
1083 1 /* Next, check if the incoming segment acknowledges any outstanding
1084 1 data. If so, we update the sequence number, reset the length of
1085 1 the outstanding data, calculate RTT estimations, and reset the
1086 1 retransmission timer. */
1087 1 if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
1088 2 uip_add32(uip_connr->snd_nxt, uip_connr->len);
1089 2 if(BUF->ackno[0] == uip_acc32[0] &&
1090 2 BUF->ackno[1] == uip_acc32[1] &&
1091 2 BUF->ackno[2] == uip_acc32[2] &&
1092 2 BUF->ackno[3] == uip_acc32[3]) {
1093 3 /* Update sequence number. */
1094 3 uip_connr->snd_nxt[0] = uip_acc32[0];
1095 3 uip_connr->snd_nxt[1] = uip_acc32[1];
1096 3 uip_connr->snd_nxt[2] = uip_acc32[2];
1097 3 uip_connr->snd_nxt[3] = uip_acc32[3];
1098 3
1099 3
1100 3 /* Do RTT estimation, unless we have done retransmissions. */
1101 3 if(uip_connr->nrtx == 0) {
1102 4 signed char m;
1103 4 m = uip_connr->rto - uip_connr->timer;
1104 4 /* This is taken directly from VJs original code in his paper */
1105 4 m = m - (uip_connr->sa >> 3);
1106 4 uip_connr->sa += m;
1107 4 if(m < 0) {
C51 COMPILER V8.15 UIP 08/11/2009 15:07:52 PAGE 19
1108 5 m = -m;
1109 5 }
1110 4 m = m - (uip_connr->sv >> 2);
1111 4 uip_connr->sv += m;
1112 4 uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
1113 4
1114 4 }
1115 3 /* Set the acknowledged flag. */
1116 3 uip_flags = UIP_ACKDATA;
1117 3 /* Reset the retransmission timer. */
1118 3 uip_connr->timer = uip_connr->rto;
1119 3 }
1120 2
1121 2 }
1122 1
1123 1 /* Do different things depending on in what state the connection is. */
1124 1 switch(uip_connr->tcpstateflags & TS_MASK) {
1125 2 /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
1126 2 implemented, since we force the application to close when the
1127 2 peer sends a FIN (hence the application goes directly from
1128 2 ESTABLISHED to LAST_ACK). */
1129 2 case SYN_RCVD:
1130 2 /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
1131 2 we are waiting for an ACK that acknowledges the data we sent
1132 2 out the last time. Therefore, we want to have the UIP_ACKDATA
1133 2 flag set. If so, we enter the ESTABLISHED state. */
1134 2 if(uip_flags & UIP_ACKDATA) {
1135 3 uip_connr->tcpstateflags = ESTABLISHED;
1136 3 uip_flags = UIP_CONNECTED;
1137 3 uip_connr->len = 0;
1138 3 if(uip_len > 0) {
1139 4 uip_flags |= UIP_NEWDATA;
1140 4 uip_add_rcv_nxt(uip_len);
1141 4 }
1142 3 uip_slen = 0;
1143 3 UIP_APPCALL();
1144 3 goto appsend;
1145 3 }
1146 2 goto drop;
1147 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[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0x04) {
/* An MSS option with the right option length. */
tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
C51 COMPILER V8.15 UIP 08/11/2009 15:07:52 PAGE 20
uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
uip_connr->initialmss =
uip_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(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
/* If the length field is zero, the options are malformed
and we don't process them further. */
break;
}
c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
}
}
}
uip_connr->tcpstateflags = ESTABLISHED;
uip_connr->rcv_nxt[0] = BUF->seqno[0];
uip_connr->rcv_nxt[1] = BUF->seqno[1];
uip_connr->rcv_nxt[2] = BUF->seqno[2];
uip_connr->rcv_nxt[3] = BUF->seqno[3];
uip_add_rcv_nxt(1);
uip_flags = UIP_CONNECTED | UIP_NEWDATA;
uip_connr->len = 0;
uip_len = 0;
uip_slen = 0;
UIP_APPCALL();
goto appsend;
}
goto reset;
#endif /* UIP_ACTIVE_OPEN */
1203 2
1204 2 case ESTABLISHED:
1205 2 /* In the ESTABLISHED state, we call upon the application to feed
1206 2 data into the uip_buf. If the UIP_ACKDATA flag is set, the
1207 2 application should put new data into the buffer, otherwise we are
1208 2 retransmitting an old segment, and the application should put that
1209 2 data into the buffer.
1210 2
1211 2 If the incoming packet is a FIN, we should close the connection on
1212 2 this side as well, and we send out a FIN and enter the LAST_ACK
1213 2 state. We require that there is no outstanding data; otherwise the
1214 2 sequence numbers will be screwed up. */
1215 2
1216 2 if(BUF->flags & TCP_FIN) {
1217 3 if(uip_outstanding(uip_connr)) {
1218 4 goto drop;
1219 4 }
1220 3 uip_add_rcv_nxt(1 + uip_len);
1221 3 uip_flags = UIP_CLOSE;
1222 3 if(uip_len > 0) {
1223 4 uip_flags |= UIP_NEWDATA;
1224 4 }
1225 3 UIP_APPCALL();
1226 3 uip_connr->len = 1;
1227 3 uip_connr->tcpstateflags = LAST_ACK;
1228 3 uip_connr->nrtx = 0;
1229 3 tcp_send_finack:
1230 3 BUF->flags = TCP_FIN | TCP_ACK;
1231 3 goto tcp_send_nodata;
C51 COMPILER V8.15 UIP 08/11/2009 15:07:52 PAGE 21
1232 3 }
1233 2
1234 2 /* Check the URG flag. If this is set, the segment carries urgent
1235 2 data that we must pass to the application. */
1236 2 if(BUF->flags & TCP_URG) {
1237 3 #if UIP_URGDATA > 0
1238 3 uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
1239 3 if(uip_urglen > uip_len) {
1240 4 /* There is more urgent data in the next segment to come. */
1241 4 uip_urglen = uip_len;
1242 4 }
1243 3 uip_add_rcv_nxt(uip_urglen);
1244 3 uip_len -= uip_urglen;
1245 3 uip_urgdata = uip_appdata;
1246 3 uip_appdata += uip_urglen;
1247 3 } else {
1248 3 uip_urglen = 0;
1249 3 #endif /* UIP_URGDATA > 0 */
1250 3 uip_appdata += (BUF->urgp[0] << 8) | BUF->urgp[1];
1251 3 uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
1252 3 }
1253 2
1254 2
1255 2 /* If uip_len > 0 we have TCP data in the packet, and we flag this
1256 2 by setting the UIP_NEWDATA flag and update the sequence number
1257 2 we acknowledge. If the application has stopped the dataflow
1258 2 using uip_stop(), we must not accept any data packets from the
1259 2 remote host. */
1260 2 if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
1261 3 uip_flags |= UIP_NEWDATA;
1262 3 uip_add_rcv_nxt(uip_len);
1263 3 }
1264 2
1265 2 /* Check if the available buffer space advertised by the other end
1266 2 is smaller than the initial MSS for this connection. If so, we
1267 2 set the current MSS to the window size to ensure that the
1268 2 application does not send more data than the other end can
1269 2 handle.
1270 2
1271 2 If the remote host advertises a zero window, we set the MSS to
1272 2 the initial MSS so that the application will send an entire MSS
1273 2 of data. This data will not be acknowledged by the receiver,
1274 2 and the application will retransmit it. This is called the
1275 2 "persistent timer" and uses the retransmission mechanim.
1276 2 */
1277 2 tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1];
1278 2 if(tmp16 > uip_connr->initialmss ||
1279 2 tmp16 == 0) {
1280 3 tmp16 = uip_connr->initialmss;
1281 3 }
1282 2 uip_connr->mss = tmp16;
1283 2
1284 2 /* If this packet constitutes an ACK for outstanding data (flagged
1285 2 by the UIP_ACKDATA flag, we should call the application since it
1286 2 might want to send more data. If the incoming packet had data
1287 2 from the peer (as flagged by the UIP_NEWDATA flag), the
1288 2 application must also be notified.
1289 2
1290 2 When the application is called, the global variable uip_len
1291 2 contains the length of the incoming data. The application can
1292 2 access the incoming data through the global pointer
1293 2 uip_appdata, which usually points 40 bytes into the uip_buf
C51 COMPILER V8.15 UIP 08/11/2009 15:07:52 PAGE 22
1294 2 array.
1295 2
1296 2 If the application wishes to send any data, this data should be
1297 2 put into the uip_appdata and the length of the data should be
1298 2 put into uip_len. If the application don't have any data to
1299 2 send, uip_len must be set to 0. */
1300 2 if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
1301 3 uip_slen = 0;
1302 3
1303 3
1304 3 UIP_APPCALL();
1305 3
1306 3 appsend:
1307 3
1308 3 if(uip_flags & UIP_ABORT) {
1309 4 uip_slen = 0;
1310 4 uip_connr->tcpstateflags = CLOSED;
1311 4 BUF->flags = TCP_RST | TCP_ACK;
1312 4 goto tcp_send_nodata;
1313 4 }
1314 3
1315 3 if(uip_flags & UIP_CLOSE) {
1316 4 uip_slen = 0;
1317 4 uip_connr->len = 1;
1318 4 uip_connr->tcpstateflags = FIN_WAIT_1;
1319 4 uip_connr->nrtx = 0;
1320 4 BUF->flags = TCP_FIN | TCP_ACK;
1321 4 goto tcp_send_nodata;
1322 4 }
1323 3
1324 3 /* If uip_slen > 0, the application has data to be sent. */
1325 3 if(uip_slen > 0) {
1326 4
1327 4 /* If the connection has acknowledged data, the contents of
13
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -