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

📄 inet.c

📁 7号信令功能代码,为开源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	ensure(ss->sock->ops, return (-EFAULT));	ensure(ss->sock->ops->connect, return (-EFAULT));	if ((err =	     ss->sock->ops->connect(ss->sock, dst, sizeof(*dst),				    O_NONBLOCK)) == 0 || err == -EINPROGRESS) {		return (0);	}	printd(("%s: %p: ERROR: from sock->ops->connect %d\n", SS_MOD_NAME, ss, err));	return (err);}/*  *  SOCKET SENDMSG *  ------------------------------------------------------------------------ */STATIC intss_sendmsg(ss_t * ss, struct msghdr *msg, int len){	int res;	ensure(ss, return (-EFAULT));	ensure(ss->sock, return (-EFAULT));	ensure(ss->sock->ops, return (-EFAULT));	ensure(ss->sock->ops->sendmsg, return (-EFAULT));	ensure(ss->sock->sk, return (-EFAULT));	ensure(ss->sock->sk->prot, return (-EFAULT));	ensure(ss->sock->sk->prot->sendmsg, return (-EFAULT));	{		mm_segment_t fs = get_fs();		set_fs(KERNEL_DS);		res = sock_sendmsg(ss->sock, msg, len);		set_fs(fs);	}	if (res <= 0)		printd(("%s: %p: ERROR: from sock->sk->prot->sendmsg %d\n", SS_MOD_NAME, ss, res));	return (res);}/*  *  SOCKET RECVMSG *  ------------------------------------------------------------------------ */STATIC intss_recvmsg(ss_t * ss, struct msghdr *msg, int size){	int res;	int sflags = MSG_DONTWAIT | MSG_NOSIGNAL;	ensure(ss, return (-EFAULT));	ensure(ss->sock, return (-EFAULT));	ensure(ss->sock->ops, return (-EFAULT));	ensure(ss->sock->ops->recvmsg, return (-EFAULT));	ensure(ss->sock->sk, return (-EFAULT));	ensure(ss->sock->sk->prot, return (-EFAULT));	ensure(ss->sock->sk->prot->recvmsg, return (-EFAULT));	{		mm_segment_t fs = get_fs();		set_fs(KERNEL_DS);		res = sock_recvmsg(ss->sock, msg, size, sflags);		set_fs(fs);	}	if (res < 0)		printd(("%s: %p: ERROR: from sock->ops->recvmsg %d\n", SS_MOD_NAME, ss, res));	return (res);}/*  *  SOCKET DISCONNECT *  ------------------------------------------------------------------------ *  Performing a sock_release (ss_socket_put) from the established state does *  not affect an abortive release for TCP, but rather, initiates an orderly *  shutdown rather than an abortive release.  We can try performing a *  protocol disconnect and see if that works better. */STATIC intss_disconnect(ss_t * ss){	int err;	ensure(ss, return (-EFAULT));	ensure(ss->sock->ops, return (-EFAULT));	ensure(ss->sock->ops->connect, return (-EFAULT));	ensure(ss->sock->sk, return (-EFAULT));	ensure(ss->sock->sk->prot, return (-EFAULT));	ensure(ss->sock->sk->prot->disconnect, return (-EFAULT));	if (!(err = ss->sock->sk->prot->disconnect(ss->sock->sk, O_NONBLOCK))) {		ss->sock->state = SS_UNCONNECTED;		return (0);	}	ss->sock->state = SS_DISCONNECTING;	printd(("%s: %p: ERROR: from sock->sk->prot->disconnect %d\n", SS_MOD_NAME, ss, err));	return (err);}/*  *  ========================================================================= * *  IP T-Provider --> T-User Primitives (Indication, Confirmation and Ack) * *  ========================================================================= *//*  *  M_ERROR *  --------------------------------------------------------------- */STATIC intm_error(queue_t *q, int error){	ss_t *ss = PRIV(q);	mblk_t *mp;	int hangup = 0;	if (error < 0)		error = -error;	switch (error) {	case EBUSY:	case ENOBUFS:	case EAGAIN:	case ENOMEM:		return (-error);	case EPIPE:	case ENETDOWN:	case EHOSTUNREACH:		hangup = 1;	}	if ((mp = ss_allocb(q, 2, BPRI_HI))) {		if (ss->sock)			ss_socket_put(xchg(&ss->sock, NULL));		if (hangup) {			printd(("%s: %p: <- M_HANGUP\n", SS_MOD_NAME, ss));			mp->b_datap->db_type = M_HANGUP;			putnext(ss->rq, mp);			error = EPIPE;		} else {			printd(("%s: %p: <- M_ERROR %d\n", SS_MOD_NAME, ss, error));			mp->b_datap->db_type = M_ERROR;			*(mp->b_wptr)++ = error;			*(mp->b_wptr)++ = error;			putnext(ss->rq, mp);		}		return (-error);	}	rare();	return (-ENOBUFS);}/*  *  T_CONN_IND          11 - Connection Indication *  --------------------------------------------------------------- */STATIC intt_conn_ind(queue_t *q, struct sockaddr *src, ss_opts_t * opts, mblk_t *cp){	ss_t *ss = PRIV(q);	mblk_t *mp;	struct T_conn_ind *p;	size_t src_len = ss_addr_size(ss, src);	size_t opt_len = ss_opts_size(ss, opts);	if (bufq_length(&ss->conq) <= ss->conind) {		if (canputnext(ss->rq)) {			if ((mp = ss_allocb(q, sizeof(*p) + src_len + opt_len, BPRI_MED))) {				mp->b_datap->db_type = M_PROTO;				p = ((typeof(p)) mp->b_wptr)++;				p->PRIM_type = T_CONN_IND;				p->SRC_length = src_len;				p->SRC_offset = src_len ? sizeof(*p) : 0;				p->OPT_length = opt_len;				p->OPT_offset = opt_len ? sizeof(*p) + src_len : 0;				p->SEQ_number = (ulong) cp;				if (src_len) {					bcopy(src, mp->b_wptr, src_len);					mp->b_wptr += src_len;				}				if (opt_len) {					ss_build_opts(ss, opts, &mp->b_wptr);				}				bufq_queue(&ss->conq, cp);				ss_set_state(ss, TS_WRES_CIND);				printd(("%s: %p: <- T_CONN_IND\n", SS_MOD_NAME, ss));				putnext(ss->rq, mp);				return (QR_ABSORBED);	/* absorbed cp */			}			ptrace(("%s: ERROR: no buffers\n", SS_MOD_NAME));			return (-ENOBUFS);		}		ptrace(("%s: ERROR: flow controlled\n", SS_MOD_NAME));		return (-EBUSY);	}	ptrace(("%s: ERROR: too many conn inds\n", SS_MOD_NAME));	return (-EAGAIN);}/*  *  T_CONN_CON          12 - Connection Confirmation *  --------------------------------------------------------------- */STATIC intt_conn_con(queue_t *q, struct sockaddr *res, ss_opts_t * opts, mblk_t *dp){	ss_t *ss = PRIV(q);	mblk_t *mp;	struct T_conn_con *p;	size_t res_len = ss_addr_size(ss, res);	size_t opt_len = ss_opts_size(ss, opts);	/* 	 * this shouldn't happen, we probably shouldn't even check 	 */	if (canputnext(ss->rq)) {		if ((mp = ss_allocb(q, sizeof(*p) + res_len + opt_len, BPRI_MED))) {			mp->b_datap->db_type = M_PROTO;			mp->b_band = 1;	/* expedite */			p = ((typeof(p)) mp->b_wptr)++;			p->PRIM_type = T_CONN_CON;			p->RES_length = res_len;			p->RES_offset = res_len ? sizeof(*p) : 0;			p->OPT_length = opt_len;			p->OPT_offset = opt_len ? sizeof(*p) + res_len : 0;			if (res_len) {				bcopy(res, mp->b_wptr, res_len);				mp->b_wptr += res_len;			}			if (opt_len) {				ss_build_opts(ss, opts, &mp->b_wptr);			}			ss_set_state(ss, TS_DATA_XFER);			printd(("%s: %p: <- T_CONN_CON\n", SS_MOD_NAME, ss));			putnext(ss->rq, mp);			return (0);		}		ptrace(("%s: ERROR: no buffers\n", SS_MOD_NAME));		return (-ENOBUFS);	}	ptrace(("%s: ERROR: flow controlled\n", SS_MOD_NAME));	return (-EBUSY);}/*  *  T_DISCON_IND        13 - Disconnect Indication *  --------------------------------------------------------------- */STATIC mblk_t *t_seq_find(ss_t * ss, mblk_t *rp){	mblk_t *mp;	if ((mp = rp)) {		struct sock *sk = ((ss_event_t *) rp->b_rptr)->sk;		lis_spin_lock(&ss->conq.q_lock);		{			for (mp = bufq_head(&ss->conq); mp && ((ss_event_t *) mp->b_rptr)->sk != sk;			     mp = mp->b_next) ;		}		lis_spin_unlock(&ss->conq.q_lock);	}	return (mp);}STATIC ulongt_seq_delete(ss_t * ss, mblk_t *rp){	mblk_t *mp;	if ((mp = t_seq_find(ss, rp))) {		struct socket *sock = NULL;		if (!ss_accept(ss, &sock, rp) && sock)			sock_release(sock);		return ((ulong) mp);	}	return (0);}STATIC intt_discon_ind(queue_t *q, struct sockaddr *res, uint orig, uint reason, mblk_t *cp, mblk_t *dp){	ss_t *ss = PRIV(q);	mblk_t *mp;	struct T_discon_ind *p;	ulong seq = 0;	(void) res;	if (canputnext(ss->rq)) {		if ((mp = ss_allocb(q, sizeof(*p), BPRI_MED))) {			if (!cp || (seq = t_seq_delete(ss, cp))) {				mp->b_datap->db_type = M_PROTO;				p = ((typeof(p)) mp->b_wptr)++;				p->PRIM_type = T_DISCON_IND;				p->DISCON_reason = reason;				p->SEQ_number = seq;				if (!bufq_length(&ss->conq))					ss_set_state(ss, TS_IDLE);				else					ss_set_state(ss, TS_WRES_CIND);				mp->b_cont = dp;				printd(("%s: %p: <- T_DISCON_IND\n", SS_MOD_NAME, ss));				putnext(ss->rq, mp);				return (0);			}			freemsg(mp);			ptrace(("%s: ERROR: bad sequence number\n", SS_MOD_NAME));			return (-EFAULT);		}		ptrace(("%s: ERROR: no buffers\n", SS_MOD_NAME));		return (-ENOBUFS);	}	ptrace(("%s: ERROR: flow controlled\n", SS_MOD_NAME));	return (-EBUSY);}/*  *  T_DATA_IND          14 - Data Indication *  --------------------------------------------------------------- */STATIC intt_data_ind(queue_t *q, uint flags, mblk_t *dp){	ss_t *ss = PRIV(q);	mblk_t *mp;	struct T_data_ind *p;	if ((mp = ss_allocb(q, sizeof(*p), BPRI_MED))) {		mp->b_datap->db_type = M_PROTO;		p = ((typeof(p)) mp->b_wptr)++;		p->PRIM_type = T_DATA_IND;		p->MORE_flag = flags;		mp->b_cont = dp;		printd(("%s: %p: <- T_DATA_IND\n", SS_MOD_NAME, ss));		putnext(ss->rq, mp);		return (QR_ABSORBED);	}	ptrace(("%s: ERROR: no buffers\n", SS_MOD_NAME));	return (-ENOBUFS);}/*  *  T_EXDATA_IND        15 - Expedited Data Indication *  --------------------------------------------------------------- */STATIC intt_exdata_ind(queue_t *q, uint flags, mblk_t *dp){	ss_t *ss = PRIV(q);	mblk_t *mp;	struct T_exdata_ind *p;	if ((mp = ss_allocb(q, sizeof(*p), BPRI_MED))) {		mp->b_datap->db_type = M_PROTO;		mp->b_band = 1;	/* expedite */		p = ((typeof(p)) mp->b_wptr)++;		p->PRIM_type = T_EXDATA_IND;		p->MORE_flag = flags;		mp->b_cont = dp;		printd(("%s: %p: <- T_EXDATA_IND\n", SS_MOD_NAME, ss));		putnext(ss->rq, mp);		return (QR_ABSORBED);	}	ptrace(("%s: ERROR: no buffers\n", SS_MOD_NAME));	return (-ENOBUFS);}/*  *  T_INFO_ACK          16 - Information acknowledgement *  --------------------------------------------------------------- */STATIC intt_info_ack(queue_t *q){	ss_t *ss = PRIV(q);	mblk_t *mp;	struct T_info_ack *p;	if ((mp = ss_allocb(q, sizeof(*p), BPRI_MED))) {		mp->b_datap->db_type = M_PCPROTO;		p = ((typeof(p)) mp->b_wptr)++;		*p = ss->p.info;		printd(("%s: %p: <- T_INFO_ACK\n", SS_MOD_NAME, ss));		putnext(ss->rq, mp);		return (0);	}	ptrace(("%s: ERROR: No buffers\n", SS_MOD_NAME));	return (-ENOBUFS);}/*  *  T_BIND_ACK          17 - Bind Acknowledgement *  --------------------------------------------------------------- */STATIC intt_bind_ack(queue_t *q, struct sockaddr *add, ulong conind){	ss_t *ss = PRIV(q);	mblk_t *mp;	struct T_bind_ack *p;	size_t add_len = ss_addr_size(ss, add);	if ((mp = ss_allocb(q, sizeof(*p) + add_len, BPRI_MED))) {		mp->b_datap->db_type = M_PCPROTO;		p = ((typeof(p)) mp->b_wptr)++;		p->PRIM_type = T_BIND_ACK;		p->ADDR_length = add_len;		p->ADDR_offset = add_len ? sizeof(*p) : 0;		p->CONIND_number = conind;		if (add_len) {			bcopy(add, mp->b_wptr, add_len);			mp->b_wptr += add_len;		}		ss_set_state(ss, TS_IDLE);		printd(("%s: %p: <- T_BIND_ACK\n", SS_MOD_NAME, ss));		putnext(ss->rq, mp);		return (0);	}	ptrace(("%s: ERROR: No buffers\n", SS_MOD_NAME));	return (-ENOBUFS);}/*  *  T_ERROR_ACK         18 - Error Acknowledgement *  ------------------------------------------------------------------------- */STATIC intt_error_ack(queue_t *q, ulong prim, long error){	ss_t *ss = PRIV(q);	mblk_t *mp;	struct T_error_ack *p;	switch (error) {	case -EBUSY:	case -EAGAIN:	case -ENOMEM:	case -ENOBUFS:		seldom();		return (error);	case 0:		never();		return (error);	}	if (!(mp = ss_allocb(q, sizeof(*p), BPRI_MED)))		goto enobufs;	mp->b_datap->db_type = M_PCPROTO;	p = ((typeof(p)) mp->b_wptr)++;	p->PRIM_type = T_ERROR_ACK;	p->ERROR_prim = prim;	p->TLI_error = error < 0 ? TSYSERR : error;	p->UNIX_error = error < 0 ? -error : 0;	/* 	 *  This is to only try and get the state correct for putnext.	 */	if (error != TOUTSTATE) {		switch (ss_get_state(ss)) {#ifdef TS_WACK_OPTREQ		case TS_WACK_OPTREQ:			ss_set_state(ss, TS_IDLE);			break;#endif		case TS_WACK_UREQ:			ss_set_state(ss, TS_IDLE);			break;		case TS_WACK_CREQ:			ss_set_state(ss, TS_IDLE);			break;		case TS_WACK_BREQ:			ss_set_state(ss, TS_UNBND);			break;		case TS_WACK_CRES:			ss_set_state(ss, TS_WRES_CIND);			break;		case TS_WACK_DREQ6:			ss_set_state(ss, TS_WCON_CREQ);			break;		case TS_WACK_DREQ7:			ss_set_state(ss, TS_WRES_CIND);			break;		case TS_WACK_DREQ9:			ss_set_state(ss, TS_DATA_XFER);			break;		case TS_WACK_DREQ10:			ss_set_state(ss, TS_WIND_ORDREL);			break;		case TS_WACK_DREQ11:			ss_set_state(ss, TS_WREQ_ORDREL);			break;			/* 			 *  Note: if we are not in a WACK state we simply do			 *  not change state.  This occurs normally when we			 *  are responding to a T_OPTMGMT_REQ in other than			 *  TS_IDLE state.			 */		}	}	printd(("%s: %p: <- T_ERROR_ACK\n", SS_MOD_NAME, ss));	putnext(ss->rq, mp);	/* 	 *  Returning -EPROTO here will make sure that the old state is	 *  restored correctl

⌨️ 快捷键说明

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