From 159f14ed40c8e49b5b206904c9d8e1f7bd373b8d Mon Sep 17 00:00:00 2001 From: davy wybiral Date: Mon, 29 Apr 2019 18:55:19 -0500 Subject: [PATCH] Udp (#34) * add udp * version bump --- hookah.go | 5 ++- internal/protocols/udp.go | 16 +++++++++ internal/protocols/udplisten.go | 61 +++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 internal/protocols/udp.go create mode 100644 internal/protocols/udplisten.go diff --git a/hookah.go b/hookah.go index 5616218..5a71a83 100644 --- a/hookah.go +++ b/hookah.go @@ -12,7 +12,7 @@ import ( ) // Version of hookah API. -const Version = "2.1.0" +const Version = "2.2.0" // API is an instance of the Hookah API. type API struct { @@ -88,6 +88,9 @@ func (a *API) registerProtocols() { a.RegisterProtocol("tcp-listen", "tcp-listen://address", protocols.TCPListen) a.RegisterProtocol("tls", "tls://address?cert=path&insecure=false", protocols.TLS) a.RegisterProtocol("tls-listen", "tls-listen://address?cert=path&key=path", protocols.TLSListen) + a.RegisterProtocol("udp", "udp://address", protocols.UDP) + a.RegisterProtocol("udp-listen", "udp-listen://address", protocols.UDPListen) + a.RegisterProtocol("udp-multicast", "udp-multicast://address", protocols.UDPMulticast) a.RegisterProtocol("unix", "unix://path/to/sock", protocols.Unix) a.RegisterProtocol("unix-listen", "unix-listen://path/to/sock", protocols.UnixListen) a.RegisterProtocol("ws", "ws://address", protocols.WS) diff --git a/internal/protocols/udp.go b/internal/protocols/udp.go new file mode 100644 index 0000000..b04eadd --- /dev/null +++ b/internal/protocols/udp.go @@ -0,0 +1,16 @@ +package protocols + +import ( + "net" + + "github.com/wybiral/hookah/pkg/node" +) + +// UDP creates a UDP client node +func UDP(addr string) (*node.Node, error) { + rwc, err := net.Dial("udp", addr) + if err != nil { + return nil, err + } + return node.New(rwc), nil +} diff --git a/internal/protocols/udplisten.go b/internal/protocols/udplisten.go new file mode 100644 index 0000000..a2e0051 --- /dev/null +++ b/internal/protocols/udplisten.go @@ -0,0 +1,61 @@ +package protocols + +import ( + "net" + "net/url" + "strings" + + "github.com/wybiral/hookah/pkg/node" +) + +// UDPListen creates a UDP listener Node +func UDPListen(addr string) (*node.Node, error) { + a, err := net.ResolveUDPAddr("udp", addr) + if err != nil { + return nil, err + } + c, err := net.ListenUDP("udp", a) + if err != nil { + return nil, err + } + n := node.New(c) + n.W = nil + return n, nil +} + +// UDPMulticast creates a UDP multicast listener Node +func UDPMulticast(arg string) (*node.Node, error) { + var err error + var opts url.Values + // Parse options + addrOpts := strings.SplitN(arg, "?", 2) + addr := addrOpts[0] + if len(addrOpts) == 2 { + op, err := url.ParseQuery(addrOpts[1]) + if err != nil { + return nil, err + } + opts = op + } + iface := opts.Get("iface") + var ifi *net.Interface + ifi = nil + if len(iface) > 0 { + // If interface is supplied, look it up + ifi, err = net.InterfaceByName(iface) + if err != nil { + return nil, err + } + } + a, err := net.ResolveUDPAddr("udp", addr) + if err != nil { + return nil, err + } + c, err := net.ListenMulticastUDP("udp", ifi, a) + if err != nil { + return nil, err + } + n := node.New(c) + n.W = nil + return n, nil +}