1

我正在使用 D5(这是事实)。我安装了 Indy9。我正在尝试接收IdMappedPortTCP端口 8041 (SSL) 上的数据并将数据重定向到Tserversocket端口 8040 上。所以我将支持 SSL over Tserversocket.

我使用以下代码:

var
  masterdir:String;
begin
  masterdir:=Extractfilepath(paramstr(0));
  IdMappedPortTCP1.Active:=false;

  datamodule2.IdMappedPortTCP1.MappedHost:='192.168.0.3';
  datamodule2.IdMappedPortTCP1.MappedPort:=8041;
  datamodule2.IdMappedPortTCP1.DefaultPort:=8040;

  IdServerIOHandlerSSL1.SSLOptions.RootCertFile:=masterdir+'mycert.pem';
  IdServerIOHandlerSSL1.SSLOptions.CertFile:=masterdir+'mycert.pem';
  IdServerIOHandlerSSL1.SSLOptions.KeyFile:=masterdir+'key.pem';
  IdMappedPortTCP1.IOHandler:=IdServerIOHandlerSSL1;
  IdMappedPortTCP1.Active:=true;
end;

如果我不使用 SSL,一切都很好。但是当我使用 SSL 时,请求永远不会到达加密的 8040 端口,我需要它不加密所以我可以处理它。

4

1 回答 1

0

从您的描述中不清楚是否TServerSocket在端口 8040 上使用 SSL。它对您的设置方式有很大影响TIdMappedPortTCP。但是,根据您的描述,您至少有向后 的MappedPortand属性分配。是监听的端口,所以应该是8041。 是连接的端口,所以应该是8040。DefaultPortDefaultPortTIdMappedPortTCPMappedPortTIdMappedPortTCP

在同一个端口上有未加密和加密的连接并不常见。大多数协议使用单独的端口。这里是这样吗?8040端口是未加密的,8041端口是加密的吗?

如果要TIdMappedPortTCP在不同的端口上接受加密和未加密的客户端,则需要向TIdMappedPortTCP.Bindings集合中添加 2 个条目,每个端口一个,并且根本不使用该DefaultPort属性。在这种情况TIdMappedPortTCP.OnConnect下,您可以检测客户端连接到哪个端口,然后AThread.OutboundClient在连接之前进行相应的配置TServerSocket

让未加密和加密的客户端连接到同一个端口是不明智的。在这种情况下,您必须嗅探前几个字节以了解客户端是否正在发送 SSL 握手,然后采取相应措施。使用单独的端口更容易。但是,某些协议确实允许客户端连接到未加密的端口,然后在需要时发送命令以激活加密。在这种情况下,您只需要 1 个端口 in TIdMappedPortTCP,因此您可以定义 1Binding或使用DefaultPort.

TIdMappedPortTCP主要用于在客户端和目标服务器之间来回直接传递原始字节。如果TServerSocket正在使用 SSL,并且您希望客户端能够正确TServerSocket使用 SSL ,那么您根本不应该使用。让客户端的原始加密数据按原样传递给,反之亦然。他们应该彼此建立安全会话,而不是与您建立安全会话。如果其中任何一个执行对等身份验证,这一点尤其重要。TIdServerIOHandlerSSLTIdMappedPortTCPTServerSocket

如果您需要处理在客户端TServerSocketTIdMappedPortTCP是为了防止)。为此,您必须在客户端和TIdMappedPortTCP之间TIdMappedPortTCP以及和之间建立单独的 SSL 会话TServerSocket。分配TIdServerIOHandlerSSLTIdMappedPortTCP仅有助于与客户端的会话。您必须手动设置会话TServerSocket。为此,您必须手动将新TIdSSLIOHandlerSocket对象分配给事件 中的AThread.OutboundClient.IOHandler属性。不会为你处理。OnConnectTIdMappedPortTCP

但是,如果TServerSocket不使用 SSL,并且您将TIdMappedPortTCP其用作 SSL 网关TServerSocket,那么您可以跳过OutboundClient.IOHandler分配,因为您只需要 1 个 SSL 会话,在TIdMappedPortTCP和客户端之间。

现在,话虽如此,Indy 9 中存在一些问题。TIdSSLIOHandlerOpenSSL.PassThrough默认情况下该属性为 False(因此假设加密最初是活动的),并TIdServerIOHandlerSSL假设每个接受的客户端连接都使用 SSL,即使它确实不是。如果未加密的客户端连接到TIdMappedPortTCP分配TIdServerIOHandlerSSL,客户端将不会被正确处理。这些问题已在 Indy 10 中修复。但在 Indy 9 中,您将无法在同一TIdMappedPortTCP组件中处理加密和未加密的客户端。但是,如果您只处理加密的客户端,则不会遇到问题。否则,创建 2TIdMappedPortTCP组件,一个监听未加密端口,另一个监听加密端口。它们可以共享相同的事件处理程序。如果需要,您可以使用该AThread.Connection.Socket.Binding.Port属性来了解客户端连接到哪个端口。

于 2015-10-09T18:18:42.950 回答