1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-12-21 17:46:58 -05:00

proxy connection

This commit is contained in:
Darien Raymond 2016-11-09 00:17:09 +01:00
parent 7a09fcdc2f
commit d343cb1ee6
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
5 changed files with 153 additions and 14 deletions

131
app/proxy/proxy.go Normal file
View 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) {
}

View File

@ -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
} }

View File

@ -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
} }

View File

@ -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
} }

View File

@ -12,7 +12,8 @@ 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) {