0

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?

auermich
  • 130
  • 10

1 Answers1

0

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!

Castaglia
  • 2,972
  • 5
  • 28
  • 49
  • But for clarification, is it common to send packet size as metadata in advance and separated to the actual payload rather than only transmitting payload? – auermich May 04 '16 at 16:00
  • If your packets have variable size (and many do), then yes, sending the packet size (as some fixed-length value) as a "prefix" is quite common. _E.g._ "read the first 4 bytes as a big-endian number indicating the length of the following packet", then "read number of bytes", then "decode/parse packet". – Castaglia May 04 '16 at 16:18
  • If you receive less bytes than expected, or the header information is malformed, would you suggest to run into a time-out (client-side) or rather send an explicit error message from server to client? Thanks for your help. – auermich May 07 '16 at 16:30
  • Depends on how helpful you want your protocol to be. Many protocols have an error reporting mechanism, so that server (or client) can send a message to the sending peer, indicating the error. This allows the peer to possibly correct the issue (or at least log that it happened). – Castaglia May 07 '16 at 16:32
  • Another issue arised during implementation. Assume that a malformed header (couldn't decode size) arrived at the server; how and how many bytes do you flush from tcp stream? You don't want to destroy legit packets after the malformed one. Moreover, as it's about instant messaging, you don't want to acknowledge header packet. So it may happen that several packets have been already sendt. – auermich May 13 '16 at 19:16
  • If the stream is that corrupted, then the only thing to do is drop the TCP connection, and force the client to re-connect, resume the stream. This why some protocols have "acknowledgments" or "checkpoints", where the server "acks" some number; the client, if it re-connects, knows that last "ack", and can resume the stream from there. (This is all part of the fun world of protocol development.) – Castaglia May 13 '16 at 20:12