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

📄 tp_usrreq.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	struct mbuf *m, *nam, *controlp;{		register struct tp_pcb *tpcb =  sototpcb(so);	int s = splnet();	int error = 0;	int flags, *outflags = &flags; 	u_long eotsdu = 0;	struct tp_event E;	IFDEBUG(D_REQUEST)		printf("usrreq(0x%x,%d,0x%x,0x%x,0x%x)\n",so,req,m,nam,outflags);		if (so->so_error)			printf("WARNING!!! so->so_error is 0x%x\n", so->so_error);	ENDDEBUG	IFTRACE(D_REQUEST)		tptraceTPCB(TPPTusrreq, "req so m state [", req, so, m, 			tpcb?tpcb->tp_state:0);	ENDTRACE	if ((u_int)tpcb == 0 && req != PRU_ATTACH) {		IFTRACE(D_REQUEST)			tptraceTPCB(TPPTusrreq, "req failed NO TPCB[", 0, 0, 0, 0);		ENDTRACE		splx(s);		return ENOTCONN;	}	switch (req) {	case PRU_ATTACH:		if (tpcb) {			error = EISCONN;		} else if ((error = tp_attach(so, (int)nam)) == 0)			tpcb = sototpcb(so);		break;	case PRU_ABORT: 	/* called from close() */		/* called for each incoming connect queued on the 		 *	parent (accepting) socket 		 */		if (tpcb->tp_state == TP_OPEN || tpcb->tp_state == TP_CONFIRMING) {			E.ATTR(T_DISC_req).e_reason = E_TP_NO_SESSION;			error = DoEvent(T_DISC_req); /* pretend it was a close() */			break;		} /* else DROP THROUGH */	case PRU_DETACH: 	/* called from close() */		/* called only after disconnect was called */		error = DoEvent(T_DETACH);		if (tpcb->tp_state == TP_CLOSED) {			if (tpcb->tp_notdetached) {				IFDEBUG(D_CONN)					printf("PRU_DETACH: not detached\n");				ENDDEBUG				tp_detach(tpcb);			}			free((caddr_t)tpcb, M_PCB);			tpcb = 0;		}		break;	case PRU_SHUTDOWN:		/* recv end may have been released; local credit might be zero  */	case PRU_DISCONNECT:		E.ATTR(T_DISC_req).e_reason = E_TP_NORMAL_DISC;		error = DoEvent(T_DISC_req);		break;	case PRU_BIND:		error =  tp_pcbbind(tpcb, nam);		break;	case PRU_LISTEN:		if (tpcb->tp_state != TP_CLOSED || tpcb->tp_lsuffixlen == 0 ||				tpcb->tp_next == 0)			error = EINVAL;		else {			register struct tp_pcb **tt;			remque(tpcb);			tpcb->tp_next = tpcb->tp_prev = tpcb;			for (tt = &tp_listeners; *tt; tt = &((*tt)->tp_nextlisten))				if ((*tt)->tp_lsuffixlen)					break;			tpcb->tp_nextlisten = *tt;			*tt = tpcb;			error = DoEvent(T_LISTEN_req);		}		break;	case PRU_CONNECT2:		error = EOPNOTSUPP; /* for unix domain sockets */		break;	case PRU_CONNECT:		IFTRACE(D_CONN)			tptraceTPCB(TPPTmisc, 			"PRU_CONNECT: so 0x%x *SHORT_LSUFXP(tpcb) 0x%x lsuflen 0x%x, class 0x%x",			tpcb->tp_sock, *SHORT_LSUFXP(tpcb), tpcb->tp_lsuffixlen,				tpcb->tp_class);		ENDTRACE		IFDEBUG(D_CONN)			printf("PRU_CONNECT: so *SHORT_LSUFXP(tpcb) 0x%x lsuflen 0x%x, class 0x%x",			tpcb->tp_sock, *SHORT_LSUFXP(tpcb), tpcb->tp_lsuffixlen,				tpcb->tp_class);		ENDDEBUG		if (tpcb->tp_lsuffixlen == 0) {			if (error = tp_pcbbind(tpcb, MNULL)) {				IFDEBUG(D_CONN)					printf("pcbbind returns error 0x%x\n", error);				ENDDEBUG				break;			}		}		IFDEBUG(D_CONN)			printf("isop 0x%x isop->isop_socket offset 12 :\n", tpcb->tp_npcb);			dump_buf(tpcb->tp_npcb, 16);		ENDDEBUG		if (error = tp_route_to(nam, tpcb, /* channel */0))			break;		IFDEBUG(D_CONN)			printf(				"PRU_CONNECT after tpcb 0x%x so 0x%x npcb 0x%x flags 0x%x\n", 				tpcb, so, tpcb->tp_npcb, tpcb->tp_flags);			printf("isop 0x%x isop->isop_socket offset 12 :\n", tpcb->tp_npcb);			dump_buf(tpcb->tp_npcb, 16);		ENDDEBUG		if (tpcb->tp_fsuffixlen ==  0) {			/* didn't set peer extended suffix */			(tpcb->tp_nlproto->nlp_getsufx)(tpcb->tp_npcb, &tpcb->tp_fsuffixlen,				tpcb->tp_fsuffix, TP_FOREIGN);		}		if (tpcb->tp_state == TP_CLOSED) {			soisconnecting(so);  			error = DoEvent(T_CONN_req);		} else {			(tpcb->tp_nlproto->nlp_pcbdisc)(tpcb->tp_npcb);			error = EISCONN;		}		IFPERF(tpcb)			u_int lsufx, fsufx;			lsufx = *(u_short *)(tpcb->tp_lsuffix);			fsufx = *(u_short *)(tpcb->tp_fsuffix);			tpmeas(tpcb->tp_lref, 				TPtime_open | (tpcb->tp_xtd_format << 4), 				&time, lsufx, fsufx, tpcb->tp_fref);		ENDPERF		break;	case PRU_ACCEPT: 		(tpcb->tp_nlproto->nlp_getnetaddr)(tpcb->tp_npcb, nam, TP_FOREIGN);		IFDEBUG(D_REQUEST)			printf("ACCEPT PEERADDDR:");			dump_buf(mtod(nam, char *), nam->m_len);		ENDDEBUG		IFPERF(tpcb)			u_int lsufx, fsufx;			lsufx = *(u_short *)(tpcb->tp_lsuffix);			fsufx = *(u_short *)(tpcb->tp_fsuffix);			tpmeas(tpcb->tp_lref, TPtime_open, 				&time, lsufx, fsufx, tpcb->tp_fref);		ENDPERF		break;	case PRU_RCVD:		if (so->so_state & SS_ISCONFIRMING) {			if (tpcb->tp_state == TP_CONFIRMING)				error = tp_confirm(tpcb);			break;		}		IFTRACE(D_DATA)			tptraceTPCB(TPPTmisc,			"RCVD BF: lcredit sent_lcdt cc hiwat \n",				tpcb->tp_lcredit, tpcb->tp_sent_lcdt,				so->so_rcv.sb_cc, so->so_rcv.sb_hiwat);			LOCAL_CREDIT(tpcb);			tptraceTPCB(TPPTmisc, 				"PRU_RCVD AF sbspace lcredit hiwat cc",				sbspace(&so->so_rcv), tpcb->tp_lcredit,				so->so_rcv.sb_cc, so->so_rcv.sb_hiwat);		ENDTRACE		IFDEBUG(D_REQUEST)			printf("RCVD: cc %d space %d hiwat %d\n",				so->so_rcv.sb_cc, sbspace(&so->so_rcv),				so->so_rcv.sb_hiwat);		ENDDEBUG		if (((int)nam) & MSG_OOB)			error = DoEvent(T_USR_Xrcvd); 		else 			error = DoEvent(T_USR_rcvd); 		break;	case PRU_RCVOOB:		if ((so->so_state & SS_ISCONNECTED) == 0) {			error = ENOTCONN;			break;		}		if (! tpcb->tp_xpd_service) {			error = EOPNOTSUPP;			break;		}		/* kludge - nam is really flags here */		error = tp_rcvoob(tpcb, so, m, outflags, (int)nam);		break;	case PRU_SEND:	case PRU_SENDOOB:		if (controlp) {			error = tp_snd_control(controlp, so, &m);			controlp = NULL;			if (error)				break;		}		if ((so->so_state & SS_ISCONFIRMING) &&		    (tpcb->tp_state == TP_CONFIRMING) &&		    (error = tp_confirm(tpcb)))			    break;		if (req == PRU_SENDOOB) {			error = (tpcb->tp_xpd_service == 0) ?						EOPNOTSUPP : tp_sendoob(tpcb, so, m, outflags);			break;		}		if (m == 0)			break;		if (m->m_flags & M_EOR) {			eotsdu = 1;			m->m_flags &= ~M_EOR;		}		if (eotsdu == 0 && m->m_pkthdr.len == 0)			break;		if (tpcb->tp_state != TP_AKWAIT && tpcb->tp_state != TP_OPEN) {			error = ENOTCONN;			break;		}		/*		 * The protocol machine copies mbuf chains,		 * prepends headers, assigns seq numbers, and		 * puts the packets on the device.		 * When they are acked they are removed from the socket buf.		 *		 * sosend calls this up until sbspace goes negative.		 * Sbspace may be made negative by appending this mbuf chain,		 * possibly by a whole cluster.		 */		{			/*			 * Could have eotsdu and no data.(presently MUST have			 * an mbuf though, even if its length == 0) 			 */			int totlen = m->m_pkthdr.len;			struct sockbuf *sb = &so->so_snd;			IFPERF(tpcb)			   PStat(tpcb, Nb_from_sess) += totlen;			   tpmeas(tpcb->tp_lref, TPtime_from_session, 0, 0, 					PStat(tpcb, Nb_from_sess), totlen);			ENDPERF			IFDEBUG(D_SYSCALL)				printf(				"PRU_SEND: eot %d before sbappend 0x%x len 0x%x to sb @ 0x%x\n",					eotsdu, m, totlen, sb);				dump_mbuf(sb->sb_mb, "so_snd.sb_mb");				dump_mbuf(m, "m : to be added");			ENDDEBUG			tp_packetize(tpcb, m, eotsdu);			IFDEBUG(D_SYSCALL)				printf("PRU_SEND: eot %d after sbappend 0x%x\n", eotsdu, m);				dump_mbuf(sb->sb_mb, "so_snd.sb_mb");			ENDDEBUG			if (tpcb->tp_state == TP_OPEN)				error = DoEvent(T_DATA_req); 			IFDEBUG(D_SYSCALL)				printf("PRU_SEND: after driver error 0x%x \n",error);				printf("so_snd 0x%x cc 0t%d mbcnt 0t%d\n",						sb, sb->sb_cc, sb->sb_mbcnt);				dump_mbuf(sb->sb_mb, "so_snd.sb_mb after driver");			ENDDEBUG		}		break;	case PRU_SOCKADDR:		(tpcb->tp_nlproto->nlp_getnetaddr)(tpcb->tp_npcb, nam, TP_LOCAL);		break;	case PRU_PEERADDR:		(tpcb->tp_nlproto->nlp_getnetaddr)(tpcb->tp_npcb, nam, TP_FOREIGN);		break;	case PRU_CONTROL:		error = EOPNOTSUPP;		break;	case PRU_PROTOSEND:	case PRU_PROTORCV:	case PRU_SENSE:	case PRU_SLOWTIMO:	case PRU_FASTTIMO:		error = EOPNOTSUPP;		break;	default:#ifdef ARGO_DEBUG		printf("tp_usrreq UNKNOWN PRU %d\n", req);#endif /* ARGO_DEBUG */		error = EOPNOTSUPP;	}	IFDEBUG(D_REQUEST)		printf("%s, so 0x%x, tpcb 0x%x, error %d, state %d\n",			"returning from tp_usrreq", so, tpcb, error,			tpcb ? tpcb->tp_state : 0);	ENDDEBUG	IFTRACE(D_REQUEST)		tptraceTPCB(TPPTusrreq, "END req so m state [", req, so, m, 			tpcb ? tpcb->tp_state : 0);	ENDTRACE	if (controlp) {		m_freem(controlp);		printf("control data unexpectedly retained in tp_usrreq()");	}	splx(s);	return error;}tp_ltrace(so, uio)struct socket *so;struct uio *uio;{	IFTRACE(D_DATA)		register struct tp_pcb *tpcb =  sototpcb(so);		if (tpcb) {			tptraceTPCB(TPPTmisc, "sosend so resid iovcnt", so,				uio->uio_resid, uio->uio_iovcnt, 0);		}	ENDTRACE}tp_confirm(tpcb)register struct tp_pcb *tpcb;{	struct tp_event E;	if (tpcb->tp_state == TP_CONFIRMING)	    return DoEvent(T_ACPT_req);	printf("Tp confirm called when not confirming; tpcb 0x%x, state 0x%x\n",		tpcb, tpcb->tp_state);	return 0;}/* * Process control data sent with sendmsg() */tp_snd_control(m, so, data)	struct mbuf *m;	struct socket *so;	register struct mbuf **data;{	register struct cmsghdr *ch;	int error = 0;	if (m && m->m_len) {		ch = mtod(m, struct cmsghdr *);		m->m_len -= sizeof (*ch);		m->m_data += sizeof (*ch);		error = tp_ctloutput(PRCO_SETOPT,							 so, ch->cmsg_level, ch->cmsg_type, &m);		if (ch->cmsg_type == TPOPT_DISC_DATA) {			if (data && *data) {				m_freem(*data);				*data = 0;			}			error = tp_usrreq(so, PRU_DISCONNECT, (struct mbuf *)0,								(caddr_t)0, (struct mbuf *)0);		}	}	if (m)		m_freem(m);	return error;}

⌨️ 快捷键说明

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