Revision 0d62c4cf slirp/tcp_input.c
b/slirp/tcp_input.c | ||
---|---|---|
81 | 81 |
if (tcp_emu((so),(m))) sbappend((so), (m)); \ |
82 | 82 |
} else \ |
83 | 83 |
sbappend((so), (m)); \ |
84 |
/* sorwakeup(so); */ \ |
|
85 | 84 |
} else {\ |
86 | 85 |
(flags) = tcp_reass((tp), (ti), (m)); \ |
87 | 86 |
tp->t_flags |= TF_ACKNOW; \ |
... | ... | |
101 | 100 |
if (tcp_emu((so),(m))) sbappend(so, (m)); \ |
102 | 101 |
} else \ |
103 | 102 |
sbappend((so), (m)); \ |
104 |
/* sorwakeup(so); */ \ |
|
105 | 103 |
} else { \ |
106 | 104 |
(flags) = tcp_reass((tp), (ti), (m)); \ |
107 | 105 |
tp->t_flags |= TF_ACKNOW; \ |
... | ... | |
211 | 209 |
remque(tcpiphdr2qlink(ti)); |
212 | 210 |
m = ti->ti_mbuf; |
213 | 211 |
ti = tcpiphdr_next(ti); |
214 |
/* if (so->so_state & SS_FCANTRCVMORE) */ |
|
215 | 212 |
if (so->so_state & SS_FCANTSENDMORE) |
216 | 213 |
m_freem(m); |
217 | 214 |
else { |
... | ... | |
221 | 218 |
sbappend(so, m); |
222 | 219 |
} |
223 | 220 |
} while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt); |
224 |
/* sorwakeup(so); */ |
|
225 | 221 |
return (flags); |
226 | 222 |
} |
227 | 223 |
|
... | ... | |
241 | 237 |
register int tiflags; |
242 | 238 |
struct socket *so = NULL; |
243 | 239 |
int todrop, acked, ourfinisacked, needoutput = 0; |
244 |
/* int dropsocket = 0; */ |
|
245 | 240 |
int iss = 0; |
246 | 241 |
u_long tiwin; |
247 | 242 |
int ret; |
248 |
/* int ts_present = 0; */ |
|
249 | 243 |
struct ex_list *ex_ptr; |
250 | 244 |
|
251 | 245 |
DEBUG_CALL("tcp_input"); |
... | ... | |
300 | 294 |
ti->ti_x1 = 0; |
301 | 295 |
ti->ti_len = htons((u_int16_t)tlen); |
302 | 296 |
len = sizeof(struct ip ) + tlen; |
303 |
/* keep checksum for ICMP reply |
|
304 |
* ti->ti_sum = cksum(m, len); |
|
305 |
* if (ti->ti_sum) { */ |
|
306 | 297 |
if(cksum(m, len)) { |
307 | 298 |
STAT(tcpstat.tcps_rcvbadsum++); |
308 | 299 |
goto drop; |
... | ... | |
322 | 313 |
if (off > sizeof (struct tcphdr)) { |
323 | 314 |
optlen = off - sizeof (struct tcphdr); |
324 | 315 |
optp = mtod(m, caddr_t) + sizeof (struct tcpiphdr); |
325 |
|
|
326 |
/* |
|
327 |
* Do quick retrieval of timestamp options ("options |
|
328 |
* prediction?"). If timestamp is the only option and it's |
|
329 |
* formatted as recommended in RFC 1323 appendix A, we |
|
330 |
* quickly get the values now and not bother calling |
|
331 |
* tcp_dooptions(), etc. |
|
332 |
*/ |
|
333 |
/* if ((optlen == TCPOLEN_TSTAMP_APPA || |
|
334 |
* (optlen > TCPOLEN_TSTAMP_APPA && |
|
335 |
* optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) && |
|
336 |
* *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) && |
|
337 |
* (ti->ti_flags & TH_SYN) == 0) { |
|
338 |
* ts_present = 1; |
|
339 |
* ts_val = ntohl(*(u_int32_t *)(optp + 4)); |
|
340 |
* ts_ecr = ntohl(*(u_int32_t *)(optp + 8)); |
|
341 |
* optp = NULL; / * we've parsed the options * / |
|
342 |
* } |
|
343 |
*/ |
|
344 | 316 |
} |
345 | 317 |
tiflags = ti->ti_flags; |
346 | 318 |
|
... | ... | |
411 | 383 |
sbreserve(&so->so_snd, TCP_SNDSPACE); |
412 | 384 |
sbreserve(&so->so_rcv, TCP_RCVSPACE); |
413 | 385 |
|
414 |
/* tcp_last_so = so; */ /* XXX ? */ |
|
415 |
/* tp = sototcpcb(so); */ |
|
416 |
|
|
417 | 386 |
so->so_laddr = ti->ti_src; |
418 | 387 |
so->so_lport = ti->ti_sport; |
419 | 388 |
so->so_faddr = ti->ti_dst; |
... | ... | |
442 | 411 |
if (tp->t_state == TCPS_CLOSED) |
443 | 412 |
goto drop; |
444 | 413 |
|
445 |
/* Unscale the window into a 32-bit value. */ |
|
446 |
/* if ((tiflags & TH_SYN) == 0) |
|
447 |
* tiwin = ti->ti_win << tp->snd_scale; |
|
448 |
* else |
|
449 |
*/ |
|
450 |
tiwin = ti->ti_win; |
|
414 |
tiwin = ti->ti_win; |
|
451 | 415 |
|
452 | 416 |
/* |
453 | 417 |
* Segment received on connection. |
... | ... | |
465 | 429 |
*/ |
466 | 430 |
if (optp && tp->t_state != TCPS_LISTEN) |
467 | 431 |
tcp_dooptions(tp, (u_char *)optp, optlen, ti); |
468 |
/* , */ |
|
469 |
/* &ts_present, &ts_val, &ts_ecr); */ |
|
470 | 432 |
|
471 | 433 |
/* |
472 | 434 |
* Header prediction: check for the two common cases |
... | ... | |
488 | 450 |
*/ |
489 | 451 |
if (tp->t_state == TCPS_ESTABLISHED && |
490 | 452 |
(tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) == TH_ACK && |
491 |
/* (!ts_present || TSTMP_GEQ(ts_val, tp->ts_recent)) && */ |
|
492 | 453 |
ti->ti_seq == tp->rcv_nxt && |
493 | 454 |
tiwin && tiwin == tp->snd_wnd && |
494 | 455 |
tp->snd_nxt == tp->snd_max) { |
495 |
/* |
|
496 |
* If last ACK falls within this segment's sequence numbers, |
|
497 |
* record the timestamp. |
|
498 |
*/ |
|
499 |
/* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && |
|
500 |
* SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len)) { |
|
501 |
* tp->ts_recent_age = tcp_now; |
|
502 |
* tp->ts_recent = ts_val; |
|
503 |
* } |
|
504 |
*/ |
|
505 | 456 |
if (ti->ti_len == 0) { |
506 | 457 |
if (SEQ_GT(ti->ti_ack, tp->snd_una) && |
507 | 458 |
SEQ_LEQ(ti->ti_ack, tp->snd_max) && |
... | ... | |
510 | 461 |
* this is a pure ack for outstanding data. |
511 | 462 |
*/ |
512 | 463 |
STAT(tcpstat.tcps_predack++); |
513 |
/* if (ts_present) |
|
514 |
* tcp_xmit_timer(tp, tcp_now-ts_ecr+1); |
|
515 |
* else |
|
516 |
*/ if (tp->t_rtt && |
|
517 |
SEQ_GT(ti->ti_ack, tp->t_rtseq)) |
|
464 |
if (tp->t_rtt && |
|
465 |
SEQ_GT(ti->ti_ack, tp->t_rtseq)) |
|
518 | 466 |
tcp_xmit_timer(tp, tp->t_rtt); |
519 | 467 |
acked = ti->ti_ack - tp->snd_una; |
520 | 468 |
STAT(tcpstat.tcps_rcvackpack++); |
... | ... | |
538 | 486 |
tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; |
539 | 487 |
|
540 | 488 |
/* |
541 |
* There's room in so_snd, sowwakup will read() |
|
542 |
* from the socket if we can |
|
543 |
*/ |
|
544 |
/* if (so->so_snd.sb_flags & SB_NOTIFY) |
|
545 |
* sowwakeup(so); |
|
546 |
*/ |
|
547 |
/* |
|
548 | 489 |
* This is called because sowwakeup might have |
549 | 490 |
* put data into so_snd. Since we don't so sowwakeup, |
550 | 491 |
* we don't need this.. XXX??? |
... | ... | |
575 | 516 |
sbappend(so, m); |
576 | 517 |
|
577 | 518 |
/* |
578 |
* XXX This is called when data arrives. Later, check |
|
579 |
* if we can actually write() to the socket |
|
580 |
* XXX Need to check? It's be NON_BLOCKING |
|
581 |
*/ |
|
582 |
/* sorwakeup(so); */ |
|
583 |
|
|
584 |
/* |
|
585 | 519 |
* If this is a short packet, then ACK now - with Nagel |
586 | 520 |
* congestion avoidance sender won't send more until |
587 | 521 |
* he gets an ACK. |
... | ... | |
644 | 578 |
vnetwork_addr.s_addr) { |
645 | 579 |
if (so->so_faddr.s_addr != vhost_addr.s_addr && |
646 | 580 |
so->so_faddr.s_addr != vnameserver_addr.s_addr) { |
647 |
#if 0 |
|
648 |
if(lastbyte==CTL_CMD || lastbyte==CTL_EXEC) { |
|
649 |
/* Command or exec adress */ |
|
650 |
so->so_state |= SS_CTL; |
|
651 |
} else |
|
652 |
#endif |
|
653 |
{ |
|
654 | 581 |
/* May be an add exec */ |
655 | 582 |
for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { |
656 | 583 |
if(ex_ptr->ex_fport == so->so_fport && |
... | ... | |
659 | 586 |
break; |
660 | 587 |
} |
661 | 588 |
} |
662 |
} |
|
663 |
if(so->so_state & SS_CTL) goto cont_input; |
|
589 |
if (so->so_state & SS_CTL) { |
|
590 |
goto cont_input; |
|
591 |
} |
|
664 | 592 |
} |
665 | 593 |
/* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */ |
666 | 594 |
} |
... | ... | |
718 | 646 |
|
719 | 647 |
if (optp) |
720 | 648 |
tcp_dooptions(tp, (u_char *)optp, optlen, ti); |
721 |
/* , */ |
|
722 |
/* &ts_present, &ts_val, &ts_ecr); */ |
|
723 | 649 |
|
724 | 650 |
if (iss) |
725 | 651 |
tp->iss = iss; |
... | ... | |
777 | 703 |
soisfconnected(so); |
778 | 704 |
tp->t_state = TCPS_ESTABLISHED; |
779 | 705 |
|
780 |
/* Do window scaling on this connection? */ |
|
781 |
/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == |
|
782 |
* (TF_RCVD_SCALE|TF_REQ_SCALE)) { |
|
783 |
* tp->snd_scale = tp->requested_s_scale; |
|
784 |
* tp->rcv_scale = tp->request_r_scale; |
|
785 |
* } |
|
786 |
*/ |
|
787 | 706 |
(void) tcp_reass(tp, (struct tcpiphdr *)0, |
788 | 707 |
(struct mbuf *)0); |
789 | 708 |
/* |
... | ... | |
816 | 735 |
} /* switch tp->t_state */ |
817 | 736 |
/* |
818 | 737 |
* States other than LISTEN or SYN_SENT. |
819 |
* First check timestamp, if present. |
|
820 |
* Then check that at least some bytes of segment are within |
|
738 |
* Check that at least some bytes of segment are within |
|
821 | 739 |
* receive window. If segment begins before rcv_nxt, |
822 | 740 |
* drop leading data (and SYN); if nothing left, just ack. |
823 |
* |
|
824 |
* RFC 1323 PAWS: If we have a timestamp reply on this segment |
|
825 |
* and it's less than ts_recent, drop it. |
|
826 | 741 |
*/ |
827 |
/* if (ts_present && (tiflags & TH_RST) == 0 && tp->ts_recent && |
|
828 |
* TSTMP_LT(ts_val, tp->ts_recent)) { |
|
829 |
* |
|
830 |
*/ /* Check to see if ts_recent is over 24 days old. */ |
|
831 |
/* if ((int)(tcp_now - tp->ts_recent_age) > TCP_PAWS_IDLE) { |
|
832 |
*/ /* |
|
833 |
* * Invalidate ts_recent. If this segment updates |
|
834 |
* * ts_recent, the age will be reset later and ts_recent |
|
835 |
* * will get a valid value. If it does not, setting |
|
836 |
* * ts_recent to zero will at least satisfy the |
|
837 |
* * requirement that zero be placed in the timestamp |
|
838 |
* * echo reply when ts_recent isn't valid. The |
|
839 |
* * age isn't reset until we get a valid ts_recent |
|
840 |
* * because we don't want out-of-order segments to be |
|
841 |
* * dropped when ts_recent is old. |
|
842 |
* */ |
|
843 |
/* tp->ts_recent = 0; |
|
844 |
* } else { |
|
845 |
* tcpstat.tcps_rcvduppack++; |
|
846 |
* tcpstat.tcps_rcvdupbyte += ti->ti_len; |
|
847 |
* tcpstat.tcps_pawsdrop++; |
|
848 |
* goto dropafterack; |
|
849 |
* } |
|
850 |
* } |
|
851 |
*/ |
|
852 |
|
|
853 | 742 |
todrop = tp->rcv_nxt - ti->ti_seq; |
854 | 743 |
if (todrop > 0) { |
855 | 744 |
if (tiflags & TH_SYN) { |
... | ... | |
948 | 837 |
} |
949 | 838 |
|
950 | 839 |
/* |
951 |
* If last ACK falls within this segment's sequence numbers, |
|
952 |
* record its timestamp. |
|
953 |
*/ |
|
954 |
/* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && |
|
955 |
* SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len + |
|
956 |
* ((tiflags & (TH_SYN|TH_FIN)) != 0))) { |
|
957 |
* tp->ts_recent_age = tcp_now; |
|
958 |
* tp->ts_recent = ts_val; |
|
959 |
* } |
|
960 |
*/ |
|
961 |
|
|
962 |
/* |
|
963 | 840 |
* If the RST bit is set examine the state: |
964 | 841 |
* SYN_RECEIVED STATE: |
965 | 842 |
* If passive open, return to LISTEN state. |
... | ... | |
972 | 849 |
if (tiflags&TH_RST) switch (tp->t_state) { |
973 | 850 |
|
974 | 851 |
case TCPS_SYN_RECEIVED: |
975 |
/* so->so_error = ECONNREFUSED; */ |
|
976 |
goto close; |
|
977 |
|
|
978 | 852 |
case TCPS_ESTABLISHED: |
979 | 853 |
case TCPS_FIN_WAIT_1: |
980 | 854 |
case TCPS_FIN_WAIT_2: |
981 | 855 |
case TCPS_CLOSE_WAIT: |
982 |
/* so->so_error = ECONNRESET; */ |
|
983 |
close: |
|
984 | 856 |
tp->t_state = TCPS_CLOSED; |
985 | 857 |
STAT(tcpstat.tcps_drops++); |
986 | 858 |
tp = tcp_close(tp); |
... | ... | |
1048 | 920 |
soisfconnected(so); |
1049 | 921 |
} |
1050 | 922 |
|
1051 |
/* Do window scaling? */ |
|
1052 |
/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == |
|
1053 |
* (TF_RCVD_SCALE|TF_REQ_SCALE)) { |
|
1054 |
* tp->snd_scale = tp->requested_s_scale; |
|
1055 |
* tp->rcv_scale = tp->request_r_scale; |
|
1056 |
* } |
|
1057 |
*/ |
|
1058 | 923 |
(void) tcp_reass(tp, (struct tcpiphdr *)0, (struct mbuf *)0); |
1059 | 924 |
tp->snd_wl1 = ti->ti_seq - 1; |
1060 | 925 |
/* Avoid ack processing; snd_una==ti_ack => dup ack */ |
... | ... | |
1155 | 1020 |
STAT(tcpstat.tcps_rcvackbyte += acked); |
1156 | 1021 |
|
1157 | 1022 |
/* |
1158 |
* If we have a timestamp reply, update smoothed |
|
1159 |
* round trip time. If no timestamp is present but |
|
1160 |
* transmit timer is running and timed sequence |
|
1023 |
* If transmit timer is running and timed sequence |
|
1161 | 1024 |
* number was acked, update smoothed round trip time. |
1162 | 1025 |
* Since we now have an rtt measurement, cancel the |
1163 | 1026 |
* timer backoff (cf., Phil Karn's retransmit alg.). |
1164 | 1027 |
* Recompute the initial retransmit timer. |
1165 | 1028 |
*/ |
1166 |
/* if (ts_present) |
|
1167 |
* tcp_xmit_timer(tp, tcp_now-ts_ecr+1); |
|
1168 |
* else |
|
1169 |
*/ |
|
1170 |
if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq)) |
|
1029 |
if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq)) |
|
1171 | 1030 |
tcp_xmit_timer(tp,tp->t_rtt); |
1172 | 1031 |
|
1173 | 1032 |
/* |
... | ... | |
1205 | 1064 |
tp->snd_wnd -= acked; |
1206 | 1065 |
ourfinisacked = 0; |
1207 | 1066 |
} |
1208 |
/* |
|
1209 |
* XXX sowwakup is called when data is acked and there's room for |
|
1210 |
* for more data... it should read() the socket |
|
1211 |
*/ |
|
1212 |
/* if (so->so_snd.sb_flags & SB_NOTIFY) |
|
1213 |
* sowwakeup(so); |
|
1214 |
*/ |
|
1215 | 1067 |
tp->snd_una = ti->ti_ack; |
1216 | 1068 |
if (SEQ_LT(tp->snd_nxt, tp->snd_una)) |
1217 | 1069 |
tp->snd_nxt = tp->snd_una; |
... | ... | |
1233 | 1085 |
* we'll hang forever. |
1234 | 1086 |
*/ |
1235 | 1087 |
if (so->so_state & SS_FCANTRCVMORE) { |
1236 |
soisfdisconnected(so); |
|
1237 | 1088 |
tp->t_timer[TCPT_2MSL] = TCP_MAXIDLE; |
1238 | 1089 |
} |
1239 | 1090 |
tp->t_state = TCPS_FIN_WAIT_2; |
... | ... | |
1251 | 1102 |
tp->t_state = TCPS_TIME_WAIT; |
1252 | 1103 |
tcp_canceltimers(tp); |
1253 | 1104 |
tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; |
1254 |
soisfdisconnected(so); |
|
1255 | 1105 |
} |
1256 | 1106 |
break; |
1257 | 1107 |
|
... | ... | |
1384 | 1234 |
* will got to TCPS_LAST_ACK, and use tcp_output() |
1385 | 1235 |
* to send the FIN. |
1386 | 1236 |
*/ |
1387 |
/* sofcantrcvmore(so); */ |
|
1388 | 1237 |
sofwdrain(so); |
1389 | 1238 |
|
1390 | 1239 |
tp->t_flags |= TF_ACKNOW; |
... | ... | |
1421 | 1270 |
tp->t_state = TCPS_TIME_WAIT; |
1422 | 1271 |
tcp_canceltimers(tp); |
1423 | 1272 |
tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; |
1424 |
soisfdisconnected(so); |
|
1425 | 1273 |
break; |
1426 | 1274 |
|
1427 | 1275 |
/* |
... | ... | |
1440 | 1288 |
* |
1441 | 1289 |
* See above. |
1442 | 1290 |
*/ |
1443 |
/* if (ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg) { |
|
1444 |
*/ |
|
1445 |
/* if ((ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg && |
|
1446 |
* (so->so_iptos & IPTOS_LOWDELAY) == 0) || |
|
1447 |
* ((so->so_iptos & IPTOS_LOWDELAY) && |
|
1448 |
* ((struct tcpiphdr_2 *)ti)->first_char == (char)27)) { |
|
1449 |
*/ |
|
1450 | 1291 |
if (ti->ti_len && (unsigned)ti->ti_len <= 5 && |
1451 | 1292 |
((struct tcpiphdr_2 *)ti)->first_char == (char)27) { |
1452 | 1293 |
tp->t_flags |= TF_ACKNOW; |
... | ... | |
1493 | 1334 |
return; |
1494 | 1335 |
} |
1495 | 1336 |
|
1496 |
/* , ts_present, ts_val, ts_ecr) */ |
|
1497 |
/* int *ts_present; |
|
1498 |
* u_int32_t *ts_val, *ts_ecr; |
|
1499 |
*/ |
|
1500 | 1337 |
static void |
1501 | 1338 |
tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti) |
1502 | 1339 |
{ |
... | ... | |
1531 | 1368 |
NTOHS(mss); |
1532 | 1369 |
(void) tcp_mss(tp, mss); /* sets t_maxseg */ |
1533 | 1370 |
break; |
1534 |
|
|
1535 |
/* case TCPOPT_WINDOW: |
|
1536 |
* if (optlen != TCPOLEN_WINDOW) |
|
1537 |
* continue; |
|
1538 |
* if (!(ti->ti_flags & TH_SYN)) |
|
1539 |
* continue; |
|
1540 |
* tp->t_flags |= TF_RCVD_SCALE; |
|
1541 |
* tp->requested_s_scale = min(cp[2], TCP_MAX_WINSHIFT); |
|
1542 |
* break; |
|
1543 |
*/ |
|
1544 |
/* case TCPOPT_TIMESTAMP: |
|
1545 |
* if (optlen != TCPOLEN_TIMESTAMP) |
|
1546 |
* continue; |
|
1547 |
* *ts_present = 1; |
|
1548 |
* memcpy((char *) ts_val, (char *)cp + 2, sizeof(*ts_val)); |
|
1549 |
* NTOHL(*ts_val); |
|
1550 |
* memcpy((char *) ts_ecr, (char *)cp + 6, sizeof(*ts_ecr)); |
|
1551 |
* NTOHL(*ts_ecr); |
|
1552 |
* |
|
1553 |
*/ /* |
|
1554 |
* * A timestamp received in a SYN makes |
|
1555 |
* * it ok to send timestamp requests and replies. |
|
1556 |
* */ |
|
1557 |
/* if (ti->ti_flags & TH_SYN) { |
|
1558 |
* tp->t_flags |= TF_RCVD_TSTMP; |
|
1559 |
* tp->ts_recent = *ts_val; |
|
1560 |
* tp->ts_recent_age = tcp_now; |
|
1561 |
* } |
|
1562 |
*/ break; |
|
1563 | 1371 |
} |
1564 | 1372 |
} |
1565 | 1373 |
} |
Also available in: Unified diff