1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-12-22 10:08:15 -05:00

cleanup internet connection

This commit is contained in:
Darien Raymond 2017-01-04 13:29:41 +01:00
parent e678000c44
commit e35e271708
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
9 changed files with 64 additions and 69 deletions

View File

@ -1,4 +1,4 @@
package tcp package internal
import ( import (
"io" "io"
@ -6,25 +6,52 @@ import (
"sync" "sync"
"time" "time"
"v2ray.com/core/transport/internet/internal" v2net "v2ray.com/core/common/net"
) )
type Connection struct { // ConnectionID is the ID of a connection.
sync.RWMutex type ConnectionID struct {
id internal.ConnectionID Local v2net.Address
reusable bool Remote v2net.Address
conn net.Conn RemotePort v2net.Port
listener internal.ConnectionRecyler
config *Config
} }
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{ return &Connection{
id: id, id: id,
conn: conn, conn: conn,
listener: manager, listener: manager,
reusable: config.IsConnectionReuse(), reuser: reuser,
config: config,
} }
} }
@ -45,6 +72,7 @@ func (v *Connection) Write(b []byte) (int, error) {
return conn.Write(b) 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 { func (v *Connection) Close() error {
if v == nil { if v == nil {
return io.ErrClosedPipe return io.ErrClosedPipe
@ -108,14 +136,14 @@ func (v *Connection) SetReusable(reusable bool) {
if v == nil { if v == nil {
return return
} }
v.reusable = reusable v.reuser.appEnable = reusable
} }
func (v *Connection) Reusable() bool { func (v *Connection) Reusable() bool {
if v == nil { if v == nil {
return false return false
} }
return v.config.IsConnectionReuse() && v.reusable return v.reuser.userEnabled && v.reuser.appEnable
} }
func (v *Connection) SysFd() (int, error) { func (v *Connection) SysFd() (int, error) {
@ -123,7 +151,7 @@ func (v *Connection) SysFd() (int, error) {
if conn == nil { if conn == nil {
return 0, io.ErrClosedPipe return 0, io.ErrClosedPipe
} }
return internal.GetSysFd(conn) return GetSysFd(conn)
} }
func (v *Connection) underlyingConn() net.Conn { func (v *Connection) underlyingConn() net.Conn {

View File

@ -5,7 +5,6 @@ import (
"sync" "sync"
"time" "time"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/common/signal" "v2ray.com/core/common/signal"
) )
@ -15,22 +14,6 @@ type ConnectionRecyler interface {
Put(ConnectionID, net.Conn) 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. // ExpiringConnection is a connection that will expire in certain time.
type ExpiringConnection struct { type ExpiringConnection struct {
conn net.Conn conn net.Conn

View File

@ -165,7 +165,7 @@ func DialKCP(src v2net.Address, dest v2net.Destination, options internet.DialerO
config.ServerName = dest.Address.Domain() config.ServerName = dest.Address.Domain()
} }
tlsConn := tls.Client(iConn, config) tlsConn := tls.Client(iConn, config)
iConn = v2tls.NewConnection(tlsConn) iConn = UnreusableConnection{Conn: tlsConn}
} }
} }

View File

@ -236,7 +236,7 @@ func (v *Listener) Accept() (internet.Connection, error) {
} }
if v.tlsConfig != nil { if v.tlsConfig != nil {
tlsConn := tls.Server(conn, v.tlsConfig) tlsConn := tls.Server(conn, v.tlsConfig)
return v2tls.NewConnection(tlsConn), nil return UnreusableConnection{Conn: tlsConn}, nil
} }
return conn, nil return conn, nil
case <-time.After(time.Second): case <-time.After(time.Second):

View File

@ -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) {}

View File

@ -66,7 +66,7 @@ func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOpti
conn = auth.Client(conn) conn = auth.Client(conn)
} }
} }
return NewConnection(id, conn, globalCache, tcpSettings), nil return internal.NewConnection(id, conn, globalCache, internal.ReuseConnection(tcpSettings.IsConnectionReuse())), nil
} }
func init() { func init() {

View File

@ -91,7 +91,7 @@ func (v *TCPListener) Accept() (internet.Connection, error) {
return nil, connErr.err return nil, connErr.err
} }
conn := connErr.conn 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): case <-time.After(time.Second * 2):
} }
} }

View File

@ -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,
}
}

View File

@ -121,18 +121,10 @@ func (ws *wsconn) RemoteAddr() net.Addr {
return ws.wsc.RemoteAddr() return ws.wsc.RemoteAddr()
} }
func (ws *wsconn) SetDeadline(t time.Time) error { func (ws *wsconn) SetDeadline(t time.Time) error {
return func() error { if err := ws.SetReadDeadline(t); err != nil {
errr := ws.SetReadDeadline(t) return err
errw := ws.SetWriteDeadline(t)
if errr == nil || errw == nil {
return nil
} }
if errr != nil { return ws.SetWriteDeadline(t)
return errr
}
return errw
}()
} }
func (ws *wsconn) SetReadDeadline(t time.Time) error { func (ws *wsconn) SetReadDeadline(t time.Time) error {
return ws.wsc.SetReadDeadline(t) return ws.wsc.SetReadDeadline(t)