2011-10-10 2 views
0

일반 TCP 서버에 SSL 프론트를 제공해야하므로 원래 서버를 일반 상태로 유지하면서 외부에 SSL 연결을 제공하는 "펌프"응용 프로그램을 만들고 있습니다.Indy SSL에서 일반 소켓 펌프

저는 SSL 요구 사항을 지원하기 위해 Indy 구성 요소를 사용하려고하지만 SSL 포트에서 데이터를 가져올 수 없습니다. 나는 다음과 같은 이벤트 처리기에 TIdTCPServer.OnExecute 할당 :

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 = 서버 측 (SSL을 추가하려는 TCP 서버의 클라이언트).

이제 정리가 필요하다는 것을 알고 있으며 1ms 대기는 꽤 아니지만 문제를 공격하기 전에 데이터를 받고 싶습니다.

내 ReadBytes가 호출되지 않습니다. cs.Readable()을 사용할 때 true을 한 번 만 받았지만 여전히 읽을 수는 없었습니다.

펌프를 만들려면 어떻게해야합니까? 데이터를 가져 오지 않는 이유는 무엇입니까?

+0

문제점 : 내 SSL 포트가 PassThrough 모드로 작동하고 있습니다. OnConnect 핸들러에서 직접 설정해야한다는 것을 알지 못했습니다. – DDS

+0

인디 10을 사용해야합니다. Indy 9 및 이전 버전에서는 서버 측 SSL IOHandler가 모든 데이터를 교환하기 전에 승인 된 모든 연결을 암호화 (PassThrough = False)했습니다. 이로 인해 혼합 SSL/비 SSL 클라이언트, STARTTLS 스타일 명령 등을 방지 할 수있었습니다. Indy 10에서 서버 측 SSL IOHandler는 암호화되지 않은 새로운 연결 (PassThrough = True)을 허용하므로 어떤 클라이언트가 SSL을 사용하는지 선택하고 언제 사용할 수 있습니까? SSL을 활성화하십시오. –

답변

4

TIdTCPServer 대신 TIdMappedPortTCP 구성 요소를 직접 사용해보십시오. TIdMappedPortTCP은 클라이언트와 다른 서버간에 데이터를주고받는 모든 작업을 처리합니다. TIdMappedPortTCP으로의 인바운드 연결이 암호화 된 경우에도 기본적으로 두 번째 서버로의 아웃 바운드 연결은 암호화되지 않습니다.

+0

데이터를 검사해야합니다. 포트는 수신 된 데이터에 따라 몇 대의 서버 중 하나로 전달됩니다. 그것은 단순한 펌프가 아닙니다. 클라이언트에 연결하기 전에 "Peek"해야합니다. 게다가, 이것은 그것을하는 좋은 방법이 될 것입니다. TIdMappedPortTCP 구성 요소의 소스를 살펴보고 어떻게해야하는지 살펴 보겠습니다. 나는 Indy에서 정확히 어떻게 해야할지 모르기 때문에 winsock select를 사용하려고 생각하고있었습니다. 그러나 저는 TIdMappedPortTCP에 대한 소스 코드를 찾을 것이라고 가정합니다. 감사! 인디 코드를 통해 당신의 이름을 모두 볼 수 있습니다. 잘 하셨어요! – DDS

+1

연결의 첫 번째 바이트 만 "peek"할 필요가 있다면,'OnConnect' 이벤트에서 그것을 할 수 있고,'TIdMappedPortTCP'가 연결 한'TIdTCPClient'의'Host' /'Post'를 동적으로 조정할 수 있습니다 이벤트 핸들러가 종료됩니다. –