Is TCP URG (urgent data) acknowledged?

后端 未结 1 1846
南笙
南笙 2021-01-18 20:56

In a TCP segment with the URG flag up there might be normal data as well. How does the receiving host handles the urgent packet? How does it acknowledge the urgent data if i

相关标签:
1条回答
  • 2021-01-18 21:53

    A bit of background:

    The TCP urgent mechanism permits a point in the data stream to be designated as the end of urgent information. Thus we have the Urgent Pointer that contains a positive offset from the sequence number in this tcp segment. This field is significant only with the URG control bit set.


    Discrepancies about the Urgent Pointer:

    RFC 793 (1981, page 17):

    The urgent pointer points to the sequence number of the octet following the urgent data.

    RFC 1011 (1987, page 8):

    Page 17 is wrong. The urgent pointer points to the last octet of urgent data (not to the first octet of non-urgent data).

    The same thing in RFC 1122 (1989, page 84):

    ..the urgent pointer points to the sequence number of the LAST octet (not LAST+1) in a sequence of urgent data.

    The intelligible RFC 6093 (2011, pages 6-7) says:

    Considering that as long as both the TCP sender and the TCP receiver implement the same semantics for the Urgent Pointer there is no functional difference in having the Urgent Pointer point to "the sequence number of the octet following the urgent data" vs. "the last octet of urgent data", and that all known implementations interpret the semantics of the Urgent Pointer as pointing to "the sequence number of the octet following the urgent data".

    Thus the updating RFC 793, RFC 1011, and RFC 1122 is

    the urgent pointer points to the sequence number of the octet following the urgent data.

    It meets virtually all existing TCP implementations.

    Note: Linux provides the net.ipv4.tcp_stdurg sysctl to override the default behaviour but this sysctl only affects the processing of incoming segments. The Urgent Pointer in outgoing segments will still be set as specified in RFC 793.


    About the data handling

    You can gain urgent data in two ways (keep in mind that the TCP concept of "urgent data" is mapped to the socket API as "out-of-band data"):

    • using recv with MSG_OOB flag set. (normally you should establish ownership of the socket with something like fcntl(sock, F_SETOWN, getpid()); and establish a signal handler for SIGURG). Thus you will be notified with SIGURG signal. The data will be read separately from the normal data stream.
    • using recv without MSG_OOB flag set. Previously, you should set SO_OOBINLINE socket option such way:

      int so_oobinline = 1; /* true */
      setsockopt(sock, SOL_SOCKET, SO_OOBINLINE, &so_oobinline, sizeof so_oobinline);

      The data remain "in-line". And you can determine the Urgent Pointer with a help of ioctl:

      int flag; /* True when at mark */
      ioctl(sock, SIOCATMARK, &flag);

    Besides it is recommended for new applications not to use the mechanism of urgent data at all to use (if so) receiving in-line, as mentioned above.
    From RFC 1122:

    The TCP urgent mechanism is NOT a mechanism for sending "out-of-band" data: the so-called "urgent data" should be delivered "in-line" to the TCP user.

    Also from RFC 793:

    TCP does not attempt to define what the user specifically does upon being notified of pending urgent data

    So you can handle as you want. It is an application level issue.

    Accordingly, the answer to your question about acknowledgements when all other data was dropped is "You can implement it in your application".
    As for tcp-ack, I found nothing special about it in the case of urgent data.



    About the length of "Urgent Data"

    Almost all implementations really can provide only one byte of "out-of-band data".
    RFC 6093 says:

    If successive indications of "urgent data" are received before the application reads the pending "out-of-band" byte, that pending byte will be discarded (i.e., overwritten by the new byte of "urgent data").

    So TCP urgent mode and its urgent pointer cannot provide marking the boundaries of the urgent data in practice.
    Rumor has it that there are some implementations that queue each of the received urgent bytes. Some of them have been known to fail to enforce any limits on the amount of "urgent data", that they queue. Thus, they become vulnerable to trivial resource exhaustion attacks.


    P. S. All of the above probably covers a little more than was asked, but that's only to make it clear for people unfamiliar with this issue.


    Some more useful links:
    TCP Urgent Pointer, buffer management, and the "Send" call
    Difference between push and urgent flags in TCP
    Understanding the urgent pointer

    0 讨论(0)
提交回复
热议问题