From e35e2717088c7bf6c59919723200b95a80d32196 Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Wed, 4 Jan 2017 13:29:41 +0100 Subject: [PATCH] cleanup internet connection --- .../internet/{tcp => internal}/connection.go | 58 ++++++++++++++----- transport/internet/internal/pool.go | 17 ------ transport/internet/kcp/dialer.go | 2 +- transport/internet/kcp/listener.go | 2 +- transport/internet/kcp/tls.go | 13 +++++ transport/internet/tcp/dialer.go | 2 +- transport/internet/tcp/hub.go | 2 +- transport/internet/tls/connection.go | 21 ------- transport/internet/websocket/wsconn.go | 16 ++--- 9 files changed, 64 insertions(+), 69 deletions(-) rename transport/internet/{tcp => internal}/connection.go (63%) create mode 100644 transport/internet/kcp/tls.go delete mode 100644 transport/internet/tls/connection.go diff --git a/transport/internet/tcp/connection.go b/transport/internet/internal/connection.go similarity index 63% rename from transport/internet/tcp/connection.go rename to transport/internet/internal/connection.go index 58ec92d60..498f1650f 100644 --- a/transport/internet/tcp/connection.go +++ b/transport/internet/internal/connection.go @@ -1,4 +1,4 @@ -package tcp +package internal import ( "io" @@ -6,25 +6,52 @@ import ( "sync" "time" - "v2ray.com/core/transport/internet/internal" + v2net "v2ray.com/core/common/net" ) -type Connection struct { - sync.RWMutex - id internal.ConnectionID - reusable bool - conn net.Conn - listener internal.ConnectionRecyler - config *Config +// ConnectionID is the ID of a connection. +type ConnectionID struct { + Local v2net.Address + Remote v2net.Address + RemotePort v2net.Port } -func NewConnection(id internal.ConnectionID, conn net.Conn, manager internal.ConnectionRecyler, config *Config) *Connection { +// NewConnectionID creates a new ConnectionId. +func NewConnectionID(source v2net.Address, dest v2net.Destination) ConnectionID { + return ConnectionID{ + Local: source, + Remote: dest.Address, + RemotePort: dest.Port, + } +} + +type Reuser struct { + userEnabled bool + appEnable bool +} + +func ReuseConnection(reuse bool) *Reuser { + return &Reuser{ + userEnabled: reuse, + appEnable: reuse, + } +} + +// Connection is an implementation of net.Conn with re-usability. +type Connection struct { + sync.RWMutex + id ConnectionID + conn net.Conn + listener ConnectionRecyler + reuser *Reuser +} + +func NewConnection(id ConnectionID, conn net.Conn, manager ConnectionRecyler, reuser *Reuser) *Connection { return &Connection{ id: id, conn: conn, listener: manager, - reusable: config.IsConnectionReuse(), - config: config, + reuser: reuser, } } @@ -45,6 +72,7 @@ func (v *Connection) Write(b []byte) (int, error) { return conn.Write(b) } +// Close implements net.Conn.Close(). If the connection is reusable, the underlying connection will be recycled. func (v *Connection) Close() error { if v == nil { return io.ErrClosedPipe @@ -108,14 +136,14 @@ func (v *Connection) SetReusable(reusable bool) { if v == nil { return } - v.reusable = reusable + v.reuser.appEnable = reusable } func (v *Connection) Reusable() bool { if v == nil { return false } - return v.config.IsConnectionReuse() && v.reusable + return v.reuser.userEnabled && v.reuser.appEnable } func (v *Connection) SysFd() (int, error) { @@ -123,7 +151,7 @@ func (v *Connection) SysFd() (int, error) { if conn == nil { return 0, io.ErrClosedPipe } - return internal.GetSysFd(conn) + return GetSysFd(conn) } func (v *Connection) underlyingConn() net.Conn { diff --git a/transport/internet/internal/pool.go b/transport/internet/internal/pool.go index 4fa5a2dcb..58df11804 100644 --- a/transport/internet/internal/pool.go +++ b/transport/internet/internal/pool.go @@ -5,7 +5,6 @@ import ( "sync" "time" - v2net "v2ray.com/core/common/net" "v2ray.com/core/common/signal" ) @@ -15,22 +14,6 @@ type ConnectionRecyler interface { Put(ConnectionID, net.Conn) } -// ConnectionID is the ID of a connection. -type ConnectionID struct { - Local v2net.Address - Remote v2net.Address - RemotePort v2net.Port -} - -// NewConnectionID creates a new ConnectionId. -func NewConnectionID(source v2net.Address, dest v2net.Destination) ConnectionID { - return ConnectionID{ - Local: source, - Remote: dest.Address, - RemotePort: dest.Port, - } -} - // ExpiringConnection is a connection that will expire in certain time. type ExpiringConnection struct { conn net.Conn diff --git a/transport/internet/kcp/dialer.go b/transport/internet/kcp/dialer.go index 71a4125be..8b9b5634d 100644 --- a/transport/internet/kcp/dialer.go +++ b/transport/internet/kcp/dialer.go @@ -165,7 +165,7 @@ func DialKCP(src v2net.Address, dest v2net.Destination, options internet.DialerO config.ServerName = dest.Address.Domain() } tlsConn := tls.Client(iConn, config) - iConn = v2tls.NewConnection(tlsConn) + iConn = UnreusableConnection{Conn: tlsConn} } } diff --git a/transport/internet/kcp/listener.go b/transport/internet/kcp/listener.go index 0d139e88e..fac317694 100644 --- a/transport/internet/kcp/listener.go +++ b/transport/internet/kcp/listener.go @@ -236,7 +236,7 @@ func (v *Listener) Accept() (internet.Connection, error) { } if v.tlsConfig != nil { tlsConn := tls.Server(conn, v.tlsConfig) - return v2tls.NewConnection(tlsConn), nil + return UnreusableConnection{Conn: tlsConn}, nil } return conn, nil case <-time.After(time.Second): diff --git a/transport/internet/kcp/tls.go b/transport/internet/kcp/tls.go new file mode 100644 index 000000000..3d036dd6a --- /dev/null +++ b/transport/internet/kcp/tls.go @@ -0,0 +1,13 @@ +package kcp + +import "net" + +type UnreusableConnection struct { + net.Conn +} + +func (c UnreusableConnection) Reusable() bool { + return false +} + +func (c UnreusableConnection) SetReusable(bool) {} diff --git a/transport/internet/tcp/dialer.go b/transport/internet/tcp/dialer.go index 612f8ba5b..5c049ea2c 100644 --- a/transport/internet/tcp/dialer.go +++ b/transport/internet/tcp/dialer.go @@ -66,7 +66,7 @@ func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOpti conn = auth.Client(conn) } } - return NewConnection(id, conn, globalCache, tcpSettings), nil + return internal.NewConnection(id, conn, globalCache, internal.ReuseConnection(tcpSettings.IsConnectionReuse())), nil } func init() { diff --git a/transport/internet/tcp/hub.go b/transport/internet/tcp/hub.go index 194457f6f..97b132e85 100644 --- a/transport/internet/tcp/hub.go +++ b/transport/internet/tcp/hub.go @@ -91,7 +91,7 @@ func (v *TCPListener) Accept() (internet.Connection, error) { return nil, connErr.err } conn := connErr.conn - return NewConnection(internal.ConnectionID{}, conn, v, v.config), nil + return internal.NewConnection(internal.ConnectionID{}, conn, v, internal.ReuseConnection(v.config.IsConnectionReuse())), nil case <-time.After(time.Second * 2): } } diff --git a/transport/internet/tls/connection.go b/transport/internet/tls/connection.go deleted file mode 100644 index 39fcd48bb..000000000 --- a/transport/internet/tls/connection.go +++ /dev/null @@ -1,21 +0,0 @@ -package tls - -import ( - "crypto/tls" -) - -type Connection struct { - *tls.Conn -} - -func (v *Connection) Reusable() bool { - return false -} - -func (v *Connection) SetReusable(bool) {} - -func NewConnection(conn *tls.Conn) *Connection { - return &Connection{ - Conn: conn, - } -} diff --git a/transport/internet/websocket/wsconn.go b/transport/internet/websocket/wsconn.go index 57b302c7d..4cd1a15a0 100644 --- a/transport/internet/websocket/wsconn.go +++ b/transport/internet/websocket/wsconn.go @@ -121,18 +121,10 @@ func (ws *wsconn) RemoteAddr() net.Addr { return ws.wsc.RemoteAddr() } func (ws *wsconn) SetDeadline(t time.Time) error { - return func() error { - errr := ws.SetReadDeadline(t) - errw := ws.SetWriteDeadline(t) - if errr == nil || errw == nil { - return nil - } - if errr != nil { - return errr - } - - return errw - }() + if err := ws.SetReadDeadline(t); err != nil { + return err + } + return ws.SetWriteDeadline(t) } func (ws *wsconn) SetReadDeadline(t time.Time) error { return ws.wsc.SetReadDeadline(t)