diff options
author | 1996-03-03 22:30:24 +0000 | |
---|---|---|
committer | 1996-03-03 22:30:24 +0000 | |
commit | b400e1581cddb46a65450a8de0c05f1c073dfc16 (patch) | |
tree | a3f55afeac650cff86821ceb59869e002564d6d4 /sys/netinet/tcp_input.c | |
parent | From NetBSD: 960217 merge (diff) | |
download | wireguard-openbsd-b400e1581cddb46a65450a8de0c05f1c073dfc16.tar.xz wireguard-openbsd-b400e1581cddb46a65450a8de0c05f1c073dfc16.zip |
From NetBSD: 960217 merge
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r-- | sys/netinet/tcp_input.c | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index b49c0e9defe..9db513df8dd 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4 +1,5 @@ -/* $NetBSD: tcp_input.c,v 1.20 1995/11/21 01:07:39 cgd Exp $ */ +/* $OpenBSD: tcp_input.c,v 1.3 1996/03/03 22:30:45 niklas Exp $ */ +/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */ /* * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994 @@ -61,9 +62,10 @@ #include <netinet/tcpip.h> #include <netinet/tcp_debug.h> +#include <machine/stdarg.h> + int tcprexmtthresh = 3; struct tcpiphdr tcp_saveti; -struct inpcb *tcp_last_inpcb = 0; extern u_long sb_max; @@ -234,26 +236,35 @@ present: * protocol specification dated September, 1981 very closely. */ void -tcp_input(m, iphlen) +#if __STDC__ +tcp_input(struct mbuf *m, ...) +#else +tcp_input(m, va_alist) register struct mbuf *m; - int iphlen; +#endif { register struct tcpiphdr *ti; register struct inpcb *inp; caddr_t optp = NULL; - int optlen; + int optlen = 0; int len, tlen, off; register struct tcpcb *tp = 0; register int tiflags; - struct socket *so; + struct socket *so = NULL; int todrop, acked, ourfinisacked, needoutput = 0; - short ostate; + short ostate = 0; struct in_addr laddr; int dropsocket = 0; int iss = 0; u_long tiwin; u_int32_t ts_val, ts_ecr; int ts_present = 0; + int iphlen; + va_list ap; + + va_start(ap, m); + iphlen = va_arg(ap, int); + va_end(ap); tcpstat.tcps_rcvtotal++; /* @@ -279,7 +290,7 @@ tcp_input(m, iphlen) bzero(ti->ti_x1, sizeof ti->ti_x1); ti->ti_len = (u_int16_t)tlen; HTONS(ti->ti_len); - if (ti->ti_sum = in_cksum(m, len)) { + if ((ti->ti_sum = in_cksum(m, len)) != 0) { tcpstat.tcps_rcvbadsum++; goto drop; } @@ -338,13 +349,10 @@ tcp_input(m, iphlen) * Locate pcb for segment. */ findpcb: - inp = tcp_last_inpcb; - if (inp == 0 || - inp->inp_lport != ti->ti_dport || - inp->inp_fport != ti->ti_sport || - inp->inp_faddr.s_addr != ti->ti_src.s_addr || - inp->inp_laddr.s_addr != ti->ti_dst.s_addr) { - ++tcpstat.tcps_pcbcachemiss; + inp = in_pcbhashlookup(&tcbtable, ti->ti_src, ti->ti_sport, + ti->ti_dst, ti->ti_dport); + if (inp == 0) { + ++tcpstat.tcps_pcbhashmiss; inp = in_pcblookup(&tcbtable, ti->ti_src, ti->ti_sport, ti->ti_dst, ti->ti_dport, INPLOOKUP_WILDCARD); /* @@ -353,9 +361,10 @@ findpcb: * If the TCB exists but is in CLOSED state, it is embryonic, * but should either do a listen or a connect soon. */ - if (inp == 0) + if (inp == 0) { + ++tcpstat.tcps_noport; goto dropwithreset; - tcp_last_inpcb = inp; + } } tp = intotcpcb(inp); @@ -395,6 +404,7 @@ findpcb: inp = (struct inpcb *)so->so_pcb; inp->inp_laddr = ti->ti_dst; inp->inp_lport = ti->ti_dport; + in_pcbrehash(inp); #if BSD>=43 inp->inp_options = ip_srcroute(); #endif @@ -1124,10 +1134,9 @@ step6: * Update window information. * Don't look at window if no ACK: TAC's send garbage on first SYN. */ - if ((tiflags & TH_ACK) && - (SEQ_LT(tp->snd_wl1, ti->ti_seq) || tp->snd_wl1 == ti->ti_seq && - (SEQ_LT(tp->snd_wl2, ti->ti_ack) || - tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd))) { + if (((tiflags & TH_ACK) && SEQ_LT(tp->snd_wl1, ti->ti_seq)) || + (tp->snd_wl1 == ti->ti_seq && SEQ_LT(tp->snd_wl2, ti->ti_ack)) || + (tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd)) { /* keep track of pure window updates */ if (ti->ti_len == 0 && tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd) @@ -1185,7 +1194,7 @@ step6: * but if two URG's are pending at once, some out-of-band * data may creep in... ick. */ - if (ti->ti_urp <= ti->ti_len + if (ti->ti_urp <= (u_int16_t) ti->ti_len #ifdef SO_OOBINLINE && (so->so_options & SO_OOBINLINE) == 0 #endif @@ -1209,7 +1218,7 @@ dodata: /* XXX */ * case PRU_RCVD). If a FIN has already been received on this * connection then we just ignore the text. */ - if ((ti->ti_len || (tiflags&TH_FIN)) && + if ((ti->ti_len || (tiflags & TH_FIN)) && TCPS_HAVERCVDFIN(tp->t_state) == 0) { TCP_REASS(tp, ti, m, so, tiflags); /* @@ -1225,9 +1234,10 @@ dodata: /* XXX */ /* * If FIN is received ACK the FIN and let the user know - * that the connection is closing. + * that the connection is closing. Ignore a FIN received before + * the connection is fully established. */ - if (tiflags & TH_FIN) { + if ((tiflags & TH_FIN) && TCPS_HAVEESTABLISHED(tp->t_state)) { if (TCPS_HAVERCVDFIN(tp->t_state) == 0) { socantrcvmore(so); tp->t_flags |= TF_ACKNOW; @@ -1236,10 +1246,8 @@ dodata: /* XXX */ switch (tp->t_state) { /* - * In SYN_RECEIVED and ESTABLISHED STATES - * enter the CLOSE_WAIT state. + * In ESTABLISHED STATE enter the CLOSE_WAIT state. */ - case TCPS_SYN_RECEIVED: case TCPS_ESTABLISHED: tp->t_state = TCPS_CLOSE_WAIT; break; @@ -1575,7 +1583,7 @@ tcp_mss(tp, offer) /* default variation is +- 1 rtt */ tp->t_rttvar = tp->t_srtt * TCP_RTTVAR_SCALE / TCP_RTT_SCALE; - TCPT_RANGESET(tp->t_rxtcur, + TCPT_RANGESET((long) tp->t_rxtcur, ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1, tp->t_rttmin, TCPTV_REXMTMAX); } |