mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-22 01:57:12 -05:00
proxy connection
This commit is contained in:
parent
7a09fcdc2f
commit
d343cb1ee6
131
app/proxy/proxy.go
Normal file
131
app/proxy/proxy.go
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
package proxy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"v2ray.com/core/app"
|
||||||
|
"v2ray.com/core/app/proxyman"
|
||||||
|
"v2ray.com/core/common/alloc"
|
||||||
|
v2io "v2ray.com/core/common/io"
|
||||||
|
"v2ray.com/core/common/log"
|
||||||
|
v2net "v2ray.com/core/common/net"
|
||||||
|
"v2ray.com/core/transport/internet"
|
||||||
|
"v2ray.com/core/transport/ray"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
APP_ID = 7
|
||||||
|
)
|
||||||
|
|
||||||
|
type OutboundProxy struct {
|
||||||
|
outboundManager proxyman.OutboundHandlerManager
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewOutboundProxy(space app.Space) *OutboundProxy {
|
||||||
|
proxy := new(OutboundProxy)
|
||||||
|
space.InitializeApplication(func() error {
|
||||||
|
if !space.HasApp(proxyman.APP_ID_OUTBOUND_MANAGER) {
|
||||||
|
return errors.New("Proxy: Outbound handler manager not found.")
|
||||||
|
}
|
||||||
|
proxy.outboundManager = space.GetApp(proxyman.APP_ID_OUTBOUND_MANAGER).(proxyman.OutboundHandlerManager)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return proxy
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *OutboundProxy) Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) {
|
||||||
|
handler := this.outboundManager.GetHandler(options.ProxyTag)
|
||||||
|
if handler == nil {
|
||||||
|
log.Warning("Proxy: Failed to get outbound handler with tag: ", options.ProxyTag)
|
||||||
|
return internet.Dial(src, dest, internet.DialerOptions{
|
||||||
|
Stream: options.Stream,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
stream := ray.NewRay()
|
||||||
|
if err := handler.Dispatch(dest, alloc.NewLocalBuffer(32).Clear(), stream); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return NewProxyConnection(src, dest, stream), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *OutboundProxy) Release() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProxyConnection struct {
|
||||||
|
stream ray.Ray
|
||||||
|
closed bool
|
||||||
|
localAddr net.Addr
|
||||||
|
remoteAddr net.Addr
|
||||||
|
|
||||||
|
reader *v2io.ChanReader
|
||||||
|
writer *v2io.ChainWriter
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProxyConnection(src v2net.Address, dest v2net.Destination, stream ray.Ray) *ProxyConnection {
|
||||||
|
return &ProxyConnection{
|
||||||
|
stream: stream,
|
||||||
|
localAddr: &net.TCPAddr{
|
||||||
|
IP: []byte{0, 0, 0, 0},
|
||||||
|
Port: 0,
|
||||||
|
},
|
||||||
|
remoteAddr: &net.TCPAddr{
|
||||||
|
IP: []byte{0, 0, 0, 0},
|
||||||
|
Port: 0,
|
||||||
|
},
|
||||||
|
reader: v2io.NewChanReader(stream.InboundOutput()),
|
||||||
|
writer: v2io.NewChainWriter(stream.InboundInput()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *ProxyConnection) Read(b []byte) (int, error) {
|
||||||
|
if this.closed {
|
||||||
|
return 0, io.EOF
|
||||||
|
}
|
||||||
|
return this.reader.Read(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *ProxyConnection) Write(b []byte) (int, error) {
|
||||||
|
if this.closed {
|
||||||
|
return 0, io.EOF
|
||||||
|
}
|
||||||
|
return this.writer.Write(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *ProxyConnection) Close() error {
|
||||||
|
this.closed = true
|
||||||
|
this.stream.InboundInput().Close()
|
||||||
|
this.stream.InboundOutput().Release()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *ProxyConnection) LocalAddr() net.Addr {
|
||||||
|
return this.localAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *ProxyConnection) RemoteAddr() net.Addr {
|
||||||
|
return this.remoteAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *ProxyConnection) SetDeadline(t time.Time) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *ProxyConnection) SetReadDeadline(t time.Time) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *ProxyConnection) SetWriteDeadline(t time.Time) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *ProxyConnection) Reusable() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *ProxyConnection) SetReusable(bool) {
|
||||||
|
|
||||||
|
}
|
@ -80,7 +80,9 @@ func (this *FreedomConnection) Dispatch(destination v2net.Destination, payload *
|
|||||||
destination = this.ResolveIP(destination)
|
destination = this.ResolveIP(destination)
|
||||||
}
|
}
|
||||||
err := retry.Timed(5, 100).On(func() error {
|
err := retry.Timed(5, 100).On(func() error {
|
||||||
rawConn, err := internet.Dial(this.meta.Address, destination, this.meta.StreamSettings)
|
rawConn, err := internet.Dial(this.meta.Address, destination, internet.DialerOptions{
|
||||||
|
Stream: this.meta.StreamSettings,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,9 @@ func (this *Client) Dispatch(destination v2net.Destination, payload *alloc.Buffe
|
|||||||
server = this.serverPicker.PickServer()
|
server = this.serverPicker.PickServer()
|
||||||
dest := server.Destination()
|
dest := server.Destination()
|
||||||
dest.Network = network
|
dest.Network = network
|
||||||
rawConn, err := internet.Dial(this.meta.Address, dest, this.meta.StreamSettings)
|
rawConn, err := internet.Dial(this.meta.Address, dest, internet.DialerOptions{
|
||||||
|
Stream: this.meta.StreamSettings,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,9 @@ func (this *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *al
|
|||||||
|
|
||||||
err := retry.Timed(5, 100).On(func() error {
|
err := retry.Timed(5, 100).On(func() error {
|
||||||
rec = this.serverPicker.PickServer()
|
rec = this.serverPicker.PickServer()
|
||||||
rawConn, err := internet.Dial(this.meta.Address, rec.Destination(), this.meta.StreamSettings)
|
rawConn, err := internet.Dial(this.meta.Address, rec.Destination(), internet.DialerOptions{
|
||||||
|
Stream: this.meta.StreamSettings,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ var (
|
|||||||
|
|
||||||
type DialerOptions struct {
|
type DialerOptions struct {
|
||||||
Stream *StreamConfig
|
Stream *StreamConfig
|
||||||
|
ProxyTag string
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
@ -23,27 +24,28 @@ var (
|
|||||||
RawTCPDialer Dialer
|
RawTCPDialer Dialer
|
||||||
UDPDialer Dialer
|
UDPDialer Dialer
|
||||||
WSDialer Dialer
|
WSDialer Dialer
|
||||||
|
ProxyDialer Dialer
|
||||||
)
|
)
|
||||||
|
|
||||||
func Dial(src v2net.Address, dest v2net.Destination, settings *StreamConfig) (Connection, error) {
|
func Dial(src v2net.Address, dest v2net.Destination, options DialerOptions) (Connection, error) {
|
||||||
|
if len(options.ProxyTag) > 0 && ProxyDialer != nil {
|
||||||
|
return ProxyDialer(src, dest, options)
|
||||||
|
}
|
||||||
|
|
||||||
var connection Connection
|
var connection Connection
|
||||||
var err error
|
var err error
|
||||||
dialerOptions := DialerOptions{
|
|
||||||
Stream: settings,
|
|
||||||
}
|
|
||||||
if dest.Network == v2net.Network_TCP {
|
if dest.Network == v2net.Network_TCP {
|
||||||
switch settings.Network {
|
switch options.Stream.Network {
|
||||||
case v2net.Network_TCP:
|
case v2net.Network_TCP:
|
||||||
connection, err = TCPDialer(src, dest, dialerOptions)
|
connection, err = TCPDialer(src, dest, options)
|
||||||
case v2net.Network_KCP:
|
case v2net.Network_KCP:
|
||||||
connection, err = KCPDialer(src, dest, dialerOptions)
|
connection, err = KCPDialer(src, dest, options)
|
||||||
case v2net.Network_WebSocket:
|
case v2net.Network_WebSocket:
|
||||||
connection, err = WSDialer(src, dest, dialerOptions)
|
connection, err = WSDialer(src, dest, options)
|
||||||
|
|
||||||
// This check has to be the last one.
|
// This check has to be the last one.
|
||||||
case v2net.Network_RawTCP:
|
case v2net.Network_RawTCP:
|
||||||
connection, err = RawTCPDialer(src, dest, dialerOptions)
|
connection, err = RawTCPDialer(src, dest, options)
|
||||||
default:
|
default:
|
||||||
return nil, ErrUnsupportedStreamType
|
return nil, ErrUnsupportedStreamType
|
||||||
}
|
}
|
||||||
@ -54,7 +56,7 @@ func Dial(src v2net.Address, dest v2net.Destination, settings *StreamConfig) (Co
|
|||||||
return connection, nil
|
return connection, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return UDPDialer(src, dest, dialerOptions)
|
return UDPDialer(src, dest, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
func DialToDest(src v2net.Address, dest v2net.Destination) (net.Conn, error) {
|
func DialToDest(src v2net.Address, dest v2net.Destination) (net.Conn, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user