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

📄 tcp_subr.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
	int errno;{	struct socket *so = tp->t_inpcb->inp_socket;	int s;	if (smp_debug){		if (smp_owner(&so->lk_socket) == 0)			panic("tcp_drop not lock owner");	}	if (TCPS_HAVERCVDSYN(tp->t_state)) {		tp->t_state = TCPS_CLOSED;		(void) tcp_output(tp);		TCPSTAT(tcps_drops++);	} else{		TCPSTAT(tcps_conndrops++);	}	so->so_error = errno;	return (tcp_close(tp));}/* * Close a TCP control block: *	discard all space held by the tcp *	discard internet protocol block *	wake up any sleepers *//* SMP:  Enter with a socket lock set. */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;	int s; 				/* SMP */	struct socket *so_tmp = NULL;	/* SMP */	int status = 0;			/* SMP */	struct inpcb *inp_tmp = NULL;	/* SMP */	struct socket *so_addr = NULL;	/* SMP */	if (smp_debug){		if (smp_owner(&so->lk_socket) == 0)			panic("tcp_close not lock owner");	}	t = tp->seg_next;	while (t != (struct tcpiphdr *)tp) {		t = (struct tcpiphdr *)t->ti_next;		m = dtom(t->ti_prev);		remque(t->ti_prev);		m_freem(m);	}	if (tp->t_template)		(void) m_free(dtom(tp->t_template));	/* Note that the manipulation with owner and the lk_tcb here	 * is due to the fact that when we are called from the timers,	 * lk_tcb is already set. */   if (smp){		if (smp_owner(&lk_tcb) == 1){#ifdef old		(void) m_free(dtom(tp));#endif		KM_FREE(tp, KM_PCB);		inp->inp_ppcb = 0;		soisdisconnected(so);		in_pcbdetach(inp);		TCPSTAT(tcps_closed++);		return ((struct tcpcb *)0);	}	{		int owner = 0;	if (( so->so_head) && (smp_owner(&so->so_head->lk_socket)) == 1){		owner = 1;		so->so_head->ref = 28;		smp_unlock(&so->so_head->lk_socket);		}	so->ref = 10;	smp_unlock(&so->lk_socket);	smp_lock(&lk_tcb, LK_RETRY);	smp_lock(&so->lk_socket, LK_RETRY);	so->ref = 0;	if (owner){		smp_lock(&so->so_head->lk_socket, LK_RETRY);		so->so_head->ref = 0;		owner = 0;		}	}   }	#ifdef old	(void) m_free(dtom(tp));#endif	KM_FREE(tp, KM_PCB);	inp->inp_ppcb = 0;	soisdisconnected(so);	in_pcbdetach(inp);	smp_unlock(&lk_tcb);	TCPSTAT(tcps_closed++);	return ((struct tcpcb *)0);}tcp_drain(){}/* * Notify a tcp user of an asynchronous error; * just wake up so that he can collect error status. */tcp_notify(inp)	register struct inpcb *inp;{	/* Ensure that socket is locked before	 * doing wakeups because low level wakeup routines write	 * to the socket.  	 */	/* Note that here, lk_tcb is already held so if we use	 * SO_LOCK, then SO_LOCK could find so->ref busy and spin	 * with lk_tcb held.  This could result in a starvation	 * panic on lk_tcb.	 */	smp_lock(&inp->inp_socket->lk_socket, LK_RETRY);	wakeup((caddr_t) &inp->inp_socket->so_timeo);        sorwakeup(inp->inp_socket);	sowwakeup(inp->inp_socket);	smp_unlock(&inp->inp_socket->lk_socket);}tcp_ctlinput(cmd, sa)	int cmd;	struct sockaddr *sa;{	extern u_char inetctlerrmap[];	struct sockaddr_in *sin;	int tcp_quench(), in_rtchange();	int s;	if ((unsigned) cmd > PRC_NCMDS)		return;	if (sa->sa_family != AF_INET && sa->sa_family != AF_IMPLINK)		return;	sin = (struct sockaddr_in *)sa;	if (sin->sin_addr.s_addr == INADDR_ANY)		return;	switch (cmd) {	case PRC_QUENCH:		s = splnet(); 		smp_lock(&lk_tcb, LK_RETRY);		in_pcbnotify(&tcb, &sin->sin_addr, 0, tcp_quench);		smp_unlock(&lk_tcb);		splx(s);		break;	case PRC_ROUTEDEAD:	case PRC_REDIRECT_NET:	case PRC_REDIRECT_HOST:	case PRC_REDIRECT_TOSNET:	case PRC_REDIRECT_TOSHOST:		s = splnet(); /* SMP */		smp_lock(&lk_tcb, LK_RETRY);		in_pcbnotify(&tcb, &sin->sin_addr, 0, in_rtchange);		smp_unlock(&lk_tcb);		splx(s);		break;	default:		if (inetctlerrmap[cmd] == 0)			return;		/* XXX */		s = splnet(); /* SMP */		smp_lock(&lk_tcb, LK_RETRY);		in_pcbnotify(&tcb, &sin->sin_addr, (int)inetctlerrmap[cmd], 			tcp_notify);		smp_unlock(&lk_tcb);		splx(s);	}}/* * When a source quench is received, close congestion window * to one segment.  We will gradually open it again as we proceed. */tcp_quench(inp)	struct inpcb *inp;{	struct tcpcb *tp = intotcpcb(inp);	if(tp)		tp->snd_cwnd = tp->t_maxseg;}#ifdef XTI/* * KEY * --- * so   - socket pointer * inp  - internet control block pointer * tp   - tcp control block pointer * fd   - file desciptor * * STATE        MINIMUM MAPPING * ----------   ----------------------------- * T_UNINIT     (getsock(fd) == 0)) * T_UNBND      (getsock(fd) > 0) * T_IDLE	(inp->inp_lport || inp->inp_fport) * T_OUTCON     (so->so_state & SS_ISCONNECTING)  * T_INCON      (((so->so_options & SO_ACCEPTCONN) && so->so_qlen > 0) || *              ((so->so_options & SO_ACCEPTCONN) && (so->so_state & SS_NBIO))) *               * T_DATAXFER   (so->so_state & SS_ISCONNECTED)  * T_OUTREL     ((so->so_state & SS_CANTSENDMORE) &&  *	          (tp->t_state >= TCPS_FIN_WAIT_1)) * T_INREL      ((!(so->so_state & SS_CANTSENDMORE)) &&  *	          (tp->t_state >= TCPS_CLOSE_WAIT)) */tcp_to_xtistate(so)     struct socket *so;{  int status;  int default_state;  struct inpcb *inp;  struct tcpcb *tp;  /*   * determine what state we are in   */  /*   * we are already past T_UNINIT state, because   * if we were a bogus descriptor or a non-socket descriptor we   * would have been caught.   */  default_state = T_UNBND;  if (so)     inp = (struct inpcb *) so->so_pcb;  if (inp)    tp = (struct tcpcb *) inp->inp_ppcb;  if (inp)    if (inp->inp_lport || inp->inp_fport) {      default_state = T_IDLE;    } else {      return(default_state);    }  else    return(default_state);  if (so) {    if (so->so_state & SS_ISCONNECTING) {      default_state = T_OUTCON;    } else if ((so->so_options & SO_ACCEPTCONN) && so->so_qlen != 0) {      default_state = T_INCON;    } else if ((so->so_options & SO_ACCEPTCONN) && (so->so_state & SS_NBIO)) {      default_state = T_INCON;    } else if (so->so_state & SS_ISCONNECTED) {      default_state = T_DATAXFER;    }  }    if (tp) {    if ((so->so_state & SS_CANTSENDMORE) && 	(tp->t_state >= TCPS_FIN_WAIT_1)) {      default_state = T_OUTREL;    } else if ((!(so->so_state & SS_CANTSENDMORE)) &&	       (tp->t_state >= TCPS_CLOSE_WAIT)) {      default_state = T_INREL;    }  }  return(default_state);}/* * Close a TCP control block: *	discard all space held by the tcp *	DONT discard internet protocol block *	wake up any sleepers *//* SMP:  Remove tp pointer only if no other routines are using it. * Enter with socket lock set. */struct tcpcb *tcp_closekeepinp(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;	int s;	if (smp_debug){		if (smp_owner(&so->lk_socket) == 0)			panic("tcp_closekeepinp not lock owner");	}	t = tp->seg_next;	while (t != (struct tcpiphdr *)tp) {		t = (struct tcpiphdr *)t->ti_next;		m = dtom(t->ti_prev);		remque(t->ti_prev);		m_freem(m);	}	if (tp->t_template)		(void) m_free(dtom(tp->t_template));	KM_FREE(tp, KM_PCB);	inp->inp_ppcb = 0;	TCPSTAT(tcps_closed++);	return ((struct tcpcb *)0);}/* *	 * cannot use bcmp because of padding * values may differ. */int  cmp_xti_tcpopts(src, dst)struct tcp_options *src;struct tcp_options *dst;{  int trace = 0;#define CMPTCPOPT(member) \  if (src->member != dst->member) { \        return(trace); } \  trace++;  CMPTCPOPT(precedence);   CMPTCPOPT(timeout);   CMPTCPOPT(max_seg_size);   CMPTCPOPT(secopt.security);   CMPTCPOPT(secopt.compartment);   CMPTCPOPT(secopt.handling);   CMPTCPOPT(secopt.tcc);   return(0);}#endif XTI

⌨️ 快捷键说明

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