X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/1aa87517a3dcc8a721afa5d99fd64544d9c86a92..4ab1a5c3d51e670b73ca6e3477d72344edf9b224:/usr/src/sys/netinet/tcp_input.c diff --git a/usr/src/sys/netinet/tcp_input.c b/usr/src/sys/netinet/tcp_input.c index 1ad4f2e5f4..d00ead02e7 100644 --- a/usr/src/sys/netinet/tcp_input.c +++ b/usr/src/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* tcp_input.c 1.55 82/02/27 */ +/* tcp_input.c 1.71 82/06/30 */ #include "../h/param.h" #include "../h/systm.h" @@ -7,6 +7,7 @@ #include "../h/socket.h" #include "../h/socketvar.h" #include "../net/in.h" +#include "../net/route.h" #include "../net/in_pcb.h" #include "../net/in_systm.h" #include "../net/if.h" @@ -19,7 +20,7 @@ #include "../net/tcp_var.h" #include "../net/tcpip.h" #include "../net/tcp_debug.h" -#include "../errno.h" +#include int tcpprintfs = 0; int tcpcksum = 1; @@ -45,8 +46,8 @@ tcp_input(m0) struct socket *so; int todrop, acked; short ostate; + struct in_addr laddr; -COUNT(TCP_INPUT); /* * Get IP and TCP header together in first mbuf. * Note: IP leaves IP header in first mbuf. @@ -72,12 +73,13 @@ COUNT(TCP_INPUT); ti->ti_next = ti->ti_prev = 0; ti->ti_x1 = 0; ti->ti_len = (u_short)tlen; -#if vax - ti->ti_len = htons(ti->ti_len); +#if vax || pdp11 + ti->ti_len = htons((u_short)ti->ti_len); #endif if (ti->ti_sum = in_cksum(m, len)) { tcpstat.tcps_badsum++; - printf("tcp cksum %x\n", ti->ti_sum); + if (tcpprintfs) + printf("tcp cksum %x\n", ti->ti_sum); goto drop; } } @@ -91,7 +93,8 @@ COUNT(TCP_INPUT); tcpstat.tcps_badoff++; goto drop; } - ti->ti_len = tlen - off; + tlen -= off; + ti->ti_len = tlen; if (off > sizeof (struct tcphdr)) { if ((m = m_pullup(m, sizeof (struct ip) + off)) == 0) { tcpstat.tcps_hdrops++; @@ -104,14 +107,22 @@ COUNT(TCP_INPUT); om->m_off = MMINOFF; om->m_len = off - sizeof (struct tcphdr); { caddr_t op = mtod(m, caddr_t) + sizeof (struct tcpiphdr); - bcopy(op, mtod(om, caddr_t), om->m_len); + bcopy(op, mtod(om, caddr_t), (unsigned)om->m_len); m->m_len -= om->m_len; - bcopy(op+om->m_len, op, m->m_len-sizeof (struct tcpiphdr)); + bcopy(op+om->m_len, op, + (unsigned)(m->m_len-sizeof (struct tcpiphdr))); } } tiflags = ti->ti_flags; -#if vax + /* + * Drop TCP and IP headers. + */ + off += sizeof (struct ip); + m->m_off += off; + m->m_len -= off; + +#if vax || pdp11 /* * Convert TCP protocol specific fields to host format. */ @@ -126,7 +137,8 @@ COUNT(TCP_INPUT); * address stored in the block to reflect anchoring. */ inp = in_pcblookup - (&tcb, ti->ti_src, ti->ti_sport, ti->ti_dst, ti->ti_dport, 1); + (&tcb, ti->ti_src, ti->ti_sport, ti->ti_dst, ti->ti_dport, + INPLOOKUP_WILDCARD); /* * If the state is CLOSED (i.e., TCB does not exist) then @@ -189,11 +201,18 @@ COUNT(TCP_INPUT); goto drop; tcp_in.sin_addr = ti->ti_src; tcp_in.sin_port = ti->ti_sport; - if (in_pcbconnect(inp, (struct sockaddr *)&tcp_in)) + laddr = inp->inp_laddr; + if (inp->inp_laddr.s_addr == 0) + inp->inp_laddr = ti->ti_dst; + if (in_pcbconnect(inp, (struct sockaddr_in *)&tcp_in)) { + inp->inp_laddr = laddr; goto drop; + } tp->t_template = tcp_template(tp); if (tp->t_template == 0) { in_pcbdisconnect(inp); + inp->inp_laddr = laddr; + tp = 0; goto drop; } tp->iss = tcp_iss; tcp_iss += TCP_ISSINCR/2; @@ -223,8 +242,10 @@ COUNT(TCP_INPUT); SEQ_GT(ti->ti_ack, tp->snd_max))) goto dropwithreset; if (tiflags & TH_RST) { - if (tiflags & TH_ACK) + if (tiflags & TH_ACK) { tcp_drop(tp, ECONNREFUSED); + tp = 0; + } goto drop; } if ((tiflags & TH_SYN) == 0) @@ -298,7 +319,8 @@ trimthenstep6: tiflags &= ~TH_URG; todrop--; } - if (todrop > ti->ti_len) + if (todrop > ti->ti_len || + todrop == ti->ti_len && (tiflags&TH_FIN) == 0) goto dropafterack; m_adj(m, todrop); ti->ti_seq += todrop; @@ -317,7 +339,7 @@ trimthenstep6: */ todrop = (ti->ti_seq+ti->ti_len) - (tp->rcv_nxt+tp->rcv_wnd); if (todrop > 0) { - if (todrop > ti->ti_len) + if (todrop >= ti->ti_len) goto dropafterack; m_adj(m, -todrop); ti->ti_len -= todrop; @@ -331,6 +353,7 @@ trimthenstep6: */ if (so->so_state & SS_USERGONE) { tcp_close(tp); + tp = 0; goto dropwithreset; } @@ -354,9 +377,14 @@ trimthenstep6: inp->inp_ppcb = 0; tp = tcp_newtcpcb(inp); tp->t_state = TCPS_LISTEN; + inp->inp_faddr.s_addr = 0; + inp->inp_fport = 0; + inp->inp_laddr.s_addr = 0; /* not quite right */ + tp = 0; goto drop; } tcp_drop(tp, ECONNREFUSED); + tp = 0; goto drop; case TCPS_ESTABLISHED: @@ -364,12 +392,14 @@ trimthenstep6: case TCPS_FIN_WAIT_2: case TCPS_CLOSE_WAIT: tcp_drop(tp, ECONNRESET); + tp = 0; goto drop; case TCPS_CLOSING: case TCPS_LAST_ACK: case TCPS_TIME_WAIT: tcp_close(tp); + tp = 0; goto drop; } @@ -379,6 +409,7 @@ trimthenstep6: */ if (tiflags & TH_SYN) { tcp_drop(tp, ECONNRESET); + tp = 0; goto dropwithreset; } @@ -464,11 +495,11 @@ trimthenstep6: sbdrop(&so->so_snd, so->so_snd.sb_cc); tp->snd_wnd -= so->so_snd.sb_cc; } else { - sbdrop(&so->so_snd.sb_cc, acked); + sbdrop(&so->so_snd, acked); tp->snd_wnd -= acked; acked = 0; } - if (so->so_snd.sb_flags & SB_WAIT) + if ((so->so_snd.sb_flags & SB_WAIT) || so->so_snd.sb_sel) sowwakeup(so); tp->snd_una = ti->ti_ack; if (SEQ_LT(tp->snd_nxt, tp->snd_una)) @@ -515,8 +546,10 @@ trimthenstep6: * and return. */ case TCPS_LAST_ACK: - if (ourfinisacked) + if (ourfinisacked) { tcp_close(tp); + tp = 0; + } goto drop; /* @@ -548,7 +581,8 @@ step6: /* * Process segments with URG. */ - if ((tiflags & TH_URG) && TCPS_HAVERCVDFIN(tp->t_state) == 0) { + if ((tiflags & TH_URG) && ti->ti_urp && + TCPS_HAVERCVDFIN(tp->t_state) == 0) { /* * If this segment advances the known urgent pointer, * then mark the data stream. This should not happen @@ -589,9 +623,6 @@ step6: */ if ((ti->ti_len || (tiflags&TH_FIN)) && TCPS_HAVERCVDFIN(tp->t_state) == 0) { - off += sizeof (struct ip); /* drop IP header */ - m->m_off += off; - m->m_len -= off; tiflags = tcp_reass(tp, ti); if (tcpnodelack == 0) tp->t_flags |= TF_DELACK; @@ -657,22 +688,25 @@ step6: /* * Return any desired output. */ - tcp_output(tp); + (void) tcp_output(tp); return; dropafterack: /* - * Generate an ACK dropping incoming segment. - * Make ACK reflect our state. + * Generate an ACK dropping incoming segment if it occupies + * sequence space, where the ACK reflects our state. */ - if (tiflags & TH_RST) + if ((tiflags&TH_RST) || + tlen == 0 && (tiflags&(TH_SYN|TH_FIN)) == 0) goto drop; + if (tp->t_inpcb->inp_socket->so_options & SO_DEBUG) + tcp_trace(TA_RESPOND, ostate, tp, &tcp_saveti, 0); tcp_respond(tp, ti, tp->rcv_nxt, tp->snd_nxt, TH_ACK); return; dropwithreset: if (om) - m_free(om); + (void) m_free(om); /* * Generate a RST, dropping incoming segment. * Make ACK acceptable to originator of segment. @@ -684,7 +718,8 @@ dropwithreset: else { if (tiflags & TH_SYN) ti->ti_len++; - tcp_respond(tp, ti, ti->ti_seq+ti->ti_len, (tcp_seq)0, TH_RST|TH_ACK); + tcp_respond(tp, ti, ti->ti_seq+ti->ti_len, (tcp_seq)0, + TH_RST|TH_ACK); } return; @@ -692,6 +727,8 @@ drop: /* * Drop space held by incoming segment and return. */ + if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) + tcp_trace(TA_DROP, ostate, tp, &tcp_saveti, 0); m_freem(m); return; } @@ -722,8 +759,8 @@ tcp_dooptions(tp, om) if (optlen != 4) continue; tp->t_maxseg = *(u_short *)(cp + 2); -#if vax - tp->t_maxseg = ntohs(tp->t_maxseg); +#if vax || pdp11 + tp->t_maxseg = ntohs((u_short)tp->t_maxseg); #endif break; @@ -752,7 +789,7 @@ printf("bad seq\n"); tp->t_iobseq = cp[2]; tp->t_iobc = cp[3]; mark = *(tcp_seq *)(cp + 4); -#if vax +#if vax || pdp11 mark = ntohl(mark); #endif so->so_oobmark = so->so_rcv.sb_cc + (mark-tp->rcv_nxt); @@ -780,7 +817,7 @@ printf("take oob ack %x and cancel rexmt\n", cp[2]); #endif TCPTRUEOOB } } - m_free(om); + (void) m_free(om); } /* @@ -794,7 +831,7 @@ tcp_pulloutofband(so, ti) struct tcpiphdr *ti; { register struct mbuf *m; - int cnt = sizeof (struct tcpiphdr) + ti->ti_urp - 1; + int cnt = ti->ti_urp - 1; m = dtom(ti); while (cnt >= 0) { @@ -804,7 +841,7 @@ tcp_pulloutofband(so, ti) tp->t_iobc = *cp; tp->t_oobflags |= TCPOOB_HAVEDATA; - bcopy(cp+1, cp, m->m_len - cnt - 1); + bcopy(cp+1, cp, (unsigned)(m->m_len - cnt - 1)); m->m_len--; return; } @@ -829,7 +866,6 @@ tcp_reass(tp, ti) struct socket *so = tp->t_inpcb->inp_socket; struct mbuf *m; int flags; -COUNT(TCP_REASS); /* * Call with ti==0 after become established to @@ -859,7 +895,7 @@ COUNT(TCP_REASS); if (i > 0) { if (i >= ti->ti_len) goto drop; - m_adj(dtom(tp), i); + m_adj(dtom(ti), i); ti->ti_len -= i; ti->ti_seq += i; } @@ -910,7 +946,7 @@ present: m = dtom(ti); ti = (struct tcpiphdr *)ti->ti_next; if (so->so_state & SS_CANTRCVMORE) - (void) m_freem(m); + m_freem(m); else sbappend(&so->so_rcv, m); } while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt);