From dadaf35cb2015fa9649e110250ee4854e8ab44f2 Mon Sep 17 00:00:00 2001 From: nadoo <287492+nadoo@users.noreply.github.com> Date: Sun, 25 Nov 2018 17:56:59 +0800 Subject: [PATCH] unix: add unix domain socket support. #59 --- main_linux.go | 1 + proxy/tls/tls.go | 7 ++- proxy/unix/unix.go | 131 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 proxy/unix/unix.go diff --git a/main_linux.go b/main_linux.go index 636e616b..ce57ebd8 100644 --- a/main_linux.go +++ b/main_linux.go @@ -2,4 +2,5 @@ package main import ( _ "github.com/nadoo/glider/proxy/redir" + _ "github.com/nadoo/glider/proxy/unix" ) diff --git a/proxy/tls/tls.go b/proxy/tls/tls.go index 19e499af..3e456f89 100644 --- a/proxy/tls/tls.go +++ b/proxy/tls/tls.go @@ -118,15 +118,18 @@ func NewTLSServer(s string, dialer proxy.Dialer) (proxy.Server, error) { } p.server, err = proxy.ServerFromURL(transport[1], dialer) + if err != nil { + return nil, err + } - return p, err + return p, nil } // ListenAndServe . func (s *TLS) ListenAndServe() { l, err := net.Listen("tcp", s.addr) if err != nil { - log.F("[tls] failed to listen on tls %s: %v", s.addr, err) + log.F("[tls] failed to listen on %s: %v", s.addr, err) return } defer l.Close() diff --git a/proxy/unix/unix.go b/proxy/unix/unix.go new file mode 100644 index 00000000..90a913ff --- /dev/null +++ b/proxy/unix/unix.go @@ -0,0 +1,131 @@ +package unix + +import ( + "errors" + "fmt" + "net" + "net/url" + "os" + "strings" + + "github.com/nadoo/glider/common/log" + "github.com/nadoo/glider/proxy" +) + +// Unix domain socket struct +type Unix struct { + dialer proxy.Dialer + addr string + + server proxy.Server +} + +func init() { + proxy.RegisterServer("unix", NewUnixServer) + proxy.RegisterDialer("unix", NewUnixDialer) +} + +// NewUnix returns unix fomain socket proxy +func NewUnix(s string, dialer proxy.Dialer) (*Unix, error) { + u, err := url.Parse(s) + if err != nil { + log.F("parse url err: %s", err) + return nil, err + } + + p := &Unix{ + dialer: dialer, + addr: u.Path, + } + + return p, nil +} + +// NewUnixDialer returns a unix domain socket dialer +func NewUnixDialer(s string, dialer proxy.Dialer) (proxy.Dialer, error) { + return NewUnix(s, dialer) +} + +// NewUnixServer returns a unix domain socket server +func NewUnixServer(s string, dialer proxy.Dialer) (proxy.Server, error) { + transport := strings.Split(s, ",") + + // prepare transport listener + // TODO: check here + if len(transport) < 2 { + err := fmt.Errorf("[unix] malformd listener: %s", s) + log.F(err.Error()) + return nil, err + } + + p, err := NewUnix(transport[0], dialer) + if err != nil { + return nil, err + } + + p.server, err = proxy.ServerFromURL(transport[1], dialer) + if err != nil { + return nil, err + } + + return p, nil +} + +// ListenAndServe serves requests +func (s *Unix) ListenAndServe() { + os.Remove(s.addr) + l, err := net.Listen("unix", s.addr) + if err != nil { + log.F("[unix] failed to listen on %s: %v", s.addr, err) + return + } + defer l.Close() + + log.F("[uinx] listening on %s", s.addr) + + for { + c, err := l.Accept() + if err != nil { + log.F("[uinx] failed to accept: %v", err) + continue + } + + go s.Serve(c) + } +} + +// Serve serves requests +func (s *Unix) Serve(c net.Conn) { + defer c.Close() + + if s.server != nil { + s.server.Serve(c) + } +} + +// Addr returns forwarder's address +func (s *Unix) Addr() string { + if s.addr == "" { + return s.dialer.Addr() + } + return s.addr +} + +// NextDialer returns the next dialer +func (s *Unix) NextDialer(dstAddr string) proxy.Dialer { return s.dialer.NextDialer(dstAddr) } + +// Dial connects to the address addr on the network net via the proxy. +func (s *Unix) Dial(network, addr string) (net.Conn, error) { + // NOTE: must be the first dialer in a chain + rc, err := net.Dial("unix", s.addr) + if err != nil { + return nil, err + } + + return rc, err +} + +// DialUDP connects to the given address via the proxy +func (s *Unix) DialUDP(network, addr string) (net.PacketConn, net.Addr, error) { + return nil, nil, errors.New("unix domain socket client does not support udp now") +}