forked from v2fly/v2ray-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
proxy.go
131 lines (109 loc) · 2.87 KB
/
proxy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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) {
}