You've already forked v2ray-core
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e35e271708 | ||
|
|
e678000c44 | ||
|
|
49210d8362 | ||
|
|
723207158f | ||
|
|
c4e2d99859 | ||
|
|
aefa53f827 | ||
|
|
588c43f291 | ||
|
|
21a15bbf74 | ||
|
|
31d6e74482 | ||
|
|
3732de18b1 | ||
|
|
ff01a886da | ||
|
|
c9a421fba6 | ||
|
|
6c39ce0714 | ||
|
|
1e5061f15e | ||
|
|
84978a501d | ||
|
|
72ae6b3bfd | ||
|
|
20fe6d10a4 | ||
|
|
7cbef6723c | ||
|
|
52e1dfaeac | ||
|
|
19e0cb40e9 | ||
|
|
5857aea881 | ||
|
|
48bddb25d7 | ||
|
|
4d6ca7efe0 |
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,3 @@ const (
|
||||
type PacketDispatcher interface {
|
||||
DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay
|
||||
}
|
||||
|
||||
type Inspector interface {
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Package proxyman defines applications for manageing inbound and outbound proxies.
|
||||
package proxyman
|
||||
|
||||
import (
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
126
common/crypto/internal/chacha_core.generated.go
Normal file
126
common/crypto/internal/chacha_core.generated.go
Normal 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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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\"")
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)}, " ")
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -10,7 +10,7 @@ enum Network {
|
||||
Unknown = 0;
|
||||
|
||||
// Native TCP provided by system.
|
||||
RawTCP = 1;
|
||||
RawTCP = 1 [deprecated=true];
|
||||
|
||||
// V2Ray specific TCP.
|
||||
TCP = 2;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
18
config.pb.go
18
config.pb.go
@@ -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"
|
||||
|
||||
2
core.go
2
core.go
@@ -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."
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -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},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ enum CipherType {
|
||||
AES_128_CFB = 1;
|
||||
AES_256_CFB = 2;
|
||||
CHACHA20 = 3;
|
||||
CHACHA20_IEFT = 4;
|
||||
CHACHA20_IETF = 4;
|
||||
}
|
||||
|
||||
message ServerConfig {
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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() {
|
||||
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
279
proxy/socks/protocol.go
Normal 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
|
||||
}
|
||||
@@ -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},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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"`
|
||||
|
||||
@@ -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()
|
||||
|
||||
7
tools/genproto/genproto.go
Normal file
7
tools/genproto/genproto.go
Normal 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
90
tools/genproto/main.go
Normal 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)
|
||||
}
|
||||
}
|
||||
2
tools/geoip/geoip.generated.go
Normal file
2
tools/geoip/geoip.generated.go
Normal file
File diff suppressed because one or more lines are too long
@@ -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
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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{}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
47
transport/internet/headers/wechat/config.pb.go
Normal file
47
transport/internet/headers/wechat/config.pb.go
Normal 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,
|
||||
}
|
||||
10
transport/internet/headers/wechat/config.proto
Normal file
10
transport/internet/headers/wechat/config.proto
Normal 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 {
|
||||
}
|
||||
36
transport/internet/headers/wechat/wechat.go
Normal file
36
transport/internet/headers/wechat/wechat.go
Normal 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{}))
|
||||
}
|
||||
20
transport/internet/headers/wechat/wechat_test.go
Normal file
20
transport/internet/headers/wechat/wechat_test.go
Normal 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
Reference in New Issue
Block a user