1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2025-01-29 20:56:30 -05:00

registerable dialer and listener

This commit is contained in:
Darien Raymond 2017-01-03 15:16:48 +01:00
parent 31d6e74482
commit 21a15bbf74
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
10 changed files with 63 additions and 60 deletions

View File

@ -20,42 +20,41 @@ type DialerOptions struct {
type Dialer func(src v2net.Address, dest v2net.Destination, options DialerOptions) (Connection, error) type Dialer func(src v2net.Address, dest v2net.Destination, options DialerOptions) (Connection, error)
var ( var (
TCPDialer Dialer networkDialerCache = make(map[v2net.Network]Dialer)
KCPDialer Dialer
UDPDialer Dialer
WSDialer Dialer
ProxyDialer Dialer ProxyDialer Dialer
) )
func RegisterNetworkDialer(network v2net.Network, dialer Dialer) error {
if _, found := networkDialerCache[network]; found {
return errors.New("Internet|Dialer: ", network, " dialer already registered.")
}
networkDialerCache[network] = dialer
return nil
}
func Dial(src v2net.Address, dest v2net.Destination, options DialerOptions) (Connection, error) { func Dial(src v2net.Address, dest v2net.Destination, options DialerOptions) (Connection, error) {
if options.Proxy.HasTag() && ProxyDialer != nil { if options.Proxy.HasTag() && ProxyDialer != nil {
log.Info("Internet: Proxying outbound connection through: ", options.Proxy.Tag) log.Info("Internet: Proxying outbound connection through: ", options.Proxy.Tag)
return ProxyDialer(src, dest, options) return ProxyDialer(src, dest, options)
} }
var connection Connection
var err error
if dest.Network == v2net.Network_TCP { if dest.Network == v2net.Network_TCP {
switch options.Stream.Network { dialer := networkDialerCache[options.Stream.Network]
case v2net.Network_TCP: if dialer == nil {
connection, err = TCPDialer(src, dest, options) return nil, errors.New("Internet|Dialer: ", options.Stream.Network, " dialer not registered.")
case v2net.Network_KCP:
connection, err = KCPDialer(src, dest, options)
case v2net.Network_WebSocket:
connection, err = WSDialer(src, dest, options)
default:
return nil, ErrUnsupportedStreamType
} }
if err != nil { return dialer(src, dest, options)
return nil, err
}
return connection, nil
} }
return UDPDialer(src, dest, options) udpDialer := networkDialerCache[v2net.Network_UDP]
if udpDialer == nil {
return nil, errors.New("Internet|Dialer: UDP dialer not registered.")
}
return udpDialer(src, dest, options)
} }
func DialToDest(src v2net.Address, dest v2net.Destination) (net.Conn, error) { // DialSystem calls system dialer to create a network connection.
func DialSystem(src v2net.Address, dest v2net.Destination) (net.Conn, error) {
return effectiveSystemDialer.Dial(src, dest) return effectiveSystemDialer.Dial(src, dest)
} }

View File

@ -17,7 +17,7 @@ func TestDialWithLocalAddr(t *testing.T) {
assert.Error(err).IsNil() assert.Error(err).IsNil()
defer server.Close() defer server.Close()
conn, err := DialToDest(v2net.LocalHostIP, v2net.TCPDestination(v2net.LocalHostIP, dest.Port)) conn, err := DialSystem(v2net.LocalHostIP, v2net.TCPDestination(v2net.LocalHostIP, dest.Port))
assert.Error(err).IsNil() assert.Error(err).IsNil()
assert.String(conn.RemoteAddr().String()).Equals("127.0.0.1:" + dest.Port.String()) assert.String(conn.RemoteAddr().String()).Equals("127.0.0.1:" + dest.Port.String())
conn.Close() conn.Close()

View File

@ -8,6 +8,7 @@ import (
"crypto/cipher" "crypto/cipher"
"v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/dice" "v2ray.com/core/common/dice"
"v2ray.com/core/common/errors" "v2ray.com/core/common/errors"
@ -115,7 +116,7 @@ func DialKCP(src v2net.Address, dest v2net.Destination, options internet.DialerO
id := internal.NewConnectionID(src, dest) id := internal.NewConnectionID(src, dest)
conn := globalPool.Get(id) conn := globalPool.Get(id)
if conn == nil { if conn == nil {
rawConn, err := internet.DialToDest(src, dest) rawConn, err := internet.DialSystem(src, dest)
if err != nil { if err != nil {
log.Error("KCP|Dialer: Failed to dial to dest: ", err) log.Error("KCP|Dialer: Failed to dial to dest: ", err)
return nil, err return nil, err
@ -172,5 +173,5 @@ func DialKCP(src v2net.Address, dest v2net.Destination, options internet.DialerO
} }
func init() { func init() {
internet.KCPDialer = DialKCP common.Must(internet.RegisterNetworkDialer(v2net.Network_KCP, DialKCP))
} }

View File

@ -9,6 +9,7 @@ import (
"crypto/cipher" "crypto/cipher"
"v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/errors" "v2ray.com/core/common/errors"
"v2ray.com/core/common/log" "v2ray.com/core/common/log"
@ -297,5 +298,5 @@ func ListenKCP(address v2net.Address, port v2net.Port, options internet.ListenOp
} }
func init() { func init() {
internet.KCPListenFunc = ListenKCP common.Must(internet.RegisterNetworkListener(v2net.Network_KCP, ListenKCP))
} }

View File

@ -4,6 +4,7 @@ import (
"crypto/tls" "crypto/tls"
"net" "net"
"v2ray.com/core/common"
"v2ray.com/core/common/errors" "v2ray.com/core/common/errors"
"v2ray.com/core/common/log" "v2ray.com/core/common/log"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
@ -34,7 +35,7 @@ func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOpti
} }
if conn == nil { if conn == nil {
var err error var err error
conn, err = internet.DialToDest(src, dest) conn, err = internet.DialSystem(src, dest)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -69,5 +70,5 @@ func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOpti
} }
func init() { func init() {
internet.TCPDialer = Dial common.Must(internet.RegisterNetworkDialer(v2net.Network_TCP, Dial))
} }

View File

@ -6,6 +6,7 @@ import (
"sync" "sync"
"time" "time"
"v2ray.com/core/common"
"v2ray.com/core/common/errors" "v2ray.com/core/common/errors"
"v2ray.com/core/common/log" "v2ray.com/core/common/log"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
@ -158,5 +159,5 @@ func (v *TCPListener) Close() error {
} }
func init() { func init() {
internet.TCPListenFunc = ListenTCP common.Must(internet.RegisterNetworkListener(v2net.Network_TCP, ListenTCP))
} }

View File

@ -13,11 +13,17 @@ import (
var ( var (
ErrClosedConnection = errors.New("Connection already closed.") ErrClosedConnection = errors.New("Connection already closed.")
KCPListenFunc ListenFunc networkListenerCache = make(map[v2net.Network]ListenFunc)
TCPListenFunc ListenFunc
WSListenFunc ListenFunc
) )
func RegisterNetworkListener(network v2net.Network, listener ListenFunc) error {
if _, found := networkListenerCache[network]; found {
return errors.New("Internet|TCPHub: ", network, " listener already registered.")
}
networkListenerCache[network] = listener
return nil
}
type ListenFunc func(address v2net.Address, port v2net.Port, options ListenOptions) (Listener, error) type ListenFunc func(address v2net.Address, port v2net.Port, options ListenOptions) (Listener, error)
type ListenOptions struct { type ListenOptions struct {
Stream *StreamConfig Stream *StreamConfig
@ -37,26 +43,16 @@ type TCPHub struct {
} }
func ListenTCP(address v2net.Address, port v2net.Port, callback ConnectionHandler, settings *StreamConfig) (*TCPHub, error) { func ListenTCP(address v2net.Address, port v2net.Port, callback ConnectionHandler, settings *StreamConfig) (*TCPHub, error) {
var listener Listener
var err error
options := ListenOptions{ options := ListenOptions{
Stream: settings, Stream: settings,
} }
switch settings.Network { listenFunc := networkListenerCache[settings.Network]
case v2net.Network_TCP: if listenFunc == nil {
listener, err = TCPListenFunc(address, port, options) return nil, errors.New("Internet|TCPHub: ", settings.Network, " listener not registered.")
case v2net.Network_KCP:
listener, err = KCPListenFunc(address, port, options)
case v2net.Network_WebSocket:
listener, err = WSListenFunc(address, port, options)
default:
log.Error("Internet|Listener: Unknown stream type: ", settings.Network)
err = ErrUnsupportedStreamType
} }
listener, err := listenFunc(address, port, options)
if err != nil { if err != nil {
log.Warning("Internet|Listener: Failed to listen on ", address, ":", port) return nil, errors.Base(err).Message("Interent|TCPHub: Failed to listen: ")
return nil, err
} }
hub := &TCPHub{ hub := &TCPHub{

View File

@ -3,6 +3,7 @@ package udp
import ( import (
"net" "net"
"v2ray.com/core/common"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
"v2ray.com/core/transport/internet" "v2ray.com/core/transport/internet"
) )
@ -18,14 +19,15 @@ func (v *Connection) Reusable() bool {
func (v *Connection) SetReusable(b bool) {} func (v *Connection) SetReusable(b bool) {}
func init() { func init() {
internet.UDPDialer = func(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) { common.Must(internet.RegisterNetworkDialer(v2net.Network_UDP,
conn, err := internet.DialToDest(src, dest) func(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) {
if err != nil { conn, err := internet.DialSystem(src, dest)
return nil, err if err != nil {
} return nil, err
// TODO: handle dialer options }
return &Connection{ // TODO: handle dialer options
UDPConn: *(conn.(*net.UDPConn)), return &Connection{
}, nil UDPConn: *(conn.(*net.UDPConn)),
} }, nil
}))
} }

View File

@ -5,6 +5,7 @@ import (
"net" "net"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"v2ray.com/core/common"
"v2ray.com/core/common/log" "v2ray.com/core/common/log"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
"v2ray.com/core/transport/internet" "v2ray.com/core/transport/internet"
@ -46,7 +47,7 @@ func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOpti
} }
func init() { func init() {
internet.WSDialer = Dial common.Must(internet.RegisterNetworkDialer(v2net.Network_WebSocket, Dial))
} }
func wsDial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (*wsconn, error) { func wsDial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (*wsconn, error) {
@ -57,7 +58,7 @@ func wsDial(src v2net.Address, dest v2net.Destination, options internet.DialerOp
wsSettings := networkSettings.(*Config) wsSettings := networkSettings.(*Config)
commonDial := func(network, addr string) (net.Conn, error) { commonDial := func(network, addr string) (net.Conn, error) {
return internet.DialToDest(src, dest) return internet.DialSystem(src, dest)
} }
dialer := websocket.Dialer{ dialer := websocket.Dialer{

View File

@ -8,6 +8,7 @@ import (
"sync" "sync"
"time" "time"
"v2ray.com/core/common"
"v2ray.com/core/common/errors" "v2ray.com/core/common/errors"
"v2ray.com/core/common/log" "v2ray.com/core/common/log"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
@ -197,5 +198,5 @@ func (v *WSListener) Close() error {
} }
func init() { func init() {
internet.WSListenFunc = ListenWS common.Must(internet.RegisterNetworkListener(v2net.Network_WebSocket, ListenWS))
} }