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:
parent
31d6e74482
commit
21a15bbf74
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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{
|
||||||
|
@ -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
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
@ -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{
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user