Перекачка Indy SSL в обычный сокет

#delphi #ssl #indy

#delphi #ssl #indy

Вопрос:

Я должен предоставить интерфейс SSL для обычного TCP-сервера, поэтому я создаю приложение «pump», которое обеспечит SSL-соединение с внешней средой, в то время как исходный сервер может оставаться простым.

Я пытаюсь использовать компоненты Indy для поддержки своих потребностей в SSL, но, похоже, я не могу получить какие-либо данные с SSL-порта. Я назначил TIdTCPServer.Выполняем следующий обработчик событий:

 procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
 c:TIdTCPClient;
 cs,ss:TIdIOHandler;
 b:TBytes;
begin
 c:=TIdTCPClient.Create(Self);
 try
   c.Host:='127.0.0.1';
   c.Port:=60675;
   c.ConnectTimeout:=500;
   c.Connect;
   ss:=c.IOHandler;
   cs:=AContext.Connection.IOHandler;
   while (cs.Connected) and (ss.Connected) do
    begin
     if cs.CheckForDataOnSource(1) then
      begin
       try
        cs.ReadBytes(b,1,False);
       except on e:Exception do
        Memo1.Lines.Add(e.Message); //BAD out of Thread context
       end;
       if Length(b)>0 then
        ss.Write(b);
      end;
     if ss.CheckForDataOnSource(1) then
      begin
       ss.ReadBytes(b,1,False);
       if Length(b)>0 then
        cs.Write(b);
      end;
    end;
 finally
   c.Free;
 end;
end;
  

К TCP-серверу подключен обработчик SSL. Я сделал то же самое на обычном HTTP-сервере, и он работал нормально, поэтому я предполагаю, что проблема не в моей настройке SSL.

cs = Клиентская сторона (серверный сокет) и ss = Серверная сторона (клиент для TCP-сервера, к которому я пытаюсь добавить SSL).

Теперь я знаю, что он нуждается в очистке, и выполнение ожидания в 1 мс не очень приятно, но прежде чем я смогу решить эту проблему, я хотел бы получить некоторые данные.

Ни один из моих readBytes не вызывается. Когда я использовал cs.Readable() , я получаю true только один раз, но я все еще не мог читать.

Что я могу сделать, чтобы создать перекачку? Почему я не получаю данные?

Комментарии:

1. Я разобрался со своей проблемой: мой SSL-порт работал в режиме сквозной передачи. Я не знал, что мне нужно было установить это самостоятельно в обработчике OnConnect.

2. Тогда вы, должно быть, используете Indy 10. В Indy 9 и более ранних версиях серверный SSL IOHandler принудительно шифровал все принятые соединения (PASSSTHROUGH = False) еще до обмена любыми данными. Это предотвратило такие вещи, как смешанные клиенты SSL / не-SSL, команды в стиле STARTTLS и т.д. В Indy 10 серверный SSL IOHandler теперь принимает новые соединения в незашифрованном виде (Passhrough = True), поэтому вы можете выбрать, какие клиенты используют SSL и когда активировать SSL.

Ответ №1:

Попробуйте использовать TIdMappedPortTCP компонент вместо TIdTCPServer напрямую. TIdMappedPortTCP выполняет всю работу по передаче данных взад и вперед между клиентом и другим сервером. По умолчанию исходящее соединение со вторым сервером не зашифровано, даже если входящее соединение с TIdMappedPortTCP зашифровано.

Комментарии:

1. Мне нужно проверить данные. Порт перенаправляется на один из нескольких серверов, в зависимости от полученных данных. Это не просто прямая перекачка. Я должен «заглянуть» перед подключением к клиенту. Кроме того, это был бы отличный способ сделать это. Я посмотрю на исходный код TIdMappedPortTCP компонента и посмотрю, как я должен это делать. Я думал об использовании winsock select сам, потому что я не знаю точно, как это сделать в Indy. Но я предполагаю, что найду этот ответ в его источнике TIdMappedPortTCP . Спасибо! Я вижу ваше имя по всему коду Indy. Отличная работа!

2. Если вам нужно только «просмотреть» первые байты соединения, вы можете сделать это в OnConnect событии, а затем динамически настроить Host / Post того, с TIdTCPClient которым TIdMappedPortTCP соединяется после завершения работы обработчика событий.