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

📄 tp_subr2.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
 */inttp_mask_to_num(x)	u_char x;{	register int j;	for(j = 4; j>=0 ;j--) {		if(x & (1<<j))			break;	}	ASSERT( (j == 4) || (j == 0) ); /* for now */	if( (j != 4) && (j != 0) ) {		printf("ASSERTION ERROR: tp_mask_to_num: x 0x%x j %d\n",			x, j);	}	IFTRACE(D_TPINPUT)		tptrace(TPPTmisc, "tp_mask_to_num(x) returns j", x, j, 0, 0);	ENDTRACE	IFDEBUG(D_TPINPUT)		printf("tp_mask_to_num(0x%x) returns 0x%x\n", x, j);	ENDDEBUG	return j;}static copyQOSparms(src, dst)	struct tp_conn_param *src, *dst;{	/* copy all but the bits stuff at the end */#define COPYSIZE (12 * sizeof(short))	bcopy((caddr_t)src, (caddr_t)dst, COPYSIZE);	dst->p_tpdusize = src->p_tpdusize;	dst->p_ack_strat = src->p_ack_strat;	dst->p_rx_strat = src->p_rx_strat;#undef COPYSIZE}/* * Determine a reasonable value for maxseg size. * If the route is known, check route for mtu. * We also initialize the congestion/slow start * window to be a single segment if the destination isn't local. * While looking at the routing entry, we also initialize other path-dependent * parameters from pre-set or cached values in the routing entry. */voidtp_mss(tpcb, nhdr_size)	register struct tp_pcb *tpcb;	int nhdr_size;{	register struct rtentry *rt;	struct ifnet *ifp;	register int rtt, mss;	u_long bufsize;	int i, ssthresh = 0, rt_mss;	struct socket *so;	if (tpcb->tp_ptpdusize)		mss = tpcb->tp_ptpdusize << 7;	else		mss = 1 << tpcb->tp_tpdusize;	so = tpcb->tp_sock;	if ((rt = *(tpcb->tp_routep)) == 0) {		bufsize = so->so_rcv.sb_hiwat;		goto punt_route;	}	ifp = rt->rt_ifp;#ifdef RTV_MTU	/* if route characteristics exist ... */	/*	 * While we're here, check if there's an initial rtt	 * or rttvar.  Convert from the route-table units	 * to hz ticks for the smoothed timers and slow-timeout units	 * for other inital variables.	 */	if (tpcb->tp_rtt == 0 && (rtt = rt->rt_rmx.rmx_rtt)) {		tpcb->tp_rtt = rtt * hz / RTM_RTTUNIT;		if (rt->rt_rmx.rmx_rttvar)			tpcb->tp_rtv = rt->rt_rmx.rmx_rttvar						* hz / RTM_RTTUNIT;		else			tpcb->tp_rtv = tpcb->tp_rtt;	}	/*	 * if there's an mtu associated with the route, use it	 */	if (rt->rt_rmx.rmx_mtu)		rt_mss = rt->rt_rmx.rmx_mtu - nhdr_size;	else#endif /* RTV_MTU */		rt_mss = (ifp->if_mtu - nhdr_size);	if (tpcb->tp_ptpdusize == 0 || /* assume application doesn't care */	    mss > rt_mss /* network won't support what was asked for */)		mss = rt_mss;	/* can propose mtu which are multiples of 128 */	mss &= ~0x7f;	/*	 * If there's a pipesize, change the socket buffer	 * to that size.	 */#ifdef RTV_SPIPE	if ((bufsize = rt->rt_rmx.rmx_sendpipe) > 0) {#endif		bufsize = min(bufsize, so->so_snd.sb_hiwat);		(void) sbreserve(&so->so_snd, bufsize);	}#ifdef RTV_SPIPE	if ((bufsize = rt->rt_rmx.rmx_recvpipe) > 0) {#endif		bufsize = min(bufsize, so->so_rcv.sb_hiwat);		(void) sbreserve(&so->so_rcv, bufsize);	} else		bufsize = so->so_rcv.sb_hiwat;#ifdef RTV_SSTHRESH	/*	 * There's some sort of gateway or interface	 * buffer limit on the path.  Use this to set	 * the slow start threshhold, but set the	 * threshold to no less than 2*mss.	 */	ssthresh = rt->rt_rmx.rmx_ssthresh;punt_route:	/*	 * The current mss is initialized to the default value.	 * If we compute a smaller value, reduce the current mss.	 * If we compute a larger value, return it for use in sending	 * a max seg size option.	 * If we received an offer, don't exceed it.	 * However, do not accept offers under 128 bytes.	 */	if (tpcb->tp_l_tpdusize)		mss = min(mss, tpcb->tp_l_tpdusize);	/*	 * We want a minimum recv window of 4 packets to	 * signal packet loss by duplicate acks.	 */	mss = min(mss, bufsize >> 2) & ~0x7f;	mss = max(mss, 128);		/* sanity */	tpcb->tp_cong_win =		(rt == 0 || (rt->rt_flags & RTF_GATEWAY)) ? mss : bufsize;	tpcb->tp_l_tpdusize = mss;	tp_rsyset(tpcb);	tpcb->tp_ssthresh = max(2 * mss, ssthresh);	/* Calculate log2 of mss */	for (i = TP_MIN_TPDUSIZE + 1; i <= TP_MAX_TPDUSIZE; i++)		if ((1 << i) > mss)			break;	i--;	tpcb->tp_tpdusize = i;#endif /* RTV_MTU */}/* * CALLED FROM: *  tp_usrreq on PRU_CONNECT and tp_input on receipt of CR *	 * FUNCTION and ARGUMENTS: * 	-- An mbuf containing the peer's network address. *  -- Our control block, which will be modified *  -- In the case of cons, a control block for that layer. * *	 * RETURNS: *	errno value	 :  *	EAFNOSUPPORT if can't find an nl_protosw for x.25 (really could panic) *	ECONNREFUSED if trying to run TP0 with non-type 37 address *  possibly other E* returned from cons_netcmd() * * SIDE EFFECTS: *   Determines recommended tpdusize, buffering and intial delays *	 based on information cached on the route. */inttp_route_to( m, tpcb, channel)	struct mbuf					*m;	register struct tp_pcb		*tpcb;	caddr_t 					channel;{	register struct sockaddr_iso *siso;	/* NOTE: this may be a sockaddr_in */	extern struct tp_conn_param tp_conn_param[];	int error = 0, save_netservice = tpcb->tp_netservice;	register struct rtentry *rt = 0;	int nhdr_size, mtu, bufsize;	siso = mtod(m, struct sockaddr_iso *);	IFTRACE(D_CONN)		tptraceTPCB(TPPTmisc, 		"route_to: so  afi netservice class",		tpcb->tp_sock, siso->siso_addr.isoa_genaddr[0], tpcb->tp_netservice,			tpcb->tp_class);	ENDTRACE	IFDEBUG(D_CONN)		printf("tp_route_to( m x%x, channel 0x%x, tpcb 0x%x netserv 0x%x)\n", 			m, channel, tpcb, tpcb->tp_netservice);		printf("m->mlen x%x, m->m_data:\n", m->m_len);		dump_buf(mtod(m, caddr_t), m->m_len);	ENDDEBUG	if (channel) {#ifdef TPCONS		struct pklcd *lcp = (struct pklcd *)channel;		struct isopcb *isop = (struct isopcb *)lcp->lcd_upnext,			*isop_new = (struct isopcb *)tpcb->tp_npcb;		/* The next 2 lines believe that you haven't		   set any network level options or done a pcbconnect		   and XXXXXXX'edly apply to both inpcb's and isopcb's */		remque(isop_new);		free(isop_new, M_PCB);		tpcb->tp_npcb = (caddr_t)isop;		tpcb->tp_netservice = ISO_CONS;		tpcb->tp_nlproto = nl_protosw + ISO_CONS;		if (isop->isop_refcnt++ == 0) {			iso_putsufx(isop, tpcb->tp_lsuffix, tpcb->tp_lsuffixlen, TP_LOCAL);			isop->isop_socket = tpcb->tp_sock;		} else			/* there are already connections sharing this */;#endif	} else {		switch (siso->siso_family) {		default:			error = EAFNOSUPPORT;			goto done;#ifdef ISO		case AF_ISO:		{			struct isopcb *isop = (struct isopcb *)tpcb->tp_npcb;			int flags = tpcb->tp_sock->so_options & SO_DONTROUTE;			tpcb->tp_netservice = ISO_CLNS;			if (clnp_route(&siso->siso_addr, &isop->isop_route,							flags, (void **)0, (void **)0) == 0) {				rt = isop->isop_route.ro_rt;				if (rt && rt->rt_flags & RTF_PROTO1)					tpcb->tp_netservice = ISO_CONS;			}		}    break;#endif#ifdef INET		case AF_INET:			tpcb->tp_netservice = IN_CLNS;#endif		}		if (tpcb->tp_nlproto->nlp_afamily != siso->siso_family) {			IFDEBUG(D_CONN)				printf("tp_route_to( CHANGING nlproto old 0x%x new 0x%x)\n", 						save_netservice, tpcb->tp_netservice);			ENDDEBUG			if (error = tp_set_npcb(tpcb))				goto done;		}		IFDEBUG(D_CONN)			printf("tp_route_to  calling nlp_pcbconn, netserv %d\n",				tpcb->tp_netservice);		ENDDEBUG		tpcb->tp_nlproto = nl_protosw + tpcb->tp_netservice;		error = (tpcb->tp_nlproto->nlp_pcbconn)(tpcb->tp_npcb, m);	}	if (error)		goto done;	nhdr_size = tpcb->tp_nlproto->nlp_mtu(tpcb); /* only gets common info */	tp_mss(tpcb, nhdr_size);done:	IFDEBUG(D_CONN)		printf("tp_route_to  returns 0x%x\n", error);	ENDDEBUG	IFTRACE(D_CONN)		tptraceTPCB(TPPTmisc, "route_to: returns: error netserv class", error, 			tpcb->tp_netservice, tpcb->tp_class, 0);	ENDTRACE	return error;}/* class zero version */voidtp0_stash( tpcb, e )	register struct tp_pcb		*tpcb;	register struct tp_event	*e;{#ifndef lint#define E e->ATTR(DT_TPDU)#else /* lint */#define E e->ev_union.EV_DT_TPDU#endif /* lint */	register struct sockbuf *sb = &tpcb->tp_sock->so_rcv;	register struct isopcb *isop = (struct isopcb *)tpcb->tp_npcb;	IFPERF(tpcb)		PStat(tpcb, Nb_from_ll) += E.e_datalen;		tpmeas(tpcb->tp_lref, TPtime_from_ll, &e->e_time,				E.e_seq, PStat(tpcb, Nb_from_ll), E.e_datalen);	ENDPERF	IFDEBUG(D_STASH)		printf("stash EQ: seq 0x%x datalen 0x%x eot 0x%x", 		E.e_seq, E.e_datalen, E.e_eot);	ENDDEBUG	IFTRACE(D_STASH)		tptraceTPCB(TPPTmisc, "stash EQ: seq len eot", 		E.e_seq, E.e_datalen, E.e_eot, 0);	ENDTRACE	if ( E.e_eot ) {		register struct mbuf *n = E.e_data;		n->m_flags |= M_EOR;		n->m_act = MNULL; /* set on tp_input */	}	sbappend(sb, E.e_data);	IFDEBUG(D_STASH)		dump_mbuf(sb->sb_mb, "stash 0: so_rcv after appending");	ENDDEBUG	if (tpcb->tp_netservice != ISO_CONS)		printf("tp0_stash: tp running over something wierd\n");	else {		register struct pklcd *lcp = (struct pklcd *)isop->isop_chan;		pk_flowcontrol(lcp, sbspace(sb) <= 0, 1);	}} voidtp0_openflow(tpcb)register struct tp_pcb *tpcb;{	register struct isopcb *isop = (struct isopcb *)tpcb->tp_npcb;	if (tpcb->tp_netservice != ISO_CONS)		printf("tp0_openflow: tp running over something wierd\n");	else {		register struct pklcd *lcp = (struct pklcd *)isop->isop_chan;		if (lcp->lcd_rxrnr_condition)			pk_flowcontrol(lcp, 0, 0);	}}#ifndef TPCONSstaticpk_flowcontrol() {}#endif#ifdef TP_PERF_MEAS/* * CALLED FROM: *  tp_ctloutput() when the user sets TPOPT_PERF_MEAS on *  and tp_newsocket() when a new connection is made from  *  a listening socket with tp_perf_on == true. * FUNCTION and ARGUMENTS: *  (tpcb) is the usual; this procedure gets a clear cluster mbuf for *  a tp_pmeas structure, and makes tpcb->tp_p_meas point to it. * RETURN VALUE: *  ENOBUFS if it cannot get a cluster mbuf. */int tp_setup_perf(tpcb)	register struct tp_pcb *tpcb;{	register struct mbuf *q;	if( tpcb->tp_p_meas == 0 ) {		MGET(q, M_WAITOK, MT_PCB);		if (q == 0)			return ENOBUFS;		MCLGET(q, M_WAITOK);		if ((q->m_flags & M_EXT) == 0) {			(void) m_free(q);			return ENOBUFS;		}		q->m_len = sizeof (struct tp_pmeas);		tpcb->tp_p_mbuf = q;		tpcb->tp_p_meas = mtod(q, struct tp_pmeas *);		bzero( (caddr_t)tpcb->tp_p_meas, sizeof (struct tp_pmeas) );		IFDEBUG(D_PERF_MEAS)			printf(			"tpcb 0x%x so 0x%x ref 0x%x tp_p_meas 0x%x tp_perf_on 0x%x\n", 				tpcb, tpcb->tp_sock, tpcb->tp_lref, 				tpcb->tp_p_meas, tpcb->tp_perf_on);		ENDDEBUG		tpcb->tp_perf_on = 1;	}	return 0;}#endif /* TP_PERF_MEAS */#ifdef ARGO_DEBUGdump_addr (addr)	register struct sockaddr *addr;{	switch( addr->sa_family ) {		case AF_INET:			dump_inaddr((struct sockaddr_in *)addr);			break;#ifdef ISO		case AF_ISO:			dump_isoaddr((struct sockaddr_iso *)addr);			break;#endif /* ISO */		default:			printf("BAD AF: 0x%x\n", addr->sa_family);			break;	}}#define	MAX_COLUMNS	8/* *	Dump the buffer to the screen in a readable format. Format is: * *		hex/dec  where hex is the hex format, dec is the decimal format. *		columns of hex/dec numbers will be printed, followed by the *		character representations (if printable). */Dump_buf(buf, len)caddr_t	buf;int		len;{	int		i,j;#define Buf ((u_char *)buf)	printf("Dump buf 0x%x len 0x%x\n", buf, len);	for (i = 0; i < len; i += MAX_COLUMNS) {		printf("+%d:\t", i);		for (j = 0; j < MAX_COLUMNS; j++) {			if (i + j < len) {				printf("%x/%d\t", Buf[i+j], Buf[i+j]);			} else {				printf("	");			}		}		for (j = 0; j < MAX_COLUMNS; j++) {			if (i + j < len) {				if (((Buf[i+j]) > 31) && ((Buf[i+j]) < 128))					printf("%c", Buf[i+j]);				else					printf(".");			}		}		printf("\n");	}}#endif /* ARGO_DEBUG */

⌨️ 快捷键说明

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