bc... [vxwork]
Home » Source Code » » tcp_subr.c

tcp_subr.c ( File view )

From:
  • By 2010-08-12
  • View(s):3
  • Download(s):0
  • Point(s): 1
			/* tcp_subr.c - TCP routines */

/* Copyright 1984-1996 Wind River Systems, Inc. */
#include "copyright_wrs.h"

/*
 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 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_subr.c	8.2 (Berkeley) 5/24/95
 */

/*
modification history
--------------------
01c,31mar97,vin  modified for hash look ups for pcbs(FREEBSD 2.2.1).
01b,30oct96,vin  changed tcp_template to return mbuf * instead of tcpiphdr.
		 changed m_free(dtom(...)) to m_free(tp->t_template).
01a,03mar96,vin  created from BSD4.4 stuff,integrated with 02i.
*/

/*
DESCRIPTION
*/

#include "vxWorks.h"
#include "net/systm.h"
#include "net/mbuf.h"
#include "sys/socket.h"
#include "net/socketvar.h"
#include "net/protosw.h"
#include "errno.h"

#include "net/route.h"
#include "net/if.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/ip_icmp.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"

/*
 * Target size of TCP PCB hash table. Will be rounded down to a prime
 * number.
 */
#ifndef TCBHASHSIZE
#define TCBHASHSIZE     128
#endif

/* patchable/settable parameters for tcp */
int 	tcp_mssdflt = TCP_MSS;
int 	tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ;
int	tcp_do_rfc1323 = 1;
u_short tcp_pcbhashsize = TCBHASHSIZE;

extern	struct inpcb * tcp_last_inpcb;

/*
 * Tcp initialization
 */
void
tcp_init()
{


	tcp_iss = random();	/* wrong, but better than a constant */
        LIST_INIT(&tcb);
        tcbinfo.listhead = &tcb;
        tcbinfo.hashbase = hashinit(tcp_pcbhashsize, MT_PCB, &tcbinfo.hashmask);
	if (max_protohdr < sizeof(struct tcpiphdr))
		max_protohdr = sizeof(struct tcpiphdr);
	if (max_linkhdr + sizeof(struct tcpiphdr) > CL_SIZE_128)
		panic("tcp_init");

}

/*
 * Create template to be used to send tcp packets on a connection.
 * Call after host entry created, allocates an mbuf and fills
 * in a skeletal tcp/ip header, minimizing the amount of work
 * necessary when the connection is used.
 */
struct mbuf *
tcp_template(tp)
	struct tcpcb *tp;
{

	register struct inpcb *inp = tp->t_inpcb;
	register struct mbuf *m;
	register struct tcpiphdr *n;

	if ((m = tp->t_template) == NULL) {

		m = mBufClGet (M_DONTWAIT, MT_HEADER, sizeof (struct tcpiphdr),
			       TRUE); 
		if (m == NULL)
			return (0);
		m->m_len = sizeof (struct tcpiphdr);
	
}
	n = mtod (m, struct tcpiphdr *);
	n->ti_next = n->ti_prev = 0;
	n->ti_x1 = 0;
	n->ti_pr = IPPROTO_TCP;
	n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
	n->ti_src = inp->inp_laddr;
	n->ti_dst = inp->inp_faddr;
	n->ti_sport = inp->inp_lport;
	n->ti_dport = inp->inp_fport;
	n->ti_seq = 0;
	n->ti_ack = 0;
	n->ti_x2 = 0;
	n->ti_off = 5;
	n->ti_flags = 0;
	n->ti_win = 0;
	n->ti_sum = 0;
	n->ti_urp = 0;
	return (m);

}

/*
 * Send a single message to the TCP at address specified by
 * the given TCP/IP header.  If m == 0, then we make a copy
 * of the tcpiphdr at ti and send directly to the addressed host.
 * This is used to force keep alive messages out using the TCP
 * template for a connection tp->t_template.  If flags are given
 * then we send a message back to the TCP which originated the
 * segment ti, and discard the mbuf containing it and any other
 * attached mbufs.
 *
 * In any case the ack and sequence number of the transmitted
 * segment are as specified by the parameters.
 */
void
tcp_respond(tp, ti, m, ack, seq, flags)
	struct tcpcb *tp;
	register struct tcpiphdr *ti;
	register struct mbuf *m;
	tcp_seq ack, seq;
	int flags;
{

	register int tlen;
	int win = 0;
	struct route *ro = 0;

	if (tp) {

		win = sbspace(&tp->t_inpcb->inp_socket->so_rcv);
		ro = &tp->t_inpcb->inp_route;
	
}
	if (m == 0) {

		m = mHdrClGet(M_DONTWAIT, MT_HEADER, CL_SIZE_128, TRUE);
		if (m == NULL)
			return;
#ifdef TCP_COMPAT_42
		tlen = 1;
#else
		tlen = 0;
#endif
		m->m_data += max_linkhdr;
		*mtod(m, struct tcpiphdr *) = *ti;
		ti = mtod(m, struct tcpiphdr *);
		flags = TH_ACK;
	
} else {

		m_freem(m->m_next);
		m->m_next = 0;
		m->m_data = (caddr_t)ti;
		m->m_len = sizeof (struct tcpiphdr);
		tlen = 0;
#define xchg(a,b,type) {
 type t; t=a; a=b; b=t; 
}
		xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_long);
		xchg(ti->ti_dport, ti->ti_sport, u_short);
#undef xchg
	
}
	ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen));
	tlen += sizeof (struct tcpiphdr);
	m->m_len = tlen;
	m->m_pkthdr.len = tlen;
	m->m_pkthdr.rcvif = (struct ifnet *) 0;
	ti->ti_next = ti->ti_prev = 0;
	ti->ti_x1 = 0;
	ti->ti_seq = htonl(seq);
	ti->ti_ack = htonl(ack);
	ti->ti_x2 = 0;
	ti->ti_off = sizeof (struct tcphdr) >> 2;
	ti->ti_flags = flags;
	if (tp)
		ti->ti_win = htons((u_short) (win >> tp->rcv_scale));
	else
		ti->ti_win = htons((u_short)win);
	ti->ti_urp = 0;
	ti->ti_sum = 0;
	ti->ti_sum = in_cksum(m, tlen);
	((struct ip *)ti)->ip_len = tlen;
	((struct ip *)ti)->ip_ttl = ip_defttl;
	(void) ip_output(m, NULL, ro, 0, NULL);

}

/*
 * Create a new TCP control block, making an
 * empty reassembly queue and hooking it to the argument
 * protocol control block.
 */
struct tcpcb *
tcp_newtcpcb(inp)
	struct inpcb *inp;
{

	register struct tcpcb *tp;

	MALLOC(tp, struct tcpcb *, sizeof(*tp), MT_PCB, M_DONTWAIT);
	if (tp == NULL)
		return ((struct tcpcb *)0);
	bzero((char *) tp, sizeof(struct tcpcb));
	tp->seg_next = tp->seg_prev = (struct tcpiphdr *)tp;
	tp->t_maxseg = tcp_mssdflt;

	tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
	tp->t_inpcb = inp;
	/*
	 * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no
	 * rtt estimate.  Set rttvar so that srtt + 2 * rttvar gives
	 * reasonable initial retransmit time.
	 */
	tp->t_srtt = TCPTV_SRTTBASE;
	tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ << 2;
	tp->t_rttmin = TCPTV_MIN;
	TCPT_RANGESET(tp->t_rxtcur, 
	    ((TCPTV_SRTTBASE >> 2) + (TCPTV_SRTTDFLT << 2)) >> 1,
	    TCPTV_MIN, TCPTV_REXMTMAX);
	tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT;
	tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT;
	inp->inp_ip.ip_ttl = ip_defttl;
	inp->inp_ppcb = (caddr_t)tp;
	return (tp);

}

/*
 * Drop a TCP connection, reporting
 * the specified error.  If connection is synchronized,
 * then send a RST to peer.
 */
struct tcpcb *
tcp_drop(tp, error)
	register struct tcpcb *tp;
	int error;
{

	struct socket *so = tp->t_inpcb->inp_socket;

	if (TCPS_HAVERCVDSYN(tp->t_state)) {

		tp->t_state = TCPS_CLOSED;
		(void) tcp_output(tp);
		tcpstat.tcps_drops++;
	
} else
		tcpstat.tcps_conndrops++;
	if (error == ETIMEDOUT && tp->t_softerror)
		error = tp->t_softerror;
	so->so_error = error;
	return (tcp_close(tp));

}

/*
 * Close a TCP control block:
 *	discard all space held by the tcp
 *	discard internet protocol block
 *	wake up any sleepers
 */
struct tcpcb *
tcp_close(tp)
	register struct tcpcb *tp;
{

	register struct tcpiphdr *t;
	struct inpcb *inp = tp->t_inpcb;
	struct socket *so = inp->inp_socket;
	register struct mbuf *m;
#ifdef RTV_RTT
	register struct rtentry *rt;

	/*
	 * If we sent enough data to get some meaningful characteristics,
	 * save them in the routing entry.  'Enough' is arbitrarily 
	 * defined as the sendpipesize (default 4K) * 16.  This would
	 * give us 16 rtt samples assuming we only get one sample per
	 * window (the usual case on a long haul net).  16 samples is
	 * enough for the srtt filter to converge to within 5% of the correct
	 * value; fewer samples and we could save a very bogus rtt.
	 *
	 * Don't update the default route's characteristics and don't
	 * update anything that the user "locked".
	 */
	if (SEQ_LT(tp->iss + so->so_snd.sb_hiwat * 16, tp->snd_max) &&
	    (rt = inp->inp_route.ro_rt) &&
	    ((struct sockaddr_in *)rt_key(rt))->sin_addr.s_addr != INADDR_ANY) {

		register u_long i;

		if ((rt->rt_rmx.rmx_locks & RTV_RTT) == 0) {

			i = tp->t_srtt *
			    (RTM_RTTUNIT / (PR_SLOWHZ * TCP_RTT_SCALE));
			if (rt->rt_rmx.rmx_rtt && i)
				/*
				 * filter this update to half the old & half
				 * the new values, converting scale.
				 * See route.h and tcp_var.h for a
				 * description of the scaling constants.
				 */
				rt->rt_rmx.rmx_rtt =
				    (rt->rt_rmx.rmx_rtt + i) / 2;
			else
				rt->rt_rmx.rmx_rtt = i;
		
}
		if ((rt->rt_rmx.rmx_locks & RTV_RTTVAR) == 0) {

			i = tp->t_rttvar *
			    (RTM_RTTUNIT / (PR_SLOWHZ * TCP_RTTVAR_SCALE));
			if (rt->rt_rmx.rmx_rttvar && i)
				rt->rt_rmx.rmx_rttvar =
				    (rt->rt_rmx.
...
...
(Not finished, please download and read the complete file)
			
...
Expand> <Close

Want complete source code? Download it here

Point(s): 1

Download
0 lines left, continue to read

File list

Tips: You can preview the content of files by clicking file names^_^
Name Size Date
if.c22.14 kB02-08-00 19:42
if_ether.c34.41 kB10-10-00 01:11
if_subr.c26.88 kB02-08-00 19:42
igmp.c9.82 kB02-08-00 19:42
in.c24.86 kB12-10-00 00:53
in_cksum.c5.30 kB02-08-00 19:42
in_pcb.c18.09 kB17-09-00 23:20
in_proto.c4.30 kB02-08-00 19:42
ip_icmp.c16.12 kB02-08-00 19:42
ip_input.c33.50 kB03-10-00 11:42
ip_mroute.c21.29 kB02-08-00 19:42
ip_output.c31.14 kB02-08-00 19:42
Makefile903.00 B12-10-00 00:53
auth.c22.52 kB02-08-00 19:42
chap.c20.51 kB02-08-00 19:42
crypt.c28.70 kB02-08-00 19:42
fsm.c17.34 kB02-08-00 19:42
if_ppp.c49.12 kB02-08-00 19:42
ipcp.c30.66 kB02-08-00 19:42
lcp.c43.73 kB02-08-00 19:42
magic.c1.76 kB02-08-00 19:42
Makefile642.00 B02-08-00 19:42
options.c36.44 kB02-08-00 19:42
pppHookLib.c5.97 kB02-08-00 19:42
pppLib.c48.16 kB02-08-00 19:42
pppSecretLib.c10.45 kB02-08-00 19:42
pppShow.c13.23 kB02-08-00 19:42
ppp_md5.c11.40 kB02-08-00 19:42
ppp_vxworks.c17.90 kB02-08-00 19:42
random.c13.32 kB02-08-00 19:42
upap.c12.58 kB02-08-00 19:42
<ppp>0.00 B27-04-06 13:46
radix.c24.00 kB10-10-00 01:11
raw_cb.c4.31 kB02-08-00 19:42
raw_ip.c11.64 kB02-08-00 19:42
raw_usrreq.c7.21 kB02-08-00 19:42
route.c22.86 kB10-10-00 01:11
rtsock.c23.88 kB10-10-00 01:11
sl_compress.c14.99 kB02-08-00 19:42
tcp_debug.c6.55 kB02-08-00 19:42
tcp_input.c50.16 kB02-08-00 19:42
tcp_output.c19.83 kB02-08-00 19:42
tcp_subr.c13.22 kB02-08-00 19:42
tcp_timer.c10.53 kB02-08-00 19:42
tcp_usrreq.c13.61 kB02-08-00 19:42
udp_usrreq.c20.71 kB02-08-00 19:42
uipc_dom.c7.10 kB02-08-00 19:42
uipc_mbuf.c22.55 kB02-08-00 19:42
uipc_sock.c27.73 kB02-08-00 19:42
uipc_sock2.c22.40 kB02-08-00 19:42
unixLib.c11.07 kB02-08-00 19:42
<netinet>0.00 B27-04-06 13:46
<vxworks的tcpip协议栈的代码>0.00 B27-04-06 13:46
...

tcp_subr.c (305.80 kB)

Need 1 point
Your Point(s)

Your Point isn't enough.

Get point immediately by PayPal

More(Debit card / Credit card / PayPal Credit / Online Banking)

Submit your source codes. Get more point

LOGIN

Don't have an account? Register now
Need any help?
Mail to: support@codeforge.com

切换到中文版?

CodeForge Chinese Version
CodeForge English Version

Where are you going?

^_^"Oops ...

Sorry!This guy is mysterious, its blog hasn't been opened, try another, please!
OK

Warm tip!

CodeForge to FavoriteFavorite by Ctrl+D