You've already forked v2ray-core
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b8e100879 | ||
|
|
57dc6c69f1 | ||
|
|
1d4b98ab9a | ||
|
|
8597642002 | ||
|
|
b6cebd127d | ||
|
|
3a6844f482 | ||
|
|
bd48556b98 | ||
|
|
2a6f4740c1 | ||
|
|
d34678d9a6 |
@@ -1,11 +1,6 @@
|
||||
package config
|
||||
|
||||
type RouterConfig interface {
|
||||
Strategy() string
|
||||
Settings() interface{}
|
||||
}
|
||||
|
||||
type ConnectionTag string
|
||||
type DetourTag string
|
||||
|
||||
type ConnectionConfig interface {
|
||||
Protocol() string
|
||||
@@ -27,6 +22,12 @@ type InboundDetourConfig interface {
|
||||
Settings() interface{}
|
||||
}
|
||||
|
||||
type OutboundDetourConfig interface {
|
||||
Protocol() string
|
||||
Tag() DetourTag
|
||||
Settings() interface{}
|
||||
}
|
||||
|
||||
type PointConfig interface {
|
||||
Port() uint16
|
||||
LogConfig() LogConfig
|
||||
|
||||
@@ -12,11 +12,12 @@ import (
|
||||
|
||||
// Config is the config for Point server.
|
||||
type Config struct {
|
||||
PortValue uint16 `json:"port"` // Port of this Point server.
|
||||
LogConfigValue *LogConfig `json:"log"`
|
||||
InboundConfigValue *ConnectionConfig `json:"inbound"`
|
||||
OutboundConfigValue *ConnectionConfig `json:"outbound"`
|
||||
InboundDetoursValue []*InboundDetourConfig `json:"inboundDetour"`
|
||||
PortValue uint16 `json:"port"` // Port of this Point server.
|
||||
LogConfigValue *LogConfig `json:"log"`
|
||||
InboundConfigValue *ConnectionConfig `json:"inbound"`
|
||||
OutboundConfigValue *ConnectionConfig `json:"outbound"`
|
||||
InboundDetoursValue []*InboundDetourConfig `json:"inboundDetour"`
|
||||
OutboundDetoursValue []*OutboundDetourConfig `json:"outboundDetour"`
|
||||
}
|
||||
|
||||
func (config *Config) Port() uint16 {
|
||||
@@ -52,6 +53,14 @@ func (this *Config) InboundDetours() []config.InboundDetourConfig {
|
||||
return detours
|
||||
}
|
||||
|
||||
func (this *Config) OutboundDetours() []config.OutboundDetourConfig {
|
||||
detours := make([]config.OutboundDetourConfig, len(this.OutboundDetoursValue))
|
||||
for idx, detour := range this.OutboundDetoursValue {
|
||||
detours[idx] = detour
|
||||
}
|
||||
return detours
|
||||
}
|
||||
|
||||
func LoadConfig(file string) (*Config, error) {
|
||||
fixedFile := os.ExpandEnv(file)
|
||||
rawConfig, err := ioutil.ReadFile(fixedFile)
|
||||
|
||||
26
app/point/config/json/outbound_detour.go
Normal file
26
app/point/config/json/outbound_detour.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/v2ray/v2ray-core/app/point/config"
|
||||
proxyconfig "github.com/v2ray/v2ray-core/proxy/common/config"
|
||||
)
|
||||
|
||||
type OutboundDetourConfig struct {
|
||||
ProtocolValue string `json:"protocol"`
|
||||
TagValue string `json:"tag"`
|
||||
SettingsValue json.RawMessage `json:"settings"`
|
||||
}
|
||||
|
||||
func (this *OutboundDetourConfig) Protocol() string {
|
||||
return this.ProtocolValue
|
||||
}
|
||||
|
||||
func (this *OutboundDetourConfig) Tag() config.DetourTag {
|
||||
return config.DetourTag(this.TagValue)
|
||||
}
|
||||
|
||||
func (this *OutboundDetourConfig) Settings() interface{} {
|
||||
return loadConnectionConfig(this.SettingsValue, this.ProtocolValue, proxyconfig.TypeOutbound)
|
||||
}
|
||||
6
app/router/config/config.go
Normal file
6
app/router/config/config.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package config
|
||||
|
||||
type RouterConfig interface {
|
||||
Strategy() string
|
||||
Settings() interface{}
|
||||
}
|
||||
25
app/router/config/json/cache.go
Normal file
25
app/router/config/json/cache.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package json
|
||||
|
||||
type ConfigObjectCreator func() interface{}
|
||||
|
||||
var (
|
||||
configCache map[string]ConfigObjectCreator
|
||||
)
|
||||
|
||||
func RegisterRouterConfig(strategy string, creator ConfigObjectCreator) error {
|
||||
// TODO: check strategy
|
||||
configCache[strategy] = creator
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateRouterConfig(strategy string) interface{} {
|
||||
creator, found := configCache[strategy]
|
||||
if !found {
|
||||
return nil
|
||||
}
|
||||
return creator()
|
||||
}
|
||||
|
||||
func init() {
|
||||
configCache = make(map[string]ConfigObjectCreator)
|
||||
}
|
||||
18
app/router/config/json/json.go
Normal file
18
app/router/config/json/json.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
type RouterConfig struct {
|
||||
StrategyValue string `json:"strategy"`
|
||||
SettingsValue json.RawMessage `json:"settings"`
|
||||
}
|
||||
|
||||
func (this *RouterConfig) Strategy() string {
|
||||
return this.StrategyValue
|
||||
}
|
||||
|
||||
func (this *RouterConfig) Settings() interface{} {
|
||||
return CreateRouterConfig(this.Strategy())
|
||||
}
|
||||
@@ -12,7 +12,7 @@ var (
|
||||
)
|
||||
|
||||
type Router interface {
|
||||
TakeDetour(v2net.Packet) (config.ConnectionTag, error)
|
||||
TakeDetour(v2net.Packet) (config.DetourTag, error)
|
||||
}
|
||||
|
||||
type RouterFactory interface {
|
||||
|
||||
1
app/router/rules/router.go
Normal file
1
app/router/rules/router.go
Normal file
@@ -0,0 +1 @@
|
||||
package rules
|
||||
@@ -1,25 +0,0 @@
|
||||
package wildcard_router
|
||||
|
||||
import (
|
||||
"github.com/v2ray/v2ray-core/app/point/config"
|
||||
"github.com/v2ray/v2ray-core/app/router"
|
||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||
)
|
||||
|
||||
type WildcardRouter struct {
|
||||
}
|
||||
|
||||
func (router *WildcardRouter) TakeDetour(packet v2net.Packet) (config.ConnectionTag, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
type WildcardRouterFactory struct {
|
||||
}
|
||||
|
||||
func (factory *WildcardRouterFactory) Create(rawConfig interface{}) (router.Router, error) {
|
||||
return &WildcardRouter{}, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
router.RegisterRouter("wildcard", &WildcardRouterFactory{})
|
||||
}
|
||||
@@ -35,15 +35,59 @@ func NewDokodemoDoor(dispatcher app.PacketDispatcher, config *json.DokodemoConfi
|
||||
}
|
||||
|
||||
func (this *DokodemoDoor) Listen(port uint16) error {
|
||||
this.accepting = true
|
||||
|
||||
if this.config.Network.HasNetwork(v2net.TCPNetwork) {
|
||||
err := this.ListenTCP(port)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if this.config.Network.HasNetwork(v2net.UDPNetwork) {
|
||||
err := this.ListenUDP(port)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *DokodemoDoor) ListenUDP(port uint16) error {
|
||||
udpConn, err := net.ListenUDP("udp", &net.UDPAddr{
|
||||
IP: []byte{0, 0, 0, 0},
|
||||
Port: int(port),
|
||||
Zone: "",
|
||||
})
|
||||
if err != nil {
|
||||
log.Error("Dokodemo failed to listen on port %d: %v", port, err)
|
||||
return err
|
||||
}
|
||||
go this.handleUDPPackets(udpConn)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *DokodemoDoor) handleUDPPackets(udpConn *net.UDPConn) {
|
||||
defer udpConn.Close()
|
||||
for this.accepting {
|
||||
buffer := alloc.NewBuffer()
|
||||
nBytes, addr, err := udpConn.ReadFromUDP(buffer.Value)
|
||||
buffer.Slice(0, nBytes)
|
||||
if err != nil {
|
||||
buffer.Release()
|
||||
log.Error("Dokodemo failed to read from UDP: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
packet := v2net.NewPacket(v2net.NewUDPDestination(this.address), buffer, false)
|
||||
ray := this.dispatcher.DispatchToOutbound(packet)
|
||||
close(ray.InboundInput())
|
||||
|
||||
for payload := range ray.InboundOutput() {
|
||||
udpConn.WriteToUDP(payload.Value, addr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *DokodemoDoor) ListenTCP(port uint16) error {
|
||||
tcpListener, err := net.ListenTCP("tcp", &net.TCPAddr{
|
||||
IP: []byte{0, 0, 0, 0},
|
||||
@@ -54,7 +98,6 @@ func (this *DokodemoDoor) ListenTCP(port uint16) error {
|
||||
log.Error("Dokodemo failed to listen on port %d: %v", port, err)
|
||||
return err
|
||||
}
|
||||
this.accepting = true
|
||||
go this.AcceptTCPConnections(tcpListener)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/v2ray/v2ray-core/proxy/dokodemo/config/json"
|
||||
_ "github.com/v2ray/v2ray-core/proxy/freedom"
|
||||
"github.com/v2ray/v2ray-core/testing/servers/tcp"
|
||||
"github.com/v2ray/v2ray-core/testing/servers/udp"
|
||||
"github.com/v2ray/v2ray-core/testing/unit"
|
||||
)
|
||||
|
||||
@@ -75,3 +76,64 @@ func TestDokodemoTCP(t *testing.T) {
|
||||
|
||||
assert.String("Processed: " + data2Send).Equals(string(response[:nBytes]))
|
||||
}
|
||||
|
||||
func TestDokodemoUDP(t *testing.T) {
|
||||
assert := unit.Assert(t)
|
||||
|
||||
port := v2nettesting.PickPort()
|
||||
|
||||
data2Send := "Data to be sent to remote."
|
||||
|
||||
udpServer := &udp.Server{
|
||||
Port: port,
|
||||
MsgProcessor: func(data []byte) []byte {
|
||||
buffer := make([]byte, 0, 2048)
|
||||
buffer = append(buffer, []byte("Processed: ")...)
|
||||
buffer = append(buffer, data...)
|
||||
return buffer
|
||||
},
|
||||
}
|
||||
_, err := udpServer.Start()
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
pointPort := v2nettesting.PickPort()
|
||||
networkList := v2netjson.NetworkList([]string{"udp"})
|
||||
config := mocks.Config{
|
||||
PortValue: pointPort,
|
||||
InboundConfigValue: &mocks.ConnectionConfig{
|
||||
ProtocolValue: "dokodemo-door",
|
||||
SettingsValue: &json.DokodemoConfig{
|
||||
Host: "127.0.0.1",
|
||||
Port: int(port),
|
||||
Network: &networkList,
|
||||
Timeout: 0,
|
||||
},
|
||||
},
|
||||
OutboundConfigValue: &mocks.ConnectionConfig{
|
||||
ProtocolValue: "freedom",
|
||||
SettingsValue: nil,
|
||||
},
|
||||
}
|
||||
|
||||
point, err := point.NewPoint(&config)
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
err = point.Start()
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
udpClient, err := net.DialUDP("udp", nil, &net.UDPAddr{
|
||||
IP: []byte{127, 0, 0, 1},
|
||||
Port: int(pointPort),
|
||||
Zone: "",
|
||||
})
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
udpClient.Write([]byte(data2Send))
|
||||
|
||||
response := make([]byte, 1024)
|
||||
nBytes, err := udpClient.Read(response)
|
||||
assert.Error(err).IsNil()
|
||||
udpClient.Close()
|
||||
|
||||
assert.String("Processed: " + data2Send).Equals(string(response[:nBytes]))
|
||||
}
|
||||
|
||||
35
proxy/socks/protocol/socks_fuzz_test.go
Normal file
35
proxy/socks/protocol/socks_fuzz_test.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/v2ray/v2ray-core/testing/fuzzing"
|
||||
)
|
||||
|
||||
const (
|
||||
Iterations = int(500000)
|
||||
)
|
||||
|
||||
func TestReadAuthentication(t *testing.T) {
|
||||
for i := 0; i < Iterations; i++ {
|
||||
ReadAuthentication(fuzzing.RandomReader())
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadUserPassRequest(t *testing.T) {
|
||||
for i := 0; i < Iterations; i++ {
|
||||
ReadUserPassRequest(fuzzing.RandomReader())
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadRequest(t *testing.T) {
|
||||
for i := 0; i < Iterations; i++ {
|
||||
ReadRequest(fuzzing.RandomReader())
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadUDPRequest(t *testing.T) {
|
||||
for i := 0; i < Iterations; i++ {
|
||||
ReadUDPRequest(fuzzing.RandomBytes())
|
||||
}
|
||||
}
|
||||
75
proxy/vmess/protocol/io/validation.go
Normal file
75
proxy/vmess/protocol/io/validation.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package io
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"hash/fnv"
|
||||
"io"
|
||||
|
||||
"github.com/v2ray/v2ray-core/common/alloc"
|
||||
"github.com/v2ray/v2ray-core/transport"
|
||||
)
|
||||
|
||||
var (
|
||||
TruncatedPayload = errors.New("Truncated payload.")
|
||||
)
|
||||
|
||||
type ValidationReader struct {
|
||||
reader io.Reader
|
||||
buffer *alloc.Buffer
|
||||
}
|
||||
|
||||
func NewValidationReader(reader io.Reader) *ValidationReader {
|
||||
return &ValidationReader{
|
||||
reader: reader,
|
||||
buffer: alloc.NewLargeBuffer().Clear(),
|
||||
}
|
||||
}
|
||||
|
||||
func (this *ValidationReader) Read(data []byte) (int, error) {
|
||||
nBytes, err := this.reader.Read(data)
|
||||
if err != nil {
|
||||
return nBytes, err
|
||||
}
|
||||
nBytesActual := 0
|
||||
dataActual := data[:]
|
||||
for {
|
||||
payload, rest, err := parsePayload(data)
|
||||
if err != nil {
|
||||
return nBytesActual, err
|
||||
}
|
||||
copy(dataActual, payload)
|
||||
nBytesActual += len(payload)
|
||||
dataActual = dataActual[nBytesActual:]
|
||||
if len(rest) == 0 {
|
||||
break
|
||||
}
|
||||
data = rest
|
||||
}
|
||||
return nBytesActual, nil
|
||||
}
|
||||
|
||||
func parsePayload(data []byte) (payload []byte, rest []byte, err error) {
|
||||
dataLen := len(data)
|
||||
if dataLen < 6 {
|
||||
err = TruncatedPayload
|
||||
return
|
||||
}
|
||||
payloadLen := int(data[0])<<8 + int(data[1])
|
||||
if dataLen < payloadLen+6 {
|
||||
err = TruncatedPayload
|
||||
return
|
||||
}
|
||||
|
||||
payload = data[6 : 6+payloadLen]
|
||||
rest = data[6+payloadLen:]
|
||||
|
||||
fnv1a := fnv.New32a()
|
||||
fnv1a.Write(payload)
|
||||
actualHash := fnv1a.Sum32()
|
||||
expectedHash := uint32(data[2])<<24 + uint32(data[3])<<16 + uint32(data[4])<<8 + uint32(data[5])
|
||||
if actualHash != expectedHash {
|
||||
err = transport.CorruptedPacket
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
29
proxy/vmess/protocol/user/testing/mocks/static_userset.go
Normal file
29
proxy/vmess/protocol/user/testing/mocks/static_userset.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package mocks
|
||||
|
||||
import (
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/config"
|
||||
)
|
||||
|
||||
type StaticUser struct {
|
||||
id *config.ID
|
||||
}
|
||||
|
||||
func (this *StaticUser) ID() *config.ID {
|
||||
return this.id
|
||||
}
|
||||
|
||||
func (this *StaticUser) Level() config.UserLevel {
|
||||
return config.UserLevelUntrusted
|
||||
}
|
||||
|
||||
type StaticUserSet struct {
|
||||
}
|
||||
|
||||
func (us *StaticUserSet) AddUser(user config.User) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (us *StaticUserSet) GetUser(userhash []byte) (config.User, int64, bool) {
|
||||
id, _ := config.NewID("703e9102-eb57-499c-8b59-faf4f371bb21")
|
||||
return &StaticUser{id: id}, 0, true
|
||||
}
|
||||
15
proxy/vmess/protocol/vmess_fuzz_test.go
Normal file
15
proxy/vmess/protocol/vmess_fuzz_test.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/protocol/user/testing/mocks"
|
||||
"github.com/v2ray/v2ray-core/testing/fuzzing"
|
||||
)
|
||||
|
||||
func TestVMessRequestReader(t *testing.T) {
|
||||
reader := NewVMessRequestReader(&mocks.StaticUserSet{})
|
||||
for i := 0; i < 1000000; i++ {
|
||||
reader.Read(fuzzing.RandomReader())
|
||||
}
|
||||
}
|
||||
17
testing/fuzzing/fuzzing.go
Normal file
17
testing/fuzzing/fuzzing.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package fuzzing
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
)
|
||||
|
||||
func RandomBytes() []byte {
|
||||
buffer := make([]byte, 256)
|
||||
rand.Read(buffer)
|
||||
return buffer[1 : 1+int(buffer[0])]
|
||||
}
|
||||
|
||||
func RandomReader() io.Reader {
|
||||
return bytes.NewReader(RandomBytes())
|
||||
}
|
||||
Reference in New Issue
Block a user