CurveCP: Usable security for the Internet


Introduction
Main features:
Confidentiality
Integrity
Availability
Efficiency
Decongestion
Addressing
Protocol details:
Packets
Nonces
Messages
Integration:
HTTP
SMTP
Programming:
Message handlers

Messages in CurveCP

This page explains the format of CurveCP messages.

CurveCP messages should not be confused with CurveCP packets. Packets are copied to and from the network and are visible to eavesdroppers. Some packets contain encrypted authenticated messages; the contents of the messages are not visible to eavesdroppers.

CurveCP messages should also not be confused with the streams of data sent by applications that use CurveCP: a byte stream from the client to the server, and a byte stream from the server to the client. Messages contain blocks of data from these streams, but they also contain extra header information, for example to accommodate lost packets.

A byte stream is a string of bytes, between 0 bytes and 2^60-1 bytes (allowing more than 200 gigabits per second continuously for a year), followed by either success or failure. The bytes in an N-byte stream have positions 0,1,2,...,N-1; the success/failure bit has position N. A message from the sender can include a block of bytes of data from anywhere in the stream; a block can include as many as 1024 bytes. A message from the receiver can acknowledge one or more ranges of data that have been successfully received. The first range acknowledged in a message always begins with position 0. Subsequent ranges acknowledged in the same message are limited to 65535 bytes. Each range boundary sent by the receiver matches a boundary of a block previously sent by the sender, but a range normally includes many blocks.

Once the receiver has acknowledged a range of bytes, the receiver is taking responsibility for all of those bytes; the sender is expected to discard those bytes and never send them again. (This differs from the behavior of TCP SACK: TCP allows selective acknowledgments to be subsequently retracted.) The sender can send the bytes again; usually this occurs because the first acknowledgment was lost. The receiver discards the redundant bytes and generates a new acknowledgment covering those bytes.

What are the contents of a message?

A message has the following contents:
  • 4 bytes: a message ID chosen by the sender.
  • 4 bytes: if nonzero, a message ID received by the sender immediately before this message was sent.
  • 8 bytes: a 64-bit unsigned integer in little-endian form, the number of bytes in the first range being acknowledged as part of this message. A range can include 0 bytes, in which case it does not actually acknowledge anything.
  • 4 bytes: a 32-bit unsigned integer in little-endian form, the number of bytes between the first range and the second range.
  • 2 bytes: a 16-bit unsigned integer in little-endian form, the number of bytes in the second range.
  • 2 bytes: a 16-bit unsigned integer in little-endian form, the number of bytes between the second range and the third range.
  • 2 bytes: a 16-bit unsigned integer in little-endian form, the number of bytes in the third range.
  • 2 bytes: a 16-bit unsigned integer in little-endian form, the number of bytes between the third range and the fourth range.
  • 2 bytes: a 16-bit unsigned integer in little-endian form, the number of bytes in the fourth range.
  • 2 bytes: a 16-bit unsigned integer in little-endian form, the number of bytes between the fourth range and the fifth range.
  • 2 bytes: a 16-bit unsigned integer in little-endian form, the number of bytes in the fifth range.
  • 2 bytes: a 16-bit unsigned integer in little-endian form, the number of bytes between the fifth range and the sixth range.
  • 2 bytes: a 16-bit unsigned integer in little-endian form, the number of bytes in the sixth range.
  • 2 bytes: a 16-bit unsigned integer in little-endian form, the sum of the following integers:
    • D, an integer between 0 and 1024, the size of the data block being sent as part of this message.
    • SUCC, either 0 or 2048, where 2048 means that this block is known to be at the end of the stream followed by success.
    • FAIL, either 0 or 4096, where 4096 means that this block is known to be at the end of the stream followed by failure.
  • 8 bytes: a 64-bit unsigned integer in little-endian form, the position of the first byte in the data block being sent. If D=0 but SUCC>0 or FAIL>0 then this is the success/failure position, i.e., the total number of bytes in the stream.
  • Zero-padding. This padding produces a total message length that is a multiple of 16 bytes, at least 16 bytes and at most 1088 bytes.
  • D bytes: the data block being sent.
The zero-padding is not limited to 15 bytes; i.e., it does not necessarily produce the smallest possible multiple of 16 bytes. Some message creators pad to a more restricted set of lengths to reduce the amount of information that the message length reveals about the length of the data block. Note, however, that traffic analysis continues to reveal a tremendous amount of information.

Does CurveCP provide flow control?

Yes. Decongestion, when used properly, automatically provides flow control. The receiver simply adds the sender's incoming messages to a queue, without looking at the messages. The receiver can impose whatever size limits it wants upon the queue, static or dynamic, without notification to the sender. When the receiver is ready to handle more data, it processes the message at the front of the queue, generating an acknowledgment if necessary.

Using decongestion to handle flow control simplifies the protocol, eliminating any need to coordinate window updates and eliminating common mistakes such as silly-window syndrome. It slightly reduces packet sizes and sometimes eliminates entire window-update packets. It can slightly increase traffic on the occasions that a computer is unable to keep up with its own network link, but decongestion automatically keeps this increase under control.

Does CurveCP allow configuration of the maximum segment size?

No. The maximum CurveCP data-block size is 1024 bytes. The maximum CurveCP message size is 1088 bytes (or 640 bytes inside Initiate packets). The maximum CurveCP packet size, including lower-layer overhead, is smaller than the 1280-byte datagrams allowed by IPv6 on all networks, the 1492-byte datagrams that have always been supported by Ethernet, the 2272-byte datagrams supported by 802.11 wireless networks, etc.

CurveCP's total packet overhead, including lower-layer overhead, is under 15% for bulk data transfer. In theory, allowing larger packets would measurably reduce this overhead; in practice, attempts to maximize packet size have a long and continuing history of damaging Internet connectivity.

Version

This is version 2011.02.15 of the messages.html web page.