Merge pull request #2582 from v2fly/master

merge fly
pull/2585/head v4.25.0
Kslr 2020-06-19 23:10:25 +08:00 committed by GitHub
commit 3628ca4713
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 170 additions and 349 deletions

21
.github/workflows/linter.yml vendored Normal file
View File

@ -0,0 +1,21 @@
name: Lint Code Base
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
name: Lint Code Base
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Lint Code Base
uses: github/super-linter@v2.0.0
env:
VALIDATE_ALL_CODEBASE: false

34
.github/workflows/test.yml vendored Normal file
View File

@ -0,0 +1,34 @@
name: Test
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
name: Test
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
steps:
- name: Set up Go 1.x
uses: actions/setup-go@v2
with:
go-version: ^1.14
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Get dependencies
run: |
go get -v -t -d ./...
- name: Test
run: go test -parallel 1 -timeout 6h -v ./...

10
.vscode/settings.json vendored
View File

@ -1,10 +0,0 @@
// Place your settings in this file to overwrite default and user settings.
{
"editor.tabSize": 2,
"protoc": {
"options": [
"--proto_path=${env.GOPATH}/src/",
"--proto_path=${env.GOPATH}/src/github.com/google/protobuf/src"
]
}
}

51
.vscode/tasks.json vendored
View File

@ -1,51 +0,0 @@
{
"version": "2.0.0",
"command": "go",
"type": "shell",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared"
},
"tasks": [
{
"label": "build",
"args": ["v2ray.com/core/..."],
"group": "build",
"problemMatcher": {
"owner": "go",
"fileLocation": ["relative", "${workspaceRoot}"],
"pattern": {
"regexp": "^([^:]+\\.go):(\\d+):(.*)",
"file": 1,
"line": 2,
"message": 3
}
}
},
{
"label": "test",
"args": ["-p", "1", "v2ray.com/core/..."],
"group": "test"
},
{
"label": "Escape Analysis",
"type": "shell",
"command": "go build -gcflags -m .",
"problemMatcher": {
"pattern": {
"regexp": "^(.*):(.*):(.*): (.*)$",
"file": 1,
"line": 2,
"column": 3,
"message": 4
},
"fileLocation": ["relative", "${fileDirname}"]
},
"options": {
"cwd": "${fileDirname}"
}
}
]
}

View File

@ -103,6 +103,7 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *
sniffingConfig: receiverConfig.GetEffectiveSniffingSettings(),
uplinkCounter: uplinkCounter,
downlinkCounter: downlinkCounter,
ctx: ctx,
}
h.workers = append(h.workers, worker)
}

View File

@ -28,6 +28,8 @@ type DynamicInboundHandler struct {
lastRefresh time.Time
mux *mux.Server
task *task.Periodic
ctx context.Context
}
func NewDynamicInboundHandler(ctx context.Context, tag string, receiverConfig *proxyman.ReceiverConfig, proxyConfig interface{}) (*DynamicInboundHandler, error) {
@ -39,6 +41,7 @@ func NewDynamicInboundHandler(ctx context.Context, tag string, receiverConfig *p
portsInUse: make(map[net.Port]bool),
mux: mux.NewServer(ctx),
v: v,
ctx: ctx,
}
mss, err := internet.ToMemoryStreamConfig(receiverConfig.StreamSettings)
@ -134,6 +137,7 @@ func (h *DynamicInboundHandler) refresh() error {
sniffingConfig: h.receiverConfig.GetEffectiveSniffingSettings(),
uplinkCounter: uplinkCounter,
downlinkCounter: downlinkCounter,
ctx: h.ctx,
}
if err := worker.Start(); err != nil {
newError("failed to create TCP worker").Base(err).AtWarning().WriteToLog()

View File

@ -43,6 +43,8 @@ type tcpWorker struct {
downlinkCounter stats.Counter
hub internet.Listener
ctx context.Context
}
func getTProxyType(s *internet.MemoryStreamConfig) internet.SocketConfig_TProxyMode {
@ -53,7 +55,7 @@ func getTProxyType(s *internet.MemoryStreamConfig) internet.SocketConfig_TProxyM
}
func (w *tcpWorker) callback(conn internet.Connection) {
ctx, cancel := context.WithCancel(context.Background())
ctx, cancel := context.WithCancel(w.ctx)
sid := session.NewID()
ctx = session.ContextWithID(ctx, sid)
@ -330,7 +332,7 @@ func (w *udpWorker) clean() error {
}
for addr, conn := range w.activeConn {
if nowSec-atomic.LoadInt64(&conn.lastActivityTime) > 8 {
if nowSec-atomic.LoadInt64(&conn.lastActivityTime) > 8 { //TODO Timeout too small
delete(w.activeConn, addr)
conn.Close() // nolint: errcheck
}

View File

@ -144,7 +144,7 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (internet.Conn
conn := net.NewConnection(net.ConnectionInputMulti(uplinkWriter), net.ConnectionOutputMulti(downlinkReader))
if config := tls.ConfigFromStreamSettings(h.streamSettings); config != nil {
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest), tls.WithNextProto("h2"))
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest))
conn = tls.Client(conn, tlsConfig)
}

View File

@ -19,7 +19,7 @@ import (
)
var (
version = "4.24.2"
version = "4.25.0"
build = "Custom"
codename = "V2Fly, a community-driven edition of V2Ray."
intro = "A unified platform for anti-censorship."

View File

@ -14,7 +14,7 @@ import (
// CreateObject creates a new object based on the given V2Ray instance and config. The V2Ray instance may be nil.
func CreateObject(v *Instance, config interface{}) (interface{}, error) {
ctx := context.Background()
ctx := v.ctx
if v != nil {
ctx = context.WithValue(ctx, v2rayKey, v)
}

View File

@ -274,12 +274,13 @@ func (c *TLSCertConfig) Build() (*tls.Certificate, error) {
}
type TLSConfig struct {
Insecure bool `json:"allowInsecure"`
InsecureCiphers bool `json:"allowInsecureCiphers"`
Certs []*TLSCertConfig `json:"certificates"`
ServerName string `json:"serverName"`
ALPN *StringList `json:"alpn"`
DiableSystemRoot bool `json:"disableSystemRoot"`
Insecure bool `json:"allowInsecure"`
InsecureCiphers bool `json:"allowInsecureCiphers"`
Certs []*TLSCertConfig `json:"certificates"`
ServerName string `json:"serverName"`
ALPN *StringList `json:"alpn"`
DisableSessionResumption bool `json:"disableSessionResumption"`
DisableSystemRoot bool `json:"disableSystemRoot"`
}
// Build implements Buildable.
@ -302,7 +303,8 @@ func (c *TLSConfig) Build() (proto.Message, error) {
if c.ALPN != nil && len(*c.ALPN) > 0 {
config.NextProtocol = []string(*c.ALPN)
}
config.DisableSystemRoot = c.DiableSystemRoot
config.DisableSessionResumption = c.DisableSessionResumption
config.DisableSystemRoot = c.DisableSystemRoot
return config, nil
}

View File

@ -82,3 +82,18 @@ def gen_targets(matrix):
name = bin_name + "_sig",
base = ":" + bin_name,
)
bin_name = "v2ray_" + os + "_" + arch + "_armv5"
foreign_go_binary(
name = bin_name,
pkg = pkg,
output = output+"_armv5",
os = os,
arch = arch,
arm = "5",
)
gpg_sign(
name = bin_name + "_sig",
base = ":" + bin_name,
)

View File

@ -188,7 +188,9 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
return nil
}
if err := task.Run(ctx, task.OnSuccess(requestDone, task.Close(link.Writer)), responseDone, tproxyRequest); err != nil {
if err := task.Run(ctx, task.OnSuccess(func() error {
return task.Run(ctx, requestDone, tproxyRequest)
}, task.Close(link.Writer)), responseDone); err != nil {
common.Interrupt(link.Reader)
common.Interrupt(link.Writer)
return newError("connection ends").Base(err)

View File

@ -132,9 +132,10 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
continue
}
currentPacketCtx := ctx
dest := request.Destination()
if inbound.Source.IsValid() {
ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
currentPacketCtx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
From: inbound.Source,
To: dest,
Status: log.AccessAccepted,
@ -142,10 +143,10 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
Email: request.User.Email,
})
}
newError("tunnelling request to ", dest).WriteToLog(session.ExportIDToError(ctx))
newError("tunnelling request to ", dest).WriteToLog(session.ExportIDToError(currentPacketCtx))
ctx = protocol.ContextWithRequestHeader(ctx, request)
udpServer.Dispatch(ctx, dest, data)
currentPacketCtx = protocol.ContextWithRequestHeader(currentPacketCtx, request)
udpServer.Dispatch(currentPacketCtx, dest, data)
}
}

View File

@ -229,10 +229,10 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
payload.Release()
continue
}
currentPacketCtx := ctx
newError("send packet to ", request.Destination(), " with ", payload.Len(), " bytes").AtDebug().WriteToLog(session.ExportIDToError(ctx))
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() {
ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
currentPacketCtx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
From: inbound.Source,
To: request.Destination(),
Status: log.AccessAccepted,
@ -240,8 +240,8 @@ func (s *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
})
}
ctx = protocol.ContextWithRequestHeader(ctx, request)
udpServer.Dispatch(ctx, request.Destination(), payload)
currentPacketCtx = protocol.ContextWithRequestHeader(currentPacketCtx, request)
udpServer.Dispatch(currentPacketCtx, request.Destination(), payload)
}
}
}

View File

@ -201,11 +201,13 @@ pkg_zip(
"//infra/control/main:v2ctl_linux_arm_armv7_sig",
"//infra/control/main:v2ctl_linux_arm_sig",
"//main:v2ray_linux_arm",
"//main:v2ray_linux_arm_sig",
"//main:v2ray_linux_arm_armv5",
"//main:v2ray_linux_arm_armv5_sig",
"//main:v2ray_linux_arm_armv6",
"//main:v2ray_linux_arm_armv6_sig",
"//main:v2ray_linux_arm_armv7",
"//main:v2ray_linux_arm_armv7_sig",
"//main:v2ray_linux_arm_sig",
],
out = "v2ray-linux-arm.zip",
mappings = gen_mappings("linux", "arm"),

View File

@ -1,26 +0,0 @@
#!/bin/bash
GO_AMD64=https://storage.googleapis.com/golang/go1.11.1.linux-amd64.tar.gz
GO_X86=https://storage.googleapis.com/golang/go1.11.1.linux-386.tar.gz
ARCH=$(uname -m)
GO_CUR=${GO_AMD64}
if [ "$ARCH" == "i686" ] || [ "$ARCH" == "i386" ]; then
GO_CUR=${GO_X86}
fi
which git > /dev/null || apt-get install git -y
if [ -z "$GOPATH" ]; then
curl -o go_latest.tar.gz ${GO_CUR}
tar -C /usr/local -xzf go_latest.tar.gz
rm go_latest.tar.gz
export PATH=$PATH:/usr/local/go/bin
mkdir /v2ray &> /dev/null
export GOPATH=/v2ray
fi
go get -insecure -u v2ray.com/core/...
go build -o $GOPATH/bin/v2ray v2ray.com/core/main
go build -o $GOPATH/bin/v2ctl v2ray.com/core/infra/control/main

View File

@ -1,208 +0,0 @@
#!/bin/bash
set -x
apt-get update
apt-get -y install \
jq `# for parsing Github API` \
git `# for go get` \
file `# for Github upload` \
pkg-config zip g++ zlib1g-dev unzip python `# for Bazel` \
openssl `# for binary digest` \
function getattr() {
curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/$2/attributes/$1
}
GITHUB_TOKEN=$(getattr "github_token" "project")
RELEASE_TAG=$(getattr "release_tag" "instance")
PRERELEASE=$(getattr "prerelease" "instance")
DOCKER_HUB_KEY=$(getattr "docker_hub_key" "project")
SIGN_KEY_PATH=$(getattr "sign_key_path" "project")
SIGN_KEY_PASS=$(getattr "sign_key_pass" "project")
VUSER=$(getattr "b_user" "project")
mkdir -p /v2/build
pushd /v2/build
BAZEL_VER=0.23.0
curl -L -O https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VER}/bazel-${BAZEL_VER}-installer-linux-x86_64.sh
chmod +x bazel-${BAZEL_VER}-installer-linux-x86_64.sh
./bazel-${BAZEL_VER}-installer-linux-x86_64.sh
popd
gsutil cp ${SIGN_KEY_PATH} /v2/build/sign_key.asc
echo ${SIGN_KEY_PASS} | gpg --passphrase-fd 0 --batch --import /v2/build/sign_key.asc
curl -L -o /v2/build/releases https://api.github.com/repos/v2ray/v2ray-core/releases
GO_INSTALL=golang.tar.gz
curl -L -o ${GO_INSTALL} https://storage.googleapis.com/golang/go1.11.5.linux-amd64.tar.gz
tar -C /usr/local -xzf ${GO_INSTALL}
export PATH=$PATH:/usr/local/go/bin
mkdir -p /v2/src
export GOPATH=/v2
# Download all source code
go get -insecure -t v2ray.com/core/...
go get -insecure -t v2ray.com/ext/...
pushd $GOPATH/src/v2ray.com/core/
git checkout tags/${RELEASE_TAG}
VERN=${RELEASE_TAG:1}
BUILDN=`date +%Y%m%d`
sed -i "s/\(version *= *\"\).*\(\"\)/\1$VERN\2/g" core.go
sed -i "s/\(build *= *\"\).*\(\"\)/\1$BUILDN\2/g" core.go
popd
pushd $GOPATH/src/v2ray.com/core/
# Update geoip.dat
curl -L -o release/config/geoip.dat "https://github.com/v2ray/geoip/raw/release/geoip.dat"
sleep 1
# Update geosite.dat
curl -L -o release/config/geosite.dat "https://github.com/v2ray/domain-list-community/raw/release/dlc.dat"
sleep 1
popd
# Take a snapshot of all required source code
pushd $GOPATH/src
# Create zip file for all sources
zip -9 -r /v2/build/src_all.zip * -x '*.git*'
popd
pushd $GOPATH/src/v2ray.com/core/
bazel build --action_env=GOPATH=$GOPATH --action_env=PATH=$PATH --action_env=GPG_PASS=${SIGN_KEY_PASS} //release:all
popd
RELBODY="https://www.v2ray.com/chapter_00/01_versions.html"
JSON_DATA=$(echo "{}" | jq -c ".tag_name=\"${RELEASE_TAG}\"")
JSON_DATA=$(echo ${JSON_DATA} | jq -c ".prerelease=${PRERELEASE}")
JSON_DATA=$(echo ${JSON_DATA} | jq -c ".body=\"${RELBODY}\"")
RELEASE_ID=$(curl --data "${JSON_DATA}" -H "Authorization: token ${GITHUB_TOKEN}" -X POST https://api.github.com/repos/v2ray/v2ray-core/releases | jq ".id")
function uploadfile() {
FILE=$1
CTYPE=$(file -b --mime-type $FILE)
sleep 1
curl -H "Authorization: token ${GITHUB_TOKEN}" -H "Content-Type: ${CTYPE}" --data-binary @$FILE "https://uploads.github.com/repos/v2ray/v2ray-core/releases/${RELEASE_ID}/assets?name=$(basename $FILE)"
sleep 1
}
function upload() {
FILE=$1
DGST=$1.dgst
openssl dgst -md5 $FILE | sed 's/([^)]*)//g' >> $DGST
openssl dgst -sha1 $FILE | sed 's/([^)]*)//g' >> $DGST
openssl dgst -sha256 $FILE | sed 's/([^)]*)//g' >> $DGST
openssl dgst -sha512 $FILE | sed 's/([^)]*)//g' >> $DGST
uploadfile $FILE
uploadfile $DGST
}
ART_ROOT=$GOPATH/src/v2ray.com/core/bazel-bin/release
upload ${ART_ROOT}/v2ray-macos.zip
upload ${ART_ROOT}/v2ray-windows-64.zip
upload ${ART_ROOT}/v2ray-windows-32.zip
upload ${ART_ROOT}/v2ray-linux-64.zip
upload ${ART_ROOT}/v2ray-linux-32.zip
upload ${ART_ROOT}/v2ray-linux-arm.zip
upload ${ART_ROOT}/v2ray-linux-arm64.zip
upload ${ART_ROOT}/v2ray-linux-mips64.zip
upload ${ART_ROOT}/v2ray-linux-mips64le.zip
upload ${ART_ROOT}/v2ray-linux-mips.zip
upload ${ART_ROOT}/v2ray-linux-mipsle.zip
upload ${ART_ROOT}/v2ray-linux-ppc64.zip
upload ${ART_ROOT}/v2ray-linux-ppc64le.zip
upload ${ART_ROOT}/v2ray-linux-s390x.zip
upload ${ART_ROOT}/v2ray-freebsd-64.zip
upload ${ART_ROOT}/v2ray-freebsd-32.zip
upload ${ART_ROOT}/v2ray-openbsd-64.zip
upload ${ART_ROOT}/v2ray-openbsd-32.zip
upload ${ART_ROOT}/v2ray-dragonfly-64.zip
upload /v2/build/src_all.zip
if [[ "${PRERELEASE}" == "false" ]]; then
DOCKER_HUB_API=https://cloud.docker.com/api/build/v1/source/62bfa37d-18ef-4b66-8f1a-35f9f3d4438b/trigger/65027872-e73e-4177-8c6c-6448d2f00d5b/call/
curl -H "Content-Type: application/json" --data '{"build": true}' -X POST "${DOCKER_HUB_API}"
# Update homebrew
pushd ${ART_ROOT}
V_HASH256=$(sha256sum v2ray-macos.zip | cut -d ' ' -f 1)
popd
echo "SHA256: ${V_HASH256}"
echo "Version: ${VERN}"
DOWNLOAD_URL="https://github.com/v2ray/v2ray-core/releases/download/v${VERN}/v2ray-macos.zip"
cd $GOPATH/src/v2ray.com/
git clone https://github.com/v2ray/homebrew-v2ray.git
echo "Updating config"
cd homebrew-v2ray
sed -i "s#^\s*url.*# url \"$DOWNLOAD_URL\"#g" Formula/v2ray-core.rb
sed -i "s#^\s*sha256.*# sha256 \"$V_HASH256\"#g" Formula/v2ray-core.rb
sed -i "s#^\s*version.*# version \"$VERN\"#g" Formula/v2ray-core.rb
echo "Updating repo"
git config user.name "Darien Raymond"
git config user.email "admin@v2ray.com"
git commit -am "update to version $VERN"
git push --quiet "https://${GITHUB_TOKEN}@github.com/v2ray/homebrew-v2ray" master:master
echo "Updating dist"
cd $GOPATH/src/v2ray.com/
mkdir dist
cd dist
git init
git config user.name "Darien Raymond"
git config user.email "admin@v2ray.com"
cp ${ART_ROOT}/v2ray-macos.zip .
cp ${ART_ROOT}/v2ray-windows-64.zip .
cp ${ART_ROOT}/v2ray-windows-32.zip .
cp ${ART_ROOT}/v2ray-linux-64.zip .
cp ${ART_ROOT}/v2ray-linux-32.zip .
cp ${ART_ROOT}/v2ray-linux-arm.zip .
cp ${ART_ROOT}/v2ray-linux-arm64.zip .
cp ${ART_ROOT}/v2ray-linux-mips64.zip .
cp ${ART_ROOT}/v2ray-linux-mips64le.zip .
cp ${ART_ROOT}/v2ray-linux-mips.zip .
cp ${ART_ROOT}/v2ray-linux-mipsle.zip .
cp ${ART_ROOT}/v2ray-linux-ppc64.zip .
cp ${ART_ROOT}/v2ray-linux-ppc64le.zip .
cp ${ART_ROOT}/v2ray-linux-s390x.zip .
cp ${ART_ROOT}/v2ray-freebsd-64.zip .
cp ${ART_ROOT}/v2ray-freebsd-32.zip .
cp ${ART_ROOT}/v2ray-openbsd-64.zip .
cp ${ART_ROOT}/v2ray-openbsd-32.zip .
cp ${ART_ROOT}/v2ray-dragonfly-64.zip .
cp /v2/build/src_all.zip .
cp "$GOPATH/src/v2ray.com/core/release/install-release.sh" ./install.sh
sed -i "s/^NEW_VER=\"\"$/NEW_VER=\"${RELEASE_TAG}\"/" install.sh
sed -i 's/^DIST_SRC=".*"$/DIST_SRC="jsdelivr"/' install.sh
git add .
git commit -m "Version ${RELEASE_TAG}"
git tag -a "${RELEASE_TAG}" -m "Version ${RELEASE_TAG}"
git remote add origin "https://${GITHUB_TOKEN}@github.com/v2ray/dist"
git push -u --force --follow-tags origin master
fi
shutdown -h now

View File

@ -1,7 +1,7 @@
#!/bin/bash
pushd "$GOPATH/src/v2ray.com/core/" || return
pushd $GOPATH/src/v2ray.com/core/
# Update geoip.dat
GEOIP_TAG=$(curl --silent "https://api.github.com/repos/v2ray/geoip/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
curl -L -o release/config/geoip.dat "https://github.com/v2ray/geoip/releases/download/${GEOIP_TAG}/geoip.dat"
@ -11,4 +11,5 @@ sleep 1
GEOSITE_TAG=$(curl --silent "https://api.github.com/repos/v2ray/domain-list-community/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
curl -L -o release/config/geosite.dat "https://github.com/v2ray/domain-list-community/releases/download/${GEOSITE_TAG}/dlc.dat"
sleep 1
popd
popd || return

View File

@ -20,12 +20,12 @@ import (
var (
globalDialerMap map[net.Destination]*http.Client
globalDailerAccess sync.Mutex
globalDialerAccess sync.Mutex
)
func getHTTPClient(ctx context.Context, dest net.Destination, tlsSettings *tls.Config) (*http.Client, error) {
globalDailerAccess.Lock()
defer globalDailerAccess.Unlock()
globalDialerAccess.Lock()
defer globalDialerAccess.Unlock()
if globalDialerMap == nil {
globalDialerMap = make(map[net.Destination]*http.Client)
@ -54,9 +54,26 @@ func getHTTPClient(ctx context.Context, dest net.Destination, tlsSettings *tls.C
if err != nil {
return nil, err
}
return gotls.Client(pconn, tlsConfig), nil
cn := gotls.Client(pconn, tlsConfig)
if err := cn.Handshake(); err != nil {
return nil, err
}
if !tlsConfig.InsecureSkipVerify {
if err := cn.VerifyHostname(tlsConfig.ServerName); err != nil {
return nil, err
}
}
state := cn.ConnectionState()
if p := state.NegotiatedProtocol; p != http2.NextProtoTLS {
return nil, newError("http2: unexpected ALPN protocol " + p + "; want q" + http2.NextProtoTLS).AtError()
}
if !state.NegotiatedProtocolIsMutual {
return nil, newError("http2: could not negotiate protocol mutually").AtError()
}
return cn, nil
},
TLSClientConfig: tlsSettings.GetTLSConfig(tls.WithDestination(dest), tls.WithNextProto("h2")),
TLSClientConfig: tlsSettings.GetTLSConfig(tls.WithDestination(dest)),
}
client := &http.Client{

View File

@ -21,7 +21,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
}
if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest), tls.WithNextProto("h2"))
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest))
if config.IsExperiment8357() {
conn = tls.UClient(conn, tlsConfig)
} else {

View File

@ -176,6 +176,8 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
config := &tls.Config{
ClientSessionCache: globalSessionCache,
RootCAs: root,
InsecureSkipVerify: c.AllowInsecure,
NextProtos: c.NextProtocol,
SessionTicketsDisabled: c.DisableSessionResumption,
}
if c == nil {
@ -186,12 +188,6 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
opt(config)
}
if !c.AllowInsecureCiphers && len(config.CipherSuites) == 0 {
// crypto/tls will use the proper ciphers
config.CipherSuites = nil
}
config.InsecureSkipVerify = c.AllowInsecure
config.Certificates = c.BuildCertificates()
config.BuildNameToCertificate()
@ -204,11 +200,8 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
config.ServerName = sn
}
if len(c.NextProtocol) > 0 {
config.NextProtos = c.NextProtocol
}
if len(config.NextProtos) == 0 {
config.NextProtos = []string{"http/1.1"}
config.NextProtos = []string{"h2", "http/1.1"}
}
return config

View File

@ -45,7 +45,7 @@ func dialWebsocket(ctx context.Context, dest net.Destination, streamSettings *in
if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
protocol = "wss"
dialer.TLSClientConfig = config.GetTLSConfig(tls.WithDestination(dest))
dialer.TLSClientConfig = config.GetTLSConfig(tls.WithDestination(dest), tls.WithNextProto("http/1.1"))
}
host := dest.NetAddr()

View File

@ -92,6 +92,8 @@ type Instance struct {
features []features.Feature
featureResolutions []resolution
running bool
ctx context.Context
}
func AddInboundHandler(server *Instance, config *InboundHandlerConfig) error {
@ -104,7 +106,7 @@ func AddInboundHandler(server *Instance, config *InboundHandlerConfig) error {
if !ok {
return newError("not an InboundHandler")
}
if err := inboundManager.AddHandler(context.Background(), handler); err != nil {
if err := inboundManager.AddHandler(server.ctx, handler); err != nil {
return err
}
return nil
@ -130,7 +132,7 @@ func AddOutboundHandler(server *Instance, config *OutboundHandlerConfig) error {
if !ok {
return newError("not an OutboundHandler")
}
if err := outboundManager.AddHandler(context.Background(), handler); err != nil {
if err := outboundManager.AddHandler(server.ctx, handler); err != nil {
return err
}
return nil
@ -157,27 +159,47 @@ func RequireFeatures(ctx context.Context, callback interface{}) error {
// The instance is not started at this point.
// To ensure V2Ray instance works properly, the config must contain one Dispatcher, one InboundHandlerManager and one OutboundHandlerManager. Other features are optional.
func New(config *Config) (*Instance, error) {
var server = &Instance{}
var server = &Instance{ctx: context.Background()}
err, done := initInstanceWithConfig(config, server)
if done {
return nil, err
}
return server, nil
}
func NewWithContext(config *Config, ctx context.Context) (*Instance, error) {
var server = &Instance{ctx: ctx}
err, done := initInstanceWithConfig(config, server)
if done {
return nil, err
}
return server, nil
}
func initInstanceWithConfig(config *Config, server *Instance) (error, bool) {
if config.Transport != nil {
features.PrintDeprecatedFeatureWarning("global transport settings")
}
if err := config.Transport.Apply(); err != nil {
return nil, err
return err, true
}
for _, appSettings := range config.App {
settings, err := appSettings.GetInstance()
if err != nil {
return nil, err
return err, true
}
obj, err := CreateObject(server, settings)
if err != nil {
return nil, err
return err, true
}
if feature, ok := obj.(features.Feature); ok {
if err := server.AddFeature(feature); err != nil {
return nil, err
return err, true
}
}
}
@ -195,24 +217,23 @@ func New(config *Config) (*Instance, error) {
for _, f := range essentialFeatures {
if server.GetFeature(f.Type) == nil {
if err := server.AddFeature(f.Instance); err != nil {
return nil, err
return err, true
}
}
}
if server.featureResolutions != nil {
return nil, newError("not all dependency are resolved.")
return newError("not all dependency are resolved."), true
}
if err := addInboundHandlers(server, config.Inbound); err != nil {
return nil, err
return err, true
}
if err := addOutboundHandlers(server, config.Outbound); err != nil {
return nil, err
return err, true
}
return server, nil
return nil, false
}
// Type implements common.HasType.