⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp_input.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/* tcp_input.c - TCP input routines *//* Copyright 1984 - 2003 Wind River Systems, Inc. */#include "copyright_wrs.h"/* * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)tcp_input.c	8.12 (Berkeley) 5/24/95 *//*modification history--------------------01j,14jan03,rae  Merged from velocecp branch (SPR #82107)01i,06mar02,vvv  fixed tcp_input to wake application only when space in send		 buffer exceeds low water mark (SPR #72177)01h,12oct01,rae  merge from truestack ver 01n, base o1f (SPRs 69629, 70328,                 70329, WindView, cleanup)01g,11oct00,gnn  enabled LAND fix by default.01f,09jan98,vin  added LAND attack fix.01e,26sep97,sgv  Removed check for PUSH flag in TCP_REASS macro01d,07jul97,vin  fixed additional bugs. 		 (timestamp echo fix Stevens VolII Sec 26.6 fig 26.20,                 connection timer bug Stevens VolII sec 28.6 fig 28.20,                 simultaneous bug fix Stevens VolII sec 28.8 fig 28.30,                 removed unnecessary code Stevens VolII sec 29.9 fig 29.22)01c,08mar97,vin  added changes to accomodate changes in pcb structure for		 hash look ups.01c,05feb97,rjc  changes for tos routing01b,22nov96,vin  added cluster support replaced m_get(..) with mBufClGet(..).01a,03mar96,vin  created from BSD4.4lite2. integrated some wrs changes from		 02q of tcp_input.c*/#include "vxWorks.h"#include "net/systm.h"#include "net/mbuf.h"#include "net/protosw.h"#include "sys/socket.h"#include "net/socketvar.h"#include "errno.h"#include "net/if.h"#include "net/route.h"#include "netinet/in.h"#include "netinet/in_pcb.h"#include "netinet/in_systm.h"#include "netinet/ip.h"#include "netinet/ip_var.h"#include "netinet/tcp.h"#include "netinet/tcp_fsm.h"#include "netinet/tcp_seq.h"#include "netinet/tcp_timer.h"#include "netinet/tcp_var.h"#include "netinet/tcpip.h"#ifdef BSDDEBUG#include "netinet/tcp_debug.h"#endif	/* BSDDEBUG */#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET#include "wvNetLib.h"#endif#endif#ifdef VIRTUAL_STACK#include "netinet/vsLib.h"#elseextern u_long sb_max;IMPORT int tcp_keepinit;IMPORT int tcp_mssdflt;#endif /* VIRTUAL_STACK */IMPORT unsigned long (*pTcpRandHook)(void);extern void _remque ();extern void _insque ();/* XXX LAND attack safe remove this after thorough investigation */UCHAR _landAttackSafe = 1;/* *  MIB-II support counts the number of TCP packets sent with the Reset Flag *  set. */#ifndef VIRTUAL_STACKlong   tcpOutRsts;tcp_seq	tcp_iss;		/* tcp initial send seq # */unsigned tcp_alpha, tcp_beta;	/* retransmission smoothing constants */struct inpcbhead tcb;           /* head of queue of active tcpcb's */struct inpcbinfo tcbinfo;struct 	tcpstat tcpstat;	/* tcp statistics */int	tcprexmtthresh = 3;     /* overridden during protocol initialization */UINT32  tcp_msl;struct	tcpiphdr tcp_saveti;struct	inpcb *tcp_last_inpcb = NULL;u_long 	tcp_now;			/* for RFC 1323 timestamps */#endif /* VIRTUAL_STACK */#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* Set common fields of event identifiers for this module. */LOCAL UCHAR wvNetModuleId = WV_NET_TCPINPUT_MODULE; /* Value for tcp_input.c */LOCAL UCHAR wvNetLocalFilter = WV_NET_NONE;     /* Available event filter */LOCAL ULONG wvNetEventId;       /* Event identifier: see wvNetLib.h */#endif    /* INCLUDE_WVNET */#endif#define TCP_PAWS_IDLE	(24 * 24 * 60 * 60 * PR_SLOWHZ)/* for modulo comparisons of timestamps */#define TSTMP_LT(a,b)	((int)((a)-(b)) < 0)#define TSTMP_GEQ(a,b)	((int)((a)-(b)) >= 0)/* * Insert segment ti into reassembly queue of tcp with * control block tp.  Return TH_FIN if reassembly now includes * a segment with FIN.  The macro form does the common case inline * (segment is the next to be received on an established connection, * and the queue is empty), avoiding linkage into and removal * from the queue and repetition of various conversions. * Set DELACK for segments received in order, but ack immediately * when segments are out of order (so fast retransmit can work). */#define	TCP_REASS(tp, ti, m, so, flags) { \	if ((ti)->ti_seq == (tp)->rcv_nxt && \	    (tp)->seg_next == (struct tcpiphdr *)(tp) && \	    (tp)->t_state == TCPS_ESTABLISHED) { \		(tp)->t_flags |= TF_DELACK; \		(tp)->rcv_nxt += (ti)->ti_len; \		flags = (ti)->ti_flags & TH_FIN; \		tcpstat.tcps_rcvpack++;\		tcpstat.tcps_rcvbyte += (ti)->ti_len;\		sbappend(&(so)->so_rcv, (m)); \		sorwakeup(so); \	} else { \		(flags) = tcp_reass((tp), (ti), (m)); \		tp->t_flags |= TF_ACKNOW; \	} \}inttcp_reass(tp, ti, m)	register struct tcpcb *tp;	register struct tcpiphdr *ti;	struct mbuf *m;{	register struct tcpiphdr *q;	struct socket *so = tp->t_inpcb->inp_socket;	int flags;	/*	 * Call with ti==0 after become established to	 * force pre-ESTABLISHED data up to user socket.	 */	if (ti == 0)		goto present;	/*	 * Find a segment which begins after this one does.	 */	for (q = tp->seg_next; q != (struct tcpiphdr *)tp;	    q = (struct tcpiphdr *)q->ti_next)		if (SEQ_GT(q->ti_seq, ti->ti_seq))			break;	/*	 * If there is a preceding segment, it may provide some of	 * our data already.  If so, drop the data from the incoming	 * segment.  If it provides all of our data, drop us.	 */	if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) {		register int i;		q = (struct tcpiphdr *)q->ti_prev;		/* conversion to int (in i) handles seq wraparound */		i = q->ti_seq + q->ti_len - ti->ti_seq;		if (i > 0) {			if (i >= ti->ti_len) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */            WV_NET_PORTIN_EVENT_3 (NET_CORE_EVENT, WV_NET_INFO, 26, 8,                               tp->t_inpcb->inp_fport, tp->t_inpcb->inp_lport,                                   WV_NETEVENT_TCPIN_DUPSEG, WV_NET_RECV,                                   so->so_fd, ti->ti_seq, ti->ti_len)#endif  /* INCLUDE_WVNET */#endif				tcpstat.tcps_rcvduppack++;				tcpstat.tcps_rcvdupbyte += ti->ti_len;				m_freem(m);				return (0);			}			m_adj(m, i);			ti->ti_len -= i;			ti->ti_seq += i;		}		q = (struct tcpiphdr *)(q->ti_next);	}	tcpstat.tcps_rcvoopack++;	tcpstat.tcps_rcvoobyte += ti->ti_len;	REASS_MBUF(ti) = m;		/* XXX */	/*	 * While we overlap succeeding segments trim them or,	 * if they are completely covered, dequeue them.	 */	while (q != (struct tcpiphdr *)tp) {		register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq;		if (i <= 0)			break;		if (i < q->ti_len) {			q->ti_seq += i;			q->ti_len -= i;			m_adj(REASS_MBUF(q), i);			break;		}		q = (struct tcpiphdr *)q->ti_next;		m = REASS_MBUF((struct tcpiphdr *)q->ti_prev);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */        WV_NET_PORTIN_EVENT_4 (NET_CORE_EVENT, WV_NET_VERBOSE, 37, 20,                               tp->t_inpcb->inp_fport, tp->t_inpcb->inp_lport,                               WV_NETEVENT_TCPIN_DUPDATA, WV_NET_RECV,                                so->so_fd, ti->ti_seq,                               ((struct tcpiphdr *)q->ti_prev)->ti_seq,                               ((struct tcpiphdr *)q->ti_prev)->ti_len)#endif  /* INCLUDE_WVNET */#endif		remque(q->ti_prev);		m_freem(m);	}	/*	 * Stick new segment in its place.	 */	insque(ti, q->ti_prev);present:	/*	 * Present data to user, advancing rcv_nxt through	 * completed sequence space.	 */	if (TCPS_HAVERCVDSYN(tp->t_state) == 0)		return (0);	ti = tp->seg_next;	if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt)		return (0);	if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len)		return (0);	do {		tp->rcv_nxt += ti->ti_len;		flags = ti->ti_flags & TH_FIN;		remque(ti);		m = REASS_MBUF(ti);		ti = (struct tcpiphdr *)ti->ti_next;		if (so->so_state & SS_CANTRCVMORE)			m_freem(m);		else			sbappend(&so->so_rcv, m);	} while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt);	sorwakeup(so);	return (flags);}/* * TCP input routine, follows pages 65-76 of the * protocol specification dated September, 1981 very closely. */voidtcp_input(m, iphlen)	register struct mbuf *m;	int iphlen;{	register struct tcpiphdr *ti;	register struct inpcb *inp;	u_char *optp = NULL;	int optlen = 0;	int len, tlen, off;	register struct tcpcb *tp = 0;	register int tiflags;	struct socket *so = NULL;	int todrop, acked, ourfinisacked, needoutput = 0;	short ostate = 0;	struct in_addr laddr;	int dropsocket = 0;	int iss = 0;	u_long tiwin, ts_val, ts_ecr;	int ts_present = 0;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_NOTICE event */        WV_NET_EVENT_0 (NET_CORE_EVENT, WV_NET_NOTICE, 18, 7,                        WV_NETEVENT_TCPIN_START, WV_NET_RECV)#endif  /* INCLUDE_WVNET */#endif	tcpstat.tcps_rcvtotal++;	/*	 * Get IP and TCP header together in first mbuf.	 * Note: IP leaves IP header in first mbuf.	 */	ti = mtod(m, struct tcpiphdr *);	if (iphlen > sizeof (struct ip))		ip_stripoptions(m, (struct mbuf *)0);	if (m->m_len < sizeof (struct tcpiphdr)) {		if ((m = m_pullup(m, sizeof (struct tcpiphdr))) == 0) {			tcpstat.tcps_rcvshort++;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */            WV_NET_EVENT_0 (NET_CORE_EVENT, WV_NET_VERBOSE, 38, 21,                            WV_NETEVENT_TCPIN_SHORTSEG, WV_NET_RECV)#endif  /* INCLUDE_WVNET */#endif			return;		}		ti = mtod(m, struct tcpiphdr *);	}	/*	 * Checksum extended TCP header and data.	 */	tlen = ((struct ip *)ti)->ip_len;	len = sizeof (struct ip) + tlen;	ti->ti_next = ti->ti_prev = 0;	ti->ti_x1 = 0;	ti->ti_len = (u_short)tlen;	HTONS(ti->ti_len);	if ((ti->ti_sum = in_cksum(m, len))) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */            WV_NET_EVENT_0 (NET_CORE_EVENT, WV_NET_CRITICAL, 30, 2,                            WV_NETEVENT_TCPIN_BADSUM, WV_NET_RECV)#endif  /* INCLUDE_WVNET */#endif		tcpstat.tcps_rcvbadsum++;		goto drop;	}	/*	 * Check that TCP offset makes sense,	 * pull out TCP options and adjust length.		XXX	 */	off = ti->ti_off << 2;	if (off < sizeof (struct tcphdr) || off > tlen) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */            WV_NET_PORTIN_EVENT_1 (NET_CORE_EVENT, WV_NET_CRITICAL, 31, 3,                                   ti->ti_sport, ti->ti_dport,                                   WV_NETEVENT_TCPIN_BADSEG, WV_NET_RECV,                                    off)#endif  /* INCLUDE_WVNET */#endif		tcpstat.tcps_rcvbadoff++;		goto drop;	}	tlen -= off;	ti->ti_len = tlen;	if (off > sizeof (struct tcphdr)) {		if (m->m_len < sizeof(struct ip) + off) {			if ((m = m_pullup(m, sizeof (struct ip) + off)) == 0) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */                WV_NET_PORTIN_EVENT_0 (NET_CORE_EVENT, WV_NET_VERBOSE, 38, 21,                                       ti->ti_sport, ti->ti_dport,                                       WV_NETEVENT_TCPIN_SHORTSEG, WV_NET_RECV)#endif  /* INCLUDE_WVNET */#endif				tcpstat.tcps_rcvshort++;				return;			}			ti = mtod(m, struct tcpiphdr *);		}		optlen = off - sizeof (struct tcphdr);		optp = mtod(m, u_char *) + sizeof (struct tcpiphdr);		/* 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -