Here is the setup:
Machine A is in cloud VPC with 172.17.x.x segment, with public IP and all ports wide open.
Machine B is behind home router which has public IP.
Step 1: get both Machine A and B up and running. They can ping each other with Tailscale 100.x.x.x IP addresses.
Step 2: cut off both machines’ connection to control server and DERP servers.
Step 3: leave it for a while.
Now comes the interesting part:
Ping from A to B, it doesn’t go through. tcpdump on Machine B’s router shows that the UDP wireguard packets do come but machine B didn’t get it. Maybe Machine B doesn’t do keep alive?
Now if I ping from machine B to A with one packet, it’ll will go through. But another weird thing happens: If I ping from A to B, only one packet can go through. I run
tailscale status -json on machine A, the peer’s CurAddr field is updated to machine B’s internal IP address 192.168.x.x:port. And now ping doesn’t go through from A to B (of course). If I ping another packet from B to A, the CurAddr field on machine A is updated correctly to machine B’s public IP on router and now this time it stays even if I ping from A to B again.
If I leave it again for a while it’ll repeat the process.
My tailscale version is 20210104 on both machines.