Net*_*pup 3 networking tcp out-of-band
在带有URG标志的tcp段中,也可能存在正常数据。接收主机如何处理紧急数据包?如果紧急数据不是数据流的一部分,它将如何确认?它是否承认其余的内容?
我知道它通常不使用,但是如果两个主机都支持有关URG标志的相同RFC,那么它们如何处理带外数据?
如果紧急数据是中止消息,则接收方将丢弃所有其他数据,但是发送方仍将希望确认已收到该消息。
一点背景:
TCP紧急机制允许将数据流中的一点指定为紧急信息的结尾。因此,我们具有紧急指针,该指针包含与该tcp段中序列号的正偏移量。仅当URG控制位设置时,此字段才有意义。
关于紧急指针的差异:
RFC 793(1981,第17页):
紧急指针指向紧随紧急数据之后的八位位组的序号。
RFC 1011(1987,第8页):
页面17是错误的。紧急指针指向紧急数据的最后一个八位位组(而不是非紧急数据的第一个八位位组)。
在同样的事情RFC 1122(1989年,84页):
..紧急指针指向紧急数据序列中的LAST八位位组的序列号(不是LAST + 1)。
考虑到只要TCP发送方和TCP接收方都为紧急指针实现相同的语义,就使紧急指针指向“紧随紧急数据之后的八位位组的序号”与“最后一个”之间没有功能上的区别。紧急数据八位位组”,并且所有已知的实现方式都将紧急指针的语义解释为指向“紧急数据后八位位组的序号”。
因此,更新RFC 793,RFC 1011和RFC 1122为
紧急指针指向紧随紧急数据之后的八位位组的序号。
它几乎可以满足所有现有的TCP实现。
注意:Linux提供了net.ipv4.tcp_stdurg sysctl覆盖默认行为的,但这sysctl仅影响传入段的处理。传出段中的紧急指针仍将按照RFC 793中的规定进行设置。
关于数据处理
您可以通过两种方式获取紧急数据(请注意,“紧急数据”的TCP概念已作为“带外数据”映射到套接字API):
recv与MSG_OOB标志设置。(通常,您应该使用类似的方法fcntl(sock, F_SETOWN, getpid());建立套接字的所有权,并为建立信号处理程序SIGURG)。因此,您将收到SIGURG信号通知。数据将与普通数据流分开读取。 使用recv不带MSG_OOB标志的情况。以前,您应该这样设置SO_OOBINLINE套接字选项:
int so_oobinline = 1; /* true */
setsockopt(sock, SOL_SOCKET, SO_OOBINLINE, &so_oobinline, sizeof so_oobinline);
数据保持“在线”。您可以借助以下方法确定紧急指示器ioctl:
int flag; /* True when at mark */
ioctl(sock, SIOCATMARK, &flag);
此外,如上所述,建议新应用程序完全不使用紧急数据机制来在线接收(如果这样)。
根据RFC 1122:
TCP紧急机制不是用于发送“带外”数据的机制:应当将“紧急数据”“内联”传递给TCP用户。
同样来自RFC 793:
TCP不会尝试定义用户在收到待处理的紧急数据时的具体操作
因此您可以根据需要进行处理。这是一个应用程序级别的问题。
因此,当所有其他数据都被删除时,有关确认的问题的答案是“您可以在应用程序中实现它”。
至于tcp-ack,在紧急数据的情况下,我发现没有什么特别的。
关于“紧急数据”的长度
几乎所有的实现实际上只能提供一个字节的“带外数据”。
RFC 6093说:
如果在应用程序读取未决的“带外”字节之前接收到“紧急数据”的连续指示,则该未决字节将被丢弃(即,被“紧急数据”的新字节覆盖)。
因此,TCP紧急模式及其紧急指针在实践中无法提供标记紧急数据的边界。
有传言说,有一些实现将每个接收到的紧急字节排队。已知其中一些无法对它们排队的“紧急数据”量实施任何限制。因此,它们变得容易受到琐碎的资源耗尽攻击。
附注:以上所有内容可能比要求的内容多一点,但这只是为了让不熟悉此问题的人明白。
一些更有用的链接:
TCP紧急指针,缓冲区管理和“发送”调用
TCP中的推入和紧急标志之间的区别
了解紧急指针
| 归档时间: |
|
| 查看次数: |
810 次 |
| 最近记录: |