mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
When a UDP server is running on a multihomed server, as is the case with pretty much _all_ Docker hosts (eg. eth0 + docker0), the kernel has to choose which source address is used when replying to a UDP client. But that process is based on heuristics and is fallible. If the address picked doesn't match the original destination address used by the client, it'll drop the datagram and return an ICMP Port Unreachable. To prevent that, we need to: - `setsockopt(IP_PKTINFO)` on proxy's sockets. - Extract the original destination address from an ancillary message every time a new 'UDP connection' is 'established' (ie. every time we insert a new entry into the UDP conntrack table). - And finally, pass a control message containing the desired source address to the kernel, every time we send a response back to the client. Also, update the inline comment on read errors in `(*UDPProxy).Run()`. This comment was misleadingly referencing ECONNREFUSED - Linux's UDP implementation never returns this error (see [1]). Instead, state why `net.ErrClosed` is perfectly fine and doesn't need to be logged (although, docker-proxy currently logs to nowhere). [1]: https://github.com/search?q=repo%3Atorvalds%2Flinux+ECONNREFUSED+path%3A%2F%5Enet%5C%2F%28ipv4%7Cipv6%29%5C%2F%28udp%7Ctcp%29%2F&type=code Signed-off-by: Albin Kerouanton <albinker@gmail.com>
27 lines
802 B
Go
27 lines
802 B
Go
// docker-proxy provides a network Proxy interface and implementations for TCP
|
|
// and UDP.
|
|
package main
|
|
|
|
// ipVersion refers to IP version - v4 or v6
|
|
type ipVersion string
|
|
|
|
const (
|
|
// IPv4 is version 4
|
|
ip4 ipVersion = "4"
|
|
// IPv4 is version 6
|
|
ip6 ipVersion = "6"
|
|
)
|
|
|
|
// Proxy defines the behavior of a proxy. It forwards traffic back and forth
|
|
// between two endpoints : the frontend and the backend.
|
|
// It can be used to do software port-mapping between two addresses.
|
|
// e.g. forward all traffic between the frontend (host) 127.0.0.1:3000
|
|
// to the backend (container) at 172.17.42.108:4000.
|
|
type Proxy interface {
|
|
// Run starts forwarding traffic back and forth between the front
|
|
// and back-end addresses.
|
|
Run()
|
|
// Close stops forwarding traffic and close both ends of the Proxy.
|
|
Close()
|
|
}
|