github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/libnetwork/portmapper/proxy.go (about) 1 package portmapper 2 3 import ( 4 "fmt" 5 "io" 6 "net" 7 8 "github.com/ishidawataru/sctp" 9 ) 10 11 type userlandProxy interface { 12 Start() error 13 Stop() error 14 } 15 16 // ipVersion refers to IP version - v4 or v6 17 type ipVersion string 18 19 const ( 20 // IPv4 is version 4 21 ipv4 ipVersion = "4" 22 // IPv4 is version 6 23 ipv6 ipVersion = "6" 24 ) 25 26 // dummyProxy just listen on some port, it is needed to prevent accidental 27 // port allocations on bound port, because without userland proxy we using 28 // iptables rules and not net.Listen 29 type dummyProxy struct { 30 listener io.Closer 31 addr net.Addr 32 ipVersion ipVersion 33 } 34 35 func newDummyProxy(proto string, hostIP net.IP, hostPort int) (userlandProxy, error) { 36 // detect version of hostIP to bind only to correct version 37 version := ipv4 38 if hostIP.To4() == nil { 39 version = ipv6 40 } 41 switch proto { 42 case "tcp": 43 addr := &net.TCPAddr{IP: hostIP, Port: hostPort} 44 return &dummyProxy{addr: addr, ipVersion: version}, nil 45 case "udp": 46 addr := &net.UDPAddr{IP: hostIP, Port: hostPort} 47 return &dummyProxy{addr: addr, ipVersion: version}, nil 48 case "sctp": 49 addr := &sctp.SCTPAddr{IPAddrs: []net.IPAddr{{IP: hostIP}}, Port: hostPort} 50 return &dummyProxy{addr: addr, ipVersion: version}, nil 51 default: 52 return nil, fmt.Errorf("Unknown addr type: %s", proto) 53 } 54 } 55 56 func (p *dummyProxy) Start() error { 57 switch addr := p.addr.(type) { 58 case *net.TCPAddr: 59 l, err := net.ListenTCP("tcp"+string(p.ipVersion), addr) 60 if err != nil { 61 return err 62 } 63 p.listener = l 64 case *net.UDPAddr: 65 l, err := net.ListenUDP("udp"+string(p.ipVersion), addr) 66 if err != nil { 67 return err 68 } 69 p.listener = l 70 case *sctp.SCTPAddr: 71 l, err := sctp.ListenSCTP("sctp"+string(p.ipVersion), addr) 72 if err != nil { 73 return err 74 } 75 p.listener = l 76 default: 77 return fmt.Errorf("Unknown addr type: %T", p.addr) 78 } 79 return nil 80 } 81 82 func (p *dummyProxy) Stop() error { 83 if p.listener != nil { 84 return p.listener.Close() 85 } 86 return nil 87 }