I’m developing a server on C# (using *Async methods). Everything works fine, until one side violates the protocol (e.g. attack on server).
The client and server interchange messages of the following structure:
- First 4 bytes define the length (N) of the message body in bytes
- The following N bytes define the message body
If someone transmits wrong length – all comunication between this client and the server becomes unpredictable.
So the idea is to create a self-synchronizing protocol the most easy way.
I’m using the TCP protocol, so the idea is to break the message into packets and no two messages should share the same packet – this way I’ll be able to ignore protocol violations and restore the communication, if something goes wrong.
I want to use the TCP for that, so the packet would be the same as TCP segment. But there are few catches:
- the MTU (which defines the MSS) could differ and there is no predefined value for the buffer size I could use (correct me if I’m wrong)
- I couldn’t find the way to manupulate TCP Segments directly (without “stream” abstraction) yet
I’m new to socket server programming, so I need help. Maybe someone can share the common solution to this problem (the fault-resistant protocol) or describe the common pitfalls, or maybe provide useful links.
I’m developing under .NET and I don’t want to use any P/Invokes if it can be avoided.
The TCP abstraction is that of a stream, with no in-built message boundaries, and you shouldn’t be trying to violate that abstraction.
The main strategy for dealing with misbehaving clients is to rigorously sanity-check all the input provided by clients (for example, it is usual to set an upper bound on the allowed size of your protocol-level messages). When the sanity checks indicate that the protocol has been violated, you stop processing of the erroneous message. You may also want to log the error, and/or report it to the client.
If the protocol violation is such that you cannot resynchronise, then you have no choice but to disconnect the client. This is fine; a misbehaving client has no right to expect any level of service.
You can design a protocol that allows resynchronisation – the simplest example is to use delimiters at the boundary between subsequent protocol messages (the delimiter itself is not allowed to occur within a message). Many of the old “line-based” internet protocols, like FTP, SMTP and IRC work this way (the delimiter in this case is the newline character).