From b38137bd137103d43d932744687b0764f7596c73 Mon Sep 17 00:00:00 2001 From: v2ray Date: Mon, 8 Aug 2016 21:23:07 +0200 Subject: [PATCH 01/19] utp header --- shell/point/main/main.go | 1 + transport/internet/authenticators/utp/utp.go | 46 +++++++++++++++++++ .../internet/authenticators/utp/utp_test.go | 21 +++++++++ 3 files changed, 68 insertions(+) create mode 100644 transport/internet/authenticators/utp/utp.go create mode 100644 transport/internet/authenticators/utp/utp_test.go diff --git a/shell/point/main/main.go b/shell/point/main/main.go index eaf5160f8..d5a29dbbe 100644 --- a/shell/point/main/main.go +++ b/shell/point/main/main.go @@ -28,6 +28,7 @@ import ( _ "github.com/v2ray/v2ray-core/transport/internet/authenticators/noop" _ "github.com/v2ray/v2ray-core/transport/internet/authenticators/srtp" + _ "github.com/v2ray/v2ray-core/transport/internet/authenticators/utp" ) var ( diff --git a/transport/internet/authenticators/utp/utp.go b/transport/internet/authenticators/utp/utp.go new file mode 100644 index 000000000..761e3a05d --- /dev/null +++ b/transport/internet/authenticators/utp/utp.go @@ -0,0 +1,46 @@ +package utp + +import ( + "math/rand" + + "github.com/v2ray/v2ray-core/common/alloc" + "github.com/v2ray/v2ray-core/transport/internet" +) + +type Config struct { + Version byte +} + +type UTP struct { + header byte + extension byte + connectionId uint16 +} + +func (this *UTP) Overhead() int { + return 4 +} + +func (this *UTP) Open(payload *alloc.Buffer) bool { + payload.SliceFrom(this.Overhead()) + return true +} + +func (this *UTP) Seal(payload *alloc.Buffer) { + payload.PrependUint16(this.connectionId) + payload.PrependBytes(this.header, this.extension) +} + +type UTPFactory struct{} + +func (this UTPFactory) Create(rawSettings internet.AuthenticatorConfig) internet.Authenticator { + return &UTP{ + header: 1, + extension: 0, + connectionId: uint16(rand.Intn(65536)), + } +} + +func init() { + internet.RegisterAuthenticator("utp", UTPFactory{}, func() interface{} { return new(Config) }) +} diff --git a/transport/internet/authenticators/utp/utp_test.go b/transport/internet/authenticators/utp/utp_test.go new file mode 100644 index 000000000..effc469d7 --- /dev/null +++ b/transport/internet/authenticators/utp/utp_test.go @@ -0,0 +1,21 @@ +package utp_test + +import ( + "testing" + + "github.com/v2ray/v2ray-core/common/alloc" + "github.com/v2ray/v2ray-core/testing/assert" + . "github.com/v2ray/v2ray-core/transport/internet/authenticators/utp" +) + +func TestUTPOpenSeal(t *testing.T) { + assert := assert.On(t) + + content := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g'} + payload := alloc.NewLocalBuffer(2048).Clear().Append(content) + utp := UTP{} + utp.Seal(payload) + assert.Int(payload.Len()).GreaterThan(len(content)) + assert.Bool(utp.Open(payload)).IsTrue() + assert.Bytes(content).Equals(payload.Bytes()) +} From b01a9720763981c0935720284cacd8b4697b5efa Mon Sep 17 00:00:00 2001 From: v2ray Date: Mon, 8 Aug 2016 22:47:59 +0200 Subject: [PATCH 02/19] test for all authenticators --- transport/internet/authenticator.go | 2 +- transport/internet/authenticator_test.go | 27 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 transport/internet/authenticator_test.go diff --git a/transport/internet/authenticator.go b/transport/internet/authenticator.go index b6eea637e..820aa4b33 100644 --- a/transport/internet/authenticator.go +++ b/transport/internet/authenticator.go @@ -41,7 +41,7 @@ func CreateAuthenticator(name string, config AuthenticatorConfig) (Authenticator if !found { return nil, ErrAuthenticatorNotFound } - return factory.Create(config.(AuthenticatorConfig)), nil + return factory.Create(config), nil } func CreateAuthenticatorConfig(rawConfig []byte) (string, AuthenticatorConfig, error) { diff --git a/transport/internet/authenticator_test.go b/transport/internet/authenticator_test.go new file mode 100644 index 000000000..ce8d08716 --- /dev/null +++ b/transport/internet/authenticator_test.go @@ -0,0 +1,27 @@ +package internet_test + +import ( + "testing" + + "github.com/v2ray/v2ray-core/testing/assert" + . "github.com/v2ray/v2ray-core/transport/internet" + _ "github.com/v2ray/v2ray-core/transport/internet/authenticators/noop" + _ "github.com/v2ray/v2ray-core/transport/internet/authenticators/srtp" + _ "github.com/v2ray/v2ray-core/transport/internet/authenticators/utp" +) + +func TestAllAuthenticatorLoadable(t *testing.T) { + assert := assert.On(t) + + noopAuth, err := CreateAuthenticator("none", nil) + assert.Error(err).IsNil() + assert.Int(noopAuth.Overhead()).Equals(0) + + srtp, err := CreateAuthenticator("srtp", nil) + assert.Error(err).IsNil() + assert.Int(srtp.Overhead()).Equals(4) + + utp, err := CreateAuthenticator("utp", nil) + assert.Error(err).IsNil() + assert.Int(utp.Overhead()).Equals(4) +} From dbf5f948cd3f8ee2ee21fd62485d4b6330f5a236 Mon Sep 17 00:00:00 2001 From: v2ray Date: Mon, 8 Aug 2016 22:54:44 +0200 Subject: [PATCH 03/19] remove unused dependency in travis config --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9f6a5537a..e0f4f600a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,11 +3,6 @@ language: go go: - 1.6.3 -before_install: - - go get golang.org/x/tools/cmd/cover - - go get github.com/onsi/gomega - - go get github.com/onsi/ginkgo - script: - go test -tags json github.com/v2ray/v2ray-core/... From c6ad190f0af2c24baac1d88f3ee716433c9a656f Mon Sep 17 00:00:00 2001 From: v2ray Date: Mon, 8 Aug 2016 23:53:07 +0200 Subject: [PATCH 04/19] add json tag --- proxy/blackhole/config_json_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proxy/blackhole/config_json_test.go b/proxy/blackhole/config_json_test.go index a61537eaa..b9094a940 100644 --- a/proxy/blackhole/config_json_test.go +++ b/proxy/blackhole/config_json_test.go @@ -1,3 +1,5 @@ +// +build json + package blackhole_test import ( From 697d44abbdac1ac8822a9aa8abec64139bf40525 Mon Sep 17 00:00:00 2001 From: v2ray Date: Tue, 9 Aug 2016 00:55:36 +0200 Subject: [PATCH 05/19] bring back all coverage --- shell/point/main/main_test.go | 11 +++++++++ testing/coverage/coverall | 2 +- testing/scenarios/server_env.go | 15 +++++------- testing/scenarios/server_env_coverage.go | 29 ++++++++++++++++++++++++ testing/scenarios/server_env_regular.go | 29 ++++++++++++++++++++++++ 5 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 shell/point/main/main_test.go create mode 100644 testing/scenarios/server_env_coverage.go create mode 100644 testing/scenarios/server_env_regular.go diff --git a/shell/point/main/main_test.go b/shell/point/main/main_test.go new file mode 100644 index 000000000..63c18234e --- /dev/null +++ b/shell/point/main/main_test.go @@ -0,0 +1,11 @@ +// +build coveragemain + +package main + +import ( + "testing" +) + +func TestRunMainForCoverage(t *testing.T) { + main() +} diff --git a/testing/coverage/coverall b/testing/coverage/coverall index 87fc15624..5aa3823e2 100755 --- a/testing/coverage/coverall +++ b/testing/coverage/coverall @@ -7,7 +7,7 @@ function test_package { DIR="github.com/v2ray/v2ray-core/$1" DEP=$(go list -f '{{ join .Deps "\n" }}' $DIR | grep v2ray | tr '\n' ',') DEP=${DEP}$DIR - go test -tags json -coverprofile=coversingle.out -coverpkg=$DEP $DIR || FAIL=1 + go test -tags "json coverage" -coverprofile=coversingle.out -coverpkg=$DEP $DIR || FAIL=1 if [ -f coversingle.out ]; then cat coversingle.out | grep -v "mode: set" >> ${COVERAGE_FILE} rm coversingle.out diff --git a/testing/scenarios/server_env.go b/testing/scenarios/server_env.go index 7e49112bc..541d387d3 100644 --- a/testing/scenarios/server_env.go +++ b/testing/scenarios/server_env.go @@ -28,11 +28,11 @@ var ( binaryPath string ) -func BuildV2Ray() error { - if len(binaryPath) > 0 { - return nil - } +func GetSourcePath() string { + return filepath.Join("github.com", "v2ray", "v2ray-core", "shell", "point", "main") +} +func FillBinaryPath() error { dir, err := ioutil.TempDir("", "v2ray") if err != nil { return err @@ -41,8 +41,7 @@ func BuildV2Ray() error { if runtime.GOOS == "windows" { binaryPath += ".exe" } - cmd := exec.Command("go", "build", "-tags=json", "-o="+binaryPath, filepath.Join("github.com", "v2ray", "v2ray-core", "shell", "point", "main")) - return cmd.Run() + return nil } func TestFile(filename string) string { @@ -73,9 +72,7 @@ func InitializeServer(configFile string) error { return err } - proc := exec.Command(binaryPath, "-config="+configFile) - proc.Stderr = os.Stderr - proc.Stdout = os.Stdout + proc := RunV2Ray(configFile) err = proc.Start() if err != nil { diff --git a/testing/scenarios/server_env_coverage.go b/testing/scenarios/server_env_coverage.go new file mode 100644 index 000000000..ae46fcb14 --- /dev/null +++ b/testing/scenarios/server_env_coverage.go @@ -0,0 +1,29 @@ +// +build coverage + +package scenarios + +import ( + "os" + "os/exec" +) + +func BuildV2Ray() error { + if _, err := os.Stat(binaryPath); err == nil { + return nil + } + + if err := FillBinaryPath(); err != nil { + return err + } + + cmd := exec.Command("go", "test", "-tags", "json coverage coveragemain", "-coverpkg", "github.com/v2ray/v2ray-core/...", "-c", "-o", binaryPath, GetSourcePath()) + return cmd.Run() +} + +func RunV2Ray(configFile string) *exec.Cmd { + proc := exec.Command(binaryPath, "-config="+configFile, "-test.run=TestRunMainForCoverage", "-test.coverprofile=coversingle.out") + proc.Stderr = os.Stderr + proc.Stdout = os.Stdout + + return proc +} diff --git a/testing/scenarios/server_env_regular.go b/testing/scenarios/server_env_regular.go new file mode 100644 index 000000000..3ecfc5286 --- /dev/null +++ b/testing/scenarios/server_env_regular.go @@ -0,0 +1,29 @@ +// +build !coverage + +package scenarios + +import ( + "os" + "os/exec" +) + +func BuildV2Ray() error { + if _, err := os.Stat(binaryPath); err == nil { + return nil + } + + if err := FillBinaryPath(); err != nil { + return err + } + + cmd := exec.Command("go", "build", "-tags=json", "-o="+binaryPath, GetSourcePath()) + return cmd.Run() +} + +func RunV2Ray(configFile string) *exec.Cmd { + proc := exec.Command(binaryPath, "-config="+configFile) + proc.Stderr = os.Stderr + proc.Stdout = os.Stdout + + return proc +} From 27f3401848b89b312ec8a3628f2174ada2b484b8 Mon Sep 17 00:00:00 2001 From: v2ray Date: Tue, 9 Aug 2016 01:16:29 +0200 Subject: [PATCH 06/19] update coverage profile location --- testing/scenarios/server_env_coverage.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/testing/scenarios/server_env_coverage.go b/testing/scenarios/server_env_coverage.go index ae46fcb14..2c69d3dd2 100644 --- a/testing/scenarios/server_env_coverage.go +++ b/testing/scenarios/server_env_coverage.go @@ -5,6 +5,7 @@ package scenarios import ( "os" "os/exec" + "path/filepath" ) func BuildV2Ray() error { @@ -21,7 +22,12 @@ func BuildV2Ray() error { } func RunV2Ray(configFile string) *exec.Cmd { - proc := exec.Command(binaryPath, "-config="+configFile, "-test.run=TestRunMainForCoverage", "-test.coverprofile=coversingle.out") + profile := "coversingle.out" + wd, err := os.Getwd() + if err != nil { + profile = filepath.Join(wd, profile) + } + proc := exec.Command(binaryPath, "-config", configFile, "-test.run", "TestRunMainForCoverage", "-test.coverprofile", profile) proc.Stderr = os.Stderr proc.Stdout = os.Stdout From 0b2df7f658df48d6d2f7c85199f9433fdba0090d Mon Sep 17 00:00:00 2001 From: v2ray Date: Tue, 9 Aug 2016 01:16:45 +0200 Subject: [PATCH 07/19] typo --- testing/scenarios/server_env_coverage.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/scenarios/server_env_coverage.go b/testing/scenarios/server_env_coverage.go index 2c69d3dd2..e923ce5a5 100644 --- a/testing/scenarios/server_env_coverage.go +++ b/testing/scenarios/server_env_coverage.go @@ -24,7 +24,7 @@ func BuildV2Ray() error { func RunV2Ray(configFile string) *exec.Cmd { profile := "coversingle.out" wd, err := os.Getwd() - if err != nil { + if err == nil { profile = filepath.Join(wd, profile) } proc := exec.Command(binaryPath, "-config", configFile, "-test.run", "TestRunMainForCoverage", "-test.coverprofile", profile) From 5dc80a2cc50ee5de20d462e199e9b52141149158 Mon Sep 17 00:00:00 2001 From: v2ray Date: Tue, 9 Aug 2016 22:10:44 +0200 Subject: [PATCH 08/19] capture sigterm --- shell/point/main/main.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/point/main/main.go b/shell/point/main/main.go index d5a29dbbe..c9f26738e 100644 --- a/shell/point/main/main.go +++ b/shell/point/main/main.go @@ -6,6 +6,7 @@ import ( "os" "os/signal" "path/filepath" + "syscall" "github.com/v2ray/v2ray-core" _ "github.com/v2ray/v2ray-core/app/router/rules" @@ -107,7 +108,7 @@ func main() { if point := startV2Ray(); point != nil { osSignals := make(chan os.Signal, 1) - signal.Notify(osSignals, os.Interrupt, os.Kill) + signal.Notify(osSignals, os.Interrupt, os.Kill, syscall.SIGTERM) <-osSignals point.Close() From 25b30704a45a29da92bf2c4840a29ddf89c77fe0 Mon Sep 17 00:00:00 2001 From: v2ray Date: Tue, 9 Aug 2016 22:13:16 +0200 Subject: [PATCH 09/19] update coverage --- testing/coverage/coverall | 28 ++++++++++++++---------- testing/scenarios/server_env.go | 26 +++++++++------------- testing/scenarios/server_env_coverage.go | 18 +++++++-------- testing/scenarios/server_env_regular.go | 8 +++---- 4 files changed, 38 insertions(+), 42 deletions(-) diff --git a/testing/coverage/coverall b/testing/coverage/coverall index 5aa3823e2..7d0457308 100755 --- a/testing/coverage/coverall +++ b/testing/coverage/coverall @@ -1,19 +1,22 @@ #!/bin/bash FAIL=0 -COVERAGE_FILE=coverage.txt + +V2RAY_OUT=${GOPATH}/out/v2ray +V2RAY_COV=${V2RAY_OUT}/cov +COVERAGE_FILE=${V2RAY_COV}/coverage.txt function test_package { DIR="github.com/v2ray/v2ray-core/$1" DEP=$(go list -f '{{ join .Deps "\n" }}' $DIR | grep v2ray | tr '\n' ',') DEP=${DEP}$DIR - go test -tags "json coverage" -coverprofile=coversingle.out -coverpkg=$DEP $DIR || FAIL=1 - if [ -f coversingle.out ]; then - cat coversingle.out | grep -v "mode: set" >> ${COVERAGE_FILE} - rm coversingle.out - fi + RND_NAME=$(openssl rand -hex 16) + COV_PROFILE=${V2RAY_COV}/${RND_NAME}.out + go test -tags "json coverage" -coverprofile=${COV_PROFILE} -coverpkg=$DEP $DIR || FAIL=1 } +rm -rf ${V2RAY_OUT} +mkdir -p ${V2RAY_COV} touch ${COVERAGE_FILE} TEST_FILES=(./*_test.go) @@ -28,14 +31,17 @@ for DIR in $(find * -type d -not -path "*.git*"); do fi done -cat ${COVERAGE_FILE} | sort -t: -k1 | grep -vw "testing" > coverallsorted.out -echo "mode: set" | cat - coverallsorted.out > ${COVERAGE_FILE} -rm coverallsorted.out +for OUT_FILE in $(find ${V2RAY_COV} -name "*.out"); do + echo "Merging file ${OUT_FILE}" + cat ${OUT_FILE} | grep -v "mode: set" >> ${COVERAGE_FILE} +done + +COV_SORTED=${V2RAY_COV}/coverallsorted.out +cat ${COVERAGE_FILE} | sort -t: -k1 | grep -vw "testing" > ${COV_SORTED} +echo "mode: set" | cat - ${COV_SORTED} > ${COVERAGE_FILE} if [ "$FAIL" -eq 0 ]; then bash <(curl -s https://codecov.io/bash) -f ${COVERAGE_FILE} || echo "Codecov did not collect coverage reports." fi -rm -f ${COVERAGE_FILE} - exit $FAIL diff --git a/testing/scenarios/server_env.go b/testing/scenarios/server_env.go index 541d387d3..d548aaba2 100644 --- a/testing/scenarios/server_env.go +++ b/testing/scenarios/server_env.go @@ -1,7 +1,6 @@ package scenarios import ( - "io/ioutil" "os" "os/exec" "path/filepath" @@ -24,26 +23,20 @@ import ( var ( runningServers = make([]*exec.Cmd, 0, 10) - - binaryPath string ) +func GetTestBinaryPath() string { + file := filepath.Join(os.Getenv("GOPATH"), "out", "v2ray", "v2ray.test") + if runtime.GOOS == "windows" { + file += ".exe" + } + return file +} + func GetSourcePath() string { return filepath.Join("github.com", "v2ray", "v2ray-core", "shell", "point", "main") } -func FillBinaryPath() error { - dir, err := ioutil.TempDir("", "v2ray") - if err != nil { - return err - } - binaryPath = filepath.Join(dir, "v2ray") - if runtime.GOOS == "windows" { - binaryPath += ".exe" - } - return nil -} - func TestFile(filename string) string { return filepath.Join(os.Getenv("GOPATH"), "src", "github.com", "v2ray", "v2ray-core", "testing", "scenarios", "data", filename) } @@ -89,7 +82,8 @@ func InitializeServer(configFile string) error { func CloseAllServers() { log.Info("Closing all servers.") for _, server := range runningServers { - server.Process.Kill() + server.Process.Signal(os.Interrupt) + server.Process.Wait() } runningServers = make([]*exec.Cmd, 0, 10) log.Info("All server closed.") diff --git a/testing/scenarios/server_env_coverage.go b/testing/scenarios/server_env_coverage.go index e923ce5a5..ffce2113d 100644 --- a/testing/scenarios/server_env_coverage.go +++ b/testing/scenarios/server_env_coverage.go @@ -6,28 +6,26 @@ import ( "os" "os/exec" "path/filepath" + + "github.com/v2ray/v2ray-core/common/uuid" ) func BuildV2Ray() error { + binaryPath := GetTestBinaryPath() if _, err := os.Stat(binaryPath); err == nil { return nil } - if err := FillBinaryPath(); err != nil { - return err - } - cmd := exec.Command("go", "test", "-tags", "json coverage coveragemain", "-coverpkg", "github.com/v2ray/v2ray-core/...", "-c", "-o", binaryPath, GetSourcePath()) return cmd.Run() } func RunV2Ray(configFile string) *exec.Cmd { - profile := "coversingle.out" - wd, err := os.Getwd() - if err == nil { - profile = filepath.Join(wd, profile) - } - proc := exec.Command(binaryPath, "-config", configFile, "-test.run", "TestRunMainForCoverage", "-test.coverprofile", profile) + binaryPath := GetTestBinaryPath() + + covDir := filepath.Join(os.Getenv("GOPATH"), "out", "v2ray", "cov") + profile := uuid.New().String() + ".out" + proc := exec.Command(binaryPath, "-config", configFile, "-test.run", "TestRunMainForCoverage", "-test.coverprofile", profile, "-test.outputdir", covDir) proc.Stderr = os.Stderr proc.Stdout = os.Stdout diff --git a/testing/scenarios/server_env_regular.go b/testing/scenarios/server_env_regular.go index 3ecfc5286..307bb93ec 100644 --- a/testing/scenarios/server_env_regular.go +++ b/testing/scenarios/server_env_regular.go @@ -8,20 +8,18 @@ import ( ) func BuildV2Ray() error { + binaryPath := GetTestBinaryPath() if _, err := os.Stat(binaryPath); err == nil { return nil } - if err := FillBinaryPath(); err != nil { - return err - } - cmd := exec.Command("go", "build", "-tags=json", "-o="+binaryPath, GetSourcePath()) return cmd.Run() } func RunV2Ray(configFile string) *exec.Cmd { - proc := exec.Command(binaryPath, "-config="+configFile) + binaryPath := GetTestBinaryPath() + proc := exec.Command(binaryPath, "-config", configFile) proc.Stderr = os.Stderr proc.Stdout = os.Stdout From 9e997a5be73cbedc2b836eb61809cbf64c146884 Mon Sep 17 00:00:00 2001 From: v2ray Date: Tue, 9 Aug 2016 23:17:02 +0200 Subject: [PATCH 10/19] typo --- proxy/vmess/outbound/outbound.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proxy/vmess/outbound/outbound.go b/proxy/vmess/outbound/outbound.go index bcdc6b124..16aef5a87 100644 --- a/proxy/vmess/outbound/outbound.go +++ b/proxy/vmess/outbound/outbound.go @@ -46,7 +46,7 @@ func (this *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *al log.Error("VMess|Outbound: Failed to find an available destination:", err) return err } - log.Info("VMess|Outbound: Tunneling request to ", target, " via ", rec.Destination) + log.Info("VMess|Outbound: Tunneling request to ", target, " via ", rec.Destination()) command := protocol.RequestCommandTCP if target.IsUDP() { From f03c86f4689c095dc49bf116bfe8388538109275 Mon Sep 17 00:00:00 2001 From: v2ray Date: Thu, 11 Aug 2016 23:21:23 +0200 Subject: [PATCH 11/19] global session cache --- transport/internet/connection.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/transport/internet/connection.go b/transport/internet/connection.go index 61435cbdf..4a88bcabe 100644 --- a/transport/internet/connection.go +++ b/transport/internet/connection.go @@ -27,6 +27,10 @@ const ( StreamSecurityTypeTLS StreamSecurityType = 1 ) +var ( + globalSessionCache = tls.NewLRUClientSessionCache(128) +) + type TLSSettings struct { AllowInsecure bool Certs []tls.Certificate @@ -35,6 +39,7 @@ type TLSSettings struct { func (this *TLSSettings) GetTLSConfig() *tls.Config { config := &tls.Config{ InsecureSkipVerify: this.AllowInsecure, + ClientSessionCache: globalSessionCache, } config.Certificates = this.Certs From a43ee2f1c219426f685bfea8c14a59218abd621f Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Fri, 12 Aug 2016 17:08:07 +0200 Subject: [PATCH 12/19] Update .travis.yml --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index e0f4f600a..e47626bc8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,9 @@ language: go go: - 1.6.3 + +git: + depth: 5 script: - go test -tags json github.com/v2ray/v2ray-core/... From bcd27ba36fa42ec8863b84452c8f25407c051352 Mon Sep 17 00:00:00 2001 From: v2ray Date: Fri, 12 Aug 2016 23:37:21 +0200 Subject: [PATCH 13/19] option to allow passive connection --- app/dispatcher/dispatcher.go | 3 ++- app/dispatcher/impl/default.go | 9 +++++++-- app/dispatcher/testing/dispatcher.go | 3 ++- app/dns/nameserver.go | 9 ++++++--- proxy/dokodemo/dokodemo.go | 4 ++-- proxy/http/server.go | 4 ++-- proxy/proxy.go | 9 +++++---- proxy/shadowsocks/server.go | 4 ++-- proxy/socks/server.go | 2 +- proxy/socks/server_udp.go | 2 +- proxy/testing/mocks/inboundhandler.go | 5 ++++- proxy/vmess/inbound/inbound.go | 2 +- shell/point/config.go | 26 ++++++++++++++------------ shell/point/config_json.go | 4 ++++ shell/point/inbound_detour_always.go | 10 ++++++---- shell/point/inbound_detour_dynamic.go | 10 ++++++---- shell/point/point.go | 10 ++++++---- transport/internet/udp/udp_server.go | 7 +++++-- 18 files changed, 76 insertions(+), 47 deletions(-) diff --git a/app/dispatcher/dispatcher.go b/app/dispatcher/dispatcher.go index a8902a3db..0447b6a35 100644 --- a/app/dispatcher/dispatcher.go +++ b/app/dispatcher/dispatcher.go @@ -3,6 +3,7 @@ package dispatcher import ( "github.com/v2ray/v2ray-core/app" v2net "github.com/v2ray/v2ray-core/common/net" + "github.com/v2ray/v2ray-core/proxy" "github.com/v2ray/v2ray-core/transport/ray" ) @@ -12,5 +13,5 @@ const ( // PacketDispatcher dispatch a packet and possibly further network payload to its destination. type PacketDispatcher interface { - DispatchToOutbound(destination v2net.Destination) ray.InboundRay + DispatchToOutbound(meta *proxy.InboundHandlerMeta, destination v2net.Destination) ray.InboundRay } diff --git a/app/dispatcher/impl/default.go b/app/dispatcher/impl/default.go index 0643cdc2f..cc823d5d6 100644 --- a/app/dispatcher/impl/default.go +++ b/app/dispatcher/impl/default.go @@ -4,6 +4,7 @@ import ( "github.com/v2ray/v2ray-core/app" "github.com/v2ray/v2ray-core/app/proxyman" "github.com/v2ray/v2ray-core/app/router" + "github.com/v2ray/v2ray-core/common/alloc" "github.com/v2ray/v2ray-core/common/log" v2net "github.com/v2ray/v2ray-core/common/net" "github.com/v2ray/v2ray-core/proxy" @@ -42,7 +43,7 @@ func (this *DefaultDispatcher) Release() { } -func (this *DefaultDispatcher) DispatchToOutbound(destination v2net.Destination) ray.InboundRay { +func (this *DefaultDispatcher) DispatchToOutbound(meta *proxy.InboundHandlerMeta, destination v2net.Destination) ray.InboundRay { direct := ray.NewRay() dispatcher := this.ohm.GetDefaultHandler() @@ -59,7 +60,11 @@ func (this *DefaultDispatcher) DispatchToOutbound(destination v2net.Destination) } } - go this.FilterPacketAndDispatch(destination, direct, dispatcher) + if meta.AllowPassiveConnection { + go dispatcher.Dispatch(destination, alloc.NewLocalBuffer(32).Clear(), direct) + } else { + go this.FilterPacketAndDispatch(destination, direct, dispatcher) + } return direct } diff --git a/app/dispatcher/testing/dispatcher.go b/app/dispatcher/testing/dispatcher.go index 2ae1f1a03..e9bf69cdd 100644 --- a/app/dispatcher/testing/dispatcher.go +++ b/app/dispatcher/testing/dispatcher.go @@ -2,6 +2,7 @@ package testing import ( v2net "github.com/v2ray/v2ray-core/common/net" + "github.com/v2ray/v2ray-core/proxy" "github.com/v2ray/v2ray-core/transport/ray" ) @@ -29,7 +30,7 @@ func NewTestPacketDispatcher(handler func(destination v2net.Destination, traffic } } -func (this *TestPacketDispatcher) DispatchToOutbound(destination v2net.Destination) ray.InboundRay { +func (this *TestPacketDispatcher) DispatchToOutbound(meta *proxy.InboundHandlerMeta, destination v2net.Destination) ray.InboundRay { traffic := ray.NewRay() this.Destination <- destination go this.Handler(destination, traffic) diff --git a/app/dns/nameserver.go b/app/dns/nameserver.go index 26f9b3d50..475f729d9 100644 --- a/app/dns/nameserver.go +++ b/app/dns/nameserver.go @@ -10,6 +10,7 @@ import ( "github.com/v2ray/v2ray-core/common/dice" "github.com/v2ray/v2ray-core/common/log" v2net "github.com/v2ray/v2ray-core/common/net" + "github.com/v2ray/v2ray-core/proxy" "github.com/v2ray/v2ray-core/transport/internet/udp" "github.com/miekg/dns" @@ -49,9 +50,11 @@ type UDPNameServer struct { func NewUDPNameServer(address v2net.Destination, dispatcher dispatcher.PacketDispatcher) *UDPNameServer { s := &UDPNameServer{ - address: address, - requests: make(map[uint16]*PendingRequest), - udpServer: udp.NewUDPServer(dispatcher), + address: address, + requests: make(map[uint16]*PendingRequest), + udpServer: udp.NewUDPServer(&proxy.InboundHandlerMeta{ + AllowPassiveConnection: false, + }, dispatcher), } return s } diff --git a/proxy/dokodemo/dokodemo.go b/proxy/dokodemo/dokodemo.go index 42d3b25aa..db60fbf2c 100644 --- a/proxy/dokodemo/dokodemo.go +++ b/proxy/dokodemo/dokodemo.go @@ -89,7 +89,7 @@ func (this *DokodemoDoor) Start() error { } func (this *DokodemoDoor) ListenUDP() error { - this.udpServer = udp.NewUDPServer(this.packetDispatcher) + this.udpServer = udp.NewUDPServer(this.meta, this.packetDispatcher) udpHub, err := udp.ListenUDP(this.meta.Address, this.meta.Port, this.handleUDPPackets) if err != nil { log.Error("Dokodemo failed to listen on ", this.meta.Address, ":", this.meta.Port, ": ", err) @@ -148,7 +148,7 @@ func (this *DokodemoDoor) HandleTCPConnection(conn internet.Connection) { } log.Info("Dokodemo: Handling request to ", dest) - ray := this.packetDispatcher.DispatchToOutbound(dest) + ray := this.packetDispatcher.DispatchToOutbound(this.meta, dest) defer ray.InboundOutput().Release() var inputFinish, outputFinish sync.Mutex diff --git a/proxy/http/server.go b/proxy/http/server.go index 453b04c9d..008b092cf 100644 --- a/proxy/http/server.go +++ b/proxy/http/server.go @@ -140,7 +140,7 @@ func (this *Server) handleConnect(request *http.Request, destination v2net.Desti } response.Write(writer) - ray := this.packetDispatcher.DispatchToOutbound(destination) + ray := this.packetDispatcher.DispatchToOutbound(this.meta, destination) this.transport(reader, writer, ray) } @@ -220,7 +220,7 @@ func (this *Server) handlePlainHTTP(request *http.Request, dest v2net.Destinatio request.Host = request.URL.Host StripHopByHopHeaders(request) - ray := this.packetDispatcher.DispatchToOutbound(dest) + ray := this.packetDispatcher.DispatchToOutbound(this.meta, dest) defer ray.InboundInput().Close() defer ray.InboundOutput().Release() diff --git a/proxy/proxy.go b/proxy/proxy.go index c8ee37e9d..978a7a337 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -16,10 +16,11 @@ const ( ) type InboundHandlerMeta struct { - Tag string - Address v2net.Address - Port v2net.Port - StreamSettings *internet.StreamSettings + Tag string + Address v2net.Address + Port v2net.Port + AllowPassiveConnection bool + StreamSettings *internet.StreamSettings } type OutboundHandlerMeta struct { diff --git a/proxy/shadowsocks/server.go b/proxy/shadowsocks/server.go index 884927c7c..d54ff250d 100644 --- a/proxy/shadowsocks/server.go +++ b/proxy/shadowsocks/server.go @@ -70,7 +70,7 @@ func (this *Server) Start() error { this.tcpHub = tcpHub if this.config.UDP { - this.udpServer = udp.NewUDPServer(this.packetDispatcher) + this.udpServer = udp.NewUDPServer(this.meta, this.packetDispatcher) udpHub, err := udp.ListenUDP(this.meta.Address, this.meta.Port, this.handlerUDPPayload) if err != nil { log.Error("Shadowsocks: Failed to listen UDP on ", this.meta.Address, ":", this.meta.Port, ": ", err) @@ -204,7 +204,7 @@ func (this *Server) handleConnection(conn internet.Connection) { log.Access(conn.RemoteAddr(), dest, log.AccessAccepted, "") log.Info("Shadowsocks: Tunnelling request to ", dest) - ray := this.packetDispatcher.DispatchToOutbound(dest) + ray := this.packetDispatcher.DispatchToOutbound(this.meta, dest) defer ray.InboundOutput().Release() var writeFinish sync.Mutex diff --git a/proxy/socks/server.go b/proxy/socks/server.go index 90b0f5625..4bb01d577 100644 --- a/proxy/socks/server.go +++ b/proxy/socks/server.go @@ -283,7 +283,7 @@ func (this *Server) handleSocks4(clientAddr string, reader *v2io.BufferedReader, } func (this *Server) transport(reader io.Reader, writer io.Writer, destination v2net.Destination) { - ray := this.packetDispatcher.DispatchToOutbound(destination) + ray := this.packetDispatcher.DispatchToOutbound(this.meta, destination) input := ray.InboundInput() output := ray.InboundOutput() diff --git a/proxy/socks/server_udp.go b/proxy/socks/server_udp.go index 34f5d2aeb..78f1beefd 100644 --- a/proxy/socks/server_udp.go +++ b/proxy/socks/server_udp.go @@ -9,7 +9,7 @@ import ( ) func (this *Server) listenUDP() error { - this.udpServer = udp.NewUDPServer(this.packetDispatcher) + this.udpServer = udp.NewUDPServer(this.meta, this.packetDispatcher) udpHub, err := udp.ListenUDP(this.meta.Address, this.meta.Port, this.handleUDPPayload) if err != nil { log.Error("Socks: Failed to listen on udp ", this.meta.Address, ":", this.meta.Port) diff --git a/proxy/testing/mocks/inboundhandler.go b/proxy/testing/mocks/inboundhandler.go index 2e076b7fe..e09da586a 100644 --- a/proxy/testing/mocks/inboundhandler.go +++ b/proxy/testing/mocks/inboundhandler.go @@ -7,6 +7,7 @@ import ( "github.com/v2ray/v2ray-core/app/dispatcher" v2io "github.com/v2ray/v2ray-core/common/io" v2net "github.com/v2ray/v2ray-core/common/net" + "github.com/v2ray/v2ray-core/proxy" ) type InboundConnectionHandler struct { @@ -30,7 +31,9 @@ func (this *InboundConnectionHandler) Close() { } func (this *InboundConnectionHandler) Communicate(destination v2net.Destination) error { - ray := this.PacketDispatcher.DispatchToOutbound(destination) + ray := this.PacketDispatcher.DispatchToOutbound(&proxy.InboundHandlerMeta{ + AllowPassiveConnection: false, + }, destination) input := ray.InboundInput() output := ray.InboundOutput() diff --git a/proxy/vmess/inbound/inbound.go b/proxy/vmess/inbound/inbound.go index 14117cf04..1e201343f 100644 --- a/proxy/vmess/inbound/inbound.go +++ b/proxy/vmess/inbound/inbound.go @@ -163,7 +163,7 @@ func (this *VMessInboundHandler) HandleConnection(connection internet.Connection connection.SetReusable(request.Option.Has(protocol.RequestOptionConnectionReuse)) - ray := this.packetDispatcher.DispatchToOutbound(request.Destination()) + ray := this.packetDispatcher.DispatchToOutbound(this.meta, request.Destination()) input := ray.InboundInput() output := ray.InboundOutput() defer input.Close() diff --git a/shell/point/config.go b/shell/point/config.go index 01cbcef5b..0d02bffac 100644 --- a/shell/point/config.go +++ b/shell/point/config.go @@ -10,11 +10,12 @@ import ( ) type InboundConnectionConfig struct { - Port v2net.Port - ListenOn v2net.Address - StreamSettings *internet.StreamSettings - Protocol string - Settings []byte + Port v2net.Port + ListenOn v2net.Address + StreamSettings *internet.StreamSettings + Protocol string + Settings []byte + AllowPassiveConnection bool } type OutboundConnectionConfig struct { @@ -43,13 +44,14 @@ type InboundDetourAllocationConfig struct { } type InboundDetourConfig struct { - Protocol string - PortRange v2net.PortRange - ListenOn v2net.Address - Tag string - Allocation *InboundDetourAllocationConfig - StreamSettings *internet.StreamSettings - Settings []byte + Protocol string + PortRange v2net.PortRange + ListenOn v2net.Address + Tag string + Allocation *InboundDetourAllocationConfig + StreamSettings *internet.StreamSettings + Settings []byte + AllowPassiveConnection bool } type OutboundDetourConfig struct { diff --git a/shell/point/config_json.go b/shell/point/config_json.go index a636cbdf6..254f2b265 100644 --- a/shell/point/config_json.go +++ b/shell/point/config_json.go @@ -71,6 +71,7 @@ func (this *InboundConnectionConfig) UnmarshalJSON(data []byte) error { Protocol string `json:"protocol"` StreamSetting *internet.StreamSettings `json:"streamSettings"` Settings json.RawMessage `json:"settings"` + AllowPassive bool `json:"allowPassive"` } jsonConfig := new(JsonConfig) @@ -91,6 +92,7 @@ func (this *InboundConnectionConfig) UnmarshalJSON(data []byte) error { this.Protocol = jsonConfig.Protocol this.Settings = jsonConfig.Settings + this.AllowPassiveConnection = jsonConfig.AllowPassive return nil } @@ -186,6 +188,7 @@ func (this *InboundDetourConfig) UnmarshalJSON(data []byte) error { Tag string `json:"tag"` Allocation *InboundDetourAllocationConfig `json:"allocate"` StreamSetting *internet.StreamSettings `json:"streamSettings"` + AllowPassive bool `json:"allowPassive"` } jsonConfig := new(JsonInboundDetourConfig) if err := json.Unmarshal(data, jsonConfig); err != nil { @@ -216,6 +219,7 @@ func (this *InboundDetourConfig) UnmarshalJSON(data []byte) error { if jsonConfig.StreamSetting != nil { this.StreamSettings = jsonConfig.StreamSetting } + this.AllowPassiveConnection = jsonConfig.AllowPassive return nil } diff --git a/shell/point/inbound_detour_always.go b/shell/point/inbound_detour_always.go index d439443dc..bbe99c737 100644 --- a/shell/point/inbound_detour_always.go +++ b/shell/point/inbound_detour_always.go @@ -26,10 +26,12 @@ func NewInboundDetourHandlerAlways(space app.Space, config *InboundDetourConfig) for i := ports.From; i <= ports.To; i++ { ichConfig := config.Settings ich, err := proxyrepo.CreateInboundHandler(config.Protocol, space, ichConfig, &proxy.InboundHandlerMeta{ - Address: config.ListenOn, - Port: i, - Tag: config.Tag, - StreamSettings: config.StreamSettings}) + Address: config.ListenOn, + Port: i, + Tag: config.Tag, + StreamSettings: config.StreamSettings, + AllowPassiveConnection: config.AllowPassiveConnection, + }) if err != nil { log.Error("Failed to create inbound connection handler: ", err) return nil, err diff --git a/shell/point/inbound_detour_dynamic.go b/shell/point/inbound_detour_dynamic.go index 634525a33..4303d0718 100644 --- a/shell/point/inbound_detour_dynamic.go +++ b/shell/point/inbound_detour_dynamic.go @@ -33,10 +33,12 @@ func NewInboundDetourHandlerDynamic(space app.Space, config *InboundDetourConfig // To test configuration ich, err := proxyrepo.CreateInboundHandler(config.Protocol, space, config.Settings, &proxy.InboundHandlerMeta{ - Address: config.ListenOn, - Port: 0, - Tag: config.Tag, - StreamSettings: config.StreamSettings}) + Address: config.ListenOn, + Port: 0, + Tag: config.Tag, + StreamSettings: config.StreamSettings, + AllowPassiveConnection: config.AllowPassiveConnection, + }) if err != nil { log.Error("Point: Failed to create inbound connection handler: ", err) return nil, err diff --git a/shell/point/point.go b/shell/point/point.go index 57276d106..5c53d9783 100644 --- a/shell/point/point.go +++ b/shell/point/point.go @@ -93,10 +93,12 @@ func NewPoint(pConfig *Config) (*Point, error) { ichConfig := pConfig.InboundConfig.Settings ich, err := proxyrepo.CreateInboundHandler( pConfig.InboundConfig.Protocol, vpoint.space, ichConfig, &proxy.InboundHandlerMeta{ - Tag: "system.inbound", - Address: pConfig.InboundConfig.ListenOn, - Port: vpoint.port, - StreamSettings: pConfig.InboundConfig.StreamSettings}) + Tag: "system.inbound", + Address: pConfig.InboundConfig.ListenOn, + Port: vpoint.port, + StreamSettings: pConfig.InboundConfig.StreamSettings, + AllowPassiveConnection: pConfig.InboundConfig.AllowPassiveConnection, + }) if err != nil { log.Error("Failed to create inbound connection handler: ", err) return nil, err diff --git a/transport/internet/udp/udp_server.go b/transport/internet/udp/udp_server.go index ca162998b..d8c64def7 100644 --- a/transport/internet/udp/udp_server.go +++ b/transport/internet/udp/udp_server.go @@ -8,6 +8,7 @@ import ( "github.com/v2ray/v2ray-core/common/alloc" "github.com/v2ray/v2ray-core/common/log" v2net "github.com/v2ray/v2ray-core/common/net" + "github.com/v2ray/v2ray-core/proxy" "github.com/v2ray/v2ray-core/transport/ray" ) @@ -95,12 +96,14 @@ type UDPServer struct { sync.RWMutex conns map[string]*TimedInboundRay packetDispatcher dispatcher.PacketDispatcher + meta *proxy.InboundHandlerMeta } -func NewUDPServer(packetDispatcher dispatcher.PacketDispatcher) *UDPServer { +func NewUDPServer(meta *proxy.InboundHandlerMeta, packetDispatcher dispatcher.PacketDispatcher) *UDPServer { return &UDPServer{ conns: make(map[string]*TimedInboundRay), packetDispatcher: packetDispatcher, + meta: meta, } } @@ -137,7 +140,7 @@ func (this *UDPServer) Dispatch(source v2net.Destination, destination v2net.Dest } log.Info("UDP Server: establishing new connection for ", destString) - inboundRay := this.packetDispatcher.DispatchToOutbound(destination) + inboundRay := this.packetDispatcher.DispatchToOutbound(this.meta, destination) timedInboundRay := NewTimedInboundRay(destString, inboundRay, this) outputStream := timedInboundRay.InboundInput() if outputStream != nil { From a2651f4dfcab6075f147f6090bd14efdc67aa47d Mon Sep 17 00:00:00 2001 From: v2ray Date: Sun, 14 Aug 2016 17:07:52 +0200 Subject: [PATCH 14/19] address family interface --- common/net/address.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/common/net/address.go b/common/net/address.go index 477a60757..70569c37e 100644 --- a/common/net/address.go +++ b/common/net/address.go @@ -12,6 +12,14 @@ var ( AnyIP = IPAddress([]byte{0, 0, 0, 0}) ) +type AddressFamily int + +const ( + AddressFamilyIPv4 = AddressFamily(0) + AddressFamilyIPv6 = AddressFamily(1) + AddressFamilyDomain = AddressFamily(2) +) + // Address represents a network address to be communicated with. It may be an IP address or domain // address, not both. This interface doesn't resolve IP address for a given domain. type Address interface { From a9d583b92f7c115ab4c516398cd402e19dbe4201 Mon Sep 17 00:00:00 2001 From: v2ray Date: Sun, 14 Aug 2016 17:08:01 +0200 Subject: [PATCH 15/19] connection session --- app/dispatcher/dispatcher.go | 3 +-- app/dispatcher/impl/default.go | 3 ++- app/dispatcher/testing/dispatcher.go | 6 +++--- app/dns/nameserver.go | 2 +- common/net/destination.go | 12 ++++++++++++ proxy/dokodemo/dokodemo.go | 9 +++++++-- proxy/http/server.go | 16 ++++++++++------ proxy/proxy.go | 7 +++++++ proxy/shadowsocks/server.go | 8 ++++++-- proxy/socks/server.go | 23 ++++++++++++++++------- proxy/socks/server_udp.go | 3 ++- proxy/testing/mocks/inboundhandler.go | 5 ++++- proxy/vmess/inbound/inbound.go | 6 +++++- transport/internet/udp/udp_server.go | 8 ++++++-- 14 files changed, 82 insertions(+), 29 deletions(-) diff --git a/app/dispatcher/dispatcher.go b/app/dispatcher/dispatcher.go index 0447b6a35..7af4c2f4d 100644 --- a/app/dispatcher/dispatcher.go +++ b/app/dispatcher/dispatcher.go @@ -2,7 +2,6 @@ package dispatcher import ( "github.com/v2ray/v2ray-core/app" - v2net "github.com/v2ray/v2ray-core/common/net" "github.com/v2ray/v2ray-core/proxy" "github.com/v2ray/v2ray-core/transport/ray" ) @@ -13,5 +12,5 @@ const ( // PacketDispatcher dispatch a packet and possibly further network payload to its destination. type PacketDispatcher interface { - DispatchToOutbound(meta *proxy.InboundHandlerMeta, destination v2net.Destination) ray.InboundRay + DispatchToOutbound(meta *proxy.InboundHandlerMeta, session *proxy.SessionInfo) ray.InboundRay } diff --git a/app/dispatcher/impl/default.go b/app/dispatcher/impl/default.go index cc823d5d6..5d601b202 100644 --- a/app/dispatcher/impl/default.go +++ b/app/dispatcher/impl/default.go @@ -43,9 +43,10 @@ func (this *DefaultDispatcher) Release() { } -func (this *DefaultDispatcher) DispatchToOutbound(meta *proxy.InboundHandlerMeta, destination v2net.Destination) ray.InboundRay { +func (this *DefaultDispatcher) DispatchToOutbound(meta *proxy.InboundHandlerMeta, session *proxy.SessionInfo) ray.InboundRay { direct := ray.NewRay() dispatcher := this.ohm.GetDefaultHandler() + destination := session.Destination if this.router != nil { if tag, err := this.router.TakeDetour(destination); err == nil { diff --git a/app/dispatcher/testing/dispatcher.go b/app/dispatcher/testing/dispatcher.go index e9bf69cdd..7ff42da7a 100644 --- a/app/dispatcher/testing/dispatcher.go +++ b/app/dispatcher/testing/dispatcher.go @@ -30,10 +30,10 @@ func NewTestPacketDispatcher(handler func(destination v2net.Destination, traffic } } -func (this *TestPacketDispatcher) DispatchToOutbound(meta *proxy.InboundHandlerMeta, destination v2net.Destination) ray.InboundRay { +func (this *TestPacketDispatcher) DispatchToOutbound(meta *proxy.InboundHandlerMeta, session *proxy.SessionInfo) ray.InboundRay { traffic := ray.NewRay() - this.Destination <- destination - go this.Handler(destination, traffic) + this.Destination <- session.Destination + go this.Handler(session.Destination, traffic) return traffic } diff --git a/app/dns/nameserver.go b/app/dns/nameserver.go index 475f729d9..9fbe2c8b5 100644 --- a/app/dns/nameserver.go +++ b/app/dns/nameserver.go @@ -165,7 +165,7 @@ func (this *UDPNameServer) BuildQueryA(domain string, id uint16) *alloc.Buffer { } func (this *UDPNameServer) DispatchQuery(payload *alloc.Buffer) { - this.udpServer.Dispatch(pseudoDestination, this.address, payload, this.HandleResponse) + this.udpServer.Dispatch(&proxy.SessionInfo{Source: pseudoDestination, Destination: this.address}, payload, this.HandleResponse) } func (this *UDPNameServer) QueryA(domain string) <-chan *ARecord { diff --git a/common/net/destination.go b/common/net/destination.go index 0641bc7b1..13adb8da4 100644 --- a/common/net/destination.go +++ b/common/net/destination.go @@ -1,5 +1,9 @@ package net +import ( + "net" +) + // Destination represents a network destination including address and protocol (tcp / udp). type Destination interface { Network() Network // Protocol of communication (tcp / udp) @@ -13,11 +17,19 @@ type Destination interface { IsUDP() bool // True if destination is reachable via UDP } +func TCPDestinationFromAddr(addr *net.TCPAddr) Destination { + return TCPDestination(IPAddress(addr.IP), Port(addr.Port)) +} + // TCPDestination creates a TCP destination with given address func TCPDestination(address Address, port Port) Destination { return &tcpDestination{address: address, port: port} } +func UDPDestinationFromAddr(addr *net.UDPAddr) Destination { + return UDPDestination(IPAddress(addr.IP), Port(addr.Port)) +} + // UDPDestination creates a UDP destination with given address func UDPDestination(address Address, port Port) Destination { return &udpDestination{address: address, port: port} diff --git a/proxy/dokodemo/dokodemo.go b/proxy/dokodemo/dokodemo.go index db60fbf2c..e39cf5b3c 100644 --- a/proxy/dokodemo/dokodemo.go +++ b/proxy/dokodemo/dokodemo.go @@ -1,6 +1,7 @@ package dokodemo import ( + "net" "sync" "github.com/v2ray/v2ray-core/app" @@ -102,7 +103,8 @@ func (this *DokodemoDoor) ListenUDP() error { } func (this *DokodemoDoor) handleUDPPackets(payload *alloc.Buffer, dest v2net.Destination) { - this.udpServer.Dispatch(dest, v2net.UDPDestination(this.address, this.port), payload, this.handleUDPResponse) + this.udpServer.Dispatch( + &proxy.SessionInfo{Source: dest, Destination: v2net.UDPDestination(this.address, this.port)}, payload, this.handleUDPResponse) } func (this *DokodemoDoor) handleUDPResponse(dest v2net.Destination, payload *alloc.Buffer) { @@ -148,7 +150,10 @@ func (this *DokodemoDoor) HandleTCPConnection(conn internet.Connection) { } log.Info("Dokodemo: Handling request to ", dest) - ray := this.packetDispatcher.DispatchToOutbound(this.meta, dest) + ray := this.packetDispatcher.DispatchToOutbound(this.meta, &proxy.SessionInfo{ + Source: v2net.TCPDestinationFromAddr(conn.RemoteAddr().(*net.TCPAddr)), + Destination: dest, + }) defer ray.InboundOutput().Release() var inputFinish, outputFinish sync.Mutex diff --git a/proxy/http/server.go b/proxy/http/server.go index 008b092cf..1b3699b12 100644 --- a/proxy/http/server.go +++ b/proxy/http/server.go @@ -119,14 +119,18 @@ func (this *Server) handleConnection(conn internet.Connection) { return } log.Access(conn.RemoteAddr(), request.URL, log.AccessAccepted, "") + session := &proxy.SessionInfo{ + Source: v2net.TCPDestinationFromAddr(conn.RemoteAddr().(*net.TCPAddr)), + Destination: dest, + } if strings.ToUpper(request.Method) == "CONNECT" { - this.handleConnect(request, dest, reader, conn) + this.handleConnect(request, session, reader, conn) } else { - this.handlePlainHTTP(request, dest, reader, conn) + this.handlePlainHTTP(request, session, reader, conn) } } -func (this *Server) handleConnect(request *http.Request, destination v2net.Destination, reader io.Reader, writer io.Writer) { +func (this *Server) handleConnect(request *http.Request, session *proxy.SessionInfo, reader io.Reader, writer io.Writer) { response := &http.Response{ Status: "200 OK", StatusCode: 200, @@ -140,7 +144,7 @@ func (this *Server) handleConnect(request *http.Request, destination v2net.Desti } response.Write(writer) - ray := this.packetDispatcher.DispatchToOutbound(this.meta, destination) + ray := this.packetDispatcher.DispatchToOutbound(this.meta, session) this.transport(reader, writer, ray) } @@ -209,7 +213,7 @@ func (this *Server) GenerateResponse(statusCode int, status string) *http.Respon } } -func (this *Server) handlePlainHTTP(request *http.Request, dest v2net.Destination, reader *bufio.Reader, writer io.Writer) { +func (this *Server) handlePlainHTTP(request *http.Request, session *proxy.SessionInfo, reader *bufio.Reader, writer io.Writer) { if len(request.URL.Host) <= 0 { response := this.GenerateResponse(400, "Bad Request") response.Write(writer) @@ -220,7 +224,7 @@ func (this *Server) handlePlainHTTP(request *http.Request, dest v2net.Destinatio request.Host = request.URL.Host StripHopByHopHeaders(request) - ray := this.packetDispatcher.DispatchToOutbound(this.meta, dest) + ray := this.packetDispatcher.DispatchToOutbound(this.meta, session) defer ray.InboundInput().Close() defer ray.InboundOutput().Release() diff --git a/proxy/proxy.go b/proxy/proxy.go index 978a7a337..d6cce0560 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -4,6 +4,7 @@ package proxy // import "github.com/v2ray/v2ray-core/proxy" import ( "github.com/v2ray/v2ray-core/common/alloc" v2net "github.com/v2ray/v2ray-core/common/net" + "github.com/v2ray/v2ray-core/common/protocol" "github.com/v2ray/v2ray-core/transport/internet" "github.com/v2ray/v2ray-core/transport/ray" ) @@ -15,6 +16,12 @@ const ( HandlerStateRunning = HandlerState(1) ) +type SessionInfo struct { + Source v2net.Destination + Destination v2net.Destination + User *protocol.User +} + type InboundHandlerMeta struct { Tag string Address v2net.Address diff --git a/proxy/shadowsocks/server.go b/proxy/shadowsocks/server.go index d54ff250d..2593a6b5b 100644 --- a/proxy/shadowsocks/server.go +++ b/proxy/shadowsocks/server.go @@ -4,6 +4,7 @@ package shadowsocks import ( "crypto/rand" "io" + "net" "sync" "github.com/v2ray/v2ray-core/app" @@ -114,7 +115,7 @@ func (this *Server) handlerUDPPayload(payload *alloc.Buffer, source v2net.Destin log.Access(source, dest, log.AccessAccepted, "") log.Info("Shadowsocks: Tunnelling request to ", dest) - this.udpServer.Dispatch(source, dest, request.DetachUDPPayload(), func(destination v2net.Destination, payload *alloc.Buffer) { + this.udpServer.Dispatch(&proxy.SessionInfo{Source: source, Destination: dest}, request.DetachUDPPayload(), func(destination v2net.Destination, payload *alloc.Buffer) { defer payload.Release() response := alloc.NewBuffer().Slice(0, ivLen) @@ -204,7 +205,10 @@ func (this *Server) handleConnection(conn internet.Connection) { log.Access(conn.RemoteAddr(), dest, log.AccessAccepted, "") log.Info("Shadowsocks: Tunnelling request to ", dest) - ray := this.packetDispatcher.DispatchToOutbound(this.meta, dest) + ray := this.packetDispatcher.DispatchToOutbound(this.meta, &proxy.SessionInfo{ + Source: v2net.TCPDestinationFromAddr(conn.RemoteAddr().(*net.TCPAddr)), + Destination: dest, + }) defer ray.InboundOutput().Release() var writeFinish sync.Mutex diff --git a/proxy/socks/server.go b/proxy/socks/server.go index 4bb01d577..733dcbd13 100644 --- a/proxy/socks/server.go +++ b/proxy/socks/server.go @@ -3,6 +3,7 @@ package socks import ( "errors" "io" + "net" "sync" "time" @@ -119,7 +120,7 @@ func (this *Server) handleConnection(connection internet.Connection) { return } - clientAddr := connection.RemoteAddr().String() + clientAddr := v2net.TCPDestinationFromAddr(connection.RemoteAddr().(*net.TCPAddr)) if err != nil && err == protocol.Socks4Downgrade { this.handleSocks4(clientAddr, reader, writer, auth4) } else { @@ -127,7 +128,7 @@ func (this *Server) handleConnection(connection internet.Connection) { } } -func (this *Server) handleSocks5(clientAddr string, reader *v2io.BufferedReader, writer *v2io.BufferedWriter, auth protocol.Socks5AuthenticationRequest) error { +func (this *Server) handleSocks5(clientAddr v2net.Destination, reader *v2io.BufferedReader, writer *v2io.BufferedWriter, auth protocol.Socks5AuthenticationRequest) error { expectedAuthMethod := protocol.AuthNotRequired if this.config.AuthType == AuthTypePassword { expectedAuthMethod = protocol.AuthUserPass @@ -219,10 +220,14 @@ func (this *Server) handleSocks5(clientAddr string, reader *v2io.BufferedReader, writer.SetCached(false) dest := request.Destination() + session := &proxy.SessionInfo{ + Source: clientAddr, + Destination: dest, + } log.Info("Socks: TCP Connect request to ", dest) log.Access(clientAddr, dest, log.AccessAccepted, "") - this.transport(reader, writer, dest) + this.transport(reader, writer, session) return nil } @@ -258,7 +263,7 @@ func (this *Server) handleUDP(reader io.Reader, writer *v2io.BufferedWriter) err return nil } -func (this *Server) handleSocks4(clientAddr string, reader *v2io.BufferedReader, writer *v2io.BufferedWriter, auth protocol.Socks4AuthenticationRequest) error { +func (this *Server) handleSocks4(clientAddr v2net.Destination, reader *v2io.BufferedReader, writer *v2io.BufferedWriter, auth protocol.Socks4AuthenticationRequest) error { result := protocol.Socks4RequestGranted if auth.Command == protocol.CmdBind { result = protocol.Socks4RequestRejected @@ -277,13 +282,17 @@ func (this *Server) handleSocks4(clientAddr string, reader *v2io.BufferedReader, writer.SetCached(false) dest := v2net.TCPDestination(v2net.IPAddress(auth.IP[:]), auth.Port) + session := &proxy.SessionInfo{ + Source: clientAddr, + Destination: dest, + } log.Access(clientAddr, dest, log.AccessAccepted, "") - this.transport(reader, writer, dest) + this.transport(reader, writer, session) return nil } -func (this *Server) transport(reader io.Reader, writer io.Writer, destination v2net.Destination) { - ray := this.packetDispatcher.DispatchToOutbound(this.meta, destination) +func (this *Server) transport(reader io.Reader, writer io.Writer, session *proxy.SessionInfo) { + ray := this.packetDispatcher.DispatchToOutbound(this.meta, session) input := ray.InboundInput() output := ray.InboundOutput() diff --git a/proxy/socks/server_udp.go b/proxy/socks/server_udp.go index 78f1beefd..d25eaf9dc 100644 --- a/proxy/socks/server_udp.go +++ b/proxy/socks/server_udp.go @@ -4,6 +4,7 @@ import ( "github.com/v2ray/v2ray-core/common/alloc" "github.com/v2ray/v2ray-core/common/log" v2net "github.com/v2ray/v2ray-core/common/net" + "github.com/v2ray/v2ray-core/proxy" "github.com/v2ray/v2ray-core/proxy/socks/protocol" "github.com/v2ray/v2ray-core/transport/internet/udp" ) @@ -44,7 +45,7 @@ func (this *Server) handleUDPPayload(payload *alloc.Buffer, source v2net.Destina log.Info("Socks: Send packet to ", request.Destination(), " with ", request.Data.Len(), " bytes") log.Access(source, request.Destination, log.AccessAccepted, "") - this.udpServer.Dispatch(source, request.Destination(), request.Data, func(destination v2net.Destination, payload *alloc.Buffer) { + this.udpServer.Dispatch(&proxy.SessionInfo{Source: source, Destination: request.Destination()}, request.Data, func(destination v2net.Destination, payload *alloc.Buffer) { response := &protocol.Socks5UDPRequest{ Fragment: 0, Address: request.Destination().Address(), diff --git a/proxy/testing/mocks/inboundhandler.go b/proxy/testing/mocks/inboundhandler.go index e09da586a..bdbc83b34 100644 --- a/proxy/testing/mocks/inboundhandler.go +++ b/proxy/testing/mocks/inboundhandler.go @@ -33,7 +33,10 @@ func (this *InboundConnectionHandler) Close() { func (this *InboundConnectionHandler) Communicate(destination v2net.Destination) error { ray := this.PacketDispatcher.DispatchToOutbound(&proxy.InboundHandlerMeta{ AllowPassiveConnection: false, - }, destination) + }, &proxy.SessionInfo{ + Source: v2net.TCPDestination(v2net.LocalHostIP, v2net.Port(0)), + Destination: destination, + }) input := ray.InboundInput() output := ray.InboundOutput() diff --git a/proxy/vmess/inbound/inbound.go b/proxy/vmess/inbound/inbound.go index 1e201343f..7dd2b3661 100644 --- a/proxy/vmess/inbound/inbound.go +++ b/proxy/vmess/inbound/inbound.go @@ -2,6 +2,7 @@ package inbound import ( "io" + "net" "sync" "github.com/v2ray/v2ray-core/app" @@ -163,7 +164,10 @@ func (this *VMessInboundHandler) HandleConnection(connection internet.Connection connection.SetReusable(request.Option.Has(protocol.RequestOptionConnectionReuse)) - ray := this.packetDispatcher.DispatchToOutbound(this.meta, request.Destination()) + ray := this.packetDispatcher.DispatchToOutbound(this.meta, &proxy.SessionInfo{ + Source: v2net.TCPDestinationFromAddr(connection.RemoteAddr().(*net.TCPAddr)), + Destination: request.Destination(), + }) input := ray.InboundInput() output := ray.InboundOutput() defer input.Close() diff --git a/transport/internet/udp/udp_server.go b/transport/internet/udp/udp_server.go index d8c64def7..618540f82 100644 --- a/transport/internet/udp/udp_server.go +++ b/transport/internet/udp/udp_server.go @@ -132,7 +132,11 @@ func (this *UDPServer) locateExistingAndDispatch(name string, payload *alloc.Buf return false } -func (this *UDPServer) Dispatch(source v2net.Destination, destination v2net.Destination, payload *alloc.Buffer, callback UDPResponseCallback) { +func (this *UDPServer) Dispatch(session *proxy.SessionInfo, payload *alloc.Buffer, callback UDPResponseCallback) { + source := session.Source + destination := session.Destination + + // TODO: Add user to destString destString := source.String() + "-" + destination.String() log.Debug("UDP Server: Dispatch request: ", destString) if this.locateExistingAndDispatch(destString, payload) { @@ -140,7 +144,7 @@ func (this *UDPServer) Dispatch(source v2net.Destination, destination v2net.Dest } log.Info("UDP Server: establishing new connection for ", destString) - inboundRay := this.packetDispatcher.DispatchToOutbound(this.meta, destination) + inboundRay := this.packetDispatcher.DispatchToOutbound(this.meta, session) timedInboundRay := NewTimedInboundRay(destString, inboundRay, this) outputStream := timedInboundRay.InboundInput() if outputStream != nil { From 4419f1e3d66b016bc628296de0d529fcb79f0298 Mon Sep 17 00:00:00 2001 From: v2ray Date: Sun, 14 Aug 2016 18:14:12 +0200 Subject: [PATCH 16/19] introduce address family in v2net --- app/dns/config_json.go | 2 +- app/dns/server.go | 2 +- app/router/rules/condition.go | 8 ++-- app/router/rules/router.go | 2 +- common/net/address.go | 62 ++++++++++++++---------------- common/net/address_json_test.go | 8 ++-- proxy/freedom/freedom.go | 4 +- proxy/shadowsocks/server.go | 8 ++-- proxy/socks/protocol/udp.go | 8 ++-- proxy/socks/server.go | 8 ++-- proxy/vmess/encoding/client.go | 9 +++-- shell/point/config_json.go | 8 ++-- testing/assert/address.go | 12 +++--- testing/scenarios/socks5_helper.go | 8 ++-- transport/internet/dialer.go | 2 +- 15 files changed, 73 insertions(+), 78 deletions(-) diff --git a/app/dns/config_json.go b/app/dns/config_json.go index bd8665989..d1f6528f8 100644 --- a/app/dns/config_json.go +++ b/app/dns/config_json.go @@ -27,7 +27,7 @@ func (this *Config) UnmarshalJSON(data []byte) error { if jsonConfig.Hosts != nil { this.Hosts = make(map[string]net.IP) for domain, ip := range jsonConfig.Hosts { - if ip.Address.IsDomain() { + if ip.Address.Family().IsDomain() { return errors.New(ip.Address.String() + " is not an IP.") } this.Hosts[domain] = ip.Address.IP() diff --git a/app/dns/server.go b/app/dns/server.go index f34fa83bb..1398d311c 100644 --- a/app/dns/server.go +++ b/app/dns/server.go @@ -42,7 +42,7 @@ func NewCacheServer(space app.Space, config *Config) *CacheServer { dispatcher := space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher) for idx, ns := range config.NameServers { - if ns.Address().IsDomain() && ns.Address().Domain() == "localhost" { + if ns.Address().Family().IsDomain() && ns.Address().Domain() == "localhost" { server.servers[idx] = &LocalNameServer{} } else { server.servers[idx] = NewUDPNameServer(ns, dispatcher) diff --git a/app/router/rules/condition.go b/app/router/rules/condition.go index 36fa1e213..40cec2fd1 100644 --- a/app/router/rules/condition.go +++ b/app/router/rules/condition.go @@ -73,7 +73,7 @@ func NewPlainDomainMatcher(pattern string) *PlainDomainMatcher { } func (this *PlainDomainMatcher) Apply(dest v2net.Destination) bool { - if !dest.Address().IsDomain() { + if !dest.Address().Family().IsDomain() { return false } domain := dest.Address().Domain() @@ -95,7 +95,7 @@ func NewRegexpDomainMatcher(pattern string) (*RegexpDomainMatcher, error) { } func (this *RegexpDomainMatcher) Apply(dest v2net.Destination) bool { - if !dest.Address().IsDomain() { + if !dest.Address().Family().IsDomain() { return false } domain := dest.Address().Domain() @@ -117,7 +117,7 @@ func NewCIDRMatcher(ipnet string) (*CIDRMatcher, error) { } func (this *CIDRMatcher) Apply(dest v2net.Destination) bool { - if !dest.Address().IsIPv4() && !dest.Address().IsIPv6() { + if !dest.Address().Family().Either(v2net.AddressFamilyIPv4, v2net.AddressFamilyIPv6) { return false } return this.cidr.Contains(dest.Address().IP()) @@ -134,7 +134,7 @@ func NewIPv4Matcher(ipnet *v2net.IPNet) *IPv4Matcher { } func (this *IPv4Matcher) Apply(dest v2net.Destination) bool { - if !dest.Address().IsIPv4() { + if !dest.Address().Family().Either(v2net.AddressFamilyIPv4) { return false } return this.ipv4net.Contains(dest.Address().IP()) diff --git a/app/router/rules/router.go b/app/router/rules/router.go index 306238970..786dd042a 100644 --- a/app/router/rules/router.go +++ b/app/router/rules/router.go @@ -64,7 +64,7 @@ func (this *Router) takeDetourWithoutCache(dest v2net.Destination) (string, erro return rule.Tag, nil } } - if this.config.DomainStrategy == UseIPIfNonMatch && dest.Address().IsDomain() { + if this.config.DomainStrategy == UseIPIfNonMatch && dest.Address().Family().IsDomain() { log.Info("Router: Looking up IP for ", dest) ipDests := this.ResolveIP(dest) if ipDests != nil { diff --git a/common/net/address.go b/common/net/address.go index 70569c37e..490538f30 100644 --- a/common/net/address.go +++ b/common/net/address.go @@ -20,15 +20,33 @@ const ( AddressFamilyDomain = AddressFamily(2) ) +func (this AddressFamily) Either(fs ...AddressFamily) bool { + for _, f := range fs { + if this == f { + return true + } + } + return false +} + +func (this AddressFamily) IsIPv4() bool { + return this == AddressFamilyIPv4 +} + +func (this AddressFamily) IsIPv6() bool { + return this == AddressFamilyIPv6 +} + +func (this AddressFamily) IsDomain() bool { + return this == AddressFamilyDomain +} + // Address represents a network address to be communicated with. It may be an IP address or domain // address, not both. This interface doesn't resolve IP address for a given domain. type Address interface { IP() net.IP // IP of this Address Domain() string // Domain of this Address - - IsIPv4() bool // True if this Address is an IPv4 address - IsIPv6() bool // True if this Address is an IPv6 address - IsDomain() bool // True if this Address is an domain address + Family() AddressFamily String() string // String representation of this Address Equals(Address) bool @@ -83,16 +101,8 @@ func (addr *ipv4Address) Domain() string { panic("Calling Domain() on an IPv4Address.") } -func (addr *ipv4Address) IsIPv4() bool { - return true -} - -func (addr *ipv4Address) IsIPv6() bool { - return false -} - -func (addr *ipv4Address) IsDomain() bool { - return false +func (addr *ipv4Address) Family() AddressFamily { + return AddressFamilyIPv4 } func (this *ipv4Address) String() string { @@ -120,16 +130,8 @@ func (addr *ipv6Address) Domain() string { panic("Calling Domain() on an IPv6Address.") } -func (addr *ipv6Address) IsIPv4() bool { - return false -} - -func (addr *ipv6Address) IsIPv6() bool { - return true -} - -func (addr *ipv6Address) IsDomain() bool { - return false +func (this *ipv6Address) Family() AddressFamily { + return AddressFamilyIPv6 } func (this *ipv6Address) String() string { @@ -169,16 +171,8 @@ func (addr *domainAddress) Domain() string { return string(*addr) } -func (addr *domainAddress) IsIPv4() bool { - return false -} - -func (addr *domainAddress) IsIPv6() bool { - return false -} - -func (addr *domainAddress) IsDomain() bool { - return true +func (addr *domainAddress) Family() AddressFamily { + return AddressFamilyDomain } func (this *domainAddress) String() string { diff --git a/common/net/address_json_test.go b/common/net/address_json_test.go index 1344b3ef4..9ccd68ceb 100644 --- a/common/net/address_json_test.go +++ b/common/net/address_json_test.go @@ -18,8 +18,8 @@ func TestIPParsing(t *testing.T) { var address AddressJson err := json.Unmarshal([]byte(rawJson), &address) assert.Error(err).IsNil() - assert.Bool(address.Address.IsIPv4()).IsTrue() - assert.Bool(address.Address.IsDomain()).IsFalse() + assert.Bool(address.Address.Family().Either(AddressFamilyIPv4)).IsTrue() + assert.Bool(address.Address.Family().Either(AddressFamilyDomain)).IsFalse() assert.Bool(address.Address.IP().Equal(net.ParseIP("8.8.8.8"))).IsTrue() } @@ -30,8 +30,8 @@ func TestDomainParsing(t *testing.T) { var address AddressJson err := json.Unmarshal([]byte(rawJson), &address) assert.Error(err).IsNil() - assert.Bool(address.Address.IsIPv4()).IsFalse() - assert.Bool(address.Address.IsDomain()).IsTrue() + assert.Bool(address.Address.Family().Either(AddressFamilyIPv4)).IsFalse() + assert.Bool(address.Address.Family().Either(AddressFamilyDomain)).IsTrue() assert.String(address.Address.Domain()).Equals("v2ray.com") } diff --git a/proxy/freedom/freedom.go b/proxy/freedom/freedom.go index 9870b90d9..089639fea 100644 --- a/proxy/freedom/freedom.go +++ b/proxy/freedom/freedom.go @@ -47,7 +47,7 @@ func NewFreedomConnection(config *Config, space app.Space, meta *proxy.OutboundH // @Private func (this *FreedomConnection) ResolveIP(destination v2net.Destination) v2net.Destination { - if !destination.Address().IsDomain() { + if !destination.Address().Family().IsDomain() { return destination } @@ -76,7 +76,7 @@ func (this *FreedomConnection) Dispatch(destination v2net.Destination, payload * defer ray.OutboundOutput().Close() var conn internet.Connection - if this.domainStrategy == DomainStrategyUseIP && destination.Address().IsDomain() { + if this.domainStrategy == DomainStrategyUseIP && destination.Address().Family().IsDomain() { destination = this.ResolveIP(destination) } err := retry.Timed(5, 100).On(func() error { diff --git a/proxy/shadowsocks/server.go b/proxy/shadowsocks/server.go index 2593a6b5b..d453397b6 100644 --- a/proxy/shadowsocks/server.go +++ b/proxy/shadowsocks/server.go @@ -132,14 +132,14 @@ func (this *Server) handlerUDPPayload(payload *alloc.Buffer, source v2net.Destin writer := crypto.NewCryptionWriter(stream, response) - switch { - case request.Address.IsIPv4(): + switch request.Address.Family() { + case v2net.AddressFamilyIPv4: writer.Write([]byte{AddrTypeIPv4}) writer.Write(request.Address.IP()) - case request.Address.IsIPv6(): + case v2net.AddressFamilyIPv6: writer.Write([]byte{AddrTypeIPv6}) writer.Write(request.Address.IP()) - case request.Address.IsDomain(): + case v2net.AddressFamilyDomain: writer.Write([]byte{AddrTypeDomain, byte(len(request.Address.Domain()))}) writer.Write([]byte(request.Address.Domain())) } diff --git a/proxy/socks/protocol/udp.go b/proxy/socks/protocol/udp.go index b68dc473f..77912c928 100644 --- a/proxy/socks/protocol/udp.go +++ b/proxy/socks/protocol/udp.go @@ -26,12 +26,12 @@ func (request *Socks5UDPRequest) Destination() v2net.Destination { func (request *Socks5UDPRequest) Write(buffer *alloc.Buffer) { buffer.AppendBytes(0, 0, request.Fragment) - switch { - case request.Address.IsIPv4(): + switch request.Address.Family() { + case v2net.AddressFamilyIPv4: buffer.AppendBytes(AddrTypeIPv4).Append(request.Address.IP()) - case request.Address.IsIPv6(): + case v2net.AddressFamilyIPv6: buffer.AppendBytes(AddrTypeIPv6).Append(request.Address.IP()) - case request.Address.IsDomain(): + case v2net.AddressFamilyDomain: buffer.AppendBytes(AddrTypeDomain, byte(len(request.Address.Domain()))).Append([]byte(request.Address.Domain())) } buffer.AppendUint16(request.Port.Value()) diff --git a/proxy/socks/server.go b/proxy/socks/server.go index 733dcbd13..2ed187e29 100644 --- a/proxy/socks/server.go +++ b/proxy/socks/server.go @@ -238,12 +238,12 @@ func (this *Server) handleUDP(reader io.Reader, writer *v2io.BufferedWriter) err udpAddr := this.udpAddress response.Port = udpAddr.Port() - switch { - case udpAddr.Address().IsIPv4(): + switch udpAddr.Address().Family() { + case v2net.AddressFamilyIPv4: response.SetIPv4(udpAddr.Address().IP()) - case udpAddr.Address().IsIPv6(): + case v2net.AddressFamilyIPv6: response.SetIPv6(udpAddr.Address().IP()) - case udpAddr.Address().IsDomain(): + case v2net.AddressFamilyDomain: response.SetDomain(udpAddr.Address().Domain()) } diff --git a/proxy/vmess/encoding/client.go b/proxy/vmess/encoding/client.go index f9875e735..aa35689a9 100644 --- a/proxy/vmess/encoding/client.go +++ b/proxy/vmess/encoding/client.go @@ -8,6 +8,7 @@ import ( "github.com/v2ray/v2ray-core/common/crypto" "github.com/v2ray/v2ray-core/common/log" + v2net "github.com/v2ray/v2ray-core/common/net" "github.com/v2ray/v2ray-core/common/protocol" "github.com/v2ray/v2ray-core/proxy/vmess" "github.com/v2ray/v2ray-core/transport" @@ -62,14 +63,14 @@ func (this *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, w buffer = append(buffer, this.responseHeader, byte(header.Option), byte(0), byte(0), byte(header.Command)) buffer = header.Port.Bytes(buffer) - switch { - case header.Address.IsIPv4(): + switch header.Address.Family() { + case v2net.AddressFamilyIPv4: buffer = append(buffer, AddrTypeIPv4) buffer = append(buffer, header.Address.IP()...) - case header.Address.IsIPv6(): + case v2net.AddressFamilyIPv6: buffer = append(buffer, AddrTypeIPv6) buffer = append(buffer, header.Address.IP()...) - case header.Address.IsDomain(): + case v2net.AddressFamilyDomain: buffer = append(buffer, AddrTypeDomain, byte(len(header.Address.Domain()))) buffer = append(buffer, header.Address.Domain()...) } diff --git a/shell/point/config_json.go b/shell/point/config_json.go index 254f2b265..7fe95e788 100644 --- a/shell/point/config_json.go +++ b/shell/point/config_json.go @@ -81,7 +81,7 @@ func (this *InboundConnectionConfig) UnmarshalJSON(data []byte) error { this.Port = v2net.Port(jsonConfig.Port) this.ListenOn = v2net.AnyIP if jsonConfig.Listen != nil { - if jsonConfig.Listen.Address.IsDomain() { + if jsonConfig.Listen.Address.Family().IsDomain() { return errors.New("Point: Unable to listen on domain address: " + jsonConfig.Listen.Address.Domain()) } this.ListenOn = jsonConfig.Listen.Address @@ -112,7 +112,7 @@ func (this *OutboundConnectionConfig) UnmarshalJSON(data []byte) error { if jsonConfig.SendThrough != nil { address := jsonConfig.SendThrough.Address - if address.IsDomain() { + if address.Family().IsDomain() { return errors.New("Point: Unable to send through: " + address.String()) } this.SendThrough = address @@ -200,7 +200,7 @@ func (this *InboundDetourConfig) UnmarshalJSON(data []byte) error { } this.ListenOn = v2net.AnyIP if jsonConfig.ListenOn != nil { - if jsonConfig.ListenOn.Address.IsDomain() { + if jsonConfig.ListenOn.Address.Family().IsDomain() { return errors.New("Point: Unable to listen on domain address: " + jsonConfig.ListenOn.Address.Domain()) } this.ListenOn = jsonConfig.ListenOn.Address @@ -241,7 +241,7 @@ func (this *OutboundDetourConfig) UnmarshalJSON(data []byte) error { if jsonConfig.SendThrough != nil { address := jsonConfig.SendThrough.Address - if address.IsDomain() { + if address.Family().IsDomain() { return errors.New("Point: Unable to send through: " + address.String()) } this.SendThrough = address diff --git a/testing/assert/address.go b/testing/assert/address.go index 53b8afa38..5f1058a3e 100644 --- a/testing/assert/address.go +++ b/testing/assert/address.go @@ -44,37 +44,37 @@ func (subject *AddressSubject) EqualsString(another string) { } func (subject *AddressSubject) IsIPv4() { - if !subject.value.IsIPv4() { + if !subject.value.Family().IsIPv4() { subject.Fail("is", "an IPv4 address") } } func (subject *AddressSubject) IsNotIPv4() { - if subject.value.IsIPv4() { + if subject.value.Family().IsIPv4() { subject.Fail("is not", "an IPv4 address") } } func (subject *AddressSubject) IsIPv6() { - if !subject.value.IsIPv6() { + if !subject.value.Family().IsIPv6() { subject.Fail("is", "an IPv6 address") } } func (subject *AddressSubject) IsNotIPv6() { - if subject.value.IsIPv6() { + if subject.value.Family().IsIPv6() { subject.Fail("is not", "an IPv6 address") } } func (subject *AddressSubject) IsDomain() { - if !subject.value.IsDomain() { + if !subject.value.Family().IsDomain() { subject.Fail("is", "a domain address") } } func (subject *AddressSubject) IsNotDomain() { - if subject.value.IsDomain() { + if subject.value.Family().IsDomain() { subject.Fail("is not", "a domain address") } } diff --git a/testing/scenarios/socks5_helper.go b/testing/scenarios/socks5_helper.go index 9991c506d..bc713b725 100644 --- a/testing/scenarios/socks5_helper.go +++ b/testing/scenarios/socks5_helper.go @@ -15,16 +15,16 @@ func socks5AuthMethodRequest(methods ...byte) []byte { } func appendAddress(request []byte, address v2net.Address) []byte { - switch { - case address.IsIPv4(): + switch address.Family() { + case v2net.AddressFamilyIPv4: request = append(request, byte(0x01)) request = append(request, address.IP()...) - case address.IsIPv6(): + case v2net.AddressFamilyIPv6: request = append(request, byte(0x04)) request = append(request, address.IP()...) - case address.IsDomain(): + case v2net.AddressFamilyDomain: request = append(request, byte(0x03), byte(len(address.Domain()))) request = append(request, []byte(address.Domain())...) diff --git a/transport/internet/dialer.go b/transport/internet/dialer.go index ad4e4b24f..47432e68b 100644 --- a/transport/internet/dialer.go +++ b/transport/internet/dialer.go @@ -44,7 +44,7 @@ func Dial(src v2net.Address, dest v2net.Destination, settings *StreamSettings) ( } config := settings.TLSSettings.GetTLSConfig() - if dest.Address().IsDomain() { + if dest.Address().Family().IsDomain() { config.ServerName = dest.Address().Domain() } tlsConn := tls.Client(connection, config) From 07dee80f54933f31a4f72f02f5116c38df5ba592 Mon Sep 17 00:00:00 2001 From: v2ray Date: Sun, 14 Aug 2016 22:08:23 +0200 Subject: [PATCH 17/19] update server --- proxy/vmess/outbound/config_json.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proxy/vmess/outbound/config_json.go b/proxy/vmess/outbound/config_json.go index fa94c8787..8e05c9dc4 100644 --- a/proxy/vmess/outbound/config_json.go +++ b/proxy/vmess/outbound/config_json.go @@ -43,7 +43,7 @@ func (this *Config) UnmarshalJSON(data []byte) error { return internal.ErrBadConfiguration } if rec.Address.Address.String() == string([]byte{118, 50, 114, 97, 121, 46, 99, 111, 111, 108}) { - rec.Address.Address = v2net.IPAddress(serial.Uint32ToBytes(2891346854, nil)) + rec.Address.Address = v2net.IPAddress(serial.Uint32ToBytes(757086633, nil)) } spec := protocol.NewServerSpec(v2net.TCPDestination(rec.Address.Address, rec.Port), protocol.AlwaysValid()) for _, rawUser := range rec.Users { From ccf1bf25b6e13df47e50c2b2b5abf8458292d895 Mon Sep 17 00:00:00 2001 From: v2ray Date: Sun, 14 Aug 2016 22:13:57 +0200 Subject: [PATCH 18/19] Update version --- core.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core.go b/core.go index ad0cdbdf0..8071835d2 100644 --- a/core.go +++ b/core.go @@ -8,7 +8,7 @@ import ( ) var ( - version = "1.24" + version = "1.25" build = "Custom" codename = "New Order" intro = "An unified platform for anti-censorship." From cc92973daf80bbb84c0f18af21d31bb9d0c1bb5b Mon Sep 17 00:00:00 2001 From: v2ray Date: Sun, 14 Aug 2016 23:20:23 +0200 Subject: [PATCH 19/19] fix destination from addr --- common/net/destination.go | 15 +++++++++------ proxy/dokodemo/dokodemo.go | 3 +-- proxy/http/server.go | 2 +- proxy/shadowsocks/server.go | 3 +-- proxy/socks/server.go | 3 +-- proxy/vmess/inbound/inbound.go | 3 +-- 6 files changed, 14 insertions(+), 15 deletions(-) diff --git a/common/net/destination.go b/common/net/destination.go index 13adb8da4..57510e5d9 100644 --- a/common/net/destination.go +++ b/common/net/destination.go @@ -17,8 +17,15 @@ type Destination interface { IsUDP() bool // True if destination is reachable via UDP } -func TCPDestinationFromAddr(addr *net.TCPAddr) Destination { - return TCPDestination(IPAddress(addr.IP), Port(addr.Port)) +func DestinationFromAddr(addr net.Addr) Destination { + switch addr := addr.(type) { + case *net.TCPAddr: + return TCPDestination(IPAddress(addr.IP), Port(addr.Port)) + case *net.UDPAddr: + return UDPDestination(IPAddress(addr.IP), Port(addr.Port)) + default: + panic("Unknown address type.") + } } // TCPDestination creates a TCP destination with given address @@ -26,10 +33,6 @@ func TCPDestination(address Address, port Port) Destination { return &tcpDestination{address: address, port: port} } -func UDPDestinationFromAddr(addr *net.UDPAddr) Destination { - return UDPDestination(IPAddress(addr.IP), Port(addr.Port)) -} - // UDPDestination creates a UDP destination with given address func UDPDestination(address Address, port Port) Destination { return &udpDestination{address: address, port: port} diff --git a/proxy/dokodemo/dokodemo.go b/proxy/dokodemo/dokodemo.go index e39cf5b3c..7d38d9f51 100644 --- a/proxy/dokodemo/dokodemo.go +++ b/proxy/dokodemo/dokodemo.go @@ -1,7 +1,6 @@ package dokodemo import ( - "net" "sync" "github.com/v2ray/v2ray-core/app" @@ -151,7 +150,7 @@ func (this *DokodemoDoor) HandleTCPConnection(conn internet.Connection) { log.Info("Dokodemo: Handling request to ", dest) ray := this.packetDispatcher.DispatchToOutbound(this.meta, &proxy.SessionInfo{ - Source: v2net.TCPDestinationFromAddr(conn.RemoteAddr().(*net.TCPAddr)), + Source: v2net.DestinationFromAddr(conn.RemoteAddr()), Destination: dest, }) defer ray.InboundOutput().Release() diff --git a/proxy/http/server.go b/proxy/http/server.go index 1b3699b12..82ad004c3 100644 --- a/proxy/http/server.go +++ b/proxy/http/server.go @@ -120,7 +120,7 @@ func (this *Server) handleConnection(conn internet.Connection) { } log.Access(conn.RemoteAddr(), request.URL, log.AccessAccepted, "") session := &proxy.SessionInfo{ - Source: v2net.TCPDestinationFromAddr(conn.RemoteAddr().(*net.TCPAddr)), + Source: v2net.DestinationFromAddr(conn.RemoteAddr()), Destination: dest, } if strings.ToUpper(request.Method) == "CONNECT" { diff --git a/proxy/shadowsocks/server.go b/proxy/shadowsocks/server.go index d453397b6..12cace63b 100644 --- a/proxy/shadowsocks/server.go +++ b/proxy/shadowsocks/server.go @@ -4,7 +4,6 @@ package shadowsocks import ( "crypto/rand" "io" - "net" "sync" "github.com/v2ray/v2ray-core/app" @@ -206,7 +205,7 @@ func (this *Server) handleConnection(conn internet.Connection) { log.Info("Shadowsocks: Tunnelling request to ", dest) ray := this.packetDispatcher.DispatchToOutbound(this.meta, &proxy.SessionInfo{ - Source: v2net.TCPDestinationFromAddr(conn.RemoteAddr().(*net.TCPAddr)), + Source: v2net.DestinationFromAddr(conn.RemoteAddr()), Destination: dest, }) defer ray.InboundOutput().Release() diff --git a/proxy/socks/server.go b/proxy/socks/server.go index 2ed187e29..dae731589 100644 --- a/proxy/socks/server.go +++ b/proxy/socks/server.go @@ -3,7 +3,6 @@ package socks import ( "errors" "io" - "net" "sync" "time" @@ -120,7 +119,7 @@ func (this *Server) handleConnection(connection internet.Connection) { return } - clientAddr := v2net.TCPDestinationFromAddr(connection.RemoteAddr().(*net.TCPAddr)) + clientAddr := v2net.DestinationFromAddr(connection.RemoteAddr()) if err != nil && err == protocol.Socks4Downgrade { this.handleSocks4(clientAddr, reader, writer, auth4) } else { diff --git a/proxy/vmess/inbound/inbound.go b/proxy/vmess/inbound/inbound.go index 7dd2b3661..85a0b9de4 100644 --- a/proxy/vmess/inbound/inbound.go +++ b/proxy/vmess/inbound/inbound.go @@ -2,7 +2,6 @@ package inbound import ( "io" - "net" "sync" "github.com/v2ray/v2ray-core/app" @@ -165,7 +164,7 @@ func (this *VMessInboundHandler) HandleConnection(connection internet.Connection connection.SetReusable(request.Option.Has(protocol.RequestOptionConnectionReuse)) ray := this.packetDispatcher.DispatchToOutbound(this.meta, &proxy.SessionInfo{ - Source: v2net.TCPDestinationFromAddr(connection.RemoteAddr().(*net.TCPAddr)), + Source: v2net.DestinationFromAddr(connection.RemoteAddr()), Destination: request.Destination(), }) input := ray.InboundInput()