|
@@ -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"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
+// 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,
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+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 {
|
|
type Connection struct {
|
|
|
sync.RWMutex
|
|
sync.RWMutex
|
|
|
- id internal.ConnectionID
|
|
|
|
|
- reusable bool
|
|
|
|
|
|
|
+ id ConnectionID
|
|
|
conn net.Conn
|
|
conn net.Conn
|
|
|
- listener internal.ConnectionRecyler
|
|
|
|
|
- config *Config
|
|
|
|
|
|
|
+ listener ConnectionRecyler
|
|
|
|
|
+ reuser *Reuser
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func NewConnection(id internal.ConnectionID, conn net.Conn, manager internal.ConnectionRecyler, config *Config) *Connection {
|
|
|
|
|
|
|
+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(),
|
|
|
|
|
- config: config,
|
|
|
|
|
|
|
+ reuser: reuser,
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -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 {
|