Search code examples
socketstcpmetadatamessageformatapplication-layer

application layer protocol - different size of packets


Assume I have defined my own application layer protocol on top of TCP for Instant Messaging. I have used a packet structure for the messages. As I am using symmetric (AES) and asymmetric (RSA) encryption, I obtain a different packet size for different message types. Now to my questions.

How to read from a socket that I receive a single application layer packet? What size should I specify?

Thanks in advance.

I have two approaches in mind.

  1. Read from the TCP stream a fixed amount of bytes that represents the actual packet size, and finally re-read from the stream the former gathered size of bytes.

  2. Read the maximal packet size from the stream. Verify the actual size of obtained bytes and decide so which message type it was.

Now, a more general question. Should I provide metadata like the packet size, encryption method, receiver, sender, etc.? If yes, should I encrypt these meta data as well?


Solution

  • Remember that with TCP, when reading from the network, there is no guarantee about the number of bytes received at that point in time. That is, a client might send a full packet in its write(), but that does not mean that your read() will receive the same number of bytes. Thus your code will always need to read some number of bytes from the network, then verify (based on the accumulated data) that you have received the necessary number of bytes, and then you can verify the packet (type, contents, etc) from there.

    Some applications use state machine encoders/decoders and fixed size buffers for reading/writing their network data; other applications dynamically allocate buffers large enough for the "full packet", then continue reading bytes from the network until the "full packet" buffer is full. Which approach you take depends on your application. Thus the size you use for reading is not as important as how your code ensures that it has received a full packet.

    As for whether you should encrypt additional metadata, that depends very much on your threat model (i.e. what threats your protocol wants to guard against, what assurances your protocol needs to provide to its clients/users). There's no easy way to answer that question without more context/details.

    Hope this helps!