Compare commits

...

23 Commits

Author SHA1 Message Date
Darien Raymond
e35e271708 cleanup internet connection 2017-01-04 13:29:41 +01:00
Darien Raymond
e678000c44 remove release() pattern 2017-01-04 12:52:24 +01:00
Darien Raymond
49210d8362 refine stream handling 2017-01-04 12:34:01 +01:00
Darien Raymond
723207158f Merge branch 'master' of https://github.com/v2ray/v2ray-core 2017-01-04 11:10:52 +01:00
Darien Raymond
c4e2d99859 refine socks tcp handling 2017-01-04 00:43:13 +01:00
Darien Raymond
aefa53f827 refine http header 2017-01-03 23:09:51 +01:00
Darien Raymond
588c43f291 kcp header as wechat video 2017-01-03 22:46:22 +01:00
Darien Raymond
21a15bbf74 registerable dialer and listener 2017-01-03 15:16:48 +01:00
Darien Raymond
31d6e74482 remove rawtcp 2017-01-03 14:53:59 +01:00
Darien Raymond
3732de18b1 remove generated package comments 2017-01-03 14:23:55 +01:00
Darien Raymond
ff01a886da simplify comments 2017-01-03 14:21:59 +01:00
Darien Raymond
c9a421fba6 remove generate package comments in .pb.go files. 2017-01-03 14:17:44 +01:00
Darien Raymond
6c39ce0714 doc 2017-01-03 13:06:03 +01:00
Darien Raymond
1e5061f15e fix #351 2017-01-03 01:37:27 +01:00
Darien Raymond
84978a501d remove go generate in travis workflow 2017-01-02 20:55:39 +01:00
Darien Raymond
72ae6b3bfd remove proto-gen script 2017-01-02 20:53:18 +01:00
Darien Raymond
20fe6d10a4 rollback gitignore change 2017-01-02 20:52:45 +01:00
Darien Raymond
7cbef6723c generate protobuf files on the fly 2017-01-02 20:43:41 +01:00
Darien Raymond
52e1dfaeac remove all generated files 2017-01-02 08:15:31 +01:00
Darien Raymond
19e0cb40e9 locker protected connection 2017-01-02 07:43:02 +01:00
Darien Raymond
5857aea881 remove inspector 2017-01-01 23:08:39 +01:00
Darien Raymond
48bddb25d7 fix lint warnings 2017-01-01 22:12:44 +01:00
Darien Raymond
4d6ca7efe0 Update version 2017-01-01 21:19:58 +01:00
128 changed files with 1218 additions and 1573 deletions

View File

@@ -1,16 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/app/dispatcher/config.proto
// DO NOT EDIT!
/*
Package dispatcher is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/app/dispatcher/config.proto
It has these top-level messages:
Config
*/
package dispatcher
import proto "github.com/golang/protobuf/proto"
@@ -28,32 +15,7 @@ var _ = math.Inf
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Config_FixDestination int32
const (
Config_Auto Config_FixDestination = 0
Config_Enabled Config_FixDestination = 1
Config_Disabled Config_FixDestination = 2
)
var Config_FixDestination_name = map[int32]string{
0: "Auto",
1: "Enabled",
2: "Disabled",
}
var Config_FixDestination_value = map[string]int32{
"Auto": 0,
"Enabled": 1,
"Disabled": 2,
}
func (x Config_FixDestination) String() string {
return proto.EnumName(Config_FixDestination_name, int32(x))
}
func (Config_FixDestination) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} }
type Config struct {
FixDestination Config_FixDestination `protobuf:"varint,1,opt,name=fix_destination,json=fixDestination,enum=v2ray.core.app.dispatcher.Config_FixDestination" json:"fix_destination,omitempty"`
}
func (m *Config) Reset() { *m = Config{} }
@@ -61,34 +23,21 @@ func (m *Config) String() string { return proto.CompactTextString(m)
func (*Config) ProtoMessage() {}
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *Config) GetFixDestination() Config_FixDestination {
if m != nil {
return m.FixDestination
}
return Config_Auto
}
func init() {
proto.RegisterType((*Config)(nil), "v2ray.core.app.dispatcher.Config")
proto.RegisterEnum("v2ray.core.app.dispatcher.Config_FixDestination", Config_FixDestination_name, Config_FixDestination_value)
}
func init() { proto.RegisterFile("v2ray.com/core/app/dispatcher/config.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 218 bytes of a gzipped FileDescriptorProto
// 134 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xd2, 0x2a, 0x33, 0x2a, 0x4a,
0xac, 0xd4, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0x2c, 0x28, 0xd0, 0x4f,
0xc9, 0x2c, 0x2e, 0x48, 0x2c, 0x49, 0xce, 0x48, 0x2d, 0xd2, 0x4f, 0xce, 0xcf, 0x4b, 0xcb, 0x4c,
0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x84, 0xa9, 0x2d, 0x4a, 0xd5, 0x4b, 0x2c, 0x28,
0xd0, 0x43, 0xa8, 0x53, 0x9a, 0xc5, 0xc8, 0xc5, 0xe6, 0x0c, 0x56, 0x2b, 0x14, 0xc9, 0xc5, 0x9f,
0x96, 0x59, 0x11, 0x9f, 0x92, 0x5a, 0x5c, 0x92, 0x99, 0x97, 0x58, 0x92, 0x99, 0x9f, 0x27, 0xc1,
0xa8, 0xc0, 0xa8, 0xc1, 0x67, 0x64, 0xa0, 0x87, 0x53, 0xbf, 0x1e, 0x44, 0xaf, 0x9e, 0x5b, 0x66,
0x85, 0x0b, 0x42, 0x5f, 0x10, 0x5f, 0x1a, 0x0a, 0x5f, 0xc9, 0x94, 0x8b, 0x0f, 0x55, 0x85, 0x10,
0x07, 0x17, 0x8b, 0x63, 0x69, 0x49, 0xbe, 0x00, 0x83, 0x10, 0x37, 0x17, 0xbb, 0x6b, 0x5e, 0x62,
0x52, 0x4e, 0x6a, 0x8a, 0x00, 0xa3, 0x10, 0x0f, 0x17, 0x87, 0x4b, 0x66, 0x31, 0x84, 0xc7, 0xe4,
0x14, 0xc2, 0x25, 0x9b, 0x9c, 0x9f, 0x8b, 0xdb, 0x76, 0x27, 0x6e, 0x88, 0xf5, 0x01, 0x20, 0x5f,
0x46, 0x71, 0x21, 0x24, 0x56, 0x31, 0x49, 0x86, 0x19, 0x05, 0x25, 0x56, 0xea, 0x39, 0x83, 0x34,
0x39, 0x16, 0x14, 0xe8, 0xb9, 0xc0, 0xe5, 0x92, 0xd8, 0xc0, 0x81, 0x62, 0x0c, 0x08, 0x00, 0x00,
0xff, 0xff, 0x63, 0xfd, 0xa7, 0xdb, 0x42, 0x01, 0x00, 0x00,
0xd0, 0x43, 0xa8, 0x53, 0xe2, 0xe0, 0x62, 0x73, 0x06, 0x2b, 0x75, 0x0a, 0xe1, 0x92, 0x4d, 0xce,
0xcf, 0xd5, 0xc3, 0xa9, 0xd4, 0x89, 0x1b, 0xa2, 0x30, 0x00, 0x64, 0x64, 0x14, 0x17, 0x42, 0x62,
0x15, 0x93, 0x64, 0x98, 0x51, 0x50, 0x62, 0xa5, 0x9e, 0x33, 0x48, 0x93, 0x63, 0x41, 0x81, 0x9e,
0x0b, 0x5c, 0x2e, 0x89, 0x0d, 0xec, 0x02, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x60, 0xf8,
0x2f, 0x3b, 0xaf, 0x00, 0x00, 0x00,
}

View File

@@ -7,11 +7,4 @@ option java_package = "com.v2ray.core.app.dispatcher";
option java_outer_classname = "ConfigProto";
message Config {
enum FixDestination {
Auto = 0;
Enabled = 1;
Disabled = 2;
}
FixDestination fix_destination = 1;
}

View File

@@ -14,6 +14,3 @@ const (
type PacketDispatcher interface {
DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay
}
type Inspector interface {
}

View File

@@ -1,6 +1,8 @@
package impl
import (
"time"
"v2ray.com/core/app"
"v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/proxyman"
@@ -27,6 +29,7 @@ func NewDefaultDispatcher(space app.Space) *DefaultDispatcher {
return d
}
// Initialize initializes the dispatcher.
// Private: Used by app.Space only.
func (v *DefaultDispatcher) Initialize(space app.Space) error {
if !space.HasApp(proxyman.APP_ID_OUTBOUND_MANAGER) {
@@ -41,12 +44,7 @@ func (v *DefaultDispatcher) Initialize(space app.Space) error {
return nil
}
func (v *DefaultDispatcher) Release() {
}
func (v *DefaultDispatcher) DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay {
direct := ray.NewRay()
dispatcher := v.ohm.GetDefaultHandler()
destination := session.Destination
@@ -63,41 +61,32 @@ func (v *DefaultDispatcher) DispatchToOutbound(session *proxy.SessionInfo) ray.I
}
}
direct := ray.NewRay()
var waitFunc func() error
if session.Inbound != nil && session.Inbound.AllowPassiveConnection {
go dispatcher.Dispatch(destination, buf.NewLocal(32), direct)
waitFunc = noOpWait()
} else {
go v.FilterPacketAndDispatch(destination, direct, dispatcher)
wdi := &waitDataInspector{
hasData: make(chan bool, 1),
}
direct.AddInspector(wdi)
waitFunc = waitForData(wdi)
}
go v.waitAndDispatch(waitFunc, destination, direct, dispatcher)
return direct
}
// FilterPacketAndDispatch waits for a payload from source and starts dispatching.
// Private: Visible for testing.
func (v *DefaultDispatcher) FilterPacketAndDispatch(destination v2net.Destination, link ray.OutboundRay, dispatcher proxy.OutboundHandler) {
payload, err := link.OutboundInput().Read()
if err != nil {
log.Info("DefaultDispatcher: No payload towards ", destination, ", stopping now.")
link.OutboundInput().Release()
link.OutboundOutput().Release()
func (v *DefaultDispatcher) waitAndDispatch(wait func() error, destination v2net.Destination, link ray.OutboundRay, dispatcher proxy.OutboundHandler) {
if err := wait(); err != nil {
log.Info("DefaultDispatcher: Failed precondition: ", err)
link.OutboundInput().ForceClose()
link.OutboundOutput().Close()
return
}
dispatcher.Dispatch(destination, payload, link)
}
func (v *DefaultDispatcher) FixDestination(payload *buf.Buffer, dest v2net.Destination) v2net.Destination {
if dest.Address.Family().IsDomain() || dest.Network != v2net.Network_TCP {
return dest
}
switch dest.Port {
case 80:
addr := DetectHTTPHost(payload)
if addr != nil {
dest.Address = addr
}
}
return dest
dispatcher.Dispatch(destination, link)
}
type DefaultDispatcherFactory struct{}
@@ -113,3 +102,38 @@ func (v DefaultDispatcherFactory) AppId() app.ID {
func init() {
app.RegisterApplicationFactory(serial.GetMessageType(new(dispatcher.Config)), DefaultDispatcherFactory{})
}
type waitDataInspector struct {
hasData chan bool
}
func (wdi *waitDataInspector) Input(*buf.Buffer) {
select {
case wdi.hasData <- true:
default:
}
}
func (wdi *waitDataInspector) WaitForData() bool {
select {
case <-wdi.hasData:
return true
case <-time.After(time.Minute):
return false
}
}
func waitForData(wdi *waitDataInspector) func() error {
return func() error {
if wdi.WaitForData() {
return nil
}
return errors.New("DefaultDispatcher: No data.")
}
}
func noOpWait() func() error {
return func() error {
return nil
}
}

View File

@@ -1,10 +0,0 @@
package impl
import (
"v2ray.com/core/common/buf"
v2net "v2ray.com/core/common/net"
)
func DetectHTTPHost(payload *buf.Buffer) v2net.Address {
return nil
}

View File

@@ -1,16 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/app/dns/config.proto
// DO NOT EDIT!
/*
Package dns is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/app/dns/config.proto
It has these top-level messages:
Config
*/
package dns
import proto "github.com/golang/protobuf/proto"

View File

@@ -66,10 +66,6 @@ func NewCacheServer(space app.Space, config *dns.Config) *CacheServer {
return server
}
func (v *CacheServer) Release() {
}
// Private: Visible for testing.
func (v *CacheServer) GetCached(domain string) []net.IP {
v.RLock()

View File

@@ -50,15 +50,10 @@ func (v *OutboundProxy) Dial(src v2net.Address, dest v2net.Destination, options
}
log.Info("Proxy: Dialing to ", dest)
stream := ray.NewRay()
go handler.Dispatch(dest, nil, stream)
go handler.Dispatch(dest, stream)
return NewConnection(src, dest, stream), nil
}
// Release implements common.Releasable.Release().
func (v *OutboundProxy) Release() {
}
type Connection struct {
stream ray.Ray
closed bool
@@ -105,9 +100,7 @@ func (v *Connection) Write(b []byte) (int, error) {
func (v *Connection) Close() error {
v.closed = true
v.stream.InboundInput().Close()
v.stream.InboundOutput().Release()
v.reader.Release()
v.writer.Release()
v.stream.InboundOutput().ForceClose()
return nil
}

View File

@@ -25,7 +25,7 @@ func TestProxyDial(t *testing.T) {
common.Must(outboundManager.SetHandler("tag", freedom.New(&freedom.Config{}, space, &proxy.OutboundHandlerMeta{
Tag: "tag",
StreamSettings: &internet.StreamConfig{
Network: v2net.Network_RawTCP,
Network: v2net.Network_TCP,
},
})))
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, outboundManager)
@@ -49,7 +49,7 @@ func TestProxyDial(t *testing.T) {
conn, err := proxy.Dial(v2net.LocalHostIP, dest, internet.DialerOptions{
Stream: &internet.StreamConfig{
Network: v2net.Network_RawTCP,
Network: v2net.Network_TCP,
},
Proxy: &internet.ProxyConfig{
Tag: "tag",

View File

@@ -1,17 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/app/proxyman/config.proto
// DO NOT EDIT!
/*
Package proxyman is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/app/proxyman/config.proto
It has these top-level messages:
InboundConfig
OutboundConfig
*/
package proxyman
import proto "github.com/golang/protobuf/proto"

View File

@@ -2,6 +2,7 @@ package outbound
import (
"sync"
"v2ray.com/core/app"
"v2ray.com/core/app/proxyman"
"v2ray.com/core/common/serial"
@@ -20,10 +21,6 @@ func New() *DefaultOutboundHandlerManager {
}
}
func (v *DefaultOutboundHandlerManager) Release() {
}
func (v *DefaultOutboundHandlerManager) GetDefaultHandler() proxy.OutboundHandler {
v.RLock()
defer v.RUnlock()

View File

@@ -1,3 +1,4 @@
// Package proxyman defines applications for manageing inbound and outbound proxies.
package proxyman
import (

View File

@@ -1,19 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/app/router/config.proto
// DO NOT EDIT!
/*
Package router is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/app/router/config.proto
It has these top-level messages:
Domain
CIDR
RoutingRule
Config
*/
package router
import proto "github.com/golang/protobuf/proto"

View File

@@ -52,10 +52,6 @@ func NewRouter(config *Config, space app.Space) *Router {
return r
}
func (v *Router) Release() {
}
// Private: Visible for testing.
func (v *Router) ResolveIP(dest v2net.Destination) []v2net.Destination {
ips := v.dnsServer.Get(dest.Address.Domain())

View File

@@ -1,9 +1,6 @@
package app
import (
"v2ray.com/core/common"
"v2ray.com/core/common/errors"
)
import "v2ray.com/core/common/errors"
type ID int
@@ -17,7 +14,6 @@ type Caller interface {
}
type Application interface {
common.Releasable
}
type ApplicationInitializer func() error

View File

@@ -1,18 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/app/web/config.proto
// DO NOT EDIT!
/*
Package web is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/app/web/config.proto
It has these top-level messages:
FileServer
Server
Config
*/
package web
import proto "github.com/golang/protobuf/proto"

View File

@@ -1,15 +1,11 @@
package web
import (
"v2ray.com/core/app"
"v2ray.com/core/common"
)
import "v2ray.com/core/app"
const (
APP_ID = app.ID(8)
)
type WebServer interface {
common.Releasable
Handle()
}

View File

@@ -8,14 +8,12 @@ import (
// Reader extends io.Reader with alloc.Buffer.
type Reader interface {
Release()
// Read reads content from underlying reader, and put it into an alloc.Buffer.
Read() (*Buffer, error)
}
// Writer extends io.Writer with alloc.Buffer.
type Writer interface {
Release()
// Write writes an alloc.Buffer into underlying writer.
Write(*Buffer) error
}

View File

@@ -1,7 +1,6 @@
package buf
import "io"
import "v2ray.com/core/common"
// BytesToBufferReader is a Reader that adjusts its reading speed automatically.
type BytesToBufferReader struct {
@@ -44,11 +43,6 @@ func (v *BytesToBufferReader) Read() (*Buffer, error) {
return buffer, nil
}
// Release implements Releasable.Release().
func (v *BytesToBufferReader) Release() {
common.Release(v.reader)
}
type BufferToBytesReader struct {
stream Reader
current *Buffer
@@ -84,10 +78,3 @@ func (v *BufferToBytesReader) Read(b []byte) (int, error) {
}
return nBytes, err
}
// Release implements Releasable.Release().
func (v *BufferToBytesReader) Release() {
v.eof = true
v.current.Release()
v.current = nil
}

View File

@@ -1,7 +1,6 @@
package buf
import "io"
import "v2ray.com/core/common"
// BufferToBytesWriter is a Writer that writes alloc.Buffer into underlying writer.
type BufferToBytesWriter struct {
@@ -24,11 +23,6 @@ func (v *BufferToBytesWriter) Write(buffer *Buffer) error {
return nil
}
// Release implements Releasable.Release().
func (v *BufferToBytesWriter) Release() {
common.Release(v.writer)
}
type BytesToBufferWriter struct {
writer Writer
}
@@ -50,8 +44,3 @@ func (v *BytesToBufferWriter) Write(payload []byte) (int, error) {
return bytesWritten, nil
}
// Release implements Releasable.Release()
func (v *BytesToBufferWriter) Release() {
v.writer.Release()
}

View File

@@ -3,7 +3,6 @@ package bufio
import (
"io"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
)
@@ -18,21 +17,11 @@ type BufferedReader struct {
func NewReader(rawReader io.Reader) *BufferedReader {
return &BufferedReader{
reader: rawReader,
buffer: buf.New(),
buffer: buf.NewLocal(1024),
buffered: true,
}
}
// Release implements Releasable.Release().
func (v *BufferedReader) Release() {
if v.buffer != nil {
v.buffer.Release()
v.buffer = nil
}
common.Release(v.reader)
}
// IsBuffered returns true if the internal cache is effective.
func (v *BufferedReader) IsBuffered() bool {
return v.buffered

View File

@@ -3,7 +3,6 @@ package bufio
import (
"io"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
)
@@ -20,7 +19,7 @@ type BufferedWriter struct {
func NewWriter(rawWriter io.Writer) *BufferedWriter {
return &BufferedWriter{
writer: rawWriter,
buffer: buf.NewSmall(),
buffer: buf.NewLocal(1024),
buffered: true,
}
}
@@ -91,16 +90,3 @@ func (v *BufferedWriter) SetBuffered(cached bool) {
v.Flush()
}
}
// Release implements common.Releasable.Release().
func (v *BufferedWriter) Release() {
if !v.buffer.IsEmpty() {
v.Flush()
}
if v.buffer != nil {
v.buffer.Release()
v.buffer = nil
}
common.Release(v.writer)
}

View File

@@ -40,14 +40,14 @@ func TestBufferedWriterLargePayload(t *testing.T) {
payload := make([]byte, 64*1024)
rand.Read(payload)
nBytes, err := writer.Write(payload[:1024])
assert.Int(nBytes).Equals(1024)
nBytes, err := writer.Write(payload[:512])
assert.Int(nBytes).Equals(512)
assert.Error(err).IsNil()
assert.Bool(content.IsEmpty()).IsTrue()
nBytes, err = writer.Write(payload[1024:])
nBytes, err = writer.Write(payload[512:])
assert.Error(err).IsNil()
assert.Int(nBytes).Equals(63 * 1024)
assert.Int(nBytes).Equals(64*1024 - 512)
assert.Bytes(content.Bytes()).Equals(payload)
}

View File

@@ -13,19 +13,6 @@ var (
ErrDuplicatedName = errors.New("Duplicated name.")
)
// Releasable interface is for those types that can release its members.
type Releasable interface {
// Release releases all references to accelerate garbage collection.
Release()
}
// Release tries to release the given object.
func Release(v interface{}) {
if releasable, ok := v.(Releasable); ok {
releasable.Release()
}
}
// Must panics if err is not nil.
func Must(err error) {
if err != nil {

View File

@@ -0,0 +1,126 @@
// GENERATED CODE. DO NOT MODIFY!
package internal
import "encoding/binary"
func ChaCha20Block(s *[16]uint32, out []byte, rounds int) {
var x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15 = s[0],s[1],s[2],s[3],s[4],s[5],s[6],s[7],s[8],s[9],s[10],s[11],s[12],s[13],s[14],s[15]
for i := 0; i < rounds; i+=2 {
var x uint32
x0+=x4
x=x12^x0
x12=(x << 16) | (x >> (32 - 16))
x8+=x12
x=x4^x8
x4=(x << 12) | (x >> (32 - 12))
x0+=x4
x=x12^x0
x12=(x << 8) | (x >> (32 - 8))
x8+=x12
x=x4^x8
x4=(x << 7) | (x >> (32 - 7))
x1+=x5
x=x13^x1
x13=(x << 16) | (x >> (32 - 16))
x9+=x13
x=x5^x9
x5=(x << 12) | (x >> (32 - 12))
x1+=x5
x=x13^x1
x13=(x << 8) | (x >> (32 - 8))
x9+=x13
x=x5^x9
x5=(x << 7) | (x >> (32 - 7))
x2+=x6
x=x14^x2
x14=(x << 16) | (x >> (32 - 16))
x10+=x14
x=x6^x10
x6=(x << 12) | (x >> (32 - 12))
x2+=x6
x=x14^x2
x14=(x << 8) | (x >> (32 - 8))
x10+=x14
x=x6^x10
x6=(x << 7) | (x >> (32 - 7))
x3+=x7
x=x15^x3
x15=(x << 16) | (x >> (32 - 16))
x11+=x15
x=x7^x11
x7=(x << 12) | (x >> (32 - 12))
x3+=x7
x=x15^x3
x15=(x << 8) | (x >> (32 - 8))
x11+=x15
x=x7^x11
x7=(x << 7) | (x >> (32 - 7))
x0+=x5
x=x15^x0
x15=(x << 16) | (x >> (32 - 16))
x10+=x15
x=x5^x10
x5=(x << 12) | (x >> (32 - 12))
x0+=x5
x=x15^x0
x15=(x << 8) | (x >> (32 - 8))
x10+=x15
x=x5^x10
x5=(x << 7) | (x >> (32 - 7))
x1+=x6
x=x12^x1
x12=(x << 16) | (x >> (32 - 16))
x11+=x12
x=x6^x11
x6=(x << 12) | (x >> (32 - 12))
x1+=x6
x=x12^x1
x12=(x << 8) | (x >> (32 - 8))
x11+=x12
x=x6^x11
x6=(x << 7) | (x >> (32 - 7))
x2+=x7
x=x13^x2
x13=(x << 16) | (x >> (32 - 16))
x8+=x13
x=x7^x8
x7=(x << 12) | (x >> (32 - 12))
x2+=x7
x=x13^x2
x13=(x << 8) | (x >> (32 - 8))
x8+=x13
x=x7^x8
x7=(x << 7) | (x >> (32 - 7))
x3+=x4
x=x14^x3
x14=(x << 16) | (x >> (32 - 16))
x9+=x14
x=x4^x9
x4=(x << 12) | (x >> (32 - 12))
x3+=x4
x=x14^x3
x14=(x << 8) | (x >> (32 - 8))
x9+=x14
x=x4^x9
x4=(x << 7) | (x >> (32 - 7))
}
binary.LittleEndian.PutUint32(out[0:4], s[0]+x0)
binary.LittleEndian.PutUint32(out[4:8], s[1]+x1)
binary.LittleEndian.PutUint32(out[8:12], s[2]+x2)
binary.LittleEndian.PutUint32(out[12:16], s[3]+x3)
binary.LittleEndian.PutUint32(out[16:20], s[4]+x4)
binary.LittleEndian.PutUint32(out[20:24], s[5]+x5)
binary.LittleEndian.PutUint32(out[24:28], s[6]+x6)
binary.LittleEndian.PutUint32(out[28:32], s[7]+x7)
binary.LittleEndian.PutUint32(out[32:36], s[8]+x8)
binary.LittleEndian.PutUint32(out[36:40], s[9]+x9)
binary.LittleEndian.PutUint32(out[40:44], s[10]+x10)
binary.LittleEndian.PutUint32(out[44:48], s[11]+x11)
binary.LittleEndian.PutUint32(out[48:52], s[12]+x12)
binary.LittleEndian.PutUint32(out[52:56], s[13]+x13)
binary.LittleEndian.PutUint32(out[56:60], s[14]+x14)
binary.LittleEndian.PutUint32(out[60:64], s[15]+x15)
}

View File

@@ -1,124 +0,0 @@
// GENERATED CODE. DO NOT MODIFY!
package internal
import "encoding/binary"
func ChaCha20Block(s *[16]uint32, out []byte, rounds int) {
var x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 = s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9], s[10], s[11], s[12], s[13], s[14], s[15]
for i := 0; i < rounds; i += 2 {
var x uint32
x0 += x4
x = x12 ^ x0
x12 = (x << 16) | (x >> (32 - 16))
x8 += x12
x = x4 ^ x8
x4 = (x << 12) | (x >> (32 - 12))
x0 += x4
x = x12 ^ x0
x12 = (x << 8) | (x >> (32 - 8))
x8 += x12
x = x4 ^ x8
x4 = (x << 7) | (x >> (32 - 7))
x1 += x5
x = x13 ^ x1
x13 = (x << 16) | (x >> (32 - 16))
x9 += x13
x = x5 ^ x9
x5 = (x << 12) | (x >> (32 - 12))
x1 += x5
x = x13 ^ x1
x13 = (x << 8) | (x >> (32 - 8))
x9 += x13
x = x5 ^ x9
x5 = (x << 7) | (x >> (32 - 7))
x2 += x6
x = x14 ^ x2
x14 = (x << 16) | (x >> (32 - 16))
x10 += x14
x = x6 ^ x10
x6 = (x << 12) | (x >> (32 - 12))
x2 += x6
x = x14 ^ x2
x14 = (x << 8) | (x >> (32 - 8))
x10 += x14
x = x6 ^ x10
x6 = (x << 7) | (x >> (32 - 7))
x3 += x7
x = x15 ^ x3
x15 = (x << 16) | (x >> (32 - 16))
x11 += x15
x = x7 ^ x11
x7 = (x << 12) | (x >> (32 - 12))
x3 += x7
x = x15 ^ x3
x15 = (x << 8) | (x >> (32 - 8))
x11 += x15
x = x7 ^ x11
x7 = (x << 7) | (x >> (32 - 7))
x0 += x5
x = x15 ^ x0
x15 = (x << 16) | (x >> (32 - 16))
x10 += x15
x = x5 ^ x10
x5 = (x << 12) | (x >> (32 - 12))
x0 += x5
x = x15 ^ x0
x15 = (x << 8) | (x >> (32 - 8))
x10 += x15
x = x5 ^ x10
x5 = (x << 7) | (x >> (32 - 7))
x1 += x6
x = x12 ^ x1
x12 = (x << 16) | (x >> (32 - 16))
x11 += x12
x = x6 ^ x11
x6 = (x << 12) | (x >> (32 - 12))
x1 += x6
x = x12 ^ x1
x12 = (x << 8) | (x >> (32 - 8))
x11 += x12
x = x6 ^ x11
x6 = (x << 7) | (x >> (32 - 7))
x2 += x7
x = x13 ^ x2
x13 = (x << 16) | (x >> (32 - 16))
x8 += x13
x = x7 ^ x8
x7 = (x << 12) | (x >> (32 - 12))
x2 += x7
x = x13 ^ x2
x13 = (x << 8) | (x >> (32 - 8))
x8 += x13
x = x7 ^ x8
x7 = (x << 7) | (x >> (32 - 7))
x3 += x4
x = x14 ^ x3
x14 = (x << 16) | (x >> (32 - 16))
x9 += x14
x = x4 ^ x9
x4 = (x << 12) | (x >> (32 - 12))
x3 += x4
x = x14 ^ x3
x14 = (x << 8) | (x >> (32 - 8))
x9 += x14
x = x4 ^ x9
x4 = (x << 7) | (x >> (32 - 7))
}
binary.LittleEndian.PutUint32(out[0:4], s[0]+x0)
binary.LittleEndian.PutUint32(out[4:8], s[1]+x1)
binary.LittleEndian.PutUint32(out[8:12], s[2]+x2)
binary.LittleEndian.PutUint32(out[12:16], s[3]+x3)
binary.LittleEndian.PutUint32(out[16:20], s[4]+x4)
binary.LittleEndian.PutUint32(out[20:24], s[5]+x5)
binary.LittleEndian.PutUint32(out[24:28], s[6]+x6)
binary.LittleEndian.PutUint32(out[28:32], s[7]+x7)
binary.LittleEndian.PutUint32(out[32:36], s[8]+x8)
binary.LittleEndian.PutUint32(out[36:40], s[9]+x9)
binary.LittleEndian.PutUint32(out[40:44], s[10]+x10)
binary.LittleEndian.PutUint32(out[44:48], s[11]+x11)
binary.LittleEndian.PutUint32(out[48:52], s[12]+x12)
binary.LittleEndian.PutUint32(out[52:56], s[13]+x13)
binary.LittleEndian.PutUint32(out[56:60], s[14]+x14)
binary.LittleEndian.PutUint32(out[60:64], s[15]+x15)
}

View File

@@ -55,13 +55,12 @@ func ChaCha20Block(s *[16]uint32, out []byte, rounds int) {
}
func main() {
file, err := os.OpenFile("chacha_core.go", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
file, err := os.OpenFile("chacha_core.generated.go", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err != nil {
log.Fatalf("Failed to generate chacha_core.go: %v", err)
}
defer file.Close()
fmt.Fprintln(file, "// GENERATED CODE. DO NOT MODIFY!")
fmt.Fprintln(file, "package internal")
fmt.Fprintln(file)
fmt.Fprintln(file, "import \"encoding/binary\"")

View File

@@ -3,8 +3,6 @@ package crypto
import (
"crypto/cipher"
"io"
"v2ray.com/core/common"
)
type CryptionReader struct {
@@ -27,11 +25,6 @@ func (v *CryptionReader) Read(data []byte) (int, error) {
return nBytes, err
}
func (v *CryptionReader) Release() {
common.Release(v.reader)
common.Release(v.stream)
}
type CryptionWriter struct {
stream cipher.Stream
writer io.Writer
@@ -50,9 +43,3 @@ func (v *CryptionWriter) Write(data []byte) (int, error) {
v.stream.XORKeyStream(data, data)
return v.writer.Write(data)
}
// Release implements common.Releasable.Release().
func (v *CryptionWriter) Release() {
common.Release(v.writer)
common.Release(v.stream)
}

View File

@@ -1,16 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/common/log/config.proto
// DO NOT EDIT!
/*
Package log is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/common/log/config.proto
It has these top-level messages:
Config
*/
package log
import proto "github.com/golang/protobuf/proto"

View File

@@ -4,12 +4,10 @@ import (
"fmt"
"strings"
"v2ray.com/core/common"
"v2ray.com/core/common/serial"
)
type LogEntry interface {
common.Releasable
fmt.Stringer
}
@@ -18,12 +16,6 @@ type ErrorLog struct {
Values []interface{}
}
func (v *ErrorLog) Release() {
for _, val := range v.Values {
common.Release(val)
}
}
func (v *ErrorLog) String() string {
return v.Prefix + serial.Concat(v.Values...)
}
@@ -35,12 +27,6 @@ type AccessLog struct {
Reason interface{}
}
func (v *AccessLog) Release() {
common.Release(v.From)
common.Release(v.To)
common.Release(v.Reason)
}
func (v *AccessLog) String() string {
return strings.Join([]string{serial.ToString(v.From), v.Status, serial.ToString(v.To), serial.ToString(v.Reason)}, " ")
}

View File

@@ -17,9 +17,7 @@ type LogWriter interface {
type NoOpLogWriter struct {
}
func (v *NoOpLogWriter) Log(entry LogEntry) {
entry.Release()
}
func (v *NoOpLogWriter) Log(entry LogEntry) {}
func (v *NoOpLogWriter) Close() {
}
@@ -38,7 +36,6 @@ func NewStdOutLogWriter() LogWriter {
func (v *StdOutLogWriter) Log(log LogEntry) {
v.logger.Print(log.String() + platform.LineSeparator())
log.Release()
}
func (v *StdOutLogWriter) Close() {
@@ -58,7 +55,6 @@ func (v *FileLogWriter) Log(log LogEntry) {
default:
// We don't expect this to happen, but don't want to block main thread as well.
}
log.Release()
}
func (v *FileLogWriter) run() {

View File

@@ -1,22 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/common/net/address.proto
// DO NOT EDIT!
/*
Package net is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/common/net/address.proto
v2ray.com/core/common/net/destination.proto
v2ray.com/core/common/net/network.proto
v2ray.com/core/common/net/port.proto
It has these top-level messages:
IPOrDomain
Endpoint
NetworkList
PortRange
*/
package net
import proto "github.com/golang/protobuf/proto"

View File

@@ -1,7 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/common/net/destination.proto
// DO NOT EDIT!
package net
import proto "github.com/golang/protobuf/proto"

View File

@@ -30,7 +30,7 @@ func (v Network) AsList() *NetworkList {
func (v Network) SystemString() string {
switch v {
case Network_TCP, Network_RawTCP:
case Network_TCP:
return "tcp"
case Network_UDP, Network_KCP:
return "udp"
@@ -41,7 +41,7 @@ func (v Network) SystemString() string {
func (v Network) URLPrefix() string {
switch v {
case Network_TCP, Network_RawTCP:
case Network_TCP:
return "tcp"
case Network_UDP:
return "udp"

View File

@@ -1,7 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/common/net/network.proto
// DO NOT EDIT!
package net
import proto "github.com/golang/protobuf/proto"

View File

@@ -10,7 +10,7 @@ enum Network {
Unknown = 0;
// Native TCP provided by system.
RawTCP = 1;
RawTCP = 1 [deprecated=true];
// V2Ray specific TCP.
TCP = 2;

View File

@@ -1,7 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/common/net/port.proto
// DO NOT EDIT!
package net
import proto "github.com/golang/protobuf/proto"

View File

@@ -4,8 +4,6 @@ import (
"io"
"net"
"time"
"v2ray.com/core/common"
)
var (
@@ -52,11 +50,6 @@ func (reader *TimeOutReader) SetTimeOut(value uint32) {
}
}
func (reader *TimeOutReader) Release() {
common.Release(reader.connection)
common.Release(reader.worker)
}
type timedReaderWorker struct {
timeout uint32
connection net.Conn

View File

@@ -1,22 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/common/protocol/command.proto
// DO NOT EDIT!
/*
Package protocol is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/common/protocol/command.proto
v2ray.com/core/common/protocol/headers.proto
v2ray.com/core/common/protocol/server_spec.proto
v2ray.com/core/common/protocol/user.proto
It has these top-level messages:
AlternativeOutboundConfig
SecurityConfig
ServerEndpoint
User
*/
package protocol
import proto "github.com/golang/protobuf/proto"

View File

@@ -1,7 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/common/protocol/headers.proto
// DO NOT EDIT!
package protocol
import proto "github.com/golang/protobuf/proto"

View File

@@ -1,7 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/common/protocol/server_spec.proto
// DO NOT EDIT!
package protocol
import proto "github.com/golang/protobuf/proto"

View File

@@ -1,7 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/common/protocol/user.proto
// DO NOT EDIT!
package protocol
import proto "github.com/golang/protobuf/proto"

View File

@@ -1,12 +1,7 @@
package protocol
import (
"v2ray.com/core/common"
)
type UserValidator interface {
common.Releasable
Add(user *User) error
Get(timeHash []byte) (*User, Timestamp, bool)
Release()
}

View File

@@ -1,16 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/common/serial/typed_message.proto
// DO NOT EDIT!
/*
Package serial is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/common/serial/typed_message.proto
It has these top-level messages:
TypedMessage
*/
package serial
import proto "github.com/golang/protobuf/proto"

View File

@@ -1,21 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/config.proto
// DO NOT EDIT!
/*
Package core is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/config.proto
It has these top-level messages:
AllocationStrategyConcurrency
AllocationStrategyRefresh
AllocationStrategy
InboundConnectionConfig
OutboundConnectionConfig
Config
*/
package core
import proto "github.com/golang/protobuf/proto"

View File

@@ -8,7 +8,7 @@ import (
)
var (
version = "2.13"
version = "2.14"
build = "Custom"
codename = "One for all"
intro = "An unified platform for anti-censorship."

View File

@@ -27,4 +27,5 @@ import (
_ "v2ray.com/core/transport/internet/headers/noop"
_ "v2ray.com/core/transport/internet/headers/srtp"
_ "v2ray.com/core/transport/internet/headers/utp"
_ "v2ray.com/core/transport/internet/headers/wechat"
)

View File

@@ -3,7 +3,6 @@ package blackhole
import (
"v2ray.com/core/app"
"v2ray.com/core/common/buf"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/proxy"
"v2ray.com/core/transport/ray"
@@ -28,13 +27,11 @@ func New(space app.Space, config *Config, meta *proxy.OutboundHandlerMeta) (prox
}
// Dispatch implements OutboundHandler.Dispatch().
func (v *Handler) Dispatch(destination v2net.Destination, payload *buf.Buffer, ray ray.OutboundRay) {
payload.Release()
func (v *Handler) Dispatch(destination v2net.Destination, ray ray.OutboundRay) {
v.response.WriteTo(ray.OutboundOutput())
ray.OutboundOutput().Close()
ray.OutboundInput().Release()
ray.OutboundInput().ForceClose()
}
// Factory is an utility for creating blackhole handlers.
@@ -43,7 +40,7 @@ type Factory struct{}
// StreamCapability implements OutboundHandlerFactory.StreamCapability().
func (v *Factory) StreamCapability() v2net.NetworkList {
return v2net.NetworkList{
Network: []v2net.Network{v2net.Network_RawTCP},
Network: []v2net.Network{v2net.Network_TCP},
}
}

View File

@@ -1,18 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/proxy/blackhole/config.proto
// DO NOT EDIT!
/*
Package blackhole is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/proxy/blackhole/config.proto
It has these top-level messages:
NoneResponse
HTTPResponse
Config
*/
package blackhole
import proto "github.com/golang/protobuf/proto"

View File

@@ -1,16 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/proxy/dokodemo/config.proto
// DO NOT EDIT!
/*
Package dokodemo is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/proxy/dokodemo/config.proto
It has these top-level messages:
Config
*/
package dokodemo
import proto "github.com/golang/protobuf/proto"

View File

@@ -143,6 +143,7 @@ func (v *DokodemoDoor) ListenTCP() error {
func (v *DokodemoDoor) HandleTCPConnection(conn internet.Connection) {
defer conn.Close()
conn.SetReusable(false)
var dest v2net.Destination
if v.config.FollowRedirect {
@@ -171,13 +172,11 @@ func (v *DokodemoDoor) HandleTCPConnection(conn internet.Connection) {
defer output.ForceClose()
reader := v2net.NewTimeOutReader(v.config.Timeout, conn)
defer reader.Release()
requestDone := signal.ExecuteAsync(func() error {
defer ray.InboundInput().Close()
v2reader := buf.NewReader(reader)
defer v2reader.Release()
if err := buf.PipeUntilEOF(v2reader, ray.InboundInput()); err != nil {
log.Info("Dokodemo: Failed to transport all TCP request: ", err)
@@ -191,7 +190,6 @@ func (v *DokodemoDoor) HandleTCPConnection(conn internet.Connection) {
defer output.ForceClose()
v2writer := buf.NewWriter(conn)
defer v2writer.Release()
if err := buf.PipeUntilEOF(output, v2writer); err != nil {
log.Info("Dokodemo: Failed to transport all TCP response: ", err)
@@ -209,7 +207,7 @@ type Factory struct{}
func (v *Factory) StreamCapability() v2net.NetworkList {
return v2net.NetworkList{
Network: []v2net.Network{v2net.Network_RawTCP},
Network: []v2net.Network{v2net.Network_TCP},
}
}

View File

@@ -47,7 +47,7 @@ func TestDokodemoTCP(t *testing.T) {
&proxy.OutboundHandlerMeta{
Address: v2net.LocalHostIP,
StreamSettings: &internet.StreamConfig{
Network: v2net.Network_RawTCP,
Network: v2net.Network_TCP,
},
}))
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, ohm)
@@ -64,7 +64,7 @@ func TestDokodemoTCP(t *testing.T) {
Address: v2net.LocalHostIP,
Port: port,
StreamSettings: &internet.StreamConfig{
Network: v2net.Network_RawTCP,
Network: v2net.Network_TCP,
}})
defer dokodemo.Close()
@@ -118,7 +118,7 @@ func TestDokodemoUDP(t *testing.T) {
&proxy.OutboundHandlerMeta{
Address: v2net.AnyIP,
StreamSettings: &internet.StreamConfig{
Network: v2net.Network_RawTCP,
Network: v2net.Network_TCP,
}}))
space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, ohm)
@@ -134,7 +134,7 @@ func TestDokodemoUDP(t *testing.T) {
Address: v2net.LocalHostIP,
Port: port,
StreamSettings: &internet.StreamConfig{
Network: v2net.Network_RawTCP,
Network: v2net.Network_TCP,
}})
defer dokodemo.Close()

View File

@@ -1,16 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/proxy/freedom/config.proto
// DO NOT EDIT!
/*
Package freedom is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/proxy/freedom/config.proto
It has these top-level messages:
Config
*/
package freedom
import proto "github.com/golang/protobuf/proto"

View File

@@ -67,10 +67,9 @@ func (v *Handler) ResolveIP(destination v2net.Destination) v2net.Destination {
return newDest
}
func (v *Handler) Dispatch(destination v2net.Destination, payload *buf.Buffer, ray ray.OutboundRay) {
func (v *Handler) Dispatch(destination v2net.Destination, ray ray.OutboundRay) {
log.Info("Freedom: Opening connection to ", destination)
defer payload.Release()
input := ray.OutboundInput()
output := ray.OutboundOutput()
defer input.ForceClose()
@@ -94,19 +93,12 @@ func (v *Handler) Dispatch(destination v2net.Destination, payload *buf.Buffer, r
}
defer conn.Close()
if !payload.IsEmpty() {
if _, err := conn.Write(payload.Bytes()); err != nil {
log.Warning("Freedom: Failed to write to destination: ", destination, ": ", err)
return
}
}
conn.SetReusable(false)
requestDone := signal.ExecuteAsync(func() error {
defer input.ForceClose()
v2writer := buf.NewWriter(conn)
defer v2writer.Release()
if err := buf.PipeUntilEOF(input, v2writer); err != nil {
return err
}
@@ -127,8 +119,6 @@ func (v *Handler) Dispatch(destination v2net.Destination, payload *buf.Buffer, r
defer output.Close()
v2reader := buf.NewReader(reader)
defer v2reader.Release()
if err := buf.PipeUntilEOF(v2reader, output); err != nil {
return err
}
@@ -144,7 +134,7 @@ type Factory struct{}
func (v *Factory) StreamCapability() v2net.NetworkList {
return v2net.NetworkList{
Network: []v2net.Network{v2net.Network_RawTCP},
Network: []v2net.Network{v2net.Network_TCP},
}
}

View File

@@ -44,7 +44,7 @@ func TestSinglePacket(t *testing.T) {
&proxy.OutboundHandlerMeta{
Address: v2net.AnyIP,
StreamSettings: &internet.StreamConfig{
Network: v2net.Network_RawTCP,
Network: v2net.Network_TCP,
},
})
assert.Error(space.Initialize()).IsNil()
@@ -53,9 +53,10 @@ func TestSinglePacket(t *testing.T) {
data2Send := "Data to be sent to remote"
payload := buf.NewLocal(2048)
payload.Append([]byte(data2Send))
traffic.InboundInput().Write(payload)
fmt.Println(tcpServerAddr.Network, tcpServerAddr.Address, tcpServerAddr.Port)
go freedom.Dispatch(tcpServerAddr, payload, traffic)
go freedom.Dispatch(tcpServerAddr, traffic)
traffic.InboundInput().Close()
respPayload, err := traffic.InboundOutput().Read()
@@ -86,7 +87,7 @@ func TestIPResolution(t *testing.T) {
&proxy.OutboundHandlerMeta{
Address: v2net.AnyIP,
StreamSettings: &internet.StreamConfig{
Network: v2net.Network_RawTCP,
Network: v2net.Network_TCP,
},
})

View File

@@ -1,17 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/proxy/http/config.proto
// DO NOT EDIT!
/*
Package http is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/proxy/http/config.proto
It has these top-level messages:
ServerConfig
ClientConfig
*/
package http
import proto "github.com/golang/protobuf/proto"

View File

@@ -100,6 +100,8 @@ func parseHost(rawHost string, defaultPort v2net.Port) (v2net.Destination, error
func (v *Server) handleConnection(conn internet.Connection) {
defer conn.Close()
conn.SetReusable(false)
timedReader := v2net.NewTimeOutReader(v.config.Timeout, conn)
reader := bufio.OriginalReaderSize(timedReader, 2048)
@@ -160,8 +162,6 @@ func (v *Server) handleConnect(request *http.Request, session *proxy.SessionInfo
defer ray.InboundInput().Close()
v2reader := buf.NewReader(reader)
defer v2reader.Release()
if err := buf.PipeUntilEOF(v2reader, ray.InboundInput()); err != nil {
return err
}
@@ -172,8 +172,6 @@ func (v *Server) handleConnect(request *http.Request, session *proxy.SessionInfo
defer ray.InboundOutput().ForceClose()
v2writer := buf.NewWriter(writer)
defer v2writer.Release()
if err := buf.PipeUntilEOF(ray.InboundOutput(), v2writer); err != nil {
return err
}
@@ -246,8 +244,6 @@ func (v *Server) handlePlainHTTP(request *http.Request, session *proxy.SessionIn
defer input.Close()
requestWriter := bufio.NewWriter(buf.NewBytesWriter(ray.InboundInput()))
defer requestWriter.Release()
err := request.Write(requestWriter)
if err != nil {
return err
@@ -289,7 +285,7 @@ type ServerFactory struct{}
// StreamCapability implements InboundHandlerFactory.StreamCapability().
func (v *ServerFactory) StreamCapability() v2net.NetworkList {
return v2net.NetworkList{
Network: []v2net.Network{v2net.Network_RawTCP},
Network: []v2net.Network{v2net.Network_TCP},
}
}

View File

@@ -64,7 +64,7 @@ func TestNormalGetRequest(t *testing.T) {
Address: v2net.LocalHostIP,
Port: port,
StreamSettings: &internet.StreamConfig{
Network: v2net.Network_RawTCP,
Network: v2net.Network_TCP,
}})
defer httpProxy.Close()

View File

@@ -2,7 +2,6 @@
package proxy
import (
"v2ray.com/core/common/buf"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/common/protocol"
"v2ray.com/core/transport/internet"
@@ -58,5 +57,5 @@ type InboundHandler interface {
// An OutboundHandler handles outbound network connection for V2Ray.
type OutboundHandler interface {
// Dispatch sends one or more Packets to its destination.
Dispatch(destination v2net.Destination, payload *buf.Buffer, ray ray.OutboundRay)
Dispatch(destination v2net.Destination, ray ray.OutboundRay)
}

View File

@@ -35,9 +35,7 @@ func NewClient(config *ClientConfig, space app.Space, meta *proxy.OutboundHandle
}
// Dispatch implements OutboundHandler.Dispatch().
func (v *Client) Dispatch(destination v2net.Destination, payload *buf.Buffer, ray ray.OutboundRay) {
defer payload.Release()
func (v *Client) Dispatch(destination v2net.Destination, ray ray.OutboundRay) {
network := destination.Network
var server *protocol.ServerSpec
@@ -89,23 +87,12 @@ func (v *Client) Dispatch(destination v2net.Destination, payload *buf.Buffer, ra
if request.Command == protocol.RequestCommandTCP {
bufferedWriter := bufio.NewWriter(conn)
defer bufferedWriter.Release()
bodyWriter, err := WriteTCPRequest(request, bufferedWriter)
defer bodyWriter.Release()
if err != nil {
log.Info("Shadowsocks|Client: Failed to write request: ", err)
return
}
if !payload.IsEmpty() {
if err := bodyWriter.Write(payload); err != nil {
log.Info("Shadowsocks|Client: Failed to write payload: ", err)
return
}
}
bufferedWriter.SetBuffered(false)
requestDone := signal.ExecuteAsync(func() error {
@@ -143,12 +130,6 @@ func (v *Client) Dispatch(destination v2net.Destination, payload *buf.Buffer, ra
Writer: conn,
Request: request,
}
if !payload.IsEmpty() {
if err := writer.Write(payload); err != nil {
log.Info("Shadowsocks|Client: Failed to write payload: ", err)
return
}
}
requestDone := signal.ExecuteAsync(func() error {
defer ray.OutboundInput().ForceClose()
@@ -187,7 +168,7 @@ type ClientFactory struct{}
// StreamCapability implements OutboundHandlerFactory.StreamCapability().
func (v *ClientFactory) StreamCapability() v2net.NetworkList {
return v2net.NetworkList{
Network: []v2net.Network{v2net.Network_TCP, v2net.Network_RawTCP},
Network: []v2net.Network{v2net.Network_TCP},
}
}

View File

@@ -31,7 +31,7 @@ func (v *Account) GetCipher() (Cipher, error) {
return &AesCfb{KeyBytes: 32}, nil
case CipherType_CHACHA20:
return &ChaCha20{IVBytes: 8}, nil
case CipherType_CHACHA20_IEFT:
case CipherType_CHACHA20_IETF:
return &ChaCha20{IVBytes: 12}, nil
default:
return nil, errors.New("Unsupported cipher.")

View File

@@ -1,18 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/proxy/shadowsocks/config.proto
// DO NOT EDIT!
/*
Package shadowsocks is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/proxy/shadowsocks/config.proto
It has these top-level messages:
Account
ServerConfig
ClientConfig
*/
package shadowsocks
import proto "github.com/golang/protobuf/proto"
@@ -39,7 +24,7 @@ const (
CipherType_AES_128_CFB CipherType = 1
CipherType_AES_256_CFB CipherType = 2
CipherType_CHACHA20 CipherType = 3
CipherType_CHACHA20_IEFT CipherType = 4
CipherType_CHACHA20_IETF CipherType = 4
)
var CipherType_name = map[int32]string{
@@ -47,14 +32,14 @@ var CipherType_name = map[int32]string{
1: "AES_128_CFB",
2: "AES_256_CFB",
3: "CHACHA20",
4: "CHACHA20_IEFT",
4: "CHACHA20_IETF",
}
var CipherType_value = map[string]int32{
"UNKNOWN": 0,
"AES_128_CFB": 1,
"AES_256_CFB": 2,
"CHACHA20": 3,
"CHACHA20_IEFT": 4,
"CHACHA20_IETF": 4,
}
func (x CipherType) String() string {
@@ -194,8 +179,8 @@ var fileDescriptor0 = []byte{
0x36, 0xcc, 0x93, 0xaf, 0x00, 0x8f, 0x6d, 0x36, 0xa9, 0x6e, 0xe6, 0x1f, 0xe6, 0x57, 0x9f, 0xe6,
0xee, 0x01, 0x7d, 0x0a, 0x24, 0x98, 0x2d, 0xe2, 0x33, 0xfe, 0x2e, 0x0e, 0xcf, 0xa7, 0xae, 0xb3,
0x5d, 0xf0, 0x37, 0x6f, 0xed, 0xa2, 0xd3, 0x54, 0x12, 0x5e, 0x04, 0xe1, 0x45, 0xc0, 0x4f, 0xdd,
0x2e, 0x7d, 0x06, 0xff, 0x6f, 0xa7, 0xf8, 0x72, 0x76, 0xbe, 0x74, 0x7b, 0xd3, 0x2f, 0xe0, 0x09,
0x2e, 0x7d, 0x06, 0xff, 0x6f, 0xa7, 0xf8, 0x72, 0xb6, 0x3c, 0x77, 0x7b, 0xd3, 0x2f, 0xe0, 0x09,
0xcc, 0xf7, 0xbe, 0xc4, 0x94, 0xb4, 0x69, 0xae, 0x1b, 0xa3, 0x9f, 0xc9, 0xce, 0xe5, 0x57, 0xe7,
0xf8, 0x23, 0x8f, 0x92, 0x9a, 0x85, 0x0d, 0xf1, 0xda, 0x12, 0x17, 0x8f, 0xe7, 0xdb, 0x43, 0x9b,
0xed, 0xd5, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x80, 0xb9, 0x5c, 0xee, 0x14, 0x03, 0x00, 0x00,
0xed, 0xd5, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1b, 0x4e, 0xca, 0xdc, 0x14, 0x03, 0x00, 0x00,
}

View File

@@ -25,7 +25,7 @@ enum CipherType {
AES_128_CFB = 1;
AES_256_CFB = 2;
CHACHA20 = 3;
CHACHA20_IEFT = 4;
CHACHA20_IETF = 4;
}
message ServerConfig {

View File

@@ -6,7 +6,6 @@ import (
"crypto/sha1"
"io"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/serial"
@@ -70,11 +69,6 @@ func NewChunkReader(reader io.Reader, auth *Authenticator) *ChunkReader {
}
}
func (v *ChunkReader) Release() {
common.Release(v.reader)
common.Release(v.auth)
}
func (v *ChunkReader) Read() (*buf.Buffer, error) {
buffer := buf.New()
if err := buffer.AppendSupplier(buf.ReadFullFrom(v.reader, 2)); err != nil {
@@ -124,11 +118,6 @@ func NewChunkWriter(writer io.Writer, auth *Authenticator) *ChunkWriter {
}
}
func (v *ChunkWriter) Release() {
common.Release(v.writer)
common.Release(v.auth)
}
func (v *ChunkWriter) Write(payload *buf.Buffer) error {
totalLength := payload.Len()
serial.Uint16ToBytes(uint16(totalLength), v.buffer[:0])

View File

@@ -378,9 +378,6 @@ func (v *UDPReader) Read() (*buf.Buffer, error) {
return payload, nil
}
func (v *UDPReader) Release() {
}
type UDPWriter struct {
Writer io.Writer
Request *protocol.RequestHeader
@@ -395,7 +392,3 @@ func (v *UDPWriter) Write(buffer *buf.Buffer) error {
payload.Release()
return err
}
func (v *UDPWriter) Release() {
}

View File

@@ -84,7 +84,7 @@ func TestUDPReaderWriter(t *testing.T) {
user := &protocol.User{
Account: serial.ToTypedMessage(&Account{
Password: "test-password",
CipherType: CipherType_CHACHA20_IEFT,
CipherType: CipherType_CHACHA20_IETF,
}),
}
cache := buf.New()

View File

@@ -147,18 +147,13 @@ func (v *Server) handleConnection(conn internet.Connection) {
conn.SetReusable(false)
timedReader := v2net.NewTimeOutReader(16, conn)
defer timedReader.Release()
bufferedReader := bufio.NewReader(timedReader)
defer bufferedReader.Release()
request, bodyReader, err := ReadTCPSession(v.user, bufferedReader)
if err != nil {
log.Access(conn.RemoteAddr(), "", log.AccessRejected, err)
log.Info("Shadowsocks|Server: Failed to create request from: ", conn.RemoteAddr(), ": ", err)
return
}
defer bodyReader.Release()
bufferedReader.SetBuffered(false)
@@ -182,14 +177,11 @@ func (v *Server) handleConnection(conn internet.Connection) {
defer ray.InboundOutput().ForceClose()
bufferedWriter := bufio.NewWriter(conn)
defer bufferedWriter.Release()
responseWriter, err := WriteTCPResponse(request, bufferedWriter)
if err != nil {
log.Warning("Shadowsocks|Server: Failed to write response: ", err)
return err
}
defer responseWriter.Release()
payload, err := ray.InboundOutput().Read()
if err != nil {
@@ -225,7 +217,7 @@ type ServerFactory struct{}
func (v *ServerFactory) StreamCapability() v2net.NetworkList {
return v2net.NetworkList{
Network: []v2net.Network{v2net.Network_TCP, v2net.Network_RawTCP},
Network: []v2net.Network{v2net.Network_TCP},
}
}

View File

@@ -1,7 +1,9 @@
// Package shadowsocks provides compatible functionality to Shadowsocks.
//
// Shadowsocks client and server are implemented as outbound and inbound respectively in V2Ray's term.
// Shadowsocks OTA is fully supported.
//
// Shadowsocks OTA is fully supported. By default both client and server enable OTA, but it can be optionally disabled.
//
// Supperted Ciphers:
// * AES-256-CFB
// * AES-128-CFB

View File

@@ -1,18 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/proxy/socks/config.proto
// DO NOT EDIT!
/*
Package socks is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/proxy/socks/config.proto
It has these top-level messages:
Account
ServerConfig
ClientConfig
*/
package socks
import proto "github.com/golang/protobuf/proto"

279
proxy/socks/protocol.go Normal file
View File

@@ -0,0 +1,279 @@
package socks
import (
"io"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/common/protocol"
"v2ray.com/core/common/serial"
"v2ray.com/core/proxy"
)
const (
socks5Version = 0x05
socks4Version = 0x04
cmdTCPConnect = 0x01
cmdTCPBind = 0x02
cmdUDPPort = 0x03
socks4RequestGranted = 90
socks4RequestRejected = 91
authNotRequired = 0x00
authGssAPI = 0x01
authPassword = 0x02
authNoMatchingMethod = 0xFF
addrTypeIPv4 = 0x01
addrTypeIPv6 = 0x04
addrTypeDomain = 0x03
statusSuccess = 0x00
statusCmdNotSupport = 0x07
)
type ServerSession struct {
config *ServerConfig
meta *proxy.InboundHandlerMeta
}
func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) {
buffer := buf.NewLocal(512)
request := new(protocol.RequestHeader)
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil {
return nil, errors.Base(err).Message("Socks|Server: Insufficient header.")
}
version := buffer.Byte(0)
if version == socks4Version {
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 6)); err != nil {
return nil, errors.Base(err).Message("Socks|Server: Insufficient header.")
}
port := v2net.PortFromBytes(buffer.BytesRange(2, 4))
address := v2net.IPAddress(buffer.BytesRange(4, 8))
_, err := readUntilNull(reader) // user id
if err != nil {
return nil, err
}
if address.IP()[0] == 0x00 {
domain, err := readUntilNull(reader)
if err != nil {
return nil, errors.Base(err).Message("Socks|Server: Failed to read domain for socks 4a.")
}
address = v2net.DomainAddress(domain)
}
switch buffer.Byte(1) {
case cmdTCPConnect:
request.Command = protocol.RequestCommandTCP
request.Address = address
request.Port = port
request.Version = socks4Version
if err := writeSocks4Response(writer, socks4RequestGranted, address, port); err != nil {
return nil, err
}
return request, nil
default:
writeSocks4Response(writer, socks4RequestRejected, address, port)
return nil, errors.New("Socks|Server: Unsupported command: ", buffer.Byte(1))
}
}
if version == socks5Version {
nMethod := int(buffer.Byte(1))
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, nMethod)); err != nil {
return nil, err
}
var expectedAuth byte = authNotRequired
if len(s.config.Accounts) > 0 {
expectedAuth = authPassword
}
if !hasAuthMethod(expectedAuth, buffer.BytesRange(2, 2+nMethod)) {
writeSocks5AuthenticationResponse(writer, authNoMatchingMethod)
return nil, errors.New("Socks|Server: No matching auth method.")
}
if expectedAuth == authPassword {
username, password, err := readUsernamePassword(reader)
if err != nil {
return nil, errors.Base(err).Message("Socks|Server: Failed to read username or password.")
}
if !s.validate(username, password) {
writeSocks5AuthenticationResponse(writer, 0xFF)
return nil, errors.Base(err).Message("Socks|Server: Invalid username or password.")
}
}
if err := writeSocks5AuthenticationResponse(writer, 0x00); err != nil {
return nil, err
}
buffer.Clear()
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 4)); err != nil {
return nil, err
}
cmd := buffer.Byte(1)
if cmd == cmdTCPBind || (cmd == cmdUDPPort && !s.config.UdpEnabled) {
writeSocks5Response(writer, statusCmdNotSupport, v2net.AnyIP, v2net.Port(0))
return nil, errors.New("Socks|Server: Unsupported command: ", cmd)
}
switch cmd {
case cmdTCPConnect:
request.Command = protocol.RequestCommandTCP
case cmdUDPPort:
request.Command = protocol.RequestCommandUDP
}
addrType := buffer.Byte(3)
buffer.Clear()
request.Version = socks5Version
switch addrType {
case addrTypeIPv4:
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 4)); err != nil {
return nil, err
}
request.Address = v2net.IPAddress(buffer.Bytes())
case addrTypeIPv6:
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 16)); err != nil {
return nil, err
}
request.Address = v2net.IPAddress(buffer.Bytes())
case addrTypeDomain:
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 1)); err != nil {
return nil, err
}
domainLength := int(buffer.Byte(0))
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, domainLength)); err != nil {
return nil, err
}
request.Address = v2net.DomainAddress(string(buffer.BytesFrom(-domainLength)))
default:
return nil, errors.New("Socks|Server: Unknown address type: ", addrType)
}
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil {
return nil, err
}
request.Port = v2net.PortFromBytes(buffer.BytesFrom(-2))
responseAddress := v2net.AnyIP
responsePort := v2net.Port(1717)
if request.Command == protocol.RequestCommandUDP {
addr := s.config.Address.AsAddress()
if addr == nil {
addr = v2net.LocalHostIP
}
responseAddress = addr
responsePort = s.meta.Port
}
if err := writeSocks5Response(writer, statusSuccess, responseAddress, responsePort); err != nil {
return nil, err
}
return request, nil
}
return nil, errors.New("Socks|Server: Unknown Socks version: ", version)
}
func (s *ServerSession) validate(username, password string) bool {
p, found := s.config.Accounts[username]
return found && p == password
}
func readUsernamePassword(reader io.Reader) (string, string, error) {
buffer := buf.NewLocal(512)
defer buffer.Release()
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil {
return "", "", err
}
nUsername := int(buffer.Byte(1))
buffer.Clear()
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, nUsername)); err != nil {
return "", "", err
}
username := buffer.String()
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 1)); err != nil {
return "", "", err
}
nPassword := int(buffer.Byte(0))
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, nPassword)); err != nil {
return "", "", err
}
password := buffer.String()
return username, password, nil
}
func readUntilNull(reader io.Reader) (string, error) {
var b [256]byte
size := 0
for {
_, err := reader.Read(b[size : size+1])
if err != nil {
return "", err
}
if b[size] == 0x00 {
return string(b[:size]), nil
}
size++
if size == 256 {
return "", errors.New("Socks|Server: Buffer overrun.")
}
}
}
func hasAuthMethod(expectedAuth byte, authCandidates []byte) bool {
for _, a := range authCandidates {
if a == expectedAuth {
return true
}
}
return false
}
func writeSocks5AuthenticationResponse(writer io.Writer, auth byte) error {
_, err := writer.Write([]byte{socks5Version, auth})
return err
}
func writeSocks5Response(writer io.Writer, errCode byte, address v2net.Address, port v2net.Port) error {
buffer := buf.NewLocal(64)
buffer.AppendBytes(socks5Version, errCode, 0x00 /* reserved */)
switch address.Family() {
case v2net.AddressFamilyIPv4:
buffer.AppendBytes(0x01)
buffer.Append(address.IP())
case v2net.AddressFamilyIPv6:
buffer.AppendBytes(0x04)
buffer.Append(address.IP())
case v2net.AddressFamilyDomain:
buffer.AppendBytes(0x03, byte(len(address.Domain())))
buffer.AppendSupplier(serial.WriteString(address.Domain()))
}
buffer.AppendSupplier(serial.WriteUint16(port.Value()))
_, err := writer.Write(buffer.Bytes())
return err
}
func writeSocks4Response(writer io.Writer, errCode byte, address v2net.Address, port v2net.Port) error {
buffer := buf.NewLocal(32)
buffer.AppendBytes(0x00, errCode)
buffer.AppendSupplier(serial.WriteUint16(port.Value()))
buffer.Append(address.IP())
_, err := writer.Write(buffer.Bytes())
return err
}

View File

@@ -10,23 +10,17 @@ import (
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/bufio"
"v2ray.com/core/common/crypto"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/log"
v2net "v2ray.com/core/common/net"
proto "v2ray.com/core/common/protocol"
"v2ray.com/core/common/serial"
"v2ray.com/core/common/signal"
"v2ray.com/core/proxy"
"v2ray.com/core/proxy/socks/protocol"
"v2ray.com/core/transport/internet"
"v2ray.com/core/transport/internet/udp"
)
var (
ErrUnsupportedSocksCommand = errors.New("Unsupported socks command.")
ErrUnsupportedAuthMethod = errors.New("Unsupported auth method.")
)
// Server is a SOCKS 5 proxy server
type Server struct {
tcpMutex sync.RWMutex
@@ -79,7 +73,7 @@ func (v *Server) Close() {
}
}
// Listen implements InboundHandler.Listen().
// Start implements InboundHandler.Start().
func (v *Server) Start() error {
if v.accepting {
return nil
@@ -107,157 +101,46 @@ func (v *Server) Start() error {
func (v *Server) handleConnection(connection internet.Connection) {
defer connection.Close()
connection.SetReusable(false)
timedReader := v2net.NewTimeOutReader(v.config.Timeout, connection)
reader := bufio.NewReader(timedReader)
defer reader.Release()
writer := bufio.NewWriter(connection)
defer writer.Release()
auth, auth4, err := protocol.ReadAuthentication(reader)
if err != nil && errors.Cause(err) != protocol.Socks4Downgrade {
if errors.Cause(err) != io.EOF {
log.Warning("Socks: failed to read authentication: ", err)
}
return
session := &ServerSession{
config: v.config,
meta: v.meta,
}
clientAddr := v2net.DestinationFromAddr(connection.RemoteAddr())
if err != nil && err == protocol.Socks4Downgrade {
v.handleSocks4(clientAddr, reader, writer, auth4)
} else {
v.handleSocks5(clientAddr, reader, writer, auth)
request, err := session.Handshake(reader, connection)
if err != nil {
log.Access(clientAddr, "", log.AccessRejected, err)
log.Info("Socks|Server: Failed to read request: ", err)
return
}
if request.Command == proto.RequestCommandTCP {
dest := request.Destination()
session := &proxy.SessionInfo{
Source: clientAddr,
Destination: dest,
Inbound: v.meta,
}
log.Info("Socks|Server: TCP Connect request to ", dest)
log.Access(clientAddr, dest, log.AccessAccepted, "")
v.transport(reader, connection, session)
return
}
if request.Command == proto.RequestCommandUDP {
v.handleUDP()
return
}
}
func (v *Server) handleSocks5(clientAddr v2net.Destination, reader *bufio.BufferedReader, writer *bufio.BufferedWriter, auth protocol.Socks5AuthenticationRequest) error {
expectedAuthMethod := protocol.AuthNotRequired
if v.config.AuthType == AuthType_PASSWORD {
expectedAuthMethod = protocol.AuthUserPass
}
if !auth.HasAuthMethod(expectedAuthMethod) {
authResponse := protocol.NewAuthenticationResponse(protocol.AuthNoMatchingMethod)
err := protocol.WriteAuthentication(writer, authResponse)
writer.Flush()
if err != nil {
log.Warning("Socks: failed to write authentication: ", err)
return err
}
log.Warning("Socks: client doesn't support any allowed auth methods.")
return ErrUnsupportedAuthMethod
}
authResponse := protocol.NewAuthenticationResponse(expectedAuthMethod)
protocol.WriteAuthentication(writer, authResponse)
err := writer.Flush()
if err != nil {
log.Error("Socks: failed to write authentication: ", err)
return err
}
if v.config.AuthType == AuthType_PASSWORD {
upRequest, err := protocol.ReadUserPassRequest(reader)
if err != nil {
log.Warning("Socks: failed to read username and password: ", err)
return err
}
status := byte(0)
if !v.config.HasAccount(upRequest.Username(), upRequest.Password()) {
status = byte(0xFF)
}
upResponse := protocol.NewSocks5UserPassResponse(status)
err = protocol.WriteUserPassResponse(writer, upResponse)
writer.Flush()
if err != nil {
log.Error("Socks: failed to write user pass response: ", err)
return err
}
if status != byte(0) {
log.Warning("Socks: Invalid user account: ", upRequest.AuthDetail())
log.Access(clientAddr, "", log.AccessRejected, crypto.ErrAuthenticationFailed)
return crypto.ErrAuthenticationFailed
}
}
request, err := protocol.ReadRequest(reader)
if err != nil {
log.Warning("Socks: failed to read request: ", err)
return err
}
if request.Command == protocol.CmdUdpAssociate && v.config.UdpEnabled {
return v.handleUDP(reader, writer)
}
if request.Command == protocol.CmdBind || request.Command == protocol.CmdUdpAssociate {
response := protocol.NewSocks5Response()
response.Error = protocol.ErrorCommandNotSupported
response.Port = v2net.Port(0)
response.SetIPv4([]byte{0, 0, 0, 0})
response.Write(writer)
writer.Flush()
if err != nil {
log.Error("Socks: failed to write response: ", err)
return err
}
log.Warning("Socks: Unsupported socks command ", request.Command)
return ErrUnsupportedSocksCommand
}
response := protocol.NewSocks5Response()
response.Error = protocol.ErrorSuccess
// Some SOCKS software requires a value other than dest. Let's fake one:
response.Port = v2net.Port(1717)
response.SetIPv4([]byte{0, 0, 0, 0})
response.Write(writer)
if err != nil {
log.Error("Socks: failed to write response: ", err)
return err
}
reader.SetBuffered(false)
writer.SetBuffered(false)
dest := request.Destination()
session := &proxy.SessionInfo{
Source: clientAddr,
Destination: dest,
Inbound: v.meta,
}
log.Info("Socks: TCP Connect request to ", dest)
log.Access(clientAddr, dest, log.AccessAccepted, "")
v.transport(reader, writer, session)
return nil
}
func (v *Server) handleUDP(reader io.Reader, writer *bufio.BufferedWriter) error {
response := protocol.NewSocks5Response()
response.Error = protocol.ErrorSuccess
udpAddr := v.udpAddress
response.Port = udpAddr.Port
switch udpAddr.Address.Family() {
case v2net.AddressFamilyIPv4:
response.SetIPv4(udpAddr.Address.IP())
case v2net.AddressFamilyIPv6:
response.SetIPv6(udpAddr.Address.IP())
case v2net.AddressFamilyDomain:
response.SetDomain(udpAddr.Address.Domain())
}
response.Write(writer)
err := writer.Flush()
if err != nil {
log.Error("Socks: failed to write response: ", err)
return err
}
func (v *Server) handleUDP() error {
// The TCP connection closes after v method returns. We need to wait until
// the client closes it.
// TODO: get notified from UDP part
@@ -266,35 +149,6 @@ func (v *Server) handleUDP(reader io.Reader, writer *bufio.BufferedWriter) error
return nil
}
func (v *Server) handleSocks4(clientAddr v2net.Destination, reader *bufio.BufferedReader, writer *bufio.BufferedWriter, auth protocol.Socks4AuthenticationRequest) error {
result := protocol.Socks4RequestGranted
if auth.Command == protocol.CmdBind {
result = protocol.Socks4RequestRejected
}
socks4Response := protocol.NewSocks4AuthenticationResponse(result, auth.Port, auth.IP[:])
socks4Response.Write(writer)
if result == protocol.Socks4RequestRejected {
log.Warning("Socks: Unsupported socks 4 command ", auth.Command)
log.Access(clientAddr, "", log.AccessRejected, ErrUnsupportedSocksCommand)
return ErrUnsupportedSocksCommand
}
reader.SetBuffered(false)
writer.SetBuffered(false)
dest := v2net.TCPDestination(v2net.IPAddress(auth.IP[:]), auth.Port)
session := &proxy.SessionInfo{
Source: clientAddr,
Destination: dest,
Inbound: v.meta,
}
log.Access(clientAddr, dest, log.AccessAccepted, "")
v.transport(reader, writer, session)
return nil
}
func (v *Server) transport(reader io.Reader, writer io.Writer, session *proxy.SessionInfo) {
ray := v.packetDispatcher.DispatchToOutbound(session)
input := ray.InboundInput()
@@ -304,8 +158,6 @@ func (v *Server) transport(reader io.Reader, writer io.Writer, session *proxy.Se
defer input.Close()
v2reader := buf.NewReader(reader)
defer v2reader.Release()
if err := buf.PipeUntilEOF(v2reader, input); err != nil {
log.Info("Socks|Server: Failed to transport all TCP request: ", err)
return err
@@ -317,8 +169,6 @@ func (v *Server) transport(reader io.Reader, writer io.Writer, session *proxy.Se
defer output.ForceClose()
v2writer := buf.NewWriter(writer)
defer v2writer.Release()
if err := buf.PipeUntilEOF(output, v2writer); err != nil {
log.Info("Socks|Server: Failed to transport all TCP response: ", err)
return err
@@ -336,7 +186,7 @@ type ServerFactory struct{}
func (v *ServerFactory) StreamCapability() v2net.NetworkList {
return v2net.NetworkList{
Network: []v2net.Network{v2net.Network_RawTCP},
Network: []v2net.Network{v2net.Network_TCP},
}
}

View File

@@ -1,16 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/proxy/vmess/account.proto
// DO NOT EDIT!
/*
Package vmess is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/proxy/vmess/account.proto
It has these top-level messages:
Account
*/
package vmess
import proto "github.com/golang/protobuf/proto"

View File

@@ -37,16 +37,6 @@ func NewServerSession(validator protocol.UserValidator) *ServerSession {
}
}
// Release implements common.Releaseable.
func (v *ServerSession) Release() {
v.userValidator = nil
v.requestBodyIV = nil
v.requestBodyKey = nil
v.responseBodyIV = nil
v.responseBodyKey = nil
v.responseWriter = nil
}
func (v *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.RequestHeader, error) {
buffer := make([]byte, 512)

View File

@@ -1,18 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/proxy/vmess/inbound/config.proto
// DO NOT EDIT!
/*
Package inbound is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/proxy/vmess/inbound/config.proto
It has these top-level messages:
DetourConfig
DefaultConfig
Config
*/
package inbound
import proto "github.com/golang/protobuf/proto"

View File

@@ -87,15 +87,15 @@ func (v *VMessInboundHandler) Port() v2net.Port {
}
func (v *VMessInboundHandler) Close() {
v.Lock()
v.accepting = false
if v.listener != nil {
v.Lock()
v.listener.Close()
v.listener = nil
v.clients.Release()
v.clients = nil
v.Unlock()
}
v.Unlock()
}
func (v *VMessInboundHandler) GetUser(email string) *protocol.User {
@@ -134,8 +134,6 @@ func transferRequest(session *encoding.ServerSession, request *protocol.RequestH
defer output.Close()
bodyReader := session.DecodeRequestBody(request, input)
defer bodyReader.Release()
if err := buf.PipeUntilEOF(bodyReader, output); err != nil {
return err
}
@@ -180,19 +178,13 @@ func (v *VMessInboundHandler) HandleConnection(connection internet.Connection) {
}
connReader := v2net.NewTimeOutReader(8, connection)
defer connReader.Release()
reader := bufio.NewReader(connReader)
defer reader.Release()
v.RLock()
if !v.accepting {
v.RUnlock()
return
}
session := encoding.NewServerSession(v.clients)
defer session.Release()
request, err := session.DecodeRequestHeader(reader)
v.RUnlock()
@@ -229,8 +221,6 @@ func (v *VMessInboundHandler) HandleConnection(connection internet.Connection) {
})
writer := bufio.NewWriter(connection)
defer writer.Release()
response := &protocol.ResponseHeader{
Command: v.generateCommand(request),
}

View File

@@ -1,16 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/proxy/vmess/outbound/config.proto
// DO NOT EDIT!
/*
Package outbound is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/proxy/vmess/outbound/config.proto
It has these top-level messages:
Config
*/
package outbound
import proto "github.com/golang/protobuf/proto"

View File

@@ -1,10 +1,13 @@
package outbound
import (
"time"
"v2ray.com/core/app"
"v2ray.com/core/common"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/bufio"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/log"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/common/protocol"
@@ -26,10 +29,9 @@ type VMessOutboundHandler struct {
}
// Dispatch implements OutboundHandler.Dispatch().
func (v *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *buf.Buffer, ray ray.OutboundRay) {
defer payload.Release()
defer ray.OutboundInput().ForceClose()
defer ray.OutboundOutput().Close()
func (v *VMessOutboundHandler) Dispatch(target v2net.Destination, outboundRay ray.OutboundRay) {
defer outboundRay.OutboundInput().ForceClose()
defer outboundRay.OutboundOutput().Close()
var rec *protocol.ServerSpec
var conn internet.Connection
@@ -77,8 +79,8 @@ func (v *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *buf.B
request.Option.Set(protocol.RequestOptionConnectionReuse)
}
input := ray.OutboundInput()
output := ray.OutboundOutput()
input := outboundRay.OutboundInput()
output := outboundRay.OutboundOutput()
session := encoding.NewClientSession(protocol.DefaultIDHash)
@@ -86,18 +88,20 @@ func (v *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *buf.B
defer input.ForceClose()
writer := bufio.NewWriter(conn)
defer writer.Release()
session.EncodeRequestHeader(request, writer)
bodyWriter := session.EncodeRequestBody(request, writer)
defer bodyWriter.Release()
if !payload.IsEmpty() {
if err := bodyWriter.Write(payload); err != nil {
return err
}
firstPayload, err := input.ReadTimeout(time.Millisecond * 500)
if err != nil && err != ray.ErrReadTimeout {
return errors.Base(err).Message("VMess|Outbound: Failed to get first payload.")
}
if !firstPayload.IsEmpty() {
if err := bodyWriter.Write(firstPayload); err != nil {
return errors.Base(err).Message("VMess|Outbound: Failed to write first payload.")
}
firstPayload.Release()
}
writer.SetBuffered(false)
if err := buf.PipeUntilEOF(input, bodyWriter); err != nil {
@@ -116,8 +120,6 @@ func (v *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *buf.B
defer output.Close()
reader := bufio.NewReader(conn)
defer reader.Release()
header, err := session.DecodeResponseHeader(reader)
if err != nil {
return err
@@ -128,8 +130,6 @@ func (v *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *buf.B
reader.SetBuffered(false)
bodyReader := session.DecodeResponseBody(request, reader)
defer bodyReader.Release()
if err := buf.PipeUntilEOF(bodyReader, output); err != nil {
return err
}

View File

@@ -2,6 +2,7 @@ package conf
import (
"strings"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/protocol"
"v2ray.com/core/common/serial"
@@ -44,7 +45,7 @@ func (v *ShadowsocksServerConfig) Build() (*serial.TypedMessage, error) {
case "chacha20":
account.CipherType = shadowsocks.CipherType_CHACHA20
case "chacha20-ietf":
account.CipherType = shadowsocks.CipherType_CHACHA20_IEFT
account.CipherType = shadowsocks.CipherType_CHACHA20_IETF
default:
return nil, errors.New("Unknown cipher method: " + cipher)
}
@@ -105,7 +106,7 @@ func (v *ShadowsocksClientConfig) Build() (*serial.TypedMessage, error) {
case "chacha20":
account.CipherType = shadowsocks.CipherType_CHACHA20
case "chacha20-ietf":
account.CipherType = shadowsocks.CipherType_CHACHA20_IEFT
account.CipherType = shadowsocks.CipherType_CHACHA20_IETF
default:
return nil, errors.New("Unknown cipher method: " + cipher)
}

View File

@@ -7,6 +7,7 @@ import (
"v2ray.com/core/transport/internet/headers/noop"
"v2ray.com/core/transport/internet/headers/srtp"
"v2ray.com/core/transport/internet/headers/utp"
"v2ray.com/core/transport/internet/headers/wechat"
)
type NoOpAuthenticator struct{}
@@ -33,6 +34,12 @@ func (UTPAuthenticator) Build() (*serial.TypedMessage, error) {
return serial.ToTypedMessage(new(utp.Config)), nil
}
type WechatVideoAuthenticator struct{}
func (WechatVideoAuthenticator) Build() (*serial.TypedMessage, error) {
return serial.ToTypedMessage(new(wechat.VideoConfig)), nil
}
type HTTPAuthenticatorRequest struct {
Version string `json:"version"`
Method string `json:"method"`

View File

@@ -17,9 +17,10 @@ import (
var (
kcpHeaderLoader = NewJSONConfigLoader(ConfigCreatorCache{
"none": func() interface{} { return new(NoOpAuthenticator) },
"srtp": func() interface{} { return new(SRTPAuthenticator) },
"utp": func() interface{} { return new(UTPAuthenticator) },
"none": func() interface{} { return new(NoOpAuthenticator) },
"srtp": func() interface{} { return new(SRTPAuthenticator) },
"utp": func() interface{} { return new(UTPAuthenticator) },
"wechat-video": func() interface{} { return new(WechatVideoAuthenticator) },
}, "type", "")
tcpHeaderLoader = NewJSONConfigLoader(ConfigCreatorCache{
@@ -185,7 +186,7 @@ type StreamConfig struct {
func (v *StreamConfig) Build() (*internet.StreamConfig, error) {
config := &internet.StreamConfig{
Network: v2net.Network_RawTCP,
Network: v2net.Network_TCP,
}
if v.Network != nil {
config.Network = (*v.Network).Build()

View File

@@ -0,0 +1,7 @@
// +build windows darwin linux
package genproto
//go:generate go get -u "github.com/golang/protobuf/protoc-gen-go"
//go:generate go get -u "github.com/golang/protobuf/proto"
//go:generate go run main.go

90
tools/genproto/main.go Normal file
View File

@@ -0,0 +1,90 @@
// +build generate
package main
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
)
var protocMap = map[string]string{
"windows": filepath.Join(os.Getenv("GOPATH"), "src", "v2ray.com", "core", ".dev", "protoc", "windows", "protoc.exe"),
"darwin": filepath.Join(os.Getenv("GOPATH"), "src", "v2ray.com", "core", ".dev", "protoc", "macos", "protoc"),
"linux": filepath.Join(os.Getenv("GOPATH"), "src", "v2ray.com", "core", ".dev", "protoc", "linux", "protoc"),
}
func main() {
protofiles := make(map[string][]string)
protoc := protocMap[runtime.GOOS]
gosrc := filepath.Join(os.Getenv("GOPATH"), "src")
filepath.Walk(filepath.Join(gosrc, "v2ray.com", "core"), func(path string, info os.FileInfo, err error) error {
if err != nil {
fmt.Println(err)
return err
}
if info.IsDir() {
return nil
}
dir := filepath.Dir(path)
filename := filepath.Base(path)
if strings.HasSuffix(filename, ".proto") {
protofiles[dir] = append(protofiles[dir], path)
}
return nil
})
for _, files := range protofiles {
args := []string{"--proto_path", gosrc, "--go_out", gosrc}
args = append(args, files...)
cmd := exec.Command(protoc, args...)
cmd.Env = append(cmd.Env, os.Environ()...)
output, err := cmd.CombinedOutput()
if len(output) > 0 {
fmt.Println(string(output))
}
if err != nil {
fmt.Println(err)
}
}
err := filepath.Walk(filepath.Join(gosrc, "v2ray.com", "core"), func(path string, info os.FileInfo, err error) error {
if err != nil {
fmt.Println(err)
return err
}
if info.IsDir() {
return nil
}
if !strings.HasSuffix(info.Name(), ".pb.go") {
return nil
}
content, err := ioutil.ReadFile(path)
if err != nil {
return err
}
pos := bytes.Index(content, []byte("\npackage"))
if pos > 0 {
if err := ioutil.WriteFile(path, content[pos+1:], info.Mode()); err != nil {
return err
}
}
return nil
})
if err != nil {
panic(err)
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,16 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/tools/geoip/geoip.proto
// DO NOT EDIT!
/*
Package geoip is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/tools/geoip/geoip.proto
It has these top-level messages:
CountryIPRange
*/
package geoip
import proto "github.com/golang/protobuf/proto"

File diff suppressed because one or more lines are too long

View File

@@ -69,7 +69,7 @@ func main() {
log.Fatalf("Failed to marshal country IPs: %v", err)
}
file, err := os.OpenFile("geoip_data.go", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
file, err := os.OpenFile("geoip.generated.go", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err != nil {
log.Fatalf("Failed to generate geoip_data.go: %v", err)
}

View File

@@ -1,30 +0,0 @@
#!/bin/bash
function detect_protoc() {
SYS_LOC=$(which protoc)
if [ -n "${SYS_LOC}" ]; then
echo ${SYS_LOC}
return
fi
if [[ "$OSTYPE" == "linux"* ]]; then
echo $GOPATH/src/v2ray.com/core/.dev/protoc/linux/protoc
elif [[ "$OSTYPE" == "darwin"* ]]; then
echo $GOPATH/src/v2ray.com/core/.dev/protoc/macos/protoc
fi
}
PROTOC=$(detect_protoc)
# Update Golang proto compiler
go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
pushd $GOPATH/src
for DIR in $(find ./v2ray.com/core -type d -not -path "*.git*"); do
TEST_FILES=($DIR/*.proto)
#echo ${TEST_FILES}
if [ -f ${TEST_FILES[0]} ]; then
${PROTOC} --proto_path=. --go_out=. $DIR/*.proto
fi
done
popd

View File

@@ -1,16 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/transport/config.proto
// DO NOT EDIT!
/*
Package transport is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/transport/config.proto
It has these top-level messages:
Config
*/
package transport
import proto "github.com/golang/protobuf/proto"

View File

@@ -1,18 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/transport/internet/config.proto
// DO NOT EDIT!
/*
Package internet is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/transport/internet/config.proto
It has these top-level messages:
NetworkSettings
StreamConfig
ProxyConfig
*/
package internet
import proto "github.com/golang/protobuf/proto"

View File

@@ -2,6 +2,7 @@ package internet
import (
"net"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/log"
v2net "v2ray.com/core/common/net"
@@ -19,47 +20,41 @@ type DialerOptions struct {
type Dialer func(src v2net.Address, dest v2net.Destination, options DialerOptions) (Connection, error)
var (
TCPDialer Dialer
KCPDialer Dialer
RawTCPDialer Dialer
UDPDialer Dialer
WSDialer Dialer
ProxyDialer Dialer
networkDialerCache = make(map[v2net.Network]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) {
if options.Proxy.HasTag() && ProxyDialer != nil {
log.Info("Internet: Proxying outbound connection through: ", options.Proxy.Tag)
return ProxyDialer(src, dest, options)
}
var connection Connection
var err error
if dest.Network == v2net.Network_TCP {
switch options.Stream.Network {
case v2net.Network_TCP:
connection, err = TCPDialer(src, dest, options)
case v2net.Network_KCP:
connection, err = KCPDialer(src, dest, options)
case v2net.Network_WebSocket:
connection, err = WSDialer(src, dest, options)
// This check has to be the last one.
case v2net.Network_RawTCP:
connection, err = RawTCPDialer(src, dest, options)
default:
return nil, ErrUnsupportedStreamType
dialer := networkDialerCache[options.Stream.Network]
if dialer == nil {
return nil, errors.New("Internet|Dialer: ", options.Stream.Network, " dialer not registered.")
}
if err != nil {
return nil, err
}
return connection, nil
return dialer(src, dest, options)
}
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)
}

View File

@@ -17,7 +17,7 @@ func TestDialWithLocalAddr(t *testing.T) {
assert.Error(err).IsNil()
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.String(conn.RemoteAddr().String()).Equals("127.0.0.1:" + dest.Port.String())
conn.Close()

View File

@@ -1,22 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/transport/internet/headers/http/config.proto
// DO NOT EDIT!
/*
Package http is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/transport/internet/headers/http/config.proto
It has these top-level messages:
Header
Version
Method
RequestConfig
Status
ResponseConfig
Config
*/
package http
import proto "github.com/golang/protobuf/proto"

View File

@@ -109,15 +109,15 @@ type HttpConn struct {
readBuffer *buf.Buffer
oneTimeReader Reader
oneTimeWriter Writer
isServer bool
errorWriter Writer
}
func NewHttpConn(conn net.Conn, reader Reader, writer Writer, isServer bool) *HttpConn {
func NewHttpConn(conn net.Conn, reader Reader, writer Writer, errorWriter Writer) *HttpConn {
return &HttpConn{
Conn: conn,
oneTimeReader: reader,
oneTimeWriter: writer,
isServer: isServer,
errorWriter: errorWriter,
}
}
@@ -157,33 +157,10 @@ func (v *HttpConn) Write(b []byte) (int, error) {
// Close implements net.Conn.Close().
func (v *HttpConn) Close() error {
if v.isServer && v.oneTimeWriter != nil {
if v.oneTimeWriter != nil && v.errorWriter != nil {
// Connection is being closed but header wasn't sent. This means the client request
// is probably not valid. Sending back a server error header in this case.
writer := formResponseHeader(&ResponseConfig{
Version: &Version{
Value: "1.1",
},
Status: &Status{
Code: "500",
Reason: "Internal Server Error",
},
Header: []*Header{
{
Name: "Connection",
Value: []string{"close"},
},
{
Name: "Cache-Control",
Value: []string{"private"},
},
{
Name: "Content-Length",
Value: []string{"0"},
},
},
})
writer.Write(v.Conn)
v.errorWriter.Write(v.Conn)
}
return v.Conn.Close()
@@ -248,14 +225,36 @@ func (v HttpAuthenticator) Client(conn net.Conn) net.Conn {
if v.config.Response != nil {
writer = v.GetClientWriter()
}
return NewHttpConn(conn, reader, writer, false)
return NewHttpConn(conn, reader, writer, new(NoOpWriter))
}
func (v HttpAuthenticator) Server(conn net.Conn) net.Conn {
if v.config.Request == nil && v.config.Response == nil {
return conn
}
return NewHttpConn(conn, new(HeaderReader), v.GetServerWriter(), true)
return NewHttpConn(conn, new(HeaderReader), v.GetServerWriter(), formResponseHeader(&ResponseConfig{
Version: &Version{
Value: "1.1",
},
Status: &Status{
Code: "500",
Reason: "Internal Server Error",
},
Header: []*Header{
{
Name: "Connection",
Value: []string{"close"},
},
{
Name: "Cache-Control",
Value: []string{"private"},
},
{
Name: "Content-Length",
Value: []string{"0"},
},
},
}))
}
type HttpAuthenticatorFactory struct{}

View File

@@ -1,16 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/transport/internet/headers/noop/config.proto
// DO NOT EDIT!
/*
Package noop is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/transport/internet/headers/noop/config.proto
It has these top-level messages:
Config
*/
package noop
import proto "github.com/golang/protobuf/proto"

View File

@@ -1,16 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/transport/internet/headers/srtp/config.proto
// DO NOT EDIT!
/*
Package srtp is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/transport/internet/headers/srtp/config.proto
It has these top-level messages:
Config
*/
package srtp
import proto "github.com/golang/protobuf/proto"

View File

@@ -1,16 +1,3 @@
// Code generated by protoc-gen-go.
// source: v2ray.com/core/transport/internet/headers/utp/config.proto
// DO NOT EDIT!
/*
Package utp is a generated protocol buffer package.
It is generated from these files:
v2ray.com/core/transport/internet/headers/utp/config.proto
It has these top-level messages:
Config
*/
package utp
import proto "github.com/golang/protobuf/proto"

View File

@@ -0,0 +1,47 @@
package wechat
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type VideoConfig struct {
}
func (m *VideoConfig) Reset() { *m = VideoConfig{} }
func (m *VideoConfig) String() string { return proto.CompactTextString(m) }
func (*VideoConfig) ProtoMessage() {}
func (*VideoConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func init() {
proto.RegisterType((*VideoConfig)(nil), "v2ray.core.transport.internet.headers.wechat.VideoConfig")
}
func init() {
proto.RegisterFile("v2ray.com/core/transport/internet/headers/wechat/config.proto", fileDescriptor0)
}
var fileDescriptor0 = []byte{
// 169 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xb2, 0x2d, 0x33, 0x2a, 0x4a,
0xac, 0xd4, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x2f, 0x29, 0x4a, 0xcc, 0x2b,
0x2e, 0xc8, 0x2f, 0x2a, 0xd1, 0xcf, 0xcc, 0x2b, 0x49, 0x2d, 0xca, 0x4b, 0x2d, 0xd1, 0xcf, 0x48,
0x4d, 0x4c, 0x49, 0x2d, 0x2a, 0xd6, 0x2f, 0x4f, 0x4d, 0xce, 0x48, 0x2c, 0xd1, 0x4f, 0xce, 0xcf,
0x4b, 0xcb, 0x4c, 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xd2, 0x81, 0x69, 0x2f, 0x4a, 0xd5,
0x83, 0x6b, 0xd5, 0x83, 0x69, 0xd5, 0x83, 0x6a, 0xd5, 0x83, 0x68, 0x55, 0xe2, 0xe5, 0xe2, 0x0e,
0xcb, 0x4c, 0x49, 0xcd, 0x77, 0x06, 0x1b, 0xe1, 0x54, 0xc6, 0x65, 0x90, 0x9c, 0x9f, 0xab, 0x47,
0x8a, 0x11, 0x4e, 0xdc, 0x10, 0xbd, 0x01, 0x20, 0xdb, 0xa3, 0xd8, 0x20, 0x82, 0xab, 0x98, 0x74,
0xc2, 0x8c, 0x82, 0x12, 0x2b, 0xf5, 0x9c, 0x41, 0x66, 0x84, 0xc0, 0xcd, 0xf0, 0x84, 0x99, 0xe1,
0x01, 0x35, 0x23, 0x1c, 0xac, 0x3c, 0x89, 0x0d, 0xec, 0x76, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff,
0xff, 0x9b, 0x6a, 0x0f, 0x19, 0xfc, 0x00, 0x00, 0x00,
}

View File

@@ -0,0 +1,10 @@
syntax = "proto3";
package v2ray.core.transport.internet.headers.wechat;
option csharp_namespace = "V2Ray.Core.Transport.Internet.Headers.Wechat";
option go_package = "wechat";
option java_package = "com.v2ray.core.transport.internet.headers.wechat";
option java_outer_classname = "ConfigProto";
message VideoConfig {
}

View File

@@ -0,0 +1,36 @@
package wechat
import (
"v2ray.com/core/common"
"v2ray.com/core/common/dice"
"v2ray.com/core/common/serial"
"v2ray.com/core/transport/internet"
)
type VideoChat struct {
sn int
}
func (vc *VideoChat) Size() int {
return 13
}
func (vc *VideoChat) Write(b []byte) (int, error) {
vc.sn++
b = append(b[:0], 0xa1, 0x08)
b = serial.IntToBytes(vc.sn, b)
b = append(b, 0x10, 0x11, 0x18, 0x30, 0x22, 0x30)
return 13, nil
}
type VideoChatFactory struct{}
func (VideoChatFactory) Create(rawSettings interface{}) internet.PacketHeader {
return &VideoChat{
sn: dice.Roll(65535),
}
}
func init() {
common.Must(internet.RegisterPacketHeader(serial.GetMessageType(new(VideoConfig)), VideoChatFactory{}))
}

View File

@@ -0,0 +1,20 @@
package wechat_test
import (
"testing"
"v2ray.com/core/common/buf"
"v2ray.com/core/testing/assert"
. "v2ray.com/core/transport/internet/headers/wechat"
)
func TestUTPWrite(t *testing.T) {
assert := assert.On(t)
video := VideoChat{}
payload := buf.NewLocal(2048)
payload.AppendSupplier(video.Write)
assert.Int(payload.Len()).Equals(video.Size())
}

Some files were not shown because too many files have changed in this diff Show More