From c52f5f85483c5b8bf901233f153616834f68cffd Mon Sep 17 00:00:00 2001 From: Riobard Date: Thu, 27 Feb 2020 02:09:25 +0800 Subject: [PATCH] Split listener into subpackage --- listen/listen.go | 51 ++++++++++++++ listener_linux.go => listen/nf_linux.go | 8 +-- listener_darwin.go => listen/pf_darwin.go | 2 +- listen/socks.go | 39 +++++++++++ listener.go | 83 ----------------------- main.go | 10 +-- tcp.go | 4 ++ 7 files changed, 102 insertions(+), 95 deletions(-) create mode 100644 listen/listen.go rename listener_linux.go => listen/nf_linux.go (89%) rename listener_darwin.go => listen/pf_darwin.go (97%) create mode 100644 listen/socks.go delete mode 100644 listener.go diff --git a/listen/listen.go b/listen/listen.go new file mode 100644 index 00000000..452fe663 --- /dev/null +++ b/listen/listen.go @@ -0,0 +1,51 @@ +package listen + +import ( + "errors" + "net" +) + +var listeners = make(map[string]func(network, address string) (net.Listener, error)) + +var ErrUnsupported = errors.New("unsupported") + +func Listen(kind, network, address string) (net.Listener, error) { + f, ok := listeners[kind] + if ok { + return f(network, address) + } + return nil, ErrUnsupported +} + +type strAddr string + +func (a strAddr) Network() string { return "tcp" } +func (a strAddr) String() string { return string(a) } + +type targetConn struct { + net.Conn + target net.Addr +} + +func (c *targetConn) LocalAddr() net.Addr { return c.target } + +type targetListener struct { + net.Listener + target net.Addr +} + +func ListenTo(network, address, target string) (net.Listener, error) { + l, err := net.Listen(network, address) + if err != nil { + return nil, err + } + return &targetListener{l, strAddr(target)}, err +} + +func (l *targetListener) Accept() (net.Conn, error) { + c, err := l.Listener.Accept() + if err != nil { + return nil, err + } + return &targetConn{c, l.target}, nil +} diff --git a/listener_linux.go b/listen/nf_linux.go similarity index 89% rename from listener_linux.go rename to listen/nf_linux.go index 403a8658..2756ce1b 100644 --- a/listener_linux.go +++ b/listen/nf_linux.go @@ -1,4 +1,4 @@ -package main +package listen import ( "context" @@ -54,9 +54,5 @@ func tproxyListen(network, address string) (net.Listener, error) { } return err2 }} - l, err := lcfg.Listen(context.Background(), network, address) - if err != nil { - return nil, err - } - return l, nil + return lcfg.Listen(context.Background(), network, address) } diff --git a/listener_darwin.go b/listen/pf_darwin.go similarity index 97% rename from listener_darwin.go rename to listen/pf_darwin.go index 0fe8a817..20e343e4 100644 --- a/listener_darwin.go +++ b/listen/pf_darwin.go @@ -1,4 +1,4 @@ -package main +package listen import ( "net" diff --git a/listen/socks.go b/listen/socks.go new file mode 100644 index 00000000..6dc1ad05 --- /dev/null +++ b/listen/socks.go @@ -0,0 +1,39 @@ +package listen + +import ( + "net" + + "github.com/riobard/go-shadowsocks2/socks" +) + +func init() { + listeners["socks"] = socksListen +} + +type socksConn struct{ net.Conn } + +func (sc socksConn) LocalAddr() net.Addr { + addr, err := socks.Handshake(sc.Conn) + if err != nil { + return nil + } + return strAddr(addr.String()) +} + +type socksListener struct{ net.Listener } + +func (l *socksListener) Accept() (net.Conn, error) { + c, err := l.Listener.Accept() + if err != nil { + return nil, err + } + return socksConn{c}, nil +} + +func socksListen(network, addr string) (net.Listener, error) { + l, err := net.Listen(network, addr) + if err != nil { + return nil, err + } + return &socksListener{l}, nil +} diff --git a/listener.go b/listener.go deleted file mode 100644 index 109cdaca..00000000 --- a/listener.go +++ /dev/null @@ -1,83 +0,0 @@ -package main - -import ( - "errors" - "net" - - "github.com/riobard/go-shadowsocks2/socks" -) - -var listeners map[string]func(network, address string) (net.Listener, error) - -func init() { - listeners = make(map[string]func(network, address string) (net.Listener, error)) -} - -func listen(kind, network, address string) (net.Listener, error) { - f, ok := listeners[kind] - if ok { - return f(network, address) - } - return nil, errors.New("unsupported listener " + kind) -} - -type strAddr string - -func (a strAddr) Network() string { return "tcp" } -func (a strAddr) String() string { return string(a) } - -type tunConn struct { - net.Conn - target net.Addr -} - -func (c *tunConn) LocalAddr() net.Addr { return c.target } - -type tunListener struct { - net.Listener - target net.Addr -} - -func tunListen(network, address, target string) (net.Listener, error) { - l, err := net.Listen(network, address) - if err != nil { - return nil, err - } - return &tunListener{l, strAddr(target)}, err -} - -func (l *tunListener) Accept() (net.Conn, error) { - c, err := l.Listener.Accept() - if err != nil { - return nil, err - } - return &tunConn{c, l.target}, nil -} - -type socksConn struct{ net.Conn } - -func (sc socksConn) LocalAddr() net.Addr { - addr, err := socks.Handshake(sc.Conn) - if err != nil { - return nil - } - return strAddr(addr.String()) -} - -type socksListener struct{ net.Listener } - -func (l *socksListener) Accept() (net.Conn, error) { - c, err := l.Listener.Accept() - if err != nil { - return nil, err - } - return socksConn{c}, nil -} - -func socksListen(network, addr string) (net.Listener, error) { - l, err := net.Listen(network, addr) - if err != nil { - return nil, err - } - return &socksListener{l}, nil -} diff --git a/main.go b/main.go index 2424f6f1..342a40b3 100644 --- a/main.go +++ b/main.go @@ -11,6 +11,7 @@ import ( "time" "github.com/riobard/go-shadowsocks2/core" + "github.com/riobard/go-shadowsocks2/listen" ) var config struct { @@ -33,7 +34,6 @@ func main() { UDPTun PairList Socks string RedirTCP string - RedirTCP6 string TproxyTCP string } @@ -82,7 +82,7 @@ func main() { if len(flags.TCPTun) > 0 { for _, p := range flags.TCPTun { - l, err := tunListen("tcp", p[0], p[1]) + l, err := listen.ListenTo("tcp", p[0], p[1]) if err != nil { log.Fatal(err) } @@ -92,7 +92,7 @@ func main() { } if flags.Socks != "" { - l, err := socksListen("tcp", flags.Socks) + l, err := listen.Listen("socks", "tcp", flags.Socks) if err != nil { log.Fatal(err) } @@ -101,7 +101,7 @@ func main() { } if flags.RedirTCP != "" { - l, err := listen("redir", "tcp", flags.RedirTCP) + l, err := listen.Listen("redir", "tcp", flags.RedirTCP) if err != nil { log.Fatal(err) } @@ -110,7 +110,7 @@ func main() { } if flags.TproxyTCP != "" { - l, err := listen("tproxy", "tcp", flags.TproxyTCP) + l, err := listen.Listen("tproxy", "tcp", flags.TproxyTCP) if err != nil { log.Fatal(err) } diff --git a/tcp.go b/tcp.go index e0a293b3..2b696114 100644 --- a/tcp.go +++ b/tcp.go @@ -19,6 +19,10 @@ func tcpLocal(l net.Listener, d Dialer) { go func() { defer c.Close() laddr := c.LocalAddr() + if laddr == nil { + logf("failed to determine target address") + return + } rc, err := d.Dial(laddr.Network(), laddr.String()) if err != nil { logf("failed to connect: %v", err)