CAICAIIs opened a new issue, #16460:
URL: https://github.com/apache/dubbo/issues/16460

   ### Pre-check
   
   - [X] I am sure that all the content I provide is in English.
   - [X] I had searched in the 
[issues](https://github.com/apache/dubbo/issues?q=is%3Aissue) and found no 
similar issues.
   
   ### Apache Dubbo Component
   
   Java SDK (apache/dubbo)
   
   ### Dubbo Version
   
   3.3.6, OpenJDK 17, Linux x86_64 (GitHub Actions runner, ubuntu-24.04: `eth0` 
10.1.0.215, `docker0` 172.18.0.1)
   
   ### Steps to reproduce this issue
   
   Triple HTTP/3 server + client on the same machine, point-to-point, loopback 
target. Single maven module, deps: `org.apache.dubbo:dubbo`, 
`dubbo-rpc-triple`, `dubbo-remoting-http3` (all 3.3.6) + `protobuf-java` 3.25.5.
   
   greet.proto:
   
   ```proto
   syntax = "proto3";
   package greet;
   option java_package = "repro.greet";
   option java_multiple_files = true;
   
   message GreetRequest { string name = 1; }
   message GreetResponse { string greeting = 1; }
   service GreetService { rpc Greet(GreetRequest) returns (GreetResponse) {} }
   ```
   
   Server: h3 enabled, negotiation off, TLS via the certs from 
dubbo-go-samples/http3/x509 (`dubbo.protocol.triple.http3.enabled=true`, 
`negotiation=false`, `dubbo.protocol.port=20000`, ssl server paths).
   
   Client:
   
   ```java
   public static void main(String[] args) throws Exception {
       System.setProperty("dubbo.protocol.triple.http3.enabled", "true");
       System.setProperty("dubbo.protocol.triple.http3.negotiation", "false");
       System.setProperty("dubbo.ssl.client-key-cert-chain-path", 
"x509/server2_cert.pem");
       System.setProperty("dubbo.ssl.client-private-key-path", 
"x509/server2_key_pkcs8.pem");
       System.setProperty("dubbo.ssl.client-trust-cert-collection-path", 
"x509/server_ca_cert.pem");
   
       System.out.println("filterLocalHost(127.0.0.1) -> " + 
NetUtils.filterLocalHost("127.0.0.1"));
   
       ReferenceConfig<GreetService> referenceConfig = new ReferenceConfig<>();
       referenceConfig.setInterface(GreetService.class);
       referenceConfig.setUrl("tri://127.0.0.1:20000?connect.timeout=10000");
       referenceConfig.setProtocol("tri");
   
       DubboBootstrap.getInstance().reference(referenceConfig).start();
       GreetService greetService = referenceConfig.get();
       GreetResponse response = 
greetService.greet(GreetRequest.newBuilder().setName("repro").build());
       System.out.println("SUCCESS! " + response.getGreeting());
   }
   ```
   
   On a multi-homed host the first line already prints the rewritten address, 
e.g. `filterLocalHost(127.0.0.1) -> 172.18.0.1`.
   
   ### Expected behavior
   
   Client connects to 127.0.0.1:20000, handshake completes.
   
   ### Actual behavior
   
   On a multi-homed host the connect always times out, and the target in the 
error is not the configured one:
   
   ```
   RemotingException: client(url: tri://127.0.0.1:20000/greet.GreetService?...) 
failed to connect to server /172.18.0.1:20000 client-side timeout 10000ms
   ```
   
   The client dials 172.18.0.1, not 127.0.0.1. tcpdump during the handshake:
   
   ```
   IP 10.1.0.215.34293 > 172.18.0.1.20000: UDP, length 1200    <- client Initial
   IP 10.1.0.215.20000 > 10.1.0.215.34293: UDP, length 88      <- server 
response, wrong source
   ```
   
   The server answers from 10.1.0.215:20000 instead of 172.18.0.1:20000. The 
client drops handshake responses from a different address than the dialed 
destination and keeps retransmitting until the timeout. The same client 
completes the QUIC handshake against a dubbo-go triple http3 server (quic-go, 
bound 0.0.0.0) on the same runner.
   
   Two code paths combine:
   
   1. `AbstractClient.getConnectAddress()` (dubbo-remoting-api) wraps the URL 
host with `NetUtils.filterLocalHost(...)`. `NetUtils.isInvalidLocalHost()` 
treats `127.*` as invalid, so the host is replaced with 
`NetUtils.getLocalHost()` (172.18.0.1, the docker0 address).
   
   2. `NettyHttp3Server` binds the QUIC transport on a wildcard 
`NioDatagramChannel` (`Start NettyHttp3Server bind /0.0.0.0:20000`) and 
responses carry the kernel-selected source (10.1.0.215, the interface towards 
the client) instead of the local destination address the client packet was sent 
to (172.18.0.1).
   
   ### Anything else
   
   Works on single-homed hosts (macOS): rewritten address and response source 
coincide, handshake succeeds. Fails the same way with connect.timeout raised to 
10s. Full CI run with tcpdump capture: 
https://github.com/apache/dubbo-go-samples/actions/runs/34701734332
   
   ### Are you willing to submit a pull request to fix on your own?
   
   - [X] Yes I am willing to submit a pull request on my own!
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to