패킷 전송 시간을 줄이는 시스템을 설계하고 싶습니다. 클라이언트에서 SYN 비트를 보내면 라우터를 통해 서버로 전송되고 서버는 라우터를 통해 클라이언트로 전송되는 SYN+ACK에 응답하게 됩니다. 라우터.
따라서 클라이언트가 라우터에 SYN을 보내고 라우터가 이를 서버에 보내고 이 패킷을 복사한 다음 SYN을 SYN+ACK로 수정하고 서버에서 이 SYN+ACK를 보내는 것과 같은 다른 작업을 수행하고 싶습니다. 라우터로 가서 클라이언트로 다시 보내기 전에 서버는 그것을 보낼 수 있고, 라우터는 그것을 받아들이고(응답이 올 때 그것을 보고) 그것을 버립니다.
위의 목표를 달성하기 위해 한 랩톱은 두 개의 이더넷 인터페이스에서 패킷을 보내고 받는 설정을 설계했으며 다른 랩톱은 라우터 역할을 하는 데스크톱입니다(패킷이 들어오면 대상으로 전달하기만 함). 라우팅 테이블을 설정했습니다. 데스크탑에서 IP 전달을 활성화합니다(라우터 역할).
모든 것이 잘 작동합니다. 랩톱에는 패킷을 보내고 받는 서버 및 클라이언트 프로그램이 있지만 문제는 패킷을 소스(소스 자체)로 보내고 싶기 때문에 경로에서 패킷을 수정합니다. netfilter 모듈을 사용하여 전체 skb를 복사하고(skb_copy 사용) 해당 IP 소스와 대상을 교환하고(NF_INET_PREROUTING에서 이 작업을 수행함) 포트 번호를 교환하지만 패킷은 항상 대상으로 전송됩니다.
패킷을 소스 자체로 보내려면 어떤 다른 수정이 필요합니까?
답변1
TCP는 연결 양쪽에서 서로 다른 시퀀스 카운터를 사용합니다. 따라서 완전한 패킷을 다시 보내면 잘못된 시퀀스 번호를 갖게 되며 상대방은 지연된 중복 패킷이라고 생각하기 때문에 거부됩니다.
그러나 보낼 수는 있습니다.콘텐츠당신이 원하는 것이면 패킷을 돌려주세요. 쉬운 방법은 socat
. 하나가 되어 해
socat TCP-LISTEN:9990 SYSTEM:"cat"
이는 들어오는 연결을 수신하고 연결이 설정되면 들어오는 데이터를 로 파이프하여 cat
동일한 데이터를 출력한 다음 TCP 연결을 통해 출력을 얻습니다.
다른 방법으로는
socat - TCP:localhost:9990
그러면 첫 번째 socat
포트 9990에 연결되어 전송 stdin
되고 응답이 작성됩니다 stdout
. 몇 줄(stdin은 CR에서만 줄을 보냅니다)을 입력하고 다시 나타나는지 확인하세요.
따라서 그것이 아이디어라면 설정을 테스트하는 데 사용할 수 있습니다. 비슷한 방법을 사용하여 모든 것을 서버로 다시 보낼 수도 있습니다.
socat TCP:server.com:1234 SYSTEM:"cat"
하지만 이렇게 하려면 서버가 연결할 때 실제로 무언가를 보내야 합니다.
그래도 문제가 해결되지 않으면 질문을 편집하고 설명하십시오.왜"패킷"을 다시 보내고 싶고문제가 무엇입니까?"패킷"을 다시 보내서 문제를 해결하시겠습니까? (설정을 테스트합니까? 서버를 테스트합니까? 다른 것이 있습니까?)
이건 정말 비슷해 보여요XY 문제.
답변2
질문이 완전히 바뀌었기 때문에 또 다른 대답은 다음과 같습니다.
서버가 실제로 SYN을 수신하기 전에 클라이언트에 SYN+ACK를 다시 보내는 작업은 무엇입니까?동기화 에이전트하다. Google의 기존 구현입니다.
이는 "패킷을 다시 보내는 것"과는 아무런 관련이 없으며 단지 초기 SYN/ACK 처리에 관한 것입니다.
아니요, 방화벽 규칙을 사용하여 이 작업을 수행하는 것은 불가능합니다. 상태를 유지해야 하기 때문입니다(또는 최소한 특정 양의 상태를 유지해야 함).