dipyalov
dipyalov

Reputation: 118

Protocol error resistant socket server

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:

  1. First 4 bytes define the length (N) of the message body in bytes
  2. 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:

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.

Upvotes: 0

Views: 778

Answers (4)

caf
caf

Reputation: 239171

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).

Upvotes: 2

ygrek
ygrek

Reputation: 6697

disconnect the misbehaving client

Upvotes: 0

Steve Townsend
Steve Townsend

Reputation: 54168

There are two separate issues here.

  1. How do you handle protocol violations?
  2. How do you plan to secure your server?

You cannot secure your server by building error correction into your protocol handler. You need secure coding practices to do that. Look into SSL for starters - if you try to make the server secure all by yourself a) it will not be, and b) it will take a long time.

You may find that once the server is secure, the issue of protocol errors is a lot simpler to resolve. This implies either a coding error on the client, or a network data integrity problem. Ruling out malice aforethought makes either problem easier to address.

Upvotes: 1

Peter K.
Peter K.

Reputation: 8108

You might want to read about the protobuf-c RPC implementation:

The client issues a 12 byte header followed by the protobuf-encoded message payload:

  • method index (encoded as a 4-byte little-endian number)
  • message length: the length of the protobuf-encoded payload (encoded 4-byte little-endian)
  • request id: a value chosen by the client to allow it to know which server response corresponds to which request, in the case of multiple outstanding requests). (encoded in 4 bytes)

The server eventually issues a similar 16 byte response:

  • status code (as a 4-byte little-endian number). One of the following values:
    0: success
    1: service failed (ie passed in NULL for the message to the closure)
    2: too many pending (client connection has too many pending requests)
  • method index (same as for request)
  • message length (same as for request)
  • request id (same as for request)

Another thing to think about added, should you try to do this over non-TCP/IP (i.e. an error-free channel) is to add a CRC check on the header and the payload.

Upvotes: 0

Related Questions