The cause was that the incus machine on shareNL could not run docker. With @RodickYu’s reminder, it was found that port binding could not be used, and --network host must be used to start it. However, this is particularly unfriendly to NAT servers, so this tool was created.
port link maintains multiple port forwarding through a background server, binding both TCP and UDP. It can forward remote ports to local ones or local ones to another local.
Why was IPC designed instead of using command-line parameters to express the port to forward?\nUsing command-line parameters (or a configuration file), the program could run as a systemd background service and automatically restart if it crashes.\n\nWith the IPC approach, when the server program restarts, its internal state (port forwarding rules) is lost.\nIf you want to package it as a systemd service, you would need to write a second service to call the client program to reinsert the port forwarding rules.
I reviewed the key code for UDP forwarding in server/forward_udp.go.
Compared to normal NAT, the two UDP connections are completely separate, and the remote server cannot obtain the client’s IP address information.
Here, simply calling connMap.Clear() is sufficient.
Using clientAddr.AddrPort() is more efficient.
It returns a netip.AddrPort type, specifically designed to be used as a map key.
Due to Go 1 compatibility guarantees, the address types in the net package cannot be changed, but their internal implementations have already been converted to netip package types.
Converting to strings involves additional operations, which are unnecessary here.
Starting from Go 1.25, you can use wg.Go() for a more concise implementation.