Revision 3b46e624 slirp/tcp_input.c
b/slirp/tcp_input.c | ||
---|---|---|
262 | 262 |
*/ |
263 | 263 |
if (m == NULL) { |
264 | 264 |
so = inso; |
265 |
|
|
265 |
|
|
266 | 266 |
/* Re-set a few variables */ |
267 | 267 |
tp = sototcpcb(so); |
268 | 268 |
m = so->so_m; |
... | ... | |
270 | 270 |
ti = so->so_ti; |
271 | 271 |
tiwin = ti->ti_win; |
272 | 272 |
tiflags = ti->ti_flags; |
273 |
|
|
273 |
|
|
274 | 274 |
goto cont_conn; |
275 | 275 |
} |
276 | 276 |
|
... | ... | |
394 | 394 |
if (so == 0) { |
395 | 395 |
if ((tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) != TH_SYN) |
396 | 396 |
goto dropwithreset; |
397 |
|
|
397 |
|
|
398 | 398 |
if ((so = socreate()) == NULL) |
399 | 399 |
goto dropwithreset; |
400 | 400 |
if (tcp_attach(so) < 0) { |
401 | 401 |
free(so); /* Not sofree (if it failed, it's not insqued) */ |
402 | 402 |
goto dropwithreset; |
403 | 403 |
} |
404 |
|
|
404 |
|
|
405 | 405 |
sbreserve(&so->so_snd, tcp_sndspace); |
406 | 406 |
sbreserve(&so->so_rcv, tcp_rcvspace); |
407 |
|
|
407 |
|
|
408 | 408 |
/* tcp_last_so = so; */ /* XXX ? */ |
409 | 409 |
/* tp = sototcpcb(so); */ |
410 |
|
|
410 |
|
|
411 | 411 |
so->so_laddr = ti->ti_src; |
412 | 412 |
so->so_lport = ti->ti_sport; |
413 | 413 |
so->so_faddr = ti->ti_dst; |
414 | 414 |
so->so_fport = ti->ti_dport; |
415 |
|
|
415 |
|
|
416 | 416 |
if ((so->so_iptos = tcp_tos(so)) == 0) |
417 | 417 |
so->so_iptos = ((struct ip *)ti)->ip_tos; |
418 |
|
|
418 |
|
|
419 | 419 |
tp = sototcpcb(so); |
420 | 420 |
tp->t_state = TCPS_LISTEN; |
421 | 421 |
} |
422 |
|
|
422 |
|
|
423 | 423 |
/* |
424 | 424 |
* If this is a still-connecting socket, this probably |
425 | 425 |
* a retransmit of the SYN. Whether it's a retransmit SYN |
... | ... | |
567 | 567 |
if (tcp_emu(so,m)) sbappend(so, m); |
568 | 568 |
} else |
569 | 569 |
sbappend(so, m); |
570 |
|
|
570 |
|
|
571 | 571 |
/* |
572 | 572 |
* XXX This is called when data arrives. Later, check |
573 | 573 |
* if we can actually write() to the socket |
574 | 574 |
* XXX Need to check? It's be NON_BLOCKING |
575 | 575 |
*/ |
576 | 576 |
/* sorwakeup(so); */ |
577 |
|
|
577 |
|
|
578 | 578 |
/* |
579 | 579 |
* If this is a short packet, then ACK now - with Nagel |
580 | 580 |
* congestion avoidance sender won't send more until |
... | ... | |
624 | 624 |
goto dropwithreset; |
625 | 625 |
if ((tiflags & TH_SYN) == 0) |
626 | 626 |
goto drop; |
627 |
|
|
627 |
|
|
628 | 628 |
/* |
629 | 629 |
* This has way too many gotos... |
630 | 630 |
* But a bit of spaghetti code never hurt anybody :) |
631 | 631 |
*/ |
632 |
|
|
632 |
|
|
633 | 633 |
/* |
634 | 634 |
* If this is destined for the control address, then flag to |
635 | 635 |
* tcp_ctl once connected, otherwise connect |
... | ... | |
658 | 658 |
} |
659 | 659 |
/* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */ |
660 | 660 |
} |
661 |
|
|
661 |
|
|
662 | 662 |
if (so->so_emu & EMU_NOCONNECT) { |
663 | 663 |
so->so_emu &= ~EMU_NOCONNECT; |
664 | 664 |
goto cont_input; |
665 | 665 |
} |
666 |
|
|
666 |
|
|
667 | 667 |
if((tcp_fconnect(so) == -1) && (errno != EINPROGRESS) && (errno != EWOULDBLOCK)) { |
668 | 668 |
u_char code=ICMP_UNREACH_NET; |
669 | 669 |
DEBUG_MISC((dfd," tcp fconnect errno = %d-%s\n", |
... | ... | |
699 | 699 |
} |
700 | 700 |
return; |
701 | 701 |
|
702 |
cont_conn:
|
|
702 |
cont_conn: |
|
703 | 703 |
/* m==NULL |
704 | 704 |
* Check if the connect succeeded |
705 | 705 |
*/ |
... | ... | |
707 | 707 |
tp = tcp_close(tp); |
708 | 708 |
goto dropwithreset; |
709 | 709 |
} |
710 |
cont_input:
|
|
710 |
cont_input: |
|
711 | 711 |
tcp_template(tp); |
712 |
|
|
712 |
|
|
713 | 713 |
if (optp) |
714 | 714 |
tcp_dooptions(tp, (u_char *)optp, optlen, ti); |
715 | 715 |
/* , */ |
716 | 716 |
/* &ts_present, &ts_val, &ts_ecr); */ |
717 |
|
|
717 |
|
|
718 | 718 |
if (iss) |
719 | 719 |
tp->iss = iss; |
720 | 720 |
else |
... | ... | |
770 | 770 |
tcpstat.tcps_connects++; |
771 | 771 |
soisfconnected(so); |
772 | 772 |
tp->t_state = TCPS_ESTABLISHED; |
773 |
|
|
773 |
|
|
774 | 774 |
/* Do window scaling on this connection? */ |
775 | 775 |
/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == |
776 | 776 |
* (TF_RCVD_SCALE|TF_REQ_SCALE)) { |
... | ... | |
866 | 866 |
* of sequence; drop it. |
867 | 867 |
*/ |
868 | 868 |
tiflags &= ~TH_FIN; |
869 |
|
|
869 |
|
|
870 | 870 |
/* |
871 | 871 |
* Send an ACK to resynchronize and drop any data. |
872 | 872 |
* But keep on processing for RST or ACK. |
... | ... | |
1022 | 1022 |
* The first data byte already in the buffer will get |
1023 | 1023 |
* lost if no correction is made. This is only needed for |
1024 | 1024 |
* SS_CTL since the buffer is empty otherwise. |
1025 |
* tp->snd_una++; or:
|
|
1025 |
* tp->snd_una++; or: |
|
1026 | 1026 |
*/ |
1027 | 1027 |
tp->snd_una=ti->ti_ack; |
1028 | 1028 |
if (so->so_state & SS_CTL) { |
... | ... | |
1040 | 1040 |
} else { |
1041 | 1041 |
soisfconnected(so); |
1042 | 1042 |
} |
1043 |
|
|
1043 |
|
|
1044 | 1044 |
/* Do window scaling? */ |
1045 | 1045 |
/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == |
1046 | 1046 |
* (TF_RCVD_SCALE|TF_REQ_SCALE)) { |
... | ... | |
1159 | 1159 |
/* if (ts_present) |
1160 | 1160 |
* tcp_xmit_timer(tp, tcp_now-ts_ecr+1); |
1161 | 1161 |
* else |
1162 |
*/
|
|
1162 |
*/ |
|
1163 | 1163 |
if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq)) |
1164 | 1164 |
tcp_xmit_timer(tp,tp->t_rtt); |
1165 | 1165 |
|
... | ... | |
1328 | 1328 |
so->so_urgc = so->so_rcv.sb_cc + |
1329 | 1329 |
(tp->rcv_up - tp->rcv_nxt); /* -1; */ |
1330 | 1330 |
tp->rcv_up = ti->ti_seq + ti->ti_urp; |
1331 |
|
|
1331 |
|
|
1332 | 1332 |
} |
1333 | 1333 |
} else |
1334 | 1334 |
/* |
... | ... | |
1379 | 1379 |
*/ |
1380 | 1380 |
/* sofcantrcvmore(so); */ |
1381 | 1381 |
sofwdrain(so); |
1382 |
|
|
1382 |
|
|
1383 | 1383 |
tp->t_flags |= TF_ACKNOW; |
1384 | 1384 |
tp->rcv_nxt++; |
1385 | 1385 |
} |
Also available in: Unified diff