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

📄 tp_usrreq.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * Copyright (c) 1991, 1993 *	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. * *	@(#)tp_usrreq.c	8.1 (Berkeley) 6/10/93 *//***********************************************************				Copyright IBM Corporation 1987                      All Rights ReservedPermission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and thatboth that copyright notice and this permission notice appear in supporting documentation, and that the name of IBM not beused in advertising or publicity pertaining to distribution of thesoftware without specific, written prior permission.  IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDINGALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALLIBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ORANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THISSOFTWARE.******************************************************************//* * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison *//*  * ARGO TP * * $Header: tp_usrreq.c,v 5.4 88/11/18 17:29:18 nhall Exp $ * $Source: /usr/argo/sys/netiso/RCS/tp_usrreq.c,v $ * * tp_usrreq(), the fellow that gets called from most of the socket code. * Pretty straighforward. * THe only really awful stuff here is the OOB processing, which is done * wholly here. * tp_rcvoob() and tp_sendoob() are contained here and called by tp_usrreq(). */#include <sys/param.h>#include <sys/systm.h>#include <sys/mbuf.h>#include <sys/socket.h>#include <sys/socketvar.h>#include <sys/domain.h>#include <sys/protosw.h>#include <sys/errno.h>#include <sys/time.h>#include <netiso/tp_param.h>#include <netiso/tp_timer.h>#include <netiso/tp_stat.h>#include <netiso/tp_seq.h>#include <netiso/tp_ip.h>#include <netiso/tp_pcb.h>#include <netiso/argo_debug.h>#include <netiso/tp_trace.h>#include <netiso/tp_meas.h>#include <netiso/iso.h>#include <netiso/iso_errno.h>int tp_attach(), tp_driver(), tp_pcbbind();int TNew;int TPNagle1, TPNagle2;struct tp_pcb *tp_listeners, *tp_intercepts;#ifdef ARGO_DEBUG/* * CALLED FROM: *  anywhere you want to debug... * FUNCTION and ARGUMENTS: *  print (str) followed by the control info in the mbufs of an mbuf chain (n) */voiddump_mbuf(n, str)	struct mbuf *n;	char *str;{	struct mbuf *nextrecord;	printf("dump %s\n", str);	if (n == MNULL)  {		printf("EMPTY:\n");		return;	}			while (n) {		nextrecord = n->m_act;		printf("RECORD:\n");		while (n) {			printf("%x : Len %x Data %x A %x Nx %x Tp %x\n",				n, n->m_len, n->m_data, n->m_act, n->m_next, n->m_type);#ifdef notdef			{				register char *p = mtod(n, char *);				register int i;				printf("data: ");				for (i = 0; i < n->m_len; i++) {					if (i%8 == 0)						printf("\n");					printf("0x%x ", *(p+i));				}				printf("\n");			}#endif /* notdef */			if (n->m_next == n) {				printf("LOOP!\n");				return;			}			n = n->m_next;		}		n = nextrecord;	}	printf("\n");}#endif /* ARGO_DEBUG *//* * CALLED FROM: *  tp_usrreq(), PRU_RCVOOB * FUNCTION and ARGUMENTS: * 	Copy data from the expedited data socket buffer into * 	the pre-allocated mbuf m. * 	There is an isomorphism between XPD TPDUs and expedited data TSDUs. * 	XPD tpdus are limited to 16 bytes of data so they fit in one mbuf. * RETURN VALUE: *  EINVAL if debugging is on and a disaster has occurred *  ENOTCONN if the socket isn't connected *  EWOULDBLOCK if the socket is in non-blocking mode and there's no *		xpd data in the buffer *  E* whatever is returned from the fsm. */tp_rcvoob(tpcb, so, m, outflags, inflags)	struct tp_pcb	*tpcb;	register struct socket	*so;	register struct mbuf 	*m;	int 		 	*outflags;	int 		 	inflags;{	register struct mbuf *n;	register struct sockbuf *sb = &so->so_rcv;	struct tp_event E;	int error = 0;	register struct mbuf **nn;	IFDEBUG(D_XPD)		printf("PRU_RCVOOB, sostate 0x%x\n", so->so_state);	ENDDEBUG	/* if you use soreceive */	if (m == MNULL)		return ENOBUFS;restart:	if ((((so->so_state & SS_ISCONNECTED) == 0)		 || (so->so_state & SS_ISDISCONNECTING) != 0) &&		(so->so_proto->pr_flags & PR_CONNREQUIRED)) {			return ENOTCONN;	}	/* Take the first mbuf off the chain.	 * Each XPD TPDU gives you a complete TSDU so the chains don't get 	 * coalesced, but one TSDU may span several mbufs.	 * Nevertheless, since n should have a most 16 bytes, it	 * will fit into m.  (size was checked in tp_input() )	 */	/*	 * Code for excision of OOB data should be added to	 * uipc_socket2.c (like sbappend).	 */		sblock(sb, M_WAITOK);	for (nn = &sb->sb_mb; n = *nn; nn = &n->m_act)		if (n->m_type == MT_OOBDATA)			break;	if (n == 0) {		IFDEBUG(D_XPD)			printf("RCVOOB: empty queue!\n");		ENDDEBUG		sbunlock(sb);		if (so->so_state & SS_NBIO) {			return  EWOULDBLOCK;		}		sbwait(sb);		goto restart;	}	m->m_len = 0;	/* Assuming at most one xpd tpdu is in the buffer at once */	while (n != MNULL) {		m->m_len += n->m_len;		bcopy(mtod(n, caddr_t), mtod(m, caddr_t), (unsigned)n->m_len);		m->m_data += n->m_len; /* so mtod() in bcopy() above gives right addr */		n = n->m_next;	}	m->m_data = m->m_dat;	m->m_flags |= M_EOR;	IFDEBUG(D_XPD)		printf("tp_rcvoob: xpdlen 0x%x\n", m->m_len);		dump_mbuf(so->so_rcv.sb_mb, "RCVOOB: Rcv socketbuf");		dump_mbuf(sb->sb_mb, "RCVOOB: Xrcv socketbuf");	ENDDEBUG	if ((inflags & MSG_PEEK) == 0) {		n = *nn;		*nn = n->m_act;		for (; n; n = m_free(n)) 			sbfree(sb, n);	}release:	sbunlock(sb);	IFTRACE(D_XPD)		tptraceTPCB(TPPTmisc, "PRU_RCVOOB @ release sb_cc m_len",			tpcb->tp_Xrcv.sb_cc, m->m_len, 0, 0);	ENDTRACE	if (error == 0)		error = DoEvent(T_USR_Xrcvd); 	return error;}/* * CALLED FROM: *  tp_usrreq(), PRU_SENDOOB * FUNCTION and ARGUMENTS: * 	Send what's in the mbuf chain (m) as an XPD TPDU. * 	The mbuf may not contain more then 16 bytes of data. * 	XPD TSDUs aren't segmented, so they translate into * 	exactly one XPD TPDU, with EOT bit set. * RETURN VALUE: *  EWOULDBLOCK if socket is in non-blocking mode and the previous *   xpd data haven't been acked yet. *  EMSGSIZE if trying to send > max-xpd bytes (16) *  ENOBUFS if ran out of mbufs */tp_sendoob(tpcb, so, xdata, outflags)	struct tp_pcb	*tpcb;	register struct socket	*so;	register struct mbuf 	*xdata;	int 		 	*outflags; /* not used */{	/*	 * Each mbuf chain represents a sequence # in the XPD seq space.	 * The first one in the queue has sequence # tp_Xuna.	 * When we add to the XPD queue, we stuff a zero-length	 * mbuf (mark) into the DATA queue, with its sequence number in m_next	 * to be assigned to this XPD tpdu, so data xfer can stop	 * when it reaches the zero-length mbuf if this XPD TPDU hasn't	 * yet been acknowledged.  	 */	register struct sockbuf *sb = &(tpcb->tp_Xsnd);	register struct mbuf 	*xmark;	register int 			len=0;	struct tp_event E;	IFDEBUG(D_XPD)		printf("tp_sendoob:");		if (xdata)			printf("xdata len 0x%x\n", xdata->m_len);	ENDDEBUG	/* DO NOT LOCK the Xsnd buffer!!!! You can have at MOST one 	 * socket buf locked at any time!!! (otherwise you might	 * sleep() in sblock() w/ a signal pending and cause the	 * system call to be aborted w/ a locked socketbuf, which	 * is a problem.  So the so_snd buffer lock	 * (done in sosend()) serves as the lock for Xpd.	 */	if (sb->sb_mb) { /* Anything already in eXpedited data sockbuf? */		if (so->so_state & SS_NBIO) {			return EWOULDBLOCK;		}		while (sb->sb_mb) {			sbunlock(&so->so_snd); /* already locked by sosend */			sbwait(&so->so_snd);			sblock(&so->so_snd, M_WAITOK);  /* sosend will unlock on return */		}	}	if (xdata == (struct mbuf *)0) {		/* empty xpd packet */		MGETHDR(xdata, M_WAIT, MT_OOBDATA);		if (xdata == NULL) {			return ENOBUFS;		}		xdata->m_len = 0;		xdata->m_pkthdr.len = 0;	}	IFDEBUG(D_XPD)		printf("tp_sendoob 1:");		if (xdata)			printf("xdata len 0x%x\n", xdata->m_len);	ENDDEBUG	xmark = xdata; /* temporary use of variable xmark */	while (xmark) {		len += xmark->m_len;		xmark = xmark->m_next;	}	if (len > TP_MAX_XPD_DATA) {		return EMSGSIZE;	}	IFDEBUG(D_XPD)		printf("tp_sendoob 2:");		if (xdata)			printf("xdata len 0x%x\n", len);	ENDDEBUG	IFTRACE(D_XPD)		tptraceTPCB(TPPTmisc, "XPD mark m_next ", xdata->m_next, 0, 0, 0);	ENDTRACE	sbappendrecord(sb, xdata);		IFDEBUG(D_XPD)		printf("tp_sendoob len 0x%x\n", len);		dump_mbuf(so->so_snd.sb_mb, "XPD request Regular sndbuf:");		dump_mbuf(tpcb->tp_Xsnd.sb_mb, "XPD request Xsndbuf:");	ENDDEBUG	return DoEvent(T_XPD_req); }/* * CALLED FROM: *  the socket routines * FUNCTION and ARGUMENTS: * 	Handles all "user requests" except the [gs]ockopts() requests. * 	The argument (req) is the request type (PRU*),  * 	(m) is an mbuf chain, generally used for send and * 	receive type requests only. * 	(nam) is used for addresses usually, in particular for the bind request. *  *//*ARGSUSED*/ProtoHooktp_usrreq(so, req, m, nam, controlp)	struct socket *so;	u_int req;

⌨️ 快捷键说明

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