当前位置: 代码网 > 服务器>网络>网络协议 > 网络运输层之(2)UDP协议

网络运输层之(2)UDP协议

2024年08月02日 网络协议 我要评论
用户数据报协议(User Datagram Protocol,简称UDP)是一种简单、高效、无连接的传输层协议。它是互联网协议族(Internet Protocol Suite)的重要组成部分,与传输控制协议(TCP)并列为传输层的两大协议之一。与面向连接、可靠传输的TCP协议不同,UDP协议采用无连接通信模式,不保证数据包的可靠传输,也不具备拥塞控制等机制。发送方只管将数据报发送出去,而不关心数据是否正确到达目的地。简单高效。

1. 介绍
1.1 概述

用户数据报协议(user datagram protocol,简称udp)是一种简单、高效、无连接的传输层协议。它是互联网协议族(internet protocol suite)的重要组成部分,与传输控制协议(tcp)并列为传输层的两大协议之一。

与面向连接、可靠传输的tcp协议不同,udp协议采用无连接通信模式,不保证数据包的可靠传输,也不具备拥塞控制等机制。发送方只管将数据报发送出去,而不关心数据是否正确到达目的地。

udp的这些特点赋予了它独特的优势:

  • 简单高效,udp协议结构简单,不需要建立连接和维护复杂状态,减少了协议开销,传输效率高。

  • 实时性好,由于不存在重传、顺序校验等可靠性机制,udp具有极低的时延,非常适合实时性要求高的应用场景。

  • 灵活性强:udp允许用户自定义传输内容和方式,根据应用需求灵活选择可靠性的实现方案。

  • 适用于分散式应用,udp天然支持一对多、多对多的通信模式,适用于分散式的应用架构。

通常情况下,udp的使用范围是较小的,在以下的场景下,使用udp才是明智的:

  • 实时性要求很高,并且几乎不能容忍重传。
  • tcp实在不方便实现多点传输的情况。
  • 需要进行nat穿越。

例如流媒体传输、实时游戏、dns查询、网络管理、路由更新等。

1.2 应用场景

下面是udp的几个典型应用场景。

  • 流媒体传输:如视频会议、直播等实时音视频应用,对传输的实时性要求很高,同时允许少量数据丢失。udp恰好满足这些需求,通过牺牲一定的可靠性来换取传输的低延迟。在流媒体应用中,udp常与rtp(实时传输协议)结合使用,通过引入时间戳、序列号等机制,在应用层实现传输的同步与可靠性控制。

  • 实时游戏:多人在线游戏对服务器与客户端之间通信的实时性要求非常高,用户体验与网络延迟密切相关。使用udp传输游戏数据,可以降低延迟,提高交互的灵敏度。游戏开发者可在应用层设计冗余和同步机制,权衡可靠性与实时性。

  • dns查询:域名解析过程通常使用udp承载dns查询和应答报文。相比tcp,udp具有更低的通信开销,可加快dns查询速度。而单个dns报文长度较小,udp的65535字节长度限制也够用。即便某次udp查询失败,dns协议也设计了重传等容错机制。

  • 网络管理和监控:诸如snmp(简单网络管理协议)、syslog(系统日志协议)等网络管理协议,通常使用udp传输数据。这类应用对实时性要求较高,并可容忍少量数据丢失。使用udp,管理进程可高效处理大量设备的状态数据,及时掌控网络运行状况。

总之,只要应用场景对传输实时性要求高,能容忍少量数据丢失,udp就可以大显身手。

在实际应用开发过程中,尤其是在linux下进行udp编程时,还需注意以下事项:

  • 数据报大小限制:udp单个数据报最大长度为65535字节,过长的报文需要在应用层分片发送、组装接收。

  • 缓冲区管理:linux提供so_rcvbuf和so_sndbuf选项,可设置udp套接字的接收和发送缓冲区大小。合理设置缓冲区大小,可优化udp性能,避免缓冲区溢出导致的数据丢失。

  • 多线程并发:udp是无连接的,相同的套接字可用于与多个对端通信。在多线程并发环境下,需妥善处理套接字的多线程访问,避免竞态条件。

  • 数据报边界:udp是基于数据报的协议,接收方应正确处理数据报边界,每次recvfrom()调用返回一个完整的udp数据报。

  • 差错处理:对于udp,内核只提供最基本的差错检查,应用层需根据需要实现可靠传输、丢包重传、顺序校验等可靠性保障机制。

  • 网络异常:要正确处理网络异常,如icmp端口不可达错误。这些错误虽不会直接影响udp通信,但可用于判断通信对端状态等。

  • udp数据包的无序性和非可靠性:udp接收的顺序不能保证和发送一致,因此应用需要考虑乱序处理。

1.3 rfc文档

以下是与udp相关的主要rfc文档列表:

  • rfc 768 - user datagram protocol (udp),最初定义udp协议的文档,规定了udp头部格式和基本操作。

  • rfc 1122 - requirements for internet hosts – communication layers,详细说明了主机实现udp时的各项要求,如校验和处理、端口复用等。

  • rfc 1123 - requirements for internet hosts – application and support,补充说明了主机实现udp的其他要求,如最大数据报长度限制等。

  • rfc 2460 - internet protocol, version 6 (ipv6) specification,定义了ipv6,其中也对udp进行了一些更新,如校验和计算中包含ipv6伪首部等。

  • rfc 2675 - ipv6 jumbograms,引入jumbogram概念,允许udp数据报超过65535字节,为ipv6扩展了udp。

  • rfc 3828 - the lightweight user datagram protocol (udp-lite),定义了udp-lite协议,是udp的变种,支持部分校验和覆盖,适用于容忍部分数据损坏的应用。

  • rfc 4113 - management information base for the user datagram protocol (udp),定义了udp的管理信息库(mib),用于网络管理系统监控udp运行状况。

  • rfc 4340 - datagram congestion control protocol (dccp),定义了数据报拥塞控制协议,可视为增强版udp,提供了拥塞控制和部分可靠性支持。

  • rfc 5405 - unicast udp usage guidelines for application designers,为应用设计者提供使用udp的指南,包括何时选择udp、如何保证可靠性等建议。

  • rfc 6935 - ipv6 and udp checksums for tunneled packets,讨论了隧道封装情况下ipv6和udp校验和的计算和处理问题。

  • rfc 8085 - udp usage guidelines,全面的udp使用指南,总结了udp最佳实践,替代了之前的rfc 5405。

  • rfc 8200 - internet protocol, version 6 (ipv6) specification,ipv6的最新规范,替代了rfc 2460,也包含了一些与udp相关的更新内容。

  • rfc 8304 - transport features of the user datagram protocol (udp) and lightweight udp (udp-lite),本文档系统地总结了udp和udp-lite协议的传输特性。

  • rfc 8899 - packetization layer path mtu discovery for datagram transports,定义了数据报传输的路径mtu发现机制,适用于包括udp在内的数据报协议。

2. 报文格式
2.1 udp格式

在ipv4和ipv6中,都用协议号17来表示udp报文。

在这里插入图片描述

各字段说明:

  • 源端口号(source port),16位,标识发送方应用程序使用的udp端口号。如果不要求对方回复,源端口可以置为0。
  • 目的端口号(destination port),16位,标识接收方应用程序使用的udp端口号。
  • 长度(length),16位,指定udp头部和数据的总字节数。最小值为8字节(仅包含头部)。由于该字段长16位,udp数据报的理论最大长度为65535字节。但对于ipv6协议,则可以支持更长的长度,此时长度信息记录在ipv6头部。
  • 校验和(checksum),16位,对udp头部、数据部分以及伪头部进行校验和计算,用于错误检测。校验和字段是可选的,如果不使用,应填为0。
  • 数据(data),长度不定,包含应用层传递下来的数据。数据部分的长度可以从length字段计算得到:length - 8 bytes
2.2 udp报文长度

udp报文长度与ip数据报长度密切相关,先回顾一下ip头部中的相关字段:

  • ipv4中的total length字段,ipv4头部的total length字段(16位)指明了ip数据报的总长度,包括头部和数据部分。udp报文作为ipv4数据报的数据部分,其长度必须与total length字段相符。

    total length = ip header length + udp length,udp length字段表示udp头部和数据部分的总长度。

  • ipv6中的payload length字段,ipv6头部的payload length字段(16位)指明了ipv6数据报中数据部分(即扩展头部和上层协议数据单元)的长度。与ipv4不同,payload length不包括ipv6头部的固定40字节。

    当udp报文通过ipv6传输时,ipv6的payload length = udp length + length of extension headers(如果有)

在ipv4中,udp length字段看似多余,因为可以通过ip头部的total length和header length计算得到。但在某些情况下,如ip分片,udp length字段可以帮助接收方正确识别和重组udp数据报。

在ipv6中,由于extension header的存在,无法直接根据ipv6头部计算上层协议数据单元的长度。因此,udp length字段对于ipv6而言并不冗余。

ipv6支持jumbogram,即超长数据报,其payload length可达4gb。在jumbogram中,udp length字段必须为0。这是因为16位的length字段无法表示jumbogram的长度。此时,应根据ipv6头部的payload length字段和extension header的长度,间接计算udp数据的长度。

2.3 udp校验和

udp校验和计算过程中引入了伪首部的概念。伪首部是为了将ip头部的某些字段纳入校验和计算,以提高可靠性。udp在ipv4和ipv6下使用不同格式的伪首部。

ipv4伪首部 + udp首部 + udp数据:

在这里插入图片描述

ipv6伪首部 + udp首部 + udp数据:

在这里插入图片描述

注意,ipv6伪首部中的udp长度字段为32位,而实际udp头部中的length字段为16位。这是为了在ipv6 jumbogram情况下支持超长udp数据报

无论是ipv4还是ipv6,udp校验和计算过程都遵循以下步骤:

  1. 构造伪首部,并将其与udp头部和数据部分合并成一个长度为16位整数倍的序列。
  2. 将序列视为一系列16位整数,并进行二进制求和,遇到进位则回卷。
  3. 将上一步得到的和取反,得到校验和结果。
  4. 将校验和放入udp头部的checksum字段。

接收方重复上述计算过程,并将结果与接收到的udp校验和字段比较。如果二者一致(均为0),则说明数据传输无误;否则,接收方应丢弃该udp数据报

在ipv4中,udp校验和字段是可选的,全0表示不启用校验和。但在ipv6中,udp校验和是强制的,不能省略。这是因为ipv6头部不包含校验和字段,完全依赖上层协议保证数据完整性

在ipv6中,udp长度字段为0时,且jumbo payload不存在的特殊情况下,也可以从ipv6负载长度推算udp长度,如果有ipv6扩展头部,需要减去所有扩展头部的大小。

2.4 udp和mtu关系

mtu(最大传输单元)是链路层对数据帧大小的限制,它直接影响了上层协议如udp的数据报大小。

在ipv4网络中,mtu的默认值为576字节(实际以太接口配置还是1500字节)。如果udp数据报(包括ip头部和udp头部)超过576字节,则需要在ip层进行分片,这会带来一些问题:

  • 分片增加了开销,降低了网络效率。
  • 如果某个分片丢失,整个数据报都需要重传,影响可靠性。
  • 某些网络设备(如nat)可能丢弃分片数据报,导致通信失败。

因此,在ipv4环境下,建议udp数据报长度不要超过576字节,以避免ip分片。应用程序可以通过控制用户数据长度,使udp数据报(含头部)不超过576字节。

在ipv6网络中,链路mtu的最小值为1280字节。ipv6数据报(含扩展头部)的长度不应超过1280字节,否则需要在ip层进行分片。

与ipv4不同,ipv6只能在源主机上分片(实际上中间设备也会进行重组和分片),所以发送时需要确定好是否分片,一般通过如下机制:

  • 路径mtu发现:通过icmpv6报文,ipv6可以动态发现端到端路径上的最小mtu,从而避免分片。
  • 数据报过大时的处理:当ipv6数据报超过mtu时,发送方会收到"packet too big"的icmpv6错误消息,应用程序可据此调整数据报大小。

因此,在ipv6环境下,建议udp应用通过路径mtu发现确定合适的数据报大小,避免在ip层分片。

在某些高速网络环境下,如数据中心内部,链路mtu可能远大于普通以太网的1500字节,支持jumbo帧。这种情况下,udp数据报也可以突破传统限制,达到几乎4gb的大小。

jumbo udp数据报主要出现在ipv6环境下。ipv6头部引入了"jumbo payload"选项,允许数据报长度超过65535字节。当使用jumbo payload选项时,udp头部的length字段必须设为0,接收方需根据ipv6头部的payload length字段确定udp数据报长度。

jumbo udp数据报适用于对传输效率要求极高,而对时延不敏感的应用,如大数据传输、存储区域网络等。应用程序需要评估网络条件和应用需求,权衡是否使用jumbo udp数据报。

2.5 udp-lite

udp-lite是udp协议的一种变种,旨在提供部分校验和覆盖的轻量级传输机制。它最早在rfc 3828中定义,后经rfc 6335修订。

传统的udp校验和覆盖整个数据报,包括头部和数据部分。而udp-lite引入了一个新的头部字段"checksum coverage",用于指定校验和覆盖的数据长度。

在这里插入图片描述

当checksum coverage字段不为0时,udp-lite校验和只计算coverage指定的字节数,其中必须包括udp-lite头部。超出coverage部分的数据不被校验和保护。

当checksum coverage字段为0时,udp-lite退化为传统的udp,校验和覆盖整个数据报

udp-lite适用于以下场景:

  • 多媒体通信,音视频数据对误码有一定容忍度,但对时延敏感。udp-lite可以只对关键数据(如帧头)进行校验,减少重传概率,提高实时性。

  • 无线传感器网络,无线链路易受干扰,误码率高。传感器数据往往具有时效性,重传代价高。udp-lite可以选择性校验关键数据,兼顾可靠性和效率。

  • 加密通信:加密数据对误码敏感,但加密操作在udp-lite校验和计算之后进行。udp-lite可以只校验加密数据的关键部分,避免加密数据的误码导致整个数据报被丢弃。

3. 实践
3.1 udp绑定本地ip地址

通常情况下,udp服务器并不限制本地接口地址,只限制了端口,如下所示:

active internet connections (servers and established)
proto recv-q send-q local address           foreign address         state      
udp        0      0 *:8000      			0.0.0.0:*    

这种情况下,可以在服务器任何本地接口上受到目的端口8000的udp报文,*表示通配符,说明对本地ip地址和报文源udp端口没有要求,0.0.0.0表示任意的报文源ip地址。

udp服务器可以绑定到特定的本地ip地址和端口。可以选择绑定到一个特定的ip地址,也可以使用通配地址(如0.0.0.0或::)绑定到所有可用的本地ip地址。

使用特定ip地址绑定可以限制服务器只在该ip地址上接收数据,增强安全性。而使用通配地址则可以接收所有本地ip地址上的数据,提高灵活性。

以下是netstat输出的示例,其中udp服务器绑定到特定ip地址192.168.1.100和通配地址0.0.0.0:

active internet connections (servers and established)
proto recv-q send-q local address           foreign address         state      
udp        0      0 192.168.1.100:8000      0.0.0.0:*                          
udp        0      0 0.0.0.0:9000            0.0.0.0:*                          
3.2 udp多地址绑定和端口复用:

udp服务器可以同时绑定到多个ip地址和端口,以处理来自不同网络接口的数据。这通常通过setsockopt()函数设置so_reuseaddr和so_reuseport选项实现。端口复用允许多个udp套接字绑定到多个ip地址和端口组合。

以下是两个udp套接字绑定到不同ip地址的同一个端口(so_reuseaddr):

active internet connections (servers and established)
proto recv-q send-q local address           foreign address         state      
udp        0      0 192.168.1.100:8000      0.0.0.0:*                          
udp        0      0 192.168.1.101:8000      0.0.0.0:*                          

对于so_reuseport端口复用来说,可以多个udp套接字绑定到同一个地址和端口,但对于单播地址,只有其中一个套接字会收到报文。对于组播和广播地址,每个udp套接字都会收到一个副本。

3.3 限制远端ip地址

为了增强安全性,udp服务器可以限制接受数据的远端ip地址范围。这可以通过以下方式实现:

  • 在应用层代码中检查远端ip地址,只处理允许范围内的数据包。
  • 使用防火墙规则限制可访问udp服务器端口的源ip地址。
  • 在支持的平台上,使用socket选项(如ip_freebind)限制可绑定的远端ip地址。

以下是netstat输出的示例,其中udp服务器只接受来自特定ip地址192.168.1.200的数据:

active internet connections (servers and established)
proto recv-q send-q local address           foreign address         state      
udp        0      0 192.168.1.100:8000      192.168.1.200:3333      established              

当指定远端ip和端口后,本地ip也会自动选择,一般根据路由来选择可达地址。

udp在接收数据报文时,绑定方式最具体的会优先收到报文。

3.4 udp相关攻击

udp协议由于其无连接、不可靠的特性,较容易被攻击者利用进行各种攻击。

udp泛洪攻击(udp flood attack),攻击者向目标系统发送大量的udp数据包,耗尽目标系统的处理资源和带宽,导致其无法正常提供服务。

攻击者通常伪造源ip地址,使攻击数据包看似来自多个不同的源,加大了防御难度。攻击数据包可能指向目标系统上的随机端口,也可能集中在特定端口上。

udp反射攻击(udp reflection attack),攻击者向大量开放udp服务的服务器发送伪造源ip地址的udp数据包,将源ip地址设置为攻击目标的ip地址。服务器收到数据包后,会向伪造的源ip地址(即攻击目标)发送响应数据包。

攻击者利用大量服务器的响应放大攻击流量,对攻击目标发起ddos攻击。常被利用的udp服务包括dns、ntp、snmp等。

  • dns放大攻击,攻击者利用dns协议的特点,伪造请求数据包,诱使dns服务器返回大量响应,对攻击目标发起ddos攻击。

  • ntp放大攻击,攻击者利用ntp协议的monlist功能,伪造请求数据包,诱使ntp服务器返回大量响应,对攻击目标发起ddos攻击。

  • snmp反射攻击,攻击者向开放snmp服务的设备发送伪造源ip地址的snmp请求,设备向伪造的源ip地址(即攻击目标)发送响应,对其发起ddos攻击。

  • tftp反射攻击,攻击者向开放tftp服务的服务器发送伪造源ip地址的读写请求,服务器向伪造的源ip地址(即攻击目标)发送响应数据包,消耗其带宽资源。







alt

once day

也信美人终作土,不堪幽梦太匆匆......

如果这篇文章为您带来了帮助或启发,不妨点个赞👍和关注,再加上一个小小的收藏⭐!

(。◕‿◕。)感谢您的阅读与支持~~~

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com