当前位置: 首页 > news >正文

BSD协议栈:UDP输入

UDP输入

输入函数的目标是把UDP数据报放到合适的插口缓存内,然后唤醒该插口上因输入阻塞的所有进程或线程(唤醒需要依靠操作系统的IPC机制)。

分为三个步骤:

1.确认消息并简单处理输入的数据

2.处理目的地址是单播类型的数据报:提交给单个socket即可

3.处理目的地址是广播或多播类型的数据报:需要找到所有需要提交的socket

处理输入的代码如下:

代码主要是验证数据报长度,有两个参数:ip_len 与 uh_ulen,这两个参数都表示数据报长度,正常情况下,它们应该是相等的。

正常情况:

uh_ulen:UDP首部加UDP数据长度

ip_len:数据报内容长度

但我们都知道网络结构是分层的,下一层对上一层来说就是内容,所以有:

ip_len
UDP首部
UDP数据
IP首部
UDP首部
UDP数据

ip_len 大于 uh_ulen:代码相信小的那个,也就是uh_ulen,此时调用m_adj丢弃mbuf后面多出来的部分,在校验和检验时会丢弃该数据报。

ip_len 小于 uh_ulen:长度出现严重错误,数据报必须立即被丢弃。

后面就是填写字段并计算校验和,在前文讲过了,就不过多赘述了。

void udp_input(m, iphlen)
	register struct mbuf *m;
	int iphlen;
{
	register struct ip *ip;
	register struct udphdr *uh;
	register struct inpcb *inp;
	struct mbuf *opts = 0;
	int len;
	struct ip save_ip;

	udpstat.udps_ipackets++;
	//此时还没有实现备份IP选项,因此需要丢弃
	if (iphlen > sizeof (struct ip)) {
		ip_stripoptions(m, (struct mbuf *)0);
		iphlen = sizeof(struct ip);
	}
	//如果IP/UDP长度不合理,那么重新安排mbuf链,使第一个mbuf至少有28个字节
	ip = mtod(m, struct ip *);
	if (m->m_len < iphlen + sizeof(struct udphdr)) {
		if ((m = m_pullup(m, iphlen + sizeof(struct udphdr))) == 0) {
			udpstat.udps_hdrops++;//状态标志位,这些代码不影响理解
			return;
		}
		ip = mtod(m, struct ip *);
	}
	uh = (struct udphdr *)((caddr_t)ip + iphlen);

	/*
	 * Make mbuf data length reflect UDP length.
	 * If not enough data to reflect UDP length, drop.
	 */
	len = ntohs((u_short)uh->uh_ulen);
	if (ip->ip_len != len) {
		if (len > ip->ip_len) {
			udpstat.udps_badlen++;
			goto bad;
		}
		m_adj(m, len - ip->ip_len);
		/* ip->ip_len = len; */
	}
	/*
	 * Save a copy of the IP header in case we want restore it
	 * for sending an ICMP error message in response.
	 */
	save_ip = *ip;

	/*
	 * Checksum extended UDP header and data.
	 */
	if (udpcksum && uh->uh_sum) {
		((struct ipovly *)ip)->ih_next = 0;
		((struct ipovly *)ip)->ih_prev = 0;
		((struct ipovly *)ip)->ih_x1 = 0;
		((struct ipovly *)ip)->ih_len = uh->uh_ulen;
		if (uh->uh_sum = in_cksum(m, len + sizeof (struct ip))) {
			udpstat.udps_badsum++;
			m_freem(m);
			return;
		}
	}
	后面的程序依次是:
	分用多播和广播数据报
	分用单播数据报
	生成ICMP端口不可达差错

相关文章:

  • Scrapy安装,创建Scrapy项目,启动Scrapy爬虫
  • 【Vue】集成Antlr4
  • k8s-对接NFS存储
  • java:用Guava的TypeToken优雅处理通配符类型(WildcardType): ? extends Number
  • JSON类型理解(前后端交互/内存对数据操作)
  • 【论文技巧】Mermaid VSCode插件制作流程图保存方法
  • POI优化Excel录入
  • LangFlow和LangChain有什么区别
  • 大数据SQL调优专题——Flink执行原理
  • Web3 通识
  • 解锁外观模式:Java 编程中的优雅架构之道
  • TortoiseSVN\bin下的没有svn.exe的解决问题
  • Linux的基础指令和环境部署,项目部署实战(下)
  • pyinstaller打包报错:INTEL MKL ERROR: 找不到指定的模块。 mkl_intel_thread.dll.
  • linux 安装启动zookeeper全过程及遇到的坑
  • C++ 模拟真人鼠标轨迹算法 - 防止游戏检测
  • 启元世界(Inspir.ai)技术浅析(七):AI Beings 平台
  • Nginx下proxy_redirect的三种配置方式
  • 【系列教程】Python第四课:条件判断 | 让程序学会思考的秘密
  • UE求职Demo开发日志#33、34 优化#2 删没用的场景和优化UI
  • 郑州一街道被指摊贩混乱经营,12345热线:已整治并加强巡查
  • 五一假期上海虹桥边检站出入境近4.7万人次,韩国入境旅客同比增118%
  • 中海油高管调整:刘永杰、刘小刚任副总裁
  • 自我田野|从城市搬到农村生活,我找回了真实和附近
  • 马斯克“星舰基地”成为新城镇,首任市长为SpaceX员工
  • 五四青年节|青春韵脚