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

📄 dn_nsp_out.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * one RTT, then reset window to min size.	 */	if ((jiffies - scp->stamp) > t)		scp->snd_window = NSP_MIN_WINDOW;	/* printk(KERN_DEBUG "Window: %lu\n", scp->snd_window); */	cb->xmit_count = 0;	if (oth)		skb_queue_tail(&scp->other_xmit_queue, skb);	else		skb_queue_tail(&scp->data_xmit_queue, skb);	if (scp->flowrem_sw != DN_SEND)		return;	dn_nsp_clone_and_send(skb, gfp);}int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff_head *q, unsigned short acknum){	struct dn_skb_cb *cb = DN_SKB_CB(skb);	struct dn_scp *scp = DN_SK(sk);	struct sk_buff *skb2, *list, *ack = NULL;	int wakeup = 0;	int try_retrans = 0;	unsigned long reftime = cb->stamp;	unsigned long pkttime;	unsigned short xmit_count;	unsigned short segnum;	skb2 = q->next;	list = (struct sk_buff *)q;	while(list != skb2) {		struct dn_skb_cb *cb2 = DN_SKB_CB(skb2);		if (before_or_equal(cb2->segnum, acknum))			ack = skb2;		/* printk(KERN_DEBUG "ack: %s %04x %04x\n", ack ? "ACK" : "SKIP", (int)cb2->segnum, (int)acknum); */		skb2 = skb2->next;		if (ack == NULL)			continue;		/* printk(KERN_DEBUG "check_xmit_queue: %04x, %d\n", acknum, cb2->xmit_count); */		/* Does _last_ packet acked have xmit_count > 1 */		try_retrans = 0;		/* Remember to wake up the sending process */		wakeup = 1;		/* Keep various statistics */		pkttime = cb2->stamp;		xmit_count = cb2->xmit_count;		segnum = cb2->segnum;		/* Remove and drop ack'ed packet */		skb_unlink(ack);		kfree_skb(ack);		ack = NULL;		/*		 * We don't expect to see acknowledgements for packets we		 * haven't sent yet.		 */		if (xmit_count == 0)			BUG();		/*		 * If the packet has only been sent once, we can use it		 * to calculate the RTT and also open the window a little		 * further.		 */		if (xmit_count == 1) {			if (equal(segnum, acknum)) 				dn_nsp_rtt(sk, (long)(pkttime - reftime));			if (scp->snd_window < scp->max_window)				scp->snd_window++;		}		/*		 * Packet has been sent more than once. If this is the last		 * packet to be acknowledged then we want to send the next		 * packet in the send queue again (assumes the remote host does		 * go-back-N error control).		 */		if (xmit_count > 1)			try_retrans = 1;	}	if (try_retrans)		dn_nsp_output(sk);	return wakeup;}void dn_nsp_send_data_ack(struct sock *sk){	struct sk_buff *skb = NULL;	if ((skb = dn_alloc_skb(sk, 9, GFP_ATOMIC)) == NULL)		return;	skb_reserve(skb, 9);	dn_mk_ack_header(sk, skb, 0x04, 9, 0);	dn_nsp_send(skb);}void dn_nsp_send_oth_ack(struct sock *sk){	struct sk_buff *skb = NULL;	if ((skb = dn_alloc_skb(sk, 9, GFP_ATOMIC)) == NULL)		return;	skb_reserve(skb, 9);	dn_mk_ack_header(sk, skb, 0x14, 9, 1);	dn_nsp_send(skb);}void dn_send_conn_ack (struct sock *sk){	struct dn_scp *scp = DN_SK(sk);	struct sk_buff *skb = NULL;        struct nsp_conn_ack_msg *msg;	if ((skb = dn_alloc_skb(sk, 3, sk->allocation)) == NULL)		return;        msg = (struct nsp_conn_ack_msg *)skb_put(skb, 3);        msg->msgflg = 0x24;                   	msg->dstaddr = scp->addrrem;	dn_nsp_send(skb);	}void dn_nsp_delayed_ack(struct sock *sk){	struct dn_scp *scp = DN_SK(sk);	if (scp->ackxmt_oth != scp->numoth_rcv)		dn_nsp_send_oth_ack(sk);	if (scp->ackxmt_dat != scp->numdat_rcv)		dn_nsp_send_data_ack(sk);}static int dn_nsp_retrans_conn_conf(struct sock *sk){	struct dn_scp *scp = DN_SK(sk);	if (scp->state == DN_CC)		dn_send_conn_conf(sk, GFP_ATOMIC);	return 0;}void dn_send_conn_conf(struct sock *sk, int gfp){	struct dn_scp *scp = DN_SK(sk);	struct sk_buff *skb = NULL;        struct nsp_conn_init_msg *msg;	unsigned char len = scp->conndata_out.opt_optl;	if ((skb = dn_alloc_skb(sk, 50 + scp->conndata_out.opt_optl, gfp)) == NULL)		return;        msg = (struct nsp_conn_init_msg *)skb_put(skb, sizeof(*msg));        msg->msgflg = 0x28;                   	msg->dstaddr = scp->addrrem;        msg->srcaddr = scp->addrloc;        msg->services = scp->services_loc;        msg->info = scp->info_loc;        msg->segsize = dn_htons(scp->segsize_loc);	*skb_put(skb,1) = len;	if (len > 0) 		memcpy(skb_put(skb, len), scp->conndata_out.opt_data, len);		dn_nsp_send(skb);	scp->persist = dn_nsp_persist(sk);	scp->persist_fxn = dn_nsp_retrans_conn_conf;}static __inline__ void dn_nsp_do_disc(struct sock *sk, unsigned char msgflg, 			unsigned short reason, int gfp, struct dst_entry *dst,			int ddl, unsigned char *dd, __u16 rem, __u16 loc){	struct sk_buff *skb = NULL;	int size = 7 + ddl + ((msgflg == NSP_DISCINIT) ? 1 : 0);	unsigned char *msg;	if ((dst == NULL) || (rem == 0)) {		if (net_ratelimit())			printk(KERN_DEBUG "DECnet: dn_nsp_do_disc: BUG! Please report this to SteveW@ACM.org rem=%u dst=%p\n", (unsigned)rem, dst);		return;	}	if ((skb = dn_alloc_skb(sk, size, gfp)) == NULL)		return;	msg = skb_put(skb, size);	*msg++ = msgflg;	*(__u16 *)msg = rem;	msg += 2;	*(__u16 *)msg = loc;	msg += 2;	*(__u16 *)msg = dn_htons(reason);	msg += 2;	if (msgflg == NSP_DISCINIT)		*msg++ = ddl;	if (ddl) {		memcpy(msg, dd, ddl);	}	/*	 * This doesn't go via the dn_nsp_send() fucntion since we need	 * to be able to send disc packets out which have no socket	 * associations.	 */	skb->dst = dst_clone(dst);	skb->dst->output(skb);}void dn_nsp_send_disc(struct sock *sk, unsigned char msgflg, 			unsigned short reason, int gfp){	struct dn_scp *scp = DN_SK(sk);	int ddl = 0;	if (msgflg == NSP_DISCINIT)		ddl = scp->discdata_out.opt_optl;	if (reason == 0)		reason = scp->discdata_out.opt_status;	dn_nsp_do_disc(sk, msgflg, reason, gfp, sk->dst_cache, ddl, 		scp->discdata_out.opt_data, scp->addrrem, scp->addrloc);}void dn_nsp_return_disc(struct sk_buff *skb, unsigned char msgflg, 			unsigned short reason){	struct dn_skb_cb *cb = DN_SKB_CB(skb);	int ddl = 0;	int gfp = GFP_ATOMIC;	dn_nsp_do_disc(NULL, msgflg, reason, gfp, skb->dst, ddl, 			NULL, cb->src_port, cb->dst_port);}void dn_nsp_send_link(struct sock *sk, unsigned char lsflags, char fcval){	struct dn_scp *scp = DN_SK(sk);	struct sk_buff *skb;	unsigned short *segnum;	unsigned char *ptr;	int gfp = GFP_ATOMIC;	if ((skb = dn_alloc_skb(sk, 13, gfp)) == NULL)		return;	skb_reserve(skb, 13);	segnum = dn_mk_ack_header(sk, skb, 0x10, 13, 1);	*segnum = dn_htons(scp->numoth);        DN_SKB_CB(skb)->segnum = scp->numoth;	seq_add(&scp->numoth, 1);	ptr = (unsigned char *)(segnum + 1);	*ptr++ = lsflags;	*ptr = fcval;	dn_nsp_queue_xmit(sk, skb, gfp, 1);	scp->persist = dn_nsp_persist(sk);	scp->persist_fxn = dn_nsp_xmit_timeout;}static int dn_nsp_retrans_conninit(struct sock *sk){	struct dn_scp *scp = DN_SK(sk);	if (scp->state == DN_CI)		dn_nsp_send_conninit(sk, NSP_RCI);	return 0;}void dn_nsp_send_conninit(struct sock *sk, unsigned char msgflg){	struct dn_scp *scp = DN_SK(sk);	struct sk_buff *skb = NULL;	struct nsp_conn_init_msg *msg;	unsigned char aux;	unsigned char menuver;	struct dn_skb_cb *cb;	unsigned char type = 1;	if ((skb = dn_alloc_skb(sk, 200, (msgflg == NSP_CI) ? sk->allocation : GFP_ATOMIC)) == NULL)		return;	cb  = DN_SKB_CB(skb);	msg = (struct nsp_conn_init_msg *)skb_put(skb,sizeof(*msg));	msg->msgflg	= msgflg;	msg->dstaddr	= 0x0000;		/* Remote Node will assign it*/	msg->srcaddr	= scp->addrloc;	msg->services	= scp->services_loc;	/* Requested flow control    */	msg->info	= scp->info_loc;	/* Version Number            */		msg->segsize	= dn_htons(scp->segsize_loc);	/* Max segment size  */		if (scp->peer.sdn_objnum)		type = 0;	skb_put(skb, dn_sockaddr2username(&scp->peer, skb->tail, type));	skb_put(skb, dn_sockaddr2username(&scp->addr, skb->tail, 2));	menuver = DN_MENUVER_ACC | DN_MENUVER_USR;	if (scp->peer.sdn_flags & SDF_PROXY)		menuver |= DN_MENUVER_PRX;	if (scp->peer.sdn_flags & SDF_UICPROXY)		menuver |= DN_MENUVER_UIC;	*skb_put(skb, 1) = menuver;	/* Menu Version		*/		aux = scp->accessdata.acc_userl;	*skb_put(skb, 1) = aux;	if (aux > 0)	memcpy(skb_put(skb, aux), scp->accessdata.acc_user, aux);	aux = scp->accessdata.acc_passl;	*skb_put(skb, 1) = aux;	if (aux > 0)	memcpy(skb_put(skb, aux), scp->accessdata.acc_pass, aux);	aux = scp->accessdata.acc_accl;	*skb_put(skb, 1) = aux;	if (aux > 0)	memcpy(skb_put(skb, aux), scp->accessdata.acc_acc, aux);	aux = scp->conndata_out.opt_optl;	*skb_put(skb, 1) = aux;	if (aux > 0)	memcpy(skb_put(skb,aux), scp->conndata_out.opt_data, aux);	scp->persist = dn_nsp_persist(sk);	scp->persist_fxn = dn_nsp_retrans_conninit;	cb->rt_flags = DN_RT_F_RQR;	dn_nsp_send(skb);	}

⌨️ 快捷键说明

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