2011-07-01 131 views
0

我正在C#上开发一个服务器(使用*异步方法)。一切正常,直到一方违反协议(例如服务器攻击)。协议错误套接字服务器

以下结构的客户端和服务器交换消息:

  1. 前4个字节定义以字节
  2. 消息体的长度(N)以下的N个字节定义消息体

如果有人发送错误的长度 - 此客户端和服务器之间的所有通信变得不可预测。

所以这个想法是创建一个最简单的方法自同步协议。

我正在使用TCP协议,所以我的想法是将消息分解成数据包,并且没有两个消息应该共享相同的数据包 - 这样我就可以忽略协议违规并恢复通信,如果有的话出错。

我想为此使用TCP,因此数据包将与TCP段相同。但也有少数渔获:

  • 的MTU(其定义了MSS)可能会有所不同,并没有为缓冲区大小没有规定值I可以使用(纠正我,如果我错了)
  • 我不能” t找到直接处理TCP段的方法(没有“流”抽象)

我是socket服务器编程的新手,所以我需要帮助。也许有人可以共享这个问题的常见解决方案(防故障协议),或者描述常见的陷阱,或者提供有用的链接。

我在.NET下开发,如果可以避免,我不想使用任何P/Invokes。

回答

2

TCP的抽象是甲流,没有内置的消息边界,你不应该试图违反该抽象。

处理行为不端客户端的主要策略是严格检查客户端提供的所有输入(例如,通常设置协议层消息的允许大小的上限)。当完整性检查表明协议已被违反时,您将停止处理错误的消息。您可能还想记录错误,并/或将其报告给客户端。

如果违反协议会导致无法重新同步,那么您别无选择,只能断开客户端连接。这可以;行为不端的客户无权期待任何服务水平。

您可以设计允许再同步的协议 - 最简单的例子是在后续协议消息之间的边界处使用分隔符(分隔符本身不允许在消息中出现)。许多旧的“基于行”的互联网协议,如FTP,SMTP和IRC以这种方式工作(本例中的分隔符是换行符)。

0

你可能想了解the protobuf-c RPC implementation

客户端发出一个12字节的头,在protobuf的编码信息的有效载荷:

  • 方法指数(编码为4个字节的小 - 端点编号)
  • 消息长度:protobuf编码有效负载的长度(编码的4字节小端编号)
  • 请求标识:客户端选择的一个值,以允许它在多个未完成的请求的情况下知道哪个服务器响应对应于哪个请求)。 (在4个字节编码)

服务器最终发出一个类似的16字节的响应:

  • 状态代码(如4个字节的小端数)。下列值的:
    0:成功
    1:服务失败(即在NULL传递该消息到闭合)
    2:太多未决(客户端连接有太多的未决请求)
  • 方法指数(相同请求)
  • 消息长度(相同请求)
  • 请求ID(相同请求)

另一件事到t如果你想通过非TCP/IP来做到这一点(即无错通道)是在头部和有效载荷上添加CRC校验。

+0

好的,如果有人在传输中插入几个破碎的字节,我应该怎么做。例如,在“方法索引”和“消息长度”之间 – dipyalov

+0

除非你打算进行比CRC校验更奇妙的事情(例如[错误检测和校正编码](http://en.wikipedia.org/wiki/) Error_detection_and_correction)),那么我不知道如何检测插入的字节不是预期的消息索引或消息长度。 –

1

这里有两个单独的问题。

  1. 你如何处理协议 违规?
  2. 你打算如何计划 保护你的服务器?

您无法通过在您的协议处理程序中构建错误纠正来保护您的服务器。你需要安全的编码做法。仔细研究一下初学者的SSL - 如果你试图让服务器全部安全,那么a)它不会,并且b)它需要很长时间。

您可能会发现,一旦服务器是安全的,协议错误的问题就更容易解决。这意味着客户端的编码错误或网络数据完整性问题。预先排除恶意行为会使问题更易于解决。

0

断开行为不当的客户端

+0

问题是要检测不正常行为和正常传输开始的地方。 – dipyalov

+0

我觉得-1这个有点苛刻。我会这么说,只要检测到任何协议错误就立即断开连接。不要尝试和重新同步,不要尝试和纠正错误,只要断开即可。因此,假设您可以知道您何时收到无效数据,请断开违规客户端。 –

+0

这不是我:)但问题仍然存在 - 如何检测missbehaviour和它发生的地方?我应该这样做吗? – dipyalov