From abbafd82f10a301e4eb882516952e255b66404fa Mon Sep 17 00:00:00 2001 From: David Scott Date: Thu, 21 Apr 2016 15:06:09 +0100 Subject: [PATCH] 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 --- alpine/packages/proxy/libproxy/proxy.go | 6 +++++- alpine/packages/proxy/libproxy/udp_proxy.go | 21 ++++++++++++--------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/alpine/packages/proxy/libproxy/proxy.go b/alpine/packages/proxy/libproxy/proxy.go index 2e6bb569b..e8fbbe0c5 100644 --- a/alpine/packages/proxy/libproxy/proxy.go +++ b/alpine/packages/proxy/libproxy/proxy.go @@ -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 { diff --git a/alpine/packages/proxy/libproxy/udp_proxy.go b/alpine/packages/proxy/libproxy/udp_proxy.go index 7b59466b0..9b6cefc42 100644 --- a/alpine/packages/proxy/libproxy/udp_proxy.go +++ b/alpine/packages/proxy/libproxy/udp_proxy.go @@ -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 }