1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2025-01-02 07:26:24 -05:00

system listener for both TCP and UDP

This commit is contained in:
Darien Raymond 2018-09-15 21:35:32 +02:00
parent 47337d6496
commit 20251bf499
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
11 changed files with 80 additions and 42 deletions

View File

@ -8,6 +8,8 @@ var DialUDP = net.DialUDP
var DialUnix = net.DialUnix var DialUnix = net.DialUnix
var Dial = net.Dial var Dial = net.Dial
type ListenConfig = net.ListenConfig
var Listen = net.Listen var Listen = net.Listen
var ListenTCP = net.ListenTCP var ListenTCP = net.ListenTCP
var ListenUDP = net.ListenUDP var ListenUDP = net.ListenUDP
@ -25,6 +27,7 @@ var CIDRMask = net.CIDRMask
type Addr = net.Addr type Addr = net.Addr
type Conn = net.Conn type Conn = net.Conn
type PacketConn = net.PacketConn
type TCPAddr = net.TCPAddr type TCPAddr = net.TCPAddr
type TCPConn = net.TCPConn type TCPConn = net.TCPConn

View File

@ -18,7 +18,7 @@ type Server struct {
ShouldClose bool ShouldClose bool
SendFirst []byte SendFirst []byte
Listen net.Address Listen net.Address
listener *net.TCPListener listener net.Listener
} }
func (server *Server) Start() (net.Destination, error) { func (server *Server) Start() (net.Destination, error) {
@ -30,17 +30,19 @@ func (server *Server) StartContext(ctx context.Context) (net.Destination, error)
if listenerAddr == nil { if listenerAddr == nil {
listenerAddr = net.LocalHostIP listenerAddr = net.LocalHostIP
} }
listener, err := internet.ListenSystemTCP(ctx, &net.TCPAddr{ listener, err := internet.ListenSystem(ctx, &net.TCPAddr{
IP: listenerAddr.IP(), IP: listenerAddr.IP(),
Port: int(server.Port), Port: int(server.Port),
}) })
if err != nil { if err != nil {
return net.Destination{}, err return net.Destination{}, err
} }
server.Port = net.Port(listener.Addr().(*net.TCPAddr).Port)
server.listener = listener
go server.acceptConnections(listener)
localAddr := listener.Addr().(*net.TCPAddr) localAddr := listener.Addr().(*net.TCPAddr)
server.Port = net.Port(localAddr.Port)
server.listener = listener
go server.acceptConnections(listener.(*net.TCPListener))
return net.TCPDestination(net.IPAddress(localAddr.IP), net.Port(localAddr.Port)), nil return net.TCPDestination(net.IPAddress(localAddr.IP), net.Port(localAddr.Port)), nil
} }

View File

@ -11,8 +11,6 @@ type key int
const ( const (
streamSettingsKey key = iota streamSettingsKey key = iota
dialerSrcKey dialerSrcKey
transportSettingsKey
securitySettingsKey
) )
func ContextWithStreamSettings(ctx context.Context, streamSettings *MemoryStreamConfig) context.Context { func ContextWithStreamSettings(ctx context.Context, streamSettings *MemoryStreamConfig) context.Context {

View File

@ -41,11 +41,15 @@ func Dial(ctx context.Context, dest net.Destination) (Connection, error) {
return dialer(ctx, dest) return dialer(ctx, dest)
} }
udpDialer := transportDialerCache["udp"] if dest.Network == net.Network_UDP {
if udpDialer == nil { udpDialer := transportDialerCache["udp"]
return nil, newError("UDP dialer not registered").AtError() if udpDialer == nil {
return nil, newError("UDP dialer not registered").AtError()
}
return udpDialer(ctx, dest)
} }
return udpDialer(ctx, dest)
return nil, newError("unknown network ", dest.Network)
} }
// DialSystem calls system dialer to create a network connection. // DialSystem calls system dialer to create a network connection.

View File

@ -117,7 +117,7 @@ func Listen(ctx context.Context, address net.Address, port net.Port, handler int
listener.server = server listener.server = server
go func() { go func() {
tcpListener, err := internet.ListenSystemTCP(ctx, &net.TCPAddr{ tcpListener, err := internet.ListenSystem(ctx, &net.TCPAddr{
IP: address.IP(), IP: address.IP(),
Port: int(port), Port: int(port),
}) })

View File

@ -8,3 +8,12 @@ func isTCPSocket(network string) bool {
return false return false
} }
} }
func isUDPSocket(network string) bool {
switch network {
case "udp", "udp4", "udp6":
return true
default:
return false
}
}

View File

@ -20,18 +20,26 @@ type SystemDialer interface {
type DefaultSystemDialer struct { type DefaultSystemDialer struct {
} }
func getSocketSettings(ctx context.Context) *SocketConfig {
streamSettings := StreamSettingsFromContext(ctx)
if streamSettings != nil && streamSettings.SocketSettings != nil {
return streamSettings.SocketSettings
}
return nil
}
func (DefaultSystemDialer) Dial(ctx context.Context, src net.Address, dest net.Destination) (net.Conn, error) { func (DefaultSystemDialer) Dial(ctx context.Context, src net.Address, dest net.Destination) (net.Conn, error) {
dialer := &net.Dialer{ dialer := &net.Dialer{
Timeout: time.Second * 60, Timeout: time.Second * 60,
DualStack: true, DualStack: true,
} }
streamSettings := StreamSettingsFromContext(ctx) sockopts := getSocketSettings(ctx)
if streamSettings != nil && streamSettings.SocketSettings != nil { if sockopts != nil {
config := streamSettings.SocketSettings
dialer.Control = func(network, address string, c syscall.RawConn) error { dialer.Control = func(network, address string, c syscall.RawConn) error {
return c.Control(func(fd uintptr) { return c.Control(func(fd uintptr) {
if err := applyOutboundSocketOptions(network, address, fd, config); err != nil { if err := applyOutboundSocketOptions(network, address, fd, sockopts); err != nil {
newError("failed to apply socket options").Base(err).WriteToLog(session.ExportIDToError(ctx)) newError("failed to apply socket options").Base(err).WriteToLog(session.ExportIDToError(ctx))
} }
}) })

View File

@ -2,38 +2,48 @@ package internet
import ( import (
"context" "context"
"syscall"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/session" "v2ray.com/core/common/session"
) )
var ( var (
effectiveTCPListener = DefaultTCPListener{} effectiveListener = DefaultListener{}
) )
type DefaultTCPListener struct{} type DefaultListener struct{}
func (tl *DefaultTCPListener) Listen(ctx context.Context, addr *net.TCPAddr) (*net.TCPListener, error) { func (*DefaultListener) Listen(ctx context.Context, addr net.Addr) (net.Listener, error) {
l, err := net.ListenTCP("tcp", addr) var lc net.ListenConfig
if err != nil {
return nil, err
}
streamSettings := StreamSettingsFromContext(ctx) sockopt := getSocketSettings(ctx)
if streamSettings != nil && streamSettings.SocketSettings != nil { if sockopt != nil {
config := streamSettings.SocketSettings lc.Control = func(network, address string, c syscall.RawConn) error {
rawConn, err := l.SyscallConn() return c.Control(func(fd uintptr) {
if err != nil { if err := applyInboundSocketOptions(network, fd, sockopt); err != nil {
return nil, err newError("failed to apply socket options to incoming connection").Base(err).WriteToLog(session.ExportIDToError(ctx))
} }
if err := rawConn.Control(func(fd uintptr) { })
if err := applyInboundSocketOptions("tcp", fd, config); err != nil {
newError("failed to apply socket options to incoming connection").Base(err).WriteToLog(session.ExportIDToError(ctx))
}
}); err != nil {
return nil, err
} }
} }
return l, nil return lc.Listen(ctx, addr.Network(), addr.String())
}
func (*DefaultListener) ListenPacket(ctx context.Context, addr net.Addr) (net.PacketConn, error) {
var lc net.ListenConfig
sockopt := getSocketSettings(ctx)
if sockopt != nil {
lc.Control = func(network, address string, c syscall.RawConn) error {
return c.Control(func(fd uintptr) {
if err := applyInboundSocketOptions(network, fd, sockopt); err != nil {
newError("failed to apply socket options to incoming connection").Base(err).WriteToLog(session.ExportIDToError(ctx))
}
})
}
}
return lc.ListenPacket(ctx, addr.Network(), addr.String())
} }

View File

@ -14,7 +14,7 @@ import (
// Listener is an internet.Listener that listens for TCP connections. // Listener is an internet.Listener that listens for TCP connections.
type Listener struct { type Listener struct {
listener *net.TCPListener listener net.Listener
tlsConfig *gotls.Config tlsConfig *gotls.Config
authConfig internet.ConnectionAuthenticator authConfig internet.ConnectionAuthenticator
config *Config config *Config
@ -23,7 +23,7 @@ type Listener struct {
// ListenTCP creates a new Listener based on configurations. // ListenTCP creates a new Listener based on configurations.
func ListenTCP(ctx context.Context, address net.Address, port net.Port, handler internet.ConnHandler) (internet.Listener, error) { func ListenTCP(ctx context.Context, address net.Address, port net.Port, handler internet.ConnHandler) (internet.Listener, error) {
listener, err := internet.ListenSystemTCP(ctx, &net.TCPAddr{ listener, err := internet.ListenSystem(ctx, &net.TCPAddr{
IP: address.IP(), IP: address.IP(),
Port: int(port), Port: int(port),
}) })

View File

@ -54,6 +54,10 @@ func ListenTCP(ctx context.Context, address net.Address, port net.Port, handler
return listener, nil return listener, nil
} }
func ListenSystemTCP(ctx context.Context, addr *net.TCPAddr) (*net.TCPListener, error) { func ListenSystem(ctx context.Context, addr net.Addr) (net.Listener, error) {
return effectiveTCPListener.Listen(ctx, addr) return effectiveListener.Listen(ctx, addr)
}
func ListenSystemPacket(ctx context.Context, addr net.Addr) (net.PacketConn, error) {
return effectiveListener.ListenPacket(ctx, addr)
} }

View File

@ -85,7 +85,7 @@ func ListenWS(ctx context.Context, address net.Address, port net.Port, addConn i
} }
func listenTCP(ctx context.Context, address net.Address, port net.Port, tlsConfig *tls.Config) (net.Listener, error) { func listenTCP(ctx context.Context, address net.Address, port net.Port, tlsConfig *tls.Config) (net.Listener, error) {
listener, err := internet.ListenSystemTCP(ctx, &net.TCPAddr{ listener, err := internet.ListenSystem(ctx, &net.TCPAddr{
IP: address.IP(), IP: address.IP(),
Port: int(port), Port: int(port),
}) })