proxy: create a udpListener interface

This represents what is needed from the frontend side of the proxy:

- the ability to receive a UDP datagram and know who it is from
- the ability to send a UDP datagram to a particular destination
- the ability to close

Signed-off-by: David Scott <dave.scott@docker.com>
This commit is contained in:
David Scott 2016-04-21 15:06:09 +01:00
parent 58ad1b7161
commit abbafd82f1
2 changed files with 17 additions and 10 deletions

View File

@ -31,7 +31,11 @@ type Proxy interface {
func NewProxy(frontendAddr, backendAddr net.Addr) (Proxy, error) {
switch frontendAddr.(type) {
case *net.UDPAddr:
return NewUDPProxy(frontendAddr.(*net.UDPAddr), backendAddr.(*net.UDPAddr))
listener, err := net.ListenUDP("udp", frontendAddr.(*net.UDPAddr))
if err != nil {
return nil, err
}
return NewUDPProxy(frontendAddr, listener, backendAddr.(*net.UDPAddr))
case *net.TCPAddr:
listener, err := net.Listen("tcp", frontendAddr.String())
if err != nil {

View File

@ -18,6 +18,12 @@ const (
UDPBufSize = 65507
)
type udpListener interface {
ReadFromUDP(b []byte) (int, *net.UDPAddr, error)
WriteToUDP(b []byte, addr *net.UDPAddr) (int, error)
Close() error
}
// A net.Addr where the IP is split into two fields so you can use it as a key
// in a map:
type connTrackKey struct {
@ -47,22 +53,19 @@ type connTrackMap map[connTrackKey]*net.UDPConn
// interface to handle UDP traffic forwarding between the frontend and backend
// addresses.
type UDPProxy struct {
listener *net.UDPConn
frontendAddr *net.UDPAddr
listener udpListener
frontendAddr net.Addr
backendAddr *net.UDPAddr
connTrackTable connTrackMap
connTrackLock sync.Mutex
}
// NewUDPProxy creates a new UDPProxy.
func NewUDPProxy(frontendAddr, backendAddr *net.UDPAddr) (*UDPProxy, error) {
listener, err := net.ListenUDP("udp", frontendAddr)
if err != nil {
return nil, err
}
func NewUDPProxy(frontendAddr net.Addr, listener udpListener, backendAddr *net.UDPAddr) (*UDPProxy, error) {
return &UDPProxy{
listener: listener,
frontendAddr: listener.LocalAddr().(*net.UDPAddr),
frontendAddr: frontendAddr,
backendAddr: backendAddr,
connTrackTable: make(connTrackMap),
}, nil
@ -112,7 +115,7 @@ func (proxy *UDPProxy) Run() {
// ECONNREFUSED like Read do (see comment in
// UDPProxy.replyLoop)
if !isClosedError(err) {
logrus.Printf("Stopping proxy on udp/%v for udp/%v (%s)", proxy.frontendAddr, proxy.backendAddr, err)
logrus.Printf("Stopping proxy on %v for udp/%v (%s)", proxy.frontendAddr, proxy.backendAddr, err)
}
break
}