Skip to content

Commit 648d418

Browse files
authored
VLESS PREVIEW 2
1 parent 788dd1e commit 648d418

File tree

7 files changed

+264
-48
lines changed

7 files changed

+264
-48
lines changed

infra/conf/vless.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,12 @@ func (c *VLessInboundConfig) Build() (proto.Message, error) {
4848
return nil, newError(`VLESS clients: invalid user`).Base(err)
4949
}
5050

51-
if account.Flow != "" {
52-
return nil, newError(`VLESS clients: "flow" is not available in this version`)
51+
switch account.Flow {
52+
case "", "xtls-rprx-origin":
53+
default:
54+
return nil, newError(`VLESS clients: "flow" only accepts "", "xtls-rprx-origin" in this version`)
5355
}
56+
5457
if account.Encryption != "" {
5558
return nil, newError(`VLESS clients: "encryption" should not in inbound settings`)
5659
}
@@ -161,9 +164,12 @@ func (c *VLessOutboundConfig) Build() (proto.Message, error) {
161164
return nil, newError(`VLESS users: invalid user`).Base(err)
162165
}
163166

164-
if account.Flow != "" {
165-
return nil, newError(`VLESS users: "flow" is not available in this version`)
167+
switch account.Flow {
168+
case "", "xtls-rprx-origin", "xtls-rprx-origin-udp443":
169+
default:
170+
return nil, newError(`VLESS users: "flow" only accepts "", "xtls-rprx-origin", "xtls-rprx-origin-udp443" in this version`)
166171
}
172+
167173
if account.Encryption != "none" {
168174
return nil, newError(`VLESS users: please add/set "encryption":"none" for every user`)
169175
}

infra/conf/vless_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ func TestVLessOutbound(t *testing.T) {
2626
"users": [
2727
{
2828
"id": "27848739-7e62-4138-9fd3-098a63964b6b",
29+
"flow": "xtls-rprx-origin-udp443",
2930
"encryption": "none",
3031
"level": 0
3132
}
@@ -46,6 +47,7 @@ func TestVLessOutbound(t *testing.T) {
4647
{
4748
Account: serial.ToTypedMessage(&vless.Account{
4849
Id: "27848739-7e62-4138-9fd3-098a63964b6b",
50+
Flow: "xtls-rprx-origin-udp443",
4951
Encryption: "none",
5052
}),
5153
Level: 0,
@@ -69,6 +71,7 @@ func TestVLessInbound(t *testing.T) {
6971
"clients": [
7072
{
7173
"id": "27848739-7e62-4138-9fd3-098a63964b6b",
74+
"flow": "xtls-rprx-origin",
7275
"level": 0,
7376
"email": "love@v2fly.org"
7477
}
@@ -94,7 +97,8 @@ func TestVLessInbound(t *testing.T) {
9497
Clients: []*protocol.User{
9598
{
9699
Account: serial.ToTypedMessage(&vless.Account{
97-
Id: "27848739-7e62-4138-9fd3-098a63964b6b",
100+
Id: "27848739-7e62-4138-9fd3-098a63964b6b",
101+
Flow: "xtls-rprx-origin",
98102
}),
99103
Level: 0,
100104
Email: "love@v2fly.org",

proxy/vless/encoding/addons.go

Lines changed: 132 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,25 @@ import (
99

1010
"v2ray.com/core/common/buf"
1111
"v2ray.com/core/common/protocol"
12+
"v2ray.com/core/proxy/vless"
1213
)
1314

1415
func EncodeHeaderAddons(buffer *buf.Buffer, addons *Addons) error {
1516

1617
switch addons.Flow {
18+
case vless.XRO:
19+
20+
if bytes, err := proto.Marshal(addons); err != nil {
21+
newError("failed to marshal addons protobuf value").Base(err)
22+
} else {
23+
if err := buffer.WriteByte(byte(len(bytes))); err != nil {
24+
return newError("failed to write addons protobuf length").Base(err)
25+
}
26+
if _, err := buffer.Write(bytes); err != nil {
27+
return newError("failed to write addons protobuf value").Base(err)
28+
}
29+
}
30+
1731
default:
1832

1933
if err := buffer.WriteByte(0); err != nil {
@@ -62,22 +76,136 @@ func DecodeHeaderAddons(buffer *buf.Buffer, reader io.Reader) (*Addons, error) {
6276
func EncodeBodyAddons(writer io.Writer, request *protocol.RequestHeader, addons *Addons) buf.Writer {
6377

6478
switch addons.Flow {
65-
default:
79+
case vless.XRO:
6680

67-
return buf.NewWriter(writer)
81+
if request.Command == protocol.RequestCommandUDP {
82+
return NewMultiLengthPacketWriter(writer.(buf.Writer))
83+
}
6884

6985
}
7086

87+
return buf.NewWriter(writer)
88+
7189
}
7290

7391
// DecodeBodyAddons returns a Reader from which caller can fetch decrypted body.
7492
func DecodeBodyAddons(reader io.Reader, request *protocol.RequestHeader, addons *Addons) buf.Reader {
7593

7694
switch addons.Flow {
77-
default:
95+
case vless.XRO:
96+
97+
if request.Command == protocol.RequestCommandUDP {
98+
return NewLengthPacketReader(reader)
99+
}
100+
101+
}
102+
103+
return buf.NewReader(reader)
78104

79-
return buf.NewReader(reader)
105+
}
80106

107+
func NewMultiLengthPacketWriter(writer buf.Writer) *MultiLengthPacketWriter {
108+
return &MultiLengthPacketWriter{
109+
Writer: writer,
81110
}
111+
}
112+
113+
type MultiLengthPacketWriter struct {
114+
buf.Writer
115+
}
82116

117+
func (w *MultiLengthPacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
118+
defer buf.ReleaseMulti(mb)
119+
mb2Write := make(buf.MultiBuffer, 0, len(mb)+1)
120+
for _, b := range mb {
121+
length := b.Len()
122+
if length == 0 || length+2 > buf.Size {
123+
continue
124+
}
125+
eb := buf.New()
126+
if err := eb.WriteByte(byte(length >> 8)); err != nil {
127+
eb.Release()
128+
continue
129+
}
130+
if err := eb.WriteByte(byte(length)); err != nil {
131+
eb.Release()
132+
continue
133+
}
134+
if _, err := eb.Write(b.Bytes()); err != nil {
135+
eb.Release()
136+
continue
137+
}
138+
mb2Write = append(mb2Write, eb)
139+
}
140+
if mb2Write.IsEmpty() {
141+
return nil
142+
}
143+
return w.Writer.WriteMultiBuffer(mb2Write)
144+
}
145+
146+
func NewLengthPacketWriter(writer io.Writer) *LengthPacketWriter {
147+
return &LengthPacketWriter{
148+
Writer: writer,
149+
cache: make([]byte, 0, 65536),
150+
}
151+
}
152+
153+
type LengthPacketWriter struct {
154+
io.Writer
155+
cache []byte
156+
}
157+
158+
func (w *LengthPacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
159+
length := mb.Len() // none of mb is nil
160+
//fmt.Println("Write", length)
161+
if length == 0 {
162+
return nil
163+
}
164+
defer func() {
165+
w.cache = w.cache[:0]
166+
}()
167+
w.cache = append(w.cache, byte(length>>8), byte(length))
168+
for i, b := range mb {
169+
w.cache = append(w.cache, b.Bytes()...)
170+
b.Release()
171+
mb[i] = nil
172+
}
173+
if _, err := w.Write(w.cache); err != nil {
174+
return newError("failed to write a packet").Base(err)
175+
}
176+
return nil
177+
}
178+
179+
func NewLengthPacketReader(reader io.Reader) *LengthPacketReader {
180+
return &LengthPacketReader{
181+
Reader: reader,
182+
cache: make([]byte, 2),
183+
}
184+
}
185+
186+
type LengthPacketReader struct {
187+
io.Reader
188+
cache []byte
189+
}
190+
191+
func (r *LengthPacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
192+
if _, err := io.ReadFull(r.Reader, r.cache); err != nil { // maybe EOF
193+
return nil, newError("failed to read packet length").Base(err)
194+
}
195+
length := int(r.cache[0])<<8 | int(r.cache[1])
196+
//fmt.Println("Read", length)
197+
mb := make(buf.MultiBuffer, 0, length/buf.Size+1)
198+
for length > 0 {
199+
size := length
200+
if length > buf.Size {
201+
size = buf.Size
202+
}
203+
length -= size
204+
b := buf.New()
205+
if _, err := b.ReadFullFrom(r.Reader, int32(size)); err != nil {
206+
return nil, newError("failed to read packet payload").Base(err)
207+
}
208+
mb = append(mb, b)
209+
}
210+
return mb, nil
83211
}

proxy/vless/encoding/encoding.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,23 +153,23 @@ func EncodeResponseHeader(writer io.Writer, request *protocol.RequestHeader, res
153153
}
154154

155155
// DecodeResponseHeader decodes and returns (if successful) a ResponseHeader from an input stream.
156-
func DecodeResponseHeader(reader io.Reader, request *protocol.RequestHeader, responseAddons *Addons) error {
156+
func DecodeResponseHeader(reader io.Reader, request *protocol.RequestHeader) (*Addons, error) {
157157

158158
buffer := buf.StackNew()
159159
defer buffer.Release()
160160

161161
if _, err := buffer.ReadFullFrom(reader, 1); err != nil {
162-
return newError("failed to read response version").Base(err)
162+
return nil, newError("failed to read response version").Base(err)
163163
}
164164

165165
if buffer.Byte(0) != request.Version {
166-
return newError("unexpected response version. Expecting ", int(request.Version), " but actually ", int(buffer.Byte(0)))
166+
return nil, newError("unexpected response version. Expecting ", int(request.Version), " but actually ", int(buffer.Byte(0)))
167167
}
168168

169169
responseAddons, err := DecodeHeaderAddons(&buffer, reader)
170170
if err != nil {
171-
return newError("failed to decode response header addons").Base(err)
171+
return nil, newError("failed to decode response header addons").Base(err)
172172
}
173173

174-
return nil
174+
return responseAddons, nil
175175
}

0 commit comments

Comments
 (0)