SOCKS5 프런트 엔드는 HTTP 프록시를 이후 전송 수단으로 사용할 수 있습니다. 클라이언트를 상대로는 SOCKS 서버로, 부모를 상대로는 HTTP CONNECT 클라이언트로 동작합니다. 두 제어 교환은 애플리케이션 스트림이 시작되기 전에 끝납니다.

SOCKS CONNECT 요청은 이미 목적지 호스트나 주소와 포트를 제공합니다. 설명을 위한 HTTP/1.1 부모 교환은 다음과 같습니다.

client → adapter: SOCKS5 CONNECT service.example.net:443
adapter → parent:
    CONNECT service.example.net:443 HTTP/1.1
    Host: service.example.net:443

parent → adapter: HTTP/1.1 200 Connection Established
                 [end of headers]
adapter → client: SOCKS5 success reply

client ↔ adapter ↔ parent ↔ service: application bytes

경계에서 결과를 변환하십시오

어댑터는 부모가 요구하는 인증을 모두 마치고 CONNECT 결과를 기다립니다. 성공한 2xx 응답이 부모 터널을 수립합니다. 그 뒤에야 어댑터는 해당 SOCKS 성공 응답을 하위 클라이언트에 돌려보내야 합니다.

부모가 작업을 거부하면 정해진 SOCKS 실패 응답을 보낸 다음 클라이언트 연결을 즉시 종료합니다. SOCKS5는 실패를 감지한 뒤 10초 안에 그 종료를 요구합니다. 부모의 HTTP 상태는 어댑터의 진단 정보로 보관하십시오. 그 상태 줄을 애플리케이션 데이터로 전달하면 클라이언트가 SOCKS 프레이밍을 기대하는 스트림에 HTTP 제어 메시지가 들어갑니다.

CONNECT가 성공하기 전까지 부모는 여전히 HTTP를 사용하며, 챌린지나 오류 응답의 프레이밍도 포함됩니다. 성공한 결과의 헤더 구분자 뒤에서 연결은 터널이 됩니다. 먼저 소비해야 할 HTTP 응답 본문은 없습니다.

헤더 뒤의 바이트를 보존하십시오

한 번의 읽기에 부모 헤더의 끝과 목적지에서 온 바이트가 함께 들어 있을 수 있습니다. 그 여분의 바이트를 하위 애플리케이션을 위해 보관하십시오. 서버가 먼저 말하는 프로토콜은 연결이 열리자마자 인사를 보낼 수 있습니다.

SOCKS 성공 응답을 보낸 뒤에는 애플리케이션 스트림을 양방향으로 중계하십시오. 어댑터는 클라이언트 메시지 하나와 서버 메시지 하나를 번갈아 다룰 필요가 없고, TLS 레코드를 이해해야 전달할 수도 없습니다. 어댑터의 프로토콜 작업은 두 터널 협상을 수립하고 변환하는 일이었습니다.

관련 글