mirror of
https://github.com/cmz0228/hysteria-dev.git
synced 2025-06-17 01:40:00 +00:00
Merge branch 'master' into wip-udp-hop
This commit is contained in:
commit
6ac5e0e455
45
.github/workflows/build-master.yml
vendored
45
.github/workflows/build-master.yml
vendored
@ -1,45 +0,0 @@
|
|||||||
name: Build master
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- 'master'
|
|
||||||
tags-ignore:
|
|
||||||
- 'v*'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
|
|
||||||
build:
|
|
||||||
name: Build
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
|
||||||
|
|
||||||
steps:
|
|
||||||
|
|
||||||
- name: Check out
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Get time
|
|
||||||
uses: gerred/actions/current-time@master
|
|
||||||
id: current-time
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
uses: tobyxdd/go-cross-build@d00fc41eb205f57dd90f6e5af4613e21c7ebe73f
|
|
||||||
env:
|
|
||||||
TIME: "${{ steps.current-time.outputs.time }}"
|
|
||||||
GOFLAGS: "-tags=gpl"
|
|
||||||
CGO_ENABLED: "0"
|
|
||||||
with:
|
|
||||||
name: hysteria
|
|
||||||
dest: dist
|
|
||||||
ldflags: -w -s -X main.appCommit=${{ github.sha }} -X main.appDate=${{ env.TIME }}
|
|
||||||
platforms: 'darwin/amd64, darwin/arm64, windows/amd64, windows/386, linux/amd64, linux/386, linux/arm, linux/arm64, linux/s390x, linux/mipsle, freebsd/amd64, freebsd/386, freebsd/arm, freebsd/arm64'
|
|
||||||
package: cmd
|
|
||||||
compress: false
|
|
||||||
|
|
||||||
- name: Archive
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: dist
|
|
||||||
path: dist
|
|
38
.github/workflows/dev-build-master.yml
vendored
Normal file
38
.github/workflows/dev-build-master.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
name: "Build master"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'master'
|
||||||
|
tags-ignore:
|
||||||
|
- 'v*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
||||||
|
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Check out
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Setup Go
|
||||||
|
uses: actions/setup-go@v3
|
||||||
|
with:
|
||||||
|
go-version: 1.19
|
||||||
|
|
||||||
|
- name: Run build script
|
||||||
|
env:
|
||||||
|
HY_APP_PLATFORMS: 'darwin/amd64,darwin/arm64,windows/amd64,windows/386,linux/amd64,linux/386,linux/arm,linux/arm64,linux/s390x,linux/mipsle,freebsd/amd64,freebsd/386,freebsd/arm,freebsd/arm64'
|
||||||
|
run: ./build.sh
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Archive
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: hysteria-binaries-${{ github.sha }}
|
||||||
|
path: ./build
|
@ -16,8 +16,8 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Get tag
|
- name: Get tag
|
||||||
uses: olegtarasov/get-tag@v2
|
id: get_tag
|
||||||
id: tagName
|
run: echo ::set-output name=tag::${GITHUB_REF#refs/tags/}
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v2
|
uses: docker/setup-qemu-action@v2
|
||||||
@ -38,7 +38,7 @@ jobs:
|
|||||||
context: .
|
context: .
|
||||||
push: true
|
push: true
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
tags: tobyxdd/hysteria:latest,tobyxdd/hysteria:${{ env.GIT_TAG_NAME }}
|
tags: tobyxdd/hysteria:latest,tobyxdd/hysteria:${{ steps.get_tag.outputs.tag }}
|
||||||
|
|
||||||
- name: Image digest
|
- name: Image digest
|
||||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
run: echo ${{ steps.docker_build.outputs.digest }}
|
61
.github/workflows/release.yml
vendored
61
.github/workflows/release.yml
vendored
@ -18,31 +18,20 @@ jobs:
|
|||||||
- name: Check out
|
- name: Check out
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Get tag
|
- name: Setup Go
|
||||||
uses: olegtarasov/get-tag@v2
|
uses: actions/setup-go@v3
|
||||||
id: tagName
|
|
||||||
|
|
||||||
- name: Get time
|
|
||||||
uses: gerred/actions/current-time@master
|
|
||||||
id: current-time
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
uses: tobyxdd/go-cross-build@d00fc41eb205f57dd90f6e5af4613e21c7ebe73f
|
|
||||||
env:
|
|
||||||
TIME: "${{ steps.current-time.outputs.time }}"
|
|
||||||
GOFLAGS: "-tags=gpl"
|
|
||||||
CGO_ENABLED: "0"
|
|
||||||
with:
|
with:
|
||||||
name: hysteria
|
go-version: 1.19
|
||||||
dest: dist
|
|
||||||
ldflags: -w -s -X main.appVersion=${{ env.GIT_TAG_NAME }} -X main.appCommit=${{ github.sha }} -X main.appDate=${{ env.TIME }}
|
- name: Run build script
|
||||||
platforms: 'darwin/amd64, darwin/arm64, windows/amd64, windows/386, linux/amd64, linux/386, linux/arm, linux/arm64, linux/s390x, linux/mipsle, freebsd/amd64, freebsd/386, freebsd/arm, freebsd/arm64'
|
env:
|
||||||
package: cmd
|
HY_APP_PLATFORMS: 'darwin/amd64,darwin/arm64,windows/amd64,windows/386,linux/amd64,linux/386,linux/arm,linux/arm64,linux/s390x,linux/mipsle,freebsd/amd64,freebsd/386,freebsd/arm,freebsd/arm64'
|
||||||
compress: false
|
run: ./build.sh
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Generate hashes
|
- name: Generate hashes
|
||||||
run: |
|
run: |
|
||||||
cd dist
|
cd build
|
||||||
for f in $(find . -type f); do
|
for f in $(find . -type f); do
|
||||||
sha256sum $f | sudo tee -a hashes.txt
|
sha256sum $f | sudo tee -a hashes.txt
|
||||||
done
|
done
|
||||||
@ -52,18 +41,18 @@ jobs:
|
|||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
./dist/hysteria-darwin-amd64
|
./build/hysteria-darwin-amd64
|
||||||
./dist/hysteria-darwin-arm64
|
./build/hysteria-darwin-arm64
|
||||||
./dist/hysteria-windows-amd64.exe
|
./build/hysteria-windows-amd64.exe
|
||||||
./dist/hysteria-windows-386.exe
|
./build/hysteria-windows-386.exe
|
||||||
./dist/hysteria-linux-amd64
|
./build/hysteria-linux-amd64
|
||||||
./dist/hysteria-linux-386
|
./build/hysteria-linux-386
|
||||||
./dist/hysteria-linux-arm
|
./build/hysteria-linux-arm
|
||||||
./dist/hysteria-linux-arm64
|
./build/hysteria-linux-arm64
|
||||||
./dist/hysteria-linux-s390x
|
./build/hysteria-linux-s390x
|
||||||
./dist/hysteria-linux-mipsle
|
./build/hysteria-linux-mipsle
|
||||||
./dist/hysteria-freebsd-amd64
|
./build/hysteria-freebsd-amd64
|
||||||
./dist/hysteria-freebsd-386
|
./build/hysteria-freebsd-386
|
||||||
./dist/hysteria-freebsd-arm
|
./build/hysteria-freebsd-arm
|
||||||
./dist/hysteria-freebsd-arm64
|
./build/hysteria-freebsd-arm64
|
||||||
./dist/hashes.txt
|
./build/hashes.txt
|
||||||
|
11
Dockerfile
11
Dockerfile
@ -11,17 +11,12 @@ ENV GOPROXY ${GOPROXY}
|
|||||||
|
|
||||||
COPY . /go/src/github.com/hynetwork/hysteria
|
COPY . /go/src/github.com/hynetwork/hysteria
|
||||||
|
|
||||||
WORKDIR /go/src/github.com/hynetwork/hysteria/cmd
|
WORKDIR /go/src/github.com/hynetwork/hysteria
|
||||||
|
|
||||||
RUN set -ex \
|
RUN set -ex \
|
||||||
&& apk add git build-base \
|
&& apk add git build-base \
|
||||||
&& export VERSION=$(git describe --tags) \
|
&& ./build.sh \
|
||||||
&& export COMMIT=$(git rev-parse HEAD) \
|
&& mv ./build/hysteria-* /go/bin/hysteria
|
||||||
&& export TIMESTAMP=$(date "+%F %T") \
|
|
||||||
&& go build -trimpath -o /go/bin/hysteria -ldflags \
|
|
||||||
"-w -s -X 'main.appVersion=${VERSION}' \
|
|
||||||
-X 'main.appCommit=${COMMIT}' \
|
|
||||||
-X 'main.appDate=${TIMESTAMP}'"
|
|
||||||
|
|
||||||
# multi-stage builds to create the final image
|
# multi-stage builds to create the final image
|
||||||
FROM alpine AS dist
|
FROM alpine AS dist
|
||||||
|
69
build.ps1
Normal file
69
build.ps1
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# Hysteria build script for Windows (PowerShell)
|
||||||
|
|
||||||
|
# Environment variable options:
|
||||||
|
# - HY_APP_VERSION: App version
|
||||||
|
# - HY_APP_COMMIT: App commit hash
|
||||||
|
# - HY_APP_PLATFORMS: Platforms to build for (e.g. "windows/amd64,linux/amd64,darwin/amd64")
|
||||||
|
|
||||||
|
if (!(Get-Command go -ErrorAction SilentlyContinue)) {
|
||||||
|
Write-Host "Error: go is not installed." -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(Get-Command git -ErrorAction SilentlyContinue)) {
|
||||||
|
Write-Host "Error: git is not installed." -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
if (!(git rev-parse --is-inside-work-tree 2>$null)) {
|
||||||
|
Write-Host "Error: not in a git repository." -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$ldflags = "-s -w -X 'main.appDate=$(Get-Date -Format "yyyy-MM-dd HH:mm:ss")'"
|
||||||
|
if ($env:HY_APP_VERSION) {
|
||||||
|
$ldflags += " -X 'main.appVersion=$($env:HY_APP_VERSION)'"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$ldflags += " -X 'main.appVersion=$(git describe --tags --always)'"
|
||||||
|
}
|
||||||
|
if ($env:HY_APP_COMMIT) {
|
||||||
|
$ldflags += " -X 'main.appCommit=$($env:HY_APP_COMMIT)'"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$ldflags += " -X 'main.appCommit=$(git rev-parse HEAD)'"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($env:HY_APP_PLATFORMS) {
|
||||||
|
$platforms = $env:HY_APP_PLATFORMS.Split(",")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$goos = go env GOOS
|
||||||
|
$goarch = go env GOARCH
|
||||||
|
$platforms = @("$goos/$goarch")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Test-Path build) {
|
||||||
|
Remove-Item -Recurse -Force build
|
||||||
|
}
|
||||||
|
New-Item -ItemType Directory -Force -Path build
|
||||||
|
|
||||||
|
Write-Host "Starting build..." -ForegroundColor Green
|
||||||
|
|
||||||
|
foreach ($platform in $platforms) {
|
||||||
|
$env:GOOS = $platform.Split("/")[0]
|
||||||
|
$env:GOARCH = $platform.Split("/")[1]
|
||||||
|
Write-Host "Building $env:GOOS/$env:GOARCH" -ForegroundColor Green
|
||||||
|
$output = "build/hysteria-$env:GOOS-$env:GOARCH"
|
||||||
|
if ($env:GOOS -eq "windows") {
|
||||||
|
$output = "$output.exe"
|
||||||
|
}
|
||||||
|
go build -o $output -tags=gpl -ldflags $ldflags -trimpath ./cmd/
|
||||||
|
if ($LastExitCode -ne 0) {
|
||||||
|
Write-Host "Error: failed to build $env:GOOS/$env:GOARCH" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Build complete." -ForegroundColor Green
|
||||||
|
|
||||||
|
Get-ChildItem -Path build | Format-Table -AutoSize
|
62
build.sh
Executable file
62
build.sh
Executable file
@ -0,0 +1,62 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Hysteria build script for Linux
|
||||||
|
# Environment variable options:
|
||||||
|
# - HY_APP_VERSION: App version
|
||||||
|
# - HY_APP_COMMIT: App commit hash
|
||||||
|
# - HY_APP_PLATFORMS: Platforms to build for (e.g. "windows/amd64,linux/amd64,darwin/amd64")
|
||||||
|
|
||||||
|
if ! [ -x "$(command -v go)" ]; then
|
||||||
|
echo 'Error: go is not installed.' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! [ -x "$(command -v git)" ]; then
|
||||||
|
echo 'Error: git is not installed.' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||||
|
echo 'Error: not in a git repository.' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ldflags="-s -w -X 'main.appDate=$(date -u '+%F %T')'"
|
||||||
|
if [ -n "$HY_APP_VERSION" ]; then
|
||||||
|
ldflags="$ldflags -X 'main.appVersion=$HY_APP_VERSION'"
|
||||||
|
else
|
||||||
|
ldflags="$ldflags -X 'main.appVersion=$(git describe --tags --always)'"
|
||||||
|
fi
|
||||||
|
if [ -n "$HY_APP_COMMIT" ]; then
|
||||||
|
ldflags="$ldflags -X 'main.appCommit=$HY_APP_COMMIT'"
|
||||||
|
else
|
||||||
|
ldflags="$ldflags -X 'main.appCommit=$(git rev-parse HEAD)'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$HY_APP_PLATFORMS" ]; then
|
||||||
|
HY_APP_PLATFORMS="$(go env GOOS)/$(go env GOARCH)"
|
||||||
|
fi
|
||||||
|
platforms=(${HY_APP_PLATFORMS//,/ })
|
||||||
|
|
||||||
|
mkdir -p build
|
||||||
|
rm -rf build/*
|
||||||
|
|
||||||
|
echo "Starting build..."
|
||||||
|
|
||||||
|
for platform in "${platforms[@]}"; do
|
||||||
|
GOOS=${platform%/*}
|
||||||
|
GOARCH=${platform#*/}
|
||||||
|
echo "Building $GOOS/$GOARCH"
|
||||||
|
output="build/hysteria-$GOOS-$GOARCH"
|
||||||
|
if [ $GOOS = "windows" ]; then
|
||||||
|
output="$output.exe"
|
||||||
|
fi
|
||||||
|
env GOOS=$GOOS GOARCH=$GOARCH go build -o $output -tags=gpl -ldflags "$ldflags" -trimpath ./cmd/
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: failed to build $GOOS/$GOARCH"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Build complete."
|
||||||
|
|
||||||
|
ls -lh build/ | awk '{print $9, $5}'
|
@ -40,6 +40,7 @@ var clientPacketConnFuncFactoryMap = map[string]pktconns.ClientPacketConnFuncFac
|
|||||||
|
|
||||||
func client(config *clientConfig) {
|
func client(config *clientConfig) {
|
||||||
logrus.WithField("config", config.String()).Info("Client configuration loaded")
|
logrus.WithField("config", config.String()).Info("Client configuration loaded")
|
||||||
|
config.Fill() // Fill default values
|
||||||
// Resolver
|
// Resolver
|
||||||
if len(config.Resolver) > 0 {
|
if len(config.Resolver) > 0 {
|
||||||
err := setResolver(config.Resolver)
|
err := setResolver(config.Resolver)
|
||||||
@ -51,15 +52,11 @@ func client(config *clientConfig) {
|
|||||||
}
|
}
|
||||||
// TLS
|
// TLS
|
||||||
tlsConfig := &tls.Config{
|
tlsConfig := &tls.Config{
|
||||||
|
NextProtos: []string{config.ALPN},
|
||||||
ServerName: config.ServerName,
|
ServerName: config.ServerName,
|
||||||
InsecureSkipVerify: config.Insecure,
|
InsecureSkipVerify: config.Insecure,
|
||||||
MinVersion: tls.VersionTLS13,
|
MinVersion: tls.VersionTLS13,
|
||||||
}
|
}
|
||||||
if config.ALPN != "" {
|
|
||||||
tlsConfig.NextProtos = []string{config.ALPN}
|
|
||||||
} else {
|
|
||||||
tlsConfig.NextProtos = []string{DefaultALPN}
|
|
||||||
}
|
|
||||||
// Load CA
|
// Load CA
|
||||||
if len(config.CustomCA) > 0 {
|
if len(config.CustomCA) > 0 {
|
||||||
bs, err := ioutil.ReadFile(config.CustomCA)
|
bs, err := ioutil.ReadFile(config.CustomCA)
|
||||||
@ -84,24 +81,11 @@ func client(config *clientConfig) {
|
|||||||
InitialConnectionReceiveWindow: config.ReceiveWindow,
|
InitialConnectionReceiveWindow: config.ReceiveWindow,
|
||||||
MaxConnectionReceiveWindow: config.ReceiveWindow,
|
MaxConnectionReceiveWindow: config.ReceiveWindow,
|
||||||
HandshakeIdleTimeout: time.Duration(config.HandshakeTimeout) * time.Second,
|
HandshakeIdleTimeout: time.Duration(config.HandshakeTimeout) * time.Second,
|
||||||
|
MaxIdleTimeout: time.Duration(config.IdleTimeout) * time.Second,
|
||||||
|
KeepAlivePeriod: time.Duration(config.IdleTimeout) * time.Second * 2 / 5,
|
||||||
DisablePathMTUDiscovery: config.DisableMTUDiscovery,
|
DisablePathMTUDiscovery: config.DisableMTUDiscovery,
|
||||||
EnableDatagrams: true,
|
EnableDatagrams: true,
|
||||||
}
|
}
|
||||||
if config.IdleTimeout == 0 {
|
|
||||||
quicConfig.MaxIdleTimeout = DefaultClientMaxIdleTimeout
|
|
||||||
quicConfig.KeepAlivePeriod = DefaultClientKeepAlivePeriod
|
|
||||||
} else {
|
|
||||||
quicConfig.MaxIdleTimeout = time.Duration(config.IdleTimeout) * time.Second
|
|
||||||
quicConfig.KeepAlivePeriod = quicConfig.MaxIdleTimeout * 2 / 5
|
|
||||||
}
|
|
||||||
if config.ReceiveWindowConn == 0 {
|
|
||||||
quicConfig.InitialStreamReceiveWindow = DefaultStreamReceiveWindow
|
|
||||||
quicConfig.MaxStreamReceiveWindow = DefaultStreamReceiveWindow
|
|
||||||
}
|
|
||||||
if config.ReceiveWindow == 0 {
|
|
||||||
quicConfig.InitialConnectionReceiveWindow = DefaultConnectionReceiveWindow
|
|
||||||
quicConfig.MaxConnectionReceiveWindow = DefaultConnectionReceiveWindow
|
|
||||||
}
|
|
||||||
if !quicConfig.DisablePathMTUDiscovery && pmtud.DisablePathMTUDiscovery {
|
if !quicConfig.DisablePathMTUDiscovery && pmtud.DisablePathMTUDiscovery {
|
||||||
logrus.Info("Path MTU Discovery is not yet supported on this platform")
|
logrus.Info("Path MTU Discovery is not yet supported on this platform")
|
||||||
}
|
}
|
||||||
@ -136,11 +120,7 @@ func client(config *clientConfig) {
|
|||||||
var err error
|
var err error
|
||||||
aclEngine, err = acl.LoadFromFile(config.ACL, transport.DefaultClientTransport.ResolveIPAddr,
|
aclEngine, err = acl.LoadFromFile(config.ACL, transport.DefaultClientTransport.ResolveIPAddr,
|
||||||
func() (*geoip2.Reader, error) {
|
func() (*geoip2.Reader, error) {
|
||||||
if len(config.MMDB) > 0 {
|
return loadMMDBReader(config.MMDB)
|
||||||
return loadMMDBReader(config.MMDB)
|
|
||||||
} else {
|
|
||||||
return loadMMDBReader(DefaultMMDBFilename)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithFields(logrus.Fields{
|
logrus.WithFields(logrus.Fields{
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/yosuke-furukawa/json5/encoding/json5"
|
"github.com/yosuke-furukawa/json5/encoding/json5"
|
||||||
@ -15,17 +14,16 @@ const (
|
|||||||
mbpsToBps = 125000
|
mbpsToBps = 125000
|
||||||
minSpeedBPS = 16384
|
minSpeedBPS = 16384
|
||||||
|
|
||||||
|
DefaultALPN = "hysteria"
|
||||||
|
|
||||||
DefaultStreamReceiveWindow = 15728640 // 15 MB/s
|
DefaultStreamReceiveWindow = 15728640 // 15 MB/s
|
||||||
DefaultConnectionReceiveWindow = 67108864 // 64 MB/s
|
DefaultConnectionReceiveWindow = 67108864 // 64 MB/s
|
||||||
DefaultMaxIncomingStreams = 1024
|
DefaultMaxIncomingStreams = 1024
|
||||||
|
|
||||||
DefaultALPN = "hysteria"
|
|
||||||
|
|
||||||
DefaultMMDBFilename = "GeoLite2-Country.mmdb"
|
DefaultMMDBFilename = "GeoLite2-Country.mmdb"
|
||||||
|
|
||||||
ServerMaxIdleTimeout = 60 * time.Second
|
ServerMaxIdleTimeoutSec = 60
|
||||||
DefaultClientMaxIdleTimeout = 20 * time.Second
|
DefaultClientIdleTimeoutSec = 20
|
||||||
DefaultClientKeepAlivePeriod = 8 * time.Second
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var rateStringRegexp = regexp.MustCompile(`^(\d+)\s*([KMGT]?)([Bb])ps$`)
|
var rateStringRegexp = regexp.MustCompile(`^(\d+)\s*([KMGT]?)([Bb])ps$`)
|
||||||
@ -98,10 +96,10 @@ func (c *serverConfig) Speed() (uint64, uint64, error) {
|
|||||||
|
|
||||||
func (c *serverConfig) Check() error {
|
func (c *serverConfig) Check() error {
|
||||||
if len(c.Listen) == 0 {
|
if len(c.Listen) == 0 {
|
||||||
return errors.New("no listen address")
|
return errors.New("missing listen address")
|
||||||
}
|
}
|
||||||
if len(c.ACME.Domains) == 0 && (len(c.CertFile) == 0 || len(c.KeyFile) == 0) {
|
if len(c.ACME.Domains) == 0 && (len(c.CertFile) == 0 || len(c.KeyFile) == 0) {
|
||||||
return errors.New("ACME domain or TLS cert not provided")
|
return errors.New("need either ACME info or cert/key files")
|
||||||
}
|
}
|
||||||
if up, down, err := c.Speed(); err != nil || (up != 0 && up < minSpeedBPS) || (down != 0 && down < minSpeedBPS) {
|
if up, down, err := c.Speed(); err != nil || (up != 0 && up < minSpeedBPS) || (down != 0 && down < minSpeedBPS) {
|
||||||
return errors.New("invalid speed")
|
return errors.New("invalid speed")
|
||||||
@ -116,6 +114,24 @@ func (c *serverConfig) Check() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *serverConfig) Fill() {
|
||||||
|
if len(c.ALPN) == 0 {
|
||||||
|
c.ALPN = DefaultALPN
|
||||||
|
}
|
||||||
|
if c.ReceiveWindowConn == 0 {
|
||||||
|
c.ReceiveWindowConn = DefaultStreamReceiveWindow
|
||||||
|
}
|
||||||
|
if c.ReceiveWindowClient == 0 {
|
||||||
|
c.ReceiveWindowClient = DefaultConnectionReceiveWindow
|
||||||
|
}
|
||||||
|
if c.MaxConnClient == 0 {
|
||||||
|
c.MaxConnClient = DefaultMaxIncomingStreams
|
||||||
|
}
|
||||||
|
if len(c.MMDB) == 0 {
|
||||||
|
c.MMDB = DefaultMMDBFilename
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *serverConfig) String() string {
|
func (c *serverConfig) String() string {
|
||||||
return fmt.Sprintf("%+v", *c)
|
return fmt.Sprintf("%+v", *c)
|
||||||
}
|
}
|
||||||
@ -128,10 +144,10 @@ type Relay struct {
|
|||||||
|
|
||||||
func (r *Relay) Check() error {
|
func (r *Relay) Check() error {
|
||||||
if len(r.Listen) == 0 {
|
if len(r.Listen) == 0 {
|
||||||
return errors.New("no relay listen address")
|
return errors.New("missing relay listen address")
|
||||||
}
|
}
|
||||||
if len(r.Remote) == 0 {
|
if len(r.Remote) == 0 {
|
||||||
return errors.New("no relay remote address")
|
return errors.New("missing relay remote address")
|
||||||
}
|
}
|
||||||
if r.Timeout != 0 && r.Timeout < 4 {
|
if r.Timeout != 0 && r.Timeout < 4 {
|
||||||
return errors.New("invalid relay timeout")
|
return errors.New("invalid relay timeout")
|
||||||
@ -252,10 +268,10 @@ func (c *clientConfig) Check() error {
|
|||||||
return errors.New("invalid TUN timeout")
|
return errors.New("invalid TUN timeout")
|
||||||
}
|
}
|
||||||
if len(c.TCPRelay.Listen) > 0 && len(c.TCPRelay.Remote) == 0 {
|
if len(c.TCPRelay.Listen) > 0 && len(c.TCPRelay.Remote) == 0 {
|
||||||
return errors.New("no TCP relay remote address")
|
return errors.New("missing TCP relay remote address")
|
||||||
}
|
}
|
||||||
if len(c.UDPRelay.Listen) > 0 && len(c.UDPRelay.Remote) == 0 {
|
if len(c.UDPRelay.Listen) > 0 && len(c.UDPRelay.Remote) == 0 {
|
||||||
return errors.New("no UDP relay remote address")
|
return errors.New("missing UDP relay remote address")
|
||||||
}
|
}
|
||||||
if c.TCPRelay.Timeout != 0 && c.TCPRelay.Timeout < 4 {
|
if c.TCPRelay.Timeout != 0 && c.TCPRelay.Timeout < 4 {
|
||||||
return errors.New("invalid TCP relay timeout")
|
return errors.New("invalid TCP relay timeout")
|
||||||
@ -283,7 +299,7 @@ func (c *clientConfig) Check() error {
|
|||||||
return errors.New("invalid TCP Redirect timeout")
|
return errors.New("invalid TCP Redirect timeout")
|
||||||
}
|
}
|
||||||
if len(c.Server) == 0 {
|
if len(c.Server) == 0 {
|
||||||
return errors.New("no server address")
|
return errors.New("missing server address")
|
||||||
}
|
}
|
||||||
if up, down, err := c.Speed(); err != nil || up < minSpeedBPS || down < minSpeedBPS {
|
if up, down, err := c.Speed(); err != nil || up < minSpeedBPS || down < minSpeedBPS {
|
||||||
return errors.New("invalid speed")
|
return errors.New("invalid speed")
|
||||||
@ -293,14 +309,32 @@ func (c *clientConfig) Check() error {
|
|||||||
return errors.New("invalid receive window size")
|
return errors.New("invalid receive window size")
|
||||||
}
|
}
|
||||||
if len(c.TCPRelay.Listen) > 0 {
|
if len(c.TCPRelay.Listen) > 0 {
|
||||||
logrus.Warn("'relay_tcp' is deprecated, please use 'relay_tcps' instead")
|
logrus.Warn("'relay_tcp' is deprecated, consider using 'relay_tcps' instead")
|
||||||
}
|
}
|
||||||
if len(c.UDPRelay.Listen) > 0 {
|
if len(c.UDPRelay.Listen) > 0 {
|
||||||
logrus.Warn("config 'relay_udp' is deprecated, please use 'relay_udps' instead")
|
logrus.Warn("'relay_udp' is deprecated, consider using 'relay_udps' instead")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *clientConfig) Fill() {
|
||||||
|
if len(c.ALPN) == 0 {
|
||||||
|
c.ALPN = DefaultALPN
|
||||||
|
}
|
||||||
|
if c.ReceiveWindowConn == 0 {
|
||||||
|
c.ReceiveWindowConn = DefaultStreamReceiveWindow
|
||||||
|
}
|
||||||
|
if c.ReceiveWindow == 0 {
|
||||||
|
c.ReceiveWindow = DefaultConnectionReceiveWindow
|
||||||
|
}
|
||||||
|
if len(c.MMDB) == 0 {
|
||||||
|
c.MMDB = DefaultMMDBFilename
|
||||||
|
}
|
||||||
|
if c.IdleTimeout == 0 {
|
||||||
|
c.IdleTimeout = DefaultClientIdleTimeoutSec
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *clientConfig) String() string {
|
func (c *clientConfig) String() string {
|
||||||
return fmt.Sprintf("%+v", *c)
|
return fmt.Sprintf("%+v", *c)
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ var serverPacketConnFuncFactoryMap = map[string]pktconns.ServerPacketConnFuncFac
|
|||||||
|
|
||||||
func server(config *serverConfig) {
|
func server(config *serverConfig) {
|
||||||
logrus.WithField("config", config.String()).Info("Server configuration loaded")
|
logrus.WithField("config", config.String()).Info("Server configuration loaded")
|
||||||
|
config.Fill() // Fill default values
|
||||||
// Resolver
|
// Resolver
|
||||||
if len(config.Resolver) > 0 {
|
if len(config.Resolver) > 0 {
|
||||||
err := setResolver(config.Resolver)
|
err := setResolver(config.Resolver)
|
||||||
@ -55,6 +56,7 @@ func server(config *serverConfig) {
|
|||||||
"error": err,
|
"error": err,
|
||||||
}).Fatal("Failed to get a certificate with ACME")
|
}).Fatal("Failed to get a certificate with ACME")
|
||||||
}
|
}
|
||||||
|
tc.NextProtos = []string{config.ALPN}
|
||||||
tc.MinVersion = tls.VersionTLS13
|
tc.MinVersion = tls.VersionTLS13
|
||||||
tlsConfig = tc
|
tlsConfig = tc
|
||||||
} else {
|
} else {
|
||||||
@ -69,14 +71,10 @@ func server(config *serverConfig) {
|
|||||||
}
|
}
|
||||||
tlsConfig = &tls.Config{
|
tlsConfig = &tls.Config{
|
||||||
GetCertificate: kpl.GetCertificateFunc(),
|
GetCertificate: kpl.GetCertificateFunc(),
|
||||||
|
NextProtos: []string{config.ALPN},
|
||||||
MinVersion: tls.VersionTLS13,
|
MinVersion: tls.VersionTLS13,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if config.ALPN != "" {
|
|
||||||
tlsConfig.NextProtos = []string{config.ALPN}
|
|
||||||
} else {
|
|
||||||
tlsConfig.NextProtos = []string{DefaultALPN}
|
|
||||||
}
|
|
||||||
// QUIC config
|
// QUIC config
|
||||||
quicConfig := &quic.Config{
|
quicConfig := &quic.Config{
|
||||||
InitialStreamReceiveWindow: config.ReceiveWindowConn,
|
InitialStreamReceiveWindow: config.ReceiveWindowConn,
|
||||||
@ -84,22 +82,11 @@ func server(config *serverConfig) {
|
|||||||
InitialConnectionReceiveWindow: config.ReceiveWindowClient,
|
InitialConnectionReceiveWindow: config.ReceiveWindowClient,
|
||||||
MaxConnectionReceiveWindow: config.ReceiveWindowClient,
|
MaxConnectionReceiveWindow: config.ReceiveWindowClient,
|
||||||
MaxIncomingStreams: int64(config.MaxConnClient),
|
MaxIncomingStreams: int64(config.MaxConnClient),
|
||||||
MaxIdleTimeout: ServerMaxIdleTimeout,
|
MaxIdleTimeout: ServerMaxIdleTimeoutSec * time.Second,
|
||||||
KeepAlivePeriod: 0, // Keep alive should solely be client's responsibility
|
KeepAlivePeriod: 0, // Keep alive should solely be client's responsibility
|
||||||
DisablePathMTUDiscovery: config.DisableMTUDiscovery,
|
DisablePathMTUDiscovery: config.DisableMTUDiscovery,
|
||||||
EnableDatagrams: true,
|
EnableDatagrams: true,
|
||||||
}
|
}
|
||||||
if config.ReceiveWindowConn == 0 {
|
|
||||||
quicConfig.InitialStreamReceiveWindow = DefaultStreamReceiveWindow
|
|
||||||
quicConfig.MaxStreamReceiveWindow = DefaultStreamReceiveWindow
|
|
||||||
}
|
|
||||||
if config.ReceiveWindowClient == 0 {
|
|
||||||
quicConfig.InitialConnectionReceiveWindow = DefaultConnectionReceiveWindow
|
|
||||||
quicConfig.MaxConnectionReceiveWindow = DefaultConnectionReceiveWindow
|
|
||||||
}
|
|
||||||
if quicConfig.MaxIncomingStreams == 0 {
|
|
||||||
quicConfig.MaxIncomingStreams = DefaultMaxIncomingStreams
|
|
||||||
}
|
|
||||||
if !quicConfig.DisablePathMTUDiscovery && pmtud.DisablePathMTUDiscovery {
|
if !quicConfig.DisablePathMTUDiscovery && pmtud.DisablePathMTUDiscovery {
|
||||||
logrus.Info("Path MTU Discovery is not yet supported on this platform")
|
logrus.Info("Path MTU Discovery is not yet supported on this platform")
|
||||||
}
|
}
|
||||||
@ -109,8 +96,8 @@ func server(config *serverConfig) {
|
|||||||
switch authMode := config.Auth.Mode; authMode {
|
switch authMode := config.Auth.Mode; authMode {
|
||||||
case "", "none":
|
case "", "none":
|
||||||
if len(config.Obfs) == 0 {
|
if len(config.Obfs) == 0 {
|
||||||
logrus.Warn("No authentication or obfuscation enabled. " +
|
logrus.Warn("Neither authentication nor obfuscation is turned on. " +
|
||||||
"Your server could be accessed by anyone! Are you sure this is what you intended?")
|
"Your server could be used by anyone! Are you sure this is what you want?")
|
||||||
}
|
}
|
||||||
authFunc = func(addr net.Addr, auth []byte, sSend uint64, sRecv uint64) (bool, string) {
|
authFunc = func(addr net.Addr, auth []byte, sSend uint64, sRecv uint64) (bool, string) {
|
||||||
return true, "Welcome"
|
return true, "Welcome"
|
||||||
@ -200,11 +187,7 @@ func server(config *serverConfig) {
|
|||||||
return ipAddr, err
|
return ipAddr, err
|
||||||
},
|
},
|
||||||
func() (*geoip2.Reader, error) {
|
func() (*geoip2.Reader, error) {
|
||||||
if len(config.MMDB) > 0 {
|
return loadMMDBReader(config.MMDB)
|
||||||
return loadMMDBReader(config.MMDB)
|
|
||||||
} else {
|
|
||||||
return loadMMDBReader(DefaultMMDBFilename)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithFields(logrus.Fields{
|
logrus.WithFields(logrus.Fields{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user