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:
parent
47337d6496
commit
20251bf499
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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.
|
||||||
|
@ -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),
|
||||||
})
|
})
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
})
|
})
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user