Compare commits

..

No commits in common. "master" and "v2.11.2" have entirely different histories.

49 changed files with 724 additions and 953 deletions

74
.github/workflows/buildx.yaml vendored Normal file
View File

@ -0,0 +1,74 @@
# ref: https://github.com/crazy-max/diun/blob/master/.github/workflows/build.yml
name: Docker
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Prepare
id: prepare
run: |
if [[ $GITHUB_REF == refs/tags/* ]]; then
echo ::set-output name=version::${GITHUB_REF#refs/tags/v}
elif [[ $GITHUB_REF == refs/heads/master ]]; then
echo ::set-output name=version::latest
elif [[ $GITHUB_REF == refs/heads/* ]]; then
echo ::set-output name=version::${GITHUB_REF#refs/heads/}
else
echo ::set-output name=version::snapshot
fi
echo ::set-output name=docker_platforms::linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/386,linux/s390x
echo ::set-output name=docker_image::${{ secrets.DOCKER_USERNAME }}/${{ github.event.repository.name }}
# https://github.com/crazy-max/ghaction-docker-buildx
- name: Set up Docker Buildx
id: buildx
uses: crazy-max/ghaction-docker-buildx@v1
with:
version: latest
- name: Environment
run: |
echo home=$HOME
echo git_ref=$GITHUB_REF
echo git_sha=$GITHUB_SHA
echo version=${{ steps.prepare.outputs.version }}
echo image=${{ steps.prepare.outputs.docker_image }}
echo platforms=${{ steps.prepare.outputs.docker_platforms }}
echo avail_platforms=${{ steps.buildx.outputs.platforms }}
# https://github.com/actions/checkout
- name: Checkout
uses: actions/checkout@v2
- name: Docker Buildx (no push)
run: |
docker buildx bake \
--set ${{ github.event.repository.name }}.platform=${{ steps.prepare.outputs.docker_platforms }} \
--set ${{ github.event.repository.name }}.output=type=image,push=false \
--set ${{ github.event.repository.name }}.tags="${{ steps.prepare.outputs.docker_image }}:${{ steps.prepare.outputs.version }}" \
--file docker-compose.yaml
- name: Docker Login
if: success()
env:
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
run: |
echo "${DOCKER_PASSWORD}" | docker login --username "${{ secrets.DOCKER_USERNAME }}" --password-stdin
- name: Docker Buildx (push)
if: success()
run: |
docker buildx bake \
--set ${{ github.event.repository.name }}.platform=${{ steps.prepare.outputs.docker_platforms }} \
--set ${{ github.event.repository.name }}.output=type=image,push=true \
--set ${{ github.event.repository.name }}.tags="${{ steps.prepare.outputs.docker_image }}:${{ steps.prepare.outputs.version }}" \
--file docker-compose.yaml
- name: Clear
if: always()
run: |
rm -f ${HOME}/.docker/config.json

View File

@ -1,72 +0,0 @@
# ref: https://docs.docker.com/ci-cd/github-actions/
# https://blog.oddbit.com/post/2020-09-25-building-multi-architecture-im/
name: docker
on:
push:
branches:
- master
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Prepare
id: prepare
run: |
DOCKER_IMAGE=${{ secrets.DOCKER_IMAGE }}
VERSION=latest
# If this is git tag, use the tag name as a docker tag
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/v}
fi
TAGS="${DOCKER_IMAGE}:${VERSION}"
# If the VERSION looks like a version number, assume that
# this is the most recent version of the image and also
# tag it 'latest'.
if [[ $VERSION =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
MAJOR_VERSION=`echo $VERSION | awk '{split($0,a,"."); print a[1]}'`
MINOR_VERSION=`echo $VERSION | awk '{split($0,a,"."); print a[2]}'`
TAGS="$TAGS,${DOCKER_IMAGE}:${MAJOR_VERSION},${DOCKER_IMAGE}:${MAJOR_VERSION}.${MINOR_VERSION},${DOCKER_IMAGE}:latest"
fi
# Set output parameters.
echo "tags=${TAGS}" >> $GITHUB_OUTPUT
echo "docker_image=${DOCKER_IMAGE}" >> $GITHUB_OUTPUT
echo "docker_platforms=linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/s390x,linux/riscv64" >> $GITHUB_OUTPUT
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
- name: Environment
run: |
echo home=$HOME
echo git_ref=$GITHUB_REF
echo git_sha=$GITHUB_SHA
echo image=${{ steps.prepare.outputs.docker_image }}
echo tags=${{ steps.prepare.outputs.tags }}
echo platforms=${{ steps.prepare.outputs.docker_platforms }}
echo avail_platforms=${{ steps.buildx.outputs.platforms }}
- name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Buildx and push
uses: docker/build-push-action@v6
with:
platforms: ${{ steps.prepare.outputs.docker_platforms }}
push: true
tags: ${{ steps.prepare.outputs.tags }}

View File

@ -1,38 +0,0 @@
name: goreleaser
on:
push:
# run only against tags
tags:
- 'v*'
permissions:
contents: write
# packages: write
# issues: write
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- run: git fetch --force --tags
- uses: actions/setup-go@v3
with:
go-version: '1.22'
cache: true
# More assembly might be required: Docker logins, GPG, etc. It all depends
# on your needs.
- uses: goreleaser/goreleaser-action@v4
with:
# either 'goreleaser' (default) or 'goreleaser-pro':
distribution: goreleaser
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro'
# distribution:
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}

2
.gitignore vendored
View File

@ -9,7 +9,6 @@ _test
release
debian
bin
dist/
# Architecture specific extensions/prefixes
*.[568vq]
@ -33,3 +32,4 @@ _testmain.go
.vscode/
cmd/gost/gost
snap

View File

@ -1,58 +0,0 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com
before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy
# you may remove this if you don't need go generate
# - go generate ./...
builds:
- env:
- CGO_ENABLED=0
main: ./cmd/gost
targets:
- darwin_amd64
- darwin_arm64
- linux_386
- linux_amd64
- linux_amd64_v3
- linux_arm_5
- linux_arm_6
- linux_arm_7
- linux_arm64
- linux_mips_softfloat
- linux_mips_hardfloat
- linux_mipsle_softfloat
- linux_mipsle_hardfloat
- linux_mips64
- linux_mips64le
- linux_s390x
- linux_riscv64
- freebsd_386
- freebsd_amd64
- windows_386
- windows_amd64
- windows_amd64_v3
- windows_arm64
archives:
- format: tar.gz
# use zip for windows archives
format_overrides:
- goos: windows
format: zip
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ incpatch .Version }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
# The lines beneath this are called `modelines`. See `:help modeline`
# Feel free to remove those if you don't want/use them.
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj

View File

@ -1,32 +1,25 @@
FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.5.0 AS xx
FROM --platform=$BUILDPLATFORM golang:1.18-alpine as builder
FROM --platform=$BUILDPLATFORM golang:1.23-alpine3.20 AS builder
COPY --from=xx / /
# Convert TARGETPLATFORM to GOARCH format
# https://github.com/tonistiigi/xx
COPY --from=tonistiigi/xx:golang / /
ARG TARGETPLATFORM
RUN xx-info env
RUN apk add --no-cache musl-dev git gcc
ENV CGO_ENABLED=0
ADD . /src
ENV XX_VERIFY_STATIC=1
WORKDIR /src
WORKDIR /app
ENV GO111MODULE=on
COPY . .
RUN cd cmd/gost && go env && go build -v
RUN cd cmd/gost && \
xx-go build && \
xx-verify gost
FROM alpine:3.20
# add iptables for tun/tap
RUN apk add --no-cache iptables
FROM alpine:latest
WORKDIR /bin/
COPY --from=builder /app/cmd/gost/gost .
COPY --from=builder /src/cmd/gost/gost .
ENTRYPOINT ["/bin/gost"]
ENTRYPOINT ["/bin/gost"]

View File

@ -20,14 +20,12 @@ PLATFORM_LIST = \
linux-mips64 \
linux-mips64le \
linux-s390x \
linux-riscv64 \
freebsd-386 \
freebsd-amd64
WINDOWS_ARCH_LIST = \
windows-386 \
windows-amd64 \
windows-arm64
windows-amd64
all: linux-amd64 darwin-amd64 windows-amd64 # Most used
@ -76,9 +74,6 @@ linux-mips64le:
linux-s390x:
GOARCH=s390x GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES)
linux-riscv64:
GOARCH=riscv64 GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES)
freebsd-386:
GOARCH=386 GOOS=freebsd $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES)
@ -91,9 +86,6 @@ windows-386:
windows-amd64:
GOARCH=amd64 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe $(GOFILES)
windows-arm64:
GOARCH=arm64 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe $(GOFILES)
gz_releases=$(addsuffix .gz, $(PLATFORM_LIST))
zip_releases=$(addsuffix .zip, $(WINDOWS_ARCH_LIST))

View File

@ -8,7 +8,6 @@ GO Simple Tunnel
[![codecov](https://codecov.io/gh/ginuerzh/gost/branch/master/graphs/badge.svg)](https://codecov.io/gh/ginuerzh/gost/branch/master)
[![GitHub release](https://img.shields.io/github/release/ginuerzh/gost.svg)](https://github.com/ginuerzh/gost/releases/latest)
[![Docker](https://img.shields.io/docker/pulls/ginuerzh/gost.svg)](https://hub.docker.com/r/ginuerzh/gost/)
[![gost](https://snapcraft.io/gost/badge.svg)](https://snapcraft.io/gost)
[English README](README_en.md)
@ -58,7 +57,7 @@ go build
#### Docker
```bash
docker run --rm ginuerzh/gost -V
docker pull ginuerzh/gost
```
#### Homebrew
@ -69,7 +68,6 @@ brew install gost
#### Ubuntu商店
```bash
sudo snap install core
sudo snap install gost
@ -195,7 +193,7 @@ gost -L=:8080 -F=h2://server_ip:443
```
#### QUIC
gost对QUIC的支持是基于[quic-go](https://github.com/quic-go/quic-go)库。
gost对QUIC的支持是基于[quic-go](https://github.com/lucas-clemente/quic-go)库。
服务端:
```bash

View File

@ -4,32 +4,33 @@ gost - GO Simple Tunnel
### A simple security tunnel written in Golang
[![GoDoc](https://godoc.org/github.com/ginuerzh/gost?status.svg)](https://godoc.org/github.com/ginuerzh/gost)
[![Build Status](https://travis-ci.org/ginuerzh/gost.svg?branch=master)](https://travis-ci.org/ginuerzh/gost)
[![Go Report Card](https://goreportcard.com/badge/github.com/ginuerzh/gost)](https://goreportcard.com/report/github.com/ginuerzh/gost)
[![codecov](https://codecov.io/gh/ginuerzh/gost/branch/master/graphs/badge.svg)](https://codecov.io/gh/ginuerzh/gost/branch/master)
[![GitHub release](https://img.shields.io/github/release/ginuerzh/gost.svg)](https://github.com/ginuerzh/gost/releases/latest)
[![Docker](https://img.shields.io/docker/pulls/ginuerzh/gost.svg)](https://hub.docker.com/r/ginuerzh/gost/)
[![gost](https://snapcraft.io/gost/badge.svg)](https://snapcraft.io/gost)
[![Snap Status](https://build.snapcraft.io/badge/ginuerzh/gost.svg)](https://build.snapcraft.io/user/ginuerzh/gost)
[![Docker Build Status](https://img.shields.io/docker/build/ginuerzh/gost.svg)](https://hub.docker.com/r/ginuerzh/gost/)
Features
------
* Listening on multiple ports
* Multi-level forward proxy - proxy chain
* Standard HTTP/HTTPS/HTTP2/SOCKS4(A)/SOCKS5 proxy protocols support
* [Probing resistance](https://v2.gost.run/en/probe_resist/) support for web proxy
* [Support multiple tunnel types](https://v2.gost.run/en/configuration/)
* [TLS encryption via negotiation support for SOCKS5 proxy](https://v2.gost.run/en/socks/)
* [Tunnel UDP over TCP](https://v2.gost.run/en/socks/)
* [TCP/UDP Transparent proxy](https://v2.gost.run/en/redirect/)
* [Local/remote TCP/UDP port forwarding](https://v2.gost.run/en/port-forwarding/)
* [Shadowsocks protocol](https://v2.gost.run/en/ss/)
* [SNI proxy](https://v2.gost.run/en/sni/)
* [Permission control](https://v2.gost.run/en/permission/)
* [Load balancing](https://v2.gost.run/en/load-balancing/)
* [Routing control](https://v2.gost.run/en/bypass/)
* DNS [resolver](https://v2.gost.run/resolver/) and [proxy](https://v2.gost.run/dns/)
* [TUN/TAP device](https://v2.gost.run/en/tuntap/)
* [Probing resistance](https://docs.ginuerzh.xyz/gost/en/probe_resist/) support for web proxy
* [Support multiple tunnel types](https://docs.ginuerzh.xyz/gost/en/configuration/)
* [TLS encryption via negotiation support for SOCKS5 proxy](https://docs.ginuerzh.xyz/gost/en/socks/)
* [Tunnel UDP over TCP](https://docs.ginuerzh.xyz/gost/en/socks/)
* [TCP/UDP Transparent proxy](https://docs.ginuerzh.xyz/gost/en/redirect/)
* [Local/remote TCP/UDP port forwarding](https://docs.ginuerzh.xyz/gost/en/port-forwarding/)
* [Shadowsocks protocol](https://docs.ginuerzh.xyz/gost/en/ss/)
* [SNI proxy](https://docs.ginuerzh.xyz/gost/en/sni/)
* [Permission control](https://docs.ginuerzh.xyz/gost/en/permission/)
* [Load balancing](https://docs.ginuerzh.xyz/gost/en/load-balancing/)
* [Routing control](https://docs.ginuerzh.xyz/gost/en/bypass/)
* DNS [resolver](https://docs.ginuerzh.xyz/gost/resolver/) and [proxy](https://docs.ginuerzh.xyz/gost/dns/)
* [TUN/TAP device](https://docs.ginuerzh.xyz/gost/en/tuntap/)
Wiki: [v2.gost.run](https://v2.gost.run/en/)
Wiki: <https://docs.ginuerzh.xyz/gost/en/>
Telegram group: <https://t.me/gogost>
@ -53,7 +54,7 @@ go build
#### Docker
```bash
docker run --rm ginuerzh/gost -V
docker pull ginuerzh/gost
```
#### Homebrew
@ -218,7 +219,7 @@ gost -L=:8080 -F=h2://server_ip:443
#### QUIC
Support for QUIC is based on library [quic-go](https://github.com/quic-go/quic-go).
Support for QUIC is based on library [quic-go](https://github.com/lucas-clemente/quic-go).
Server:

View File

@ -3,7 +3,6 @@ package gost
import (
"context"
"errors"
"fmt"
"net"
"syscall"
"time"
@ -21,7 +20,6 @@ type Chain struct {
isRoute bool
Retries int
Mark int
Interface string
nodeGroups []*NodeGroup
route []Node // nodes in the selected route
}
@ -38,14 +36,10 @@ func NewChain(nodes ...Node) *Chain {
// newRoute creates a chain route.
// a chain route is the final route after node selection.
func (c *Chain) newRoute(nodes ...Node) *Chain {
route := NewChain(nodes...)
route.isRoute = true
if !c.IsEmpty() {
route.Interface = c.Interface
route.Mark = c.Mark
}
return route
func newRoute(nodes ...Node) *Chain {
chain := NewChain(nodes...)
chain.isRoute = true
return chain
}
// Nodes returns the proxy nodes that the chain holds.
@ -143,9 +137,6 @@ func (c *Chain) dialWithOptions(ctx context.Context, network, address string, op
if options == nil {
options = &ChainOptions{}
}
if c == nil {
c = &Chain{}
}
route, err := c.selectRouteFor(address)
if err != nil {
return nil, err
@ -154,9 +145,6 @@ func (c *Chain) dialWithOptions(ctx context.Context, network, address string, op
ipAddr := address
if address != "" {
ipAddr = c.resolve(address, options.Resolver, options.Hosts)
if ipAddr == "" {
return nil, fmt.Errorf("resolver: domain %s does not exists", address)
}
}
timeout := options.Timeout
@ -178,18 +166,6 @@ func (c *Chain) dialWithOptions(ctx context.Context, network, address string, op
}
}
if c.Interface != "" {
controlFunction = func(_, _ string, cc syscall.RawConn) error {
return cc.Control(func(fd uintptr) {
err := setSocketInterface(int(fd), c.Interface)
if err != nil {
log.Logf("net dialer set interface %s error: %s", c.Interface, err)
}
})
}
}
if route.IsEmpty() {
switch network {
case "udp", "udp4", "udp6":
@ -234,11 +210,9 @@ func (*Chain) resolve(addr string, resolver Resolver, hosts *Hosts) string {
if err != nil {
log.Logf("[resolver] %s: %v", host, err)
}
if len(ips) == 0 {
log.Logf("[resolver] %s: domain does not exists", host)
return ""
if len(ips) > 0 {
return net.JoinHostPort(ips[0].String(), port)
}
return net.JoinHostPort(ips[0].String(), port)
}
return addr
}
@ -329,13 +303,13 @@ func (c *Chain) selectRoute() (route *Chain, err error) {
// selectRouteFor selects route with bypass testing.
func (c *Chain) selectRouteFor(addr string) (route *Chain, err error) {
if c.IsEmpty() {
return c.newRoute(), nil
return newRoute(), nil
}
if c.isRoute {
return c, nil
}
route = c.newRoute()
route = newRoute()
var nl []Node
for _, group := range c.nodeGroups {
@ -353,7 +327,7 @@ func (c *Chain) selectRouteFor(addr string) (route *Chain, err error) {
node.DialOptions = append(node.DialOptions,
ChainDialOption(route),
)
route = c.newRoute() // cutoff the chain for multiplex node.
route = newRoute() // cutoff the chain for multiplex node.
}
route.AddNode(node)

View File

@ -5,7 +5,8 @@ import (
"crypto/tls"
"crypto/x509"
"encoding/json"
"fmt"
"errors"
"io/ioutil"
"net"
"net/url"
"os"
@ -57,11 +58,7 @@ func tlsConfig(certFile, keyFile, caFile string) (*tls.Config, error) {
cfg := &tls.Config{Certificates: []tls.Certificate{cert}}
pool, err := loadCA(caFile)
if err != nil {
return nil, err
}
if pool != nil {
if pool, _ := loadCA(caFile); pool != nil {
cfg.ClientCAs = pool
cfg.ClientAuth = tls.RequireAndVerifyClientCert
}
@ -74,12 +71,12 @@ func loadCA(caFile string) (cp *x509.CertPool, err error) {
return
}
cp = x509.NewCertPool()
data, err := os.ReadFile(caFile)
data, err := ioutil.ReadFile(caFile)
if err != nil {
return nil, err
}
if !cp.AppendCertsFromPEM(data) {
return nil, fmt.Errorf("loadCA %s: AppendCertsFromPEM failed", caFile)
return nil, errors.New("AppendCertsFromPEM failed")
}
return
}
@ -110,7 +107,6 @@ func parseUsers(authFile string) (users []*url.Userinfo, err error) {
if err != nil {
return
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
@ -156,38 +152,33 @@ func parseIP(s string, port string) (ips []string) {
port = "8080" // default port
}
addrFn := func(s, port string) string {
c := strings.Count(s, ":")
if c == 0 || //ipv4 or domain
s[len(s)-1] == ']' { //[ipv6]
return s + ":" + port
}
if c > 1 && s[0] != '[' { // ipv6
return "[" + s + "]:" + port
}
return s //ipv4:port or [ipv6]:port
}
file, err := os.Open(s)
if err != nil {
ss := strings.Split(s, ",")
for _, s := range ss {
s = strings.TrimSpace(s)
if s != "" {
ips = append(ips, addrFn(s, port))
// TODO: support IPv6
if !strings.Contains(s, ":") {
s = s + ":" + port
}
ips = append(ips, s)
}
}
return
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if line == "" || strings.HasPrefix(line, "#") {
continue
}
ips = append(ips, addrFn(line, port))
if !strings.Contains(line, ":") {
line = line + ":" + port
}
ips = append(ips, line)
}
return
}

View File

@ -33,7 +33,6 @@ func init() {
flag.Var(&baseCfg.route.ServeNodes, "L", "listen address, can listen on multiple ports (required)")
flag.IntVar(&baseCfg.route.Mark, "M", 0, "Specify out connection mark")
flag.StringVar(&configureFile, "C", "", "configure file")
flag.StringVar(&baseCfg.route.Interface, "I", "", "Interface to bind")
flag.BoolVar(&baseCfg.Debug, "D", false, "enable debug log")
flag.BoolVar(&printVersion, "V", false, "print version")
if pprofEnabled {

View File

@ -5,6 +5,7 @@ import (
"bytes"
"encoding/json"
"io"
"io/ioutil"
"strconv"
"strings"
"time"
@ -13,16 +14,14 @@ import (
)
type peerConfig struct {
Strategy string `json:"strategy"`
MaxFails int `json:"max_fails"`
FastestCount int `json:"fastest_count"` // topN fastest node count
FailTimeout time.Duration
period time.Duration // the period for live reloading
Nodes []string `json:"nodes"`
group *gost.NodeGroup
baseNodes []gost.Node
stopped chan struct{}
Strategy string `json:"strategy"`
MaxFails int `json:"max_fails"`
FailTimeout time.Duration
period time.Duration // the period for live reloading
Nodes []string `json:"nodes"`
group *gost.NodeGroup
baseNodes []gost.Node
stopped chan struct{}
}
func newPeerConfig() *peerConfig {
@ -53,7 +52,6 @@ func (cfg *peerConfig) Reload(r io.Reader) error {
FailTimeout: cfg.FailTimeout,
},
&gost.InvalidFilter{},
gost.NewFastestFilter(0, cfg.FastestCount),
),
gost.WithStrategy(gost.NewStrategy(cfg.Strategy)),
)
@ -85,7 +83,7 @@ func (cfg *peerConfig) Reload(r io.Reader) error {
}
func (cfg *peerConfig) parse(r io.Reader) error {
data, err := io.ReadAll(r)
data, err := ioutil.ReadAll(r)
if err != nil {
return err
}
@ -128,8 +126,6 @@ func (cfg *peerConfig) parse(r io.Reader) error {
cfg.Strategy = ss[1]
case "max_fails":
cfg.MaxFails, _ = strconv.Atoi(ss[1])
case "fastest_count":
cfg.FastestCount, _ = strconv.Atoi(ss[1])
case "fail_timeout":
cfg.FailTimeout, _ = time.ParseDuration(ss[1])
case "reload":

View File

@ -31,14 +31,12 @@ type route struct {
ChainNodes stringList
Retries int
Mark int
Interface string
}
func (r *route) parseChain() (*gost.Chain, error) {
chain := gost.NewChain()
chain.Retries = r.Retries
chain.Mark = r.Mark
chain.Interface = r.Interface
gid := 1 // group ID
for _, ns := range r.ChainNodes {
@ -66,7 +64,6 @@ func (r *route) parseChain() (*gost.Chain, error) {
FailTimeout: nodes[0].GetDuration("fail_timeout"),
},
&gost.InvalidFilter{},
gost.NewFastestFilter(0, nodes[0].GetInt("fastest_count")),
),
gost.WithStrategy(gost.NewStrategy(nodes[0].Get("strategy"))),
)
@ -213,12 +210,6 @@ func parseChainNode(ns string) (nodes []gost.Node, err error) {
Timeout: timeout,
IdleTimeout: node.GetDuration("idle"),
}
if config.KeepAlive {
config.KeepAlivePeriod = node.GetDuration("ttl")
if config.KeepAlivePeriod == 0 {
config.KeepAlivePeriod = 10 * time.Second
}
}
if cipher := node.Get("cipher"); cipher != "" {
sum := sha256.Sum256([]byte(cipher))
@ -242,8 +233,6 @@ func parseChainNode(ns string) (nodes []gost.Node, err error) {
tr = gost.FakeTCPTransporter()
case "udp":
tr = gost.UDPTransporter()
case "vsock":
tr = gost.VSOCKTransporter()
default:
tr = gost.TCPTransporter()
}
@ -467,12 +456,6 @@ func (r *route) GenRouters() ([]router, error) {
Timeout: timeout,
IdleTimeout: node.GetDuration("idle"),
}
if config.KeepAlive {
config.KeepAlivePeriod = node.GetDuration("ttl")
if config.KeepAlivePeriod == 0 {
config.KeepAlivePeriod = 10 * time.Second
}
}
if cipher := node.Get("cipher"); cipher != "" {
sum := sha256.Sum256([]byte(cipher))
config.Key = sum[:]
@ -492,8 +475,6 @@ func (r *route) GenRouters() ([]router, error) {
chain.Nodes()[len(chain.Nodes())-1].Client.Transporter = gost.SSHForwardTransporter()
}
ln, err = gost.TCPListener(node.Addr)
case "vsock":
ln, err = gost.VSOCKListener(node.Addr)
case "udp":
ln, err = gost.UDPListener(node.Addr, &gost.UDPListenConfig{
TTL: ttl,
@ -669,8 +650,6 @@ func (r *route) GenRouters() ([]router, error) {
gost.IPsHandlerOption(ips),
gost.TCPModeHandlerOption(node.GetBool("tcp")),
gost.IPRoutesHandlerOption(tunRoutes...),
gost.ProxyAgentHandlerOption(node.Get("proxyAgent")),
gost.HTTPTunnelHandlerOption(node.GetBool("httpTunnel")),
)
rt := router{

View File

@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/url"
@ -35,7 +36,7 @@ func init() {
var (
httpTestHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
data, _ := io.ReadAll(r.Body)
data, _ := ioutil.ReadAll(r.Body)
if len(data) == 0 {
data = []byte("Hello World!")
}
@ -86,7 +87,7 @@ func httpRoundtrip(conn net.Conn, targetURL string, data []byte) (err error) {
return errors.New(resp.Status)
}
recv, err := io.ReadAll(resp.Body)
recv, err := ioutil.ReadAll(resp.Body)
if err != nil {
return
}

3
dns.go
View File

@ -7,6 +7,7 @@ import (
"encoding/base64"
"errors"
"io"
"io/ioutil"
"net"
"net/http"
"strconv"
@ -266,7 +267,7 @@ func (l *dnsListener) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}
buf, err = io.ReadAll(r.Body)
buf, err = ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return

4
docker-compose.yaml Normal file
View File

@ -0,0 +1,4 @@
version: "3.4"
services:
gost:
build: .

View File

@ -131,7 +131,6 @@ func (h *tcpDirectForwardHandler) Handle(conn net.Conn) {
cc, err = h.options.Chain.Dial(node.Addr,
RetryChainOption(h.options.Retries),
TimeoutChainOption(h.options.Timeout),
ResolverChainOption(h.options.Resolver),
)
if err != nil {
log.Logf("[tcp] %s -> %s : %s", conn.RemoteAddr(), conn.LocalAddr(), err)
@ -198,12 +197,7 @@ func (h *udpDirectForwardHandler) Handle(conn net.Conn) {
}
}
cc, err := h.options.Chain.DialContext(
context.Background(),
"udp",
node.Addr,
ResolverChainOption(h.options.Resolver),
)
cc, err := h.options.Chain.DialContext(context.Background(), "udp", node.Addr)
if err != nil {
node.MarkDead()
log.Logf("[udp] %s - %s : %s", conn.RemoteAddr(), conn.LocalAddr(), err)

66
go.mod
View File

@ -1,60 +1,60 @@
module github.com/ginuerzh/gost
go 1.22
replace github.com/templexxx/cpu v0.0.7 => github.com/templexxx/cpu v0.0.10-0.20211111114238-98168dcec14a
go 1.17
require (
git.torproject.org/pluggable-transports/goptlib.git v1.3.0
git.torproject.org/pluggable-transports/goptlib.git v1.2.0
github.com/LiamHaworth/go-tproxy v0.0.0-20190726054950-ef7efd7f24ed
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
github.com/docker/libcontainer v2.2.1+incompatible
github.com/go-gost/gosocks4 v0.0.1
github.com/go-gost/gosocks5 v0.3.0
github.com/go-gost/relay v0.1.1-0.20211123134818-8ef7fd81ffd7
github.com/go-gost/tls-dissector v0.0.2-0.20220408131628-aac992c27451
github.com/go-gost/tls-dissector v0.0.2-0.20211125135007-2b5d5bd9c07e
github.com/go-log/log v0.2.0
github.com/gobwas/glob v0.2.3
github.com/gorilla/websocket v1.5.1
github.com/klauspost/compress v1.17.6
github.com/mdlayher/vsock v1.2.1
github.com/miekg/dns v1.1.58
github.com/quic-go/quic-go v0.45.0
github.com/gorilla/websocket v1.4.2
github.com/klauspost/compress v1.13.6
github.com/lucas-clemente/quic-go v0.26.0
github.com/miekg/dns v1.1.43
github.com/milosgajdos/tenus v0.0.3
github.com/ryanuber/go-glob v1.0.0
github.com/shadowsocks/go-shadowsocks2 v0.1.5
github.com/shadowsocks/shadowsocks-go v0.0.0-20200409064450-3e585ff90601
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
github.com/xtaci/kcp-go/v5 v5.6.7
github.com/xtaci/smux v1.5.24
github.com/xtaci/kcp-go v5.4.20+incompatible
github.com/xtaci/smux v1.5.16
github.com/xtaci/tcpraw v1.2.25
gitlab.com/yawning/obfs4.git v0.0.0-20220204003609-77af0cba934d
golang.org/x/crypto v0.24.0
golang.org/x/net v0.26.0
gitlab.com/yawning/obfs4.git v0.0.0-20210511220700-e330d1b7024b
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064
golang.org/x/net v0.0.0-20220325170049-de3da57026de
)
require (
filippo.io/edwards25519 v1.0.0-rc.1.0.20210721174708-390f27c3be20 // indirect
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
github.com/cheekybits/genny v1.0.0 // indirect
github.com/coreos/go-iptables v0.6.0 // indirect
github.com/dchest/siphash v1.2.2 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/google/gopacket v1.1.19 // indirect
github.com/google/pprof v0.0.0-20240528025155-186aa0362fba // indirect
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
github.com/klauspost/reedsolomon v1.12.0 // indirect
github.com/mdlayher/socket v0.4.1 // indirect
github.com/onsi/ginkgo/v2 v2.19.0 // indirect
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
github.com/klauspost/reedsolomon v1.9.15 // indirect
github.com/marten-seemann/qtls-go1-16 v0.1.5 // indirect
github.com/marten-seemann/qtls-go1-17 v0.1.1 // indirect
github.com/marten-seemann/qtls-go1-18 v0.1.1 // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
github.com/templexxx/cpu v0.1.0 // indirect
github.com/templexxx/xorsimd v0.4.2 // indirect
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect
github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 // indirect
gitlab.com/yawning/edwards25519-extra.git v0.0.0-20211229043746-2f91fcc9fbdb // indirect
go.uber.org/mock v0.4.0 // indirect
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect
golang.org/x/mod v0.18.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/tools v0.22.0 // indirect
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
golang.org/x/sys v0.0.0-20220325203850-36772127a21f // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/tools v0.1.10 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
)

359
go.sum
View File

@ -1,48 +1,81 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
filippo.io/edwards25519 v1.0.0-rc.1.0.20210721174708-390f27c3be20 h1:iJoUgXvhagsNMrJrvavw7vu1eG8+hm6jLOxlLFcoODw=
filippo.io/edwards25519 v1.0.0-rc.1.0.20210721174708-390f27c3be20/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
git.torproject.org/pluggable-transports/goptlib.git v1.0.0/go.mod h1:YT4XMSkuEXbtqlydr9+OxqFAyspUv0Gr9qhM3B++o/Q=
git.torproject.org/pluggable-transports/goptlib.git v1.3.0 h1:G+iuRUblCCC2xnO+0ag1/4+aaM98D5mjWP1M0v9s8a0=
git.torproject.org/pluggable-transports/goptlib.git v1.3.0/go.mod h1:4PBMl1dg7/3vMWSoWb46eGWlrxkUyn/CAJmxhDLAlDs=
git.torproject.org/pluggable-transports/goptlib.git v1.2.0 h1:0qRF7Dw5qXd0FtZkjWUiAh5GTutRtDGL4GXUDJ4qMHs=
git.torproject.org/pluggable-transports/goptlib.git v1.2.0/go.mod h1:4PBMl1dg7/3vMWSoWb46eGWlrxkUyn/CAJmxhDLAlDs=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/LiamHaworth/go-tproxy v0.0.0-20190726054950-ef7efd7f24ed h1:eqa6queieK8SvoszxCu0WwH7lSVeL4/N/f1JwOMw1G4=
github.com/LiamHaworth/go-tproxy v0.0.0-20190726054950-ef7efd7f24ed/go.mod h1:rA52xkgZwql9LRZXWb2arHEFP6qSR48KY2xOfWzEciQ=
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY=
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk=
github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/siphash v1.2.1/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
github.com/dchest/siphash v1.2.2 h1:9DFz8tQwl9pTVt5iok/9zKyzA1Q6bRGiF3HPiEEVr9I=
github.com/dchest/siphash v1.2.2/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
github.com/docker/libcontainer v2.2.1+incompatible h1:++SbbkCw+X8vAd4j2gOCzZ2Nn7s2xFALTf7LZKmM1/0=
github.com/docker/libcontainer v2.2.1+incompatible/go.mod h1:osvj61pYsqhNCMLGX31xr7klUBhHb/ZBuXS0o1Fvwbw=
github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-gost/gosocks4 v0.0.1 h1:+k1sec8HlELuQV7rWftIkmy8UijzUt2I6t+iMPlGB2s=
github.com/go-gost/gosocks4 v0.0.1/go.mod h1:3B6L47HbU/qugDg4JnoFPHgJXE43Inz8Bah1QaN9qCc=
github.com/go-gost/gosocks5 v0.3.0 h1:Hkmp9YDRBSCJd7xywW6dBPT6B9aQTkuWd+3WCheJiJA=
github.com/go-gost/gosocks5 v0.3.0/go.mod h1:1G6I7HP7VFVxveGkoK8mnprnJqSqJjdcASKsdUn4Pp4=
github.com/go-gost/relay v0.1.1-0.20211123134818-8ef7fd81ffd7 h1:itaaJhQJ19kUXEB4Igb0EbY8m+1Py2AaNNSBds/9gk4=
github.com/go-gost/relay v0.1.1-0.20211123134818-8ef7fd81ffd7/go.mod h1:lcX+23LCQ3khIeASBo+tJ/WbwXFO32/N5YN6ucuYTG8=
github.com/go-gost/tls-dissector v0.0.2-0.20220408131628-aac992c27451 h1:xj8gUZGYO3nb5+6Bjw9+tsFkA9sYynrOvDvvC4uDV2I=
github.com/go-gost/tls-dissector v0.0.2-0.20220408131628-aac992c27451/go.mod h1:/9QfdewqmHdaE362Hv5nDaSWLx3pCmtD870d6GaquXs=
github.com/go-gost/tls-dissector v0.0.2-0.20211125135007-2b5d5bd9c07e h1:73NGqAs22ey3wJkIYVD/ACEoovuIuOlEzQTEoqrO5+U=
github.com/go-gost/tls-dissector v0.0.2-0.20211125135007-2b5d5bd9c07e/go.mod h1:/9QfdewqmHdaE362Hv5nDaSWLx3pCmtD870d6GaquXs=
github.com/go-log/log v0.2.0 h1:z8i91GBudxD5L3RmF0KVpetCbcGWAV7q1Tw1eRwQM9Q=
github.com/go-log/log v0.2.0/go.mod h1:xzCnwajcues/6w7lne3yK2QU7DBPW7kqbgPGG5AF65U=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
@ -51,141 +84,295 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/pprof v0.0.0-20240528025155-186aa0362fba h1:ql1qNgCyOB7iAEk8JTNM+zJrgIbnyCKX/wdlyPufP5g=
github.com/google/pprof v0.0.0-20240528025155-186aa0362fba/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI=
github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/klauspost/reedsolomon v1.12.0 h1:I5FEp3xSwVCcEh3F5A7dofEfhXdF/bWhQWPH+XwBFno=
github.com/klauspost/reedsolomon v1.12.0/go.mod h1:EPLZJeh4l27pUGC3aXOjheaoh1I9yut7xTURiW3LQ9Y=
github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
github.com/mdlayher/vsock v1.2.1 h1:pC1mTJTvjo1r9n9fbm7S1j04rCgCzhCOS5DY0zqHlnQ=
github.com/mdlayher/vsock v1.2.1/go.mod h1:NRfCibel++DgeMD8z/hP+PPTjlNJsdPOmxcnENvE+SE=
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/reedsolomon v1.9.15 h1:g2erWKD2M6rgnPf89fCji6jNlhMKMdXcuNHMW1SYCIo=
github.com/klauspost/reedsolomon v1.9.15/go.mod h1:eqPAcE7xar5CIzcdfwydOEdcmchAKAP/qs14y4GCBOk=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lucas-clemente/quic-go v0.26.0 h1:ALBQXr9UJ8A1LyzvceX4jd9QFsHvlI0RR6BkV16o00A=
github.com/lucas-clemente/quic-go v0.26.0/go.mod h1:AzgQoPda7N+3IqMMMkywBKggIFo2KT6pfnlrQ2QieeI=
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc=
github.com/marten-seemann/qtls-go1-16 v0.1.5 h1:o9JrYPPco/Nukd/HpOHMHZoBDXQqoNtUCmny98/1uqQ=
github.com/marten-seemann/qtls-go1-16 v0.1.5/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk=
github.com/marten-seemann/qtls-go1-17 v0.1.1 h1:DQjHPq+aOzUeh9/lixAGunn6rIOQyWChPSI4+hgW7jc=
github.com/marten-seemann/qtls-go1-17 v0.1.1/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s=
github.com/marten-seemann/qtls-go1-18 v0.1.1 h1:qp7p7XXUFL7fpBvSS1sWD+uSqPvzNQK43DH+/qEkj0Y=
github.com/marten-seemann/qtls-go1-18 v0.1.1/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg=
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
github.com/milosgajdos/tenus v0.0.3 h1:jmaJzwaY1DUyYVD0lM4U+uvP2kkEg1VahDqRFxIkVBE=
github.com/milosgajdos/tenus v0.0.3/go.mod h1:eIjx29vNeDOYWJuCnaHY2r4fq5egetV26ry3on7p8qY=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak=
github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/quic-go/quic-go v0.45.0 h1:OHmkQGM37luZITyTSu6ff03HP/2IrwDX1ZFiNEhSFUE=
github.com/quic-go/quic-go v0.45.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI=
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shadowsocks/go-shadowsocks2 v0.1.5 h1:PDSQv9y2S85Fl7VBeOMF9StzeXZyK1HakRm86CUbr28=
github.com/shadowsocks/go-shadowsocks2 v0.1.5/go.mod h1:AGGpIoek4HRno4xzyFiAtLHkOpcoznZEkAccaI/rplM=
github.com/shadowsocks/shadowsocks-go v0.0.0-20200409064450-3e585ff90601 h1:XU9hik0exChEmY92ALW4l9WnDodxLVS9yOSNh2SizaQ=
github.com/shadowsocks/shadowsocks-go v0.0.0-20200409064450-3e585ff90601/go.mod h1:mttDPaeLm87u74HMrP+n2tugXvIKWcwff/cqSX0lehY=
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=
github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI=
github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=
github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=
github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg=
github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw=
github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y=
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=
github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ=
github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I=
github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0=
github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=
github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk=
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 h1:TG/diQgUe0pntT/2D9tmUCz4VNwm9MfrtPr0SU2qSX8=
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/templexxx/cpu v0.1.0 h1:wVM+WIJP2nYaxVxqgHPD4wGA2aJ9rvrQRV8CvFzNb40=
github.com/templexxx/cpu v0.1.0/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
github.com/templexxx/xorsimd v0.4.2 h1:ocZZ+Nvu65LGHmCLZ7OoCtg8Fx8jnHKK37SjvngUoVI=
github.com/templexxx/xorsimd v0.4.2/go.mod h1:HgwaPoDREdi6OnULpSfxhzaiiSUY4Fi3JPn1wpt28NI=
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU=
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b h1:fj5tQ8acgNUr6O8LEplsxDhUIe2573iLkJc+PqnzZTI=
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
github.com/xtaci/kcp-go/v5 v5.6.7 h1:7+rnxNFIsjEwTXQk4cSZpXM4pO0hqtpwE1UFFoJBffA=
github.com/xtaci/kcp-go/v5 v5.6.7/go.mod h1:oE9j2NVqAkuKO5o8ByKGch3vgVX3BNf8zqP8JiGq0bM=
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
github.com/xtaci/kcp-go v5.4.20+incompatible h1:TN1uey3Raw0sTz0Fg8GkfM0uH3YwzhnZWQ1bABv5xAg=
github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E=
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0=
github.com/xtaci/smux v1.5.24 h1:77emW9dtnOxxOQ5ltR+8BbsX1kzcOxQ5gB+aaV9hXOY=
github.com/xtaci/smux v1.5.24/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
github.com/xtaci/smux v1.5.16 h1:FBPYOkW8ZTjLKUM4LI4xnnuuDC8CQ/dB04HD519WoEk=
github.com/xtaci/smux v1.5.16/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
github.com/xtaci/tcpraw v1.2.25 h1:VDlqo0op17JeXBM6e2G9ocCNLOJcw9mZbobMbJjo0vk=
github.com/xtaci/tcpraw v1.2.25/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
gitlab.com/yawning/edwards25519-extra.git v0.0.0-20211229043746-2f91fcc9fbdb h1:qRSZHsODmAP5qDvb3YsO7Qnf3TRiVbGxNG/WYnlM4/o=
gitlab.com/yawning/edwards25519-extra.git v0.0.0-20211229043746-2f91fcc9fbdb/go.mod h1:gvdJuZuO/tPZyhEV8K3Hmoxv/DWud5L4qEQxfYjEUTo=
gitlab.com/yawning/obfs4.git v0.0.0-20220204003609-77af0cba934d h1:tJ8F7ABaQ3p3wjxwXiWSktVDgjZEXkvaRawd2rIq5ws=
gitlab.com/yawning/obfs4.git v0.0.0-20220204003609-77af0cba934d/go.mod h1:9GcM8QNU9/wXtEEH2q8bVOnPI7FtIF6VVLzZ1l6Hgf8=
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec/go.mod h1:BZ1RAoRPbCxum9Grlv5aeksu2H8BiKehBYooU2LFiOQ=
gitlab.com/yawning/obfs4.git v0.0.0-20210511220700-e330d1b7024b h1:w/f20IHUkUYEp+xYgpKz4Bs78zms0DbjPZCep5lc0xA=
gitlab.com/yawning/obfs4.git v0.0.0-20210511220700-e330d1b7024b/go.mod h1:OM1ngEp5brdANPox+rqk2AGTLQvzobyB5Dwm3vu3CgM=
gitlab.com/yawning/utls.git v0.0.12-1/go.mod h1:3ONKiSFR9Im/c3t5RKmMJTVdmZN496FNyk3mjrY1dyo=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 h1:S25/rfnfsMVgORT4/J61MJ7rdyseOZOyvLIrZEZ7s6s=
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM=
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190328230028-74de082e2cca/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220325170049-de3da57026de h1:pZB1TWnKi+o4bENlbzAgLrEbY4RMYmUIRobMcSmfeYc=
golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220325203850-36772127a21f h1:TrmogKRsSOxRMJbLYGrB4SBbW+LJcEllYBLME5Zk5pU=
golang.org/x/sys v0.0.0-20220325203850-36772127a21f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
@ -196,9 +383,25 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=

View File

@ -20,7 +20,7 @@ import (
)
// Version is the gost version.
const Version = "2.12.0"
const Version = "2.11.2"
// Debug is a flag that enables the debug log.
var Debug bool
@ -80,8 +80,6 @@ var (
// DefaultUserAgent is the default HTTP User-Agent header used by HTTP and websocket.
DefaultUserAgent = "Chrome/78.0.3904.106"
DefaultProxyAgent = "gost/" + Version
// DefaultMTU is the default mtu for tun/tap device
DefaultMTU = 1350
)
@ -149,7 +147,9 @@ func (rw *readWriter) Write(p []byte) (n int, err error) {
return rw.w.Write(p)
}
var nopClientConn = &nopConn{}
var (
nopClientConn = &nopConn{}
)
// a nop connection implements net.Conn,
// it does nothing.

BIN
gost.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

View File

@ -42,8 +42,6 @@ type HandlerOptions struct {
IPs []string
TCPMode bool
IPRoutes []IPRoute
ProxyAgent string
HTTPTunnel bool
}
// HandlerOption allows a common way to set handler options.
@ -213,20 +211,6 @@ func IPRoutesHandlerOption(routes ...IPRoute) HandlerOption {
}
}
// ProxyAgentHandlerOption sets the proxy agent for http handler.
func ProxyAgentHandlerOption(agent string) HandlerOption {
return func(opts *HandlerOptions) {
opts.ProxyAgent = agent
}
}
// HTTPTunnelHandlerOption sets the Tunnel mode for HTTP client used in HTTP handler.
func HTTPTunnelHandlerOption(tunnelMode bool) HandlerOption {
return func(opts *HandlerOptions) {
opts.HTTPTunnel = tunnelMode
}
}
type autoHandler struct {
options *HandlerOptions
}

78
http.go
View File

@ -6,7 +6,6 @@ import (
"context"
"encoding/base64"
"fmt"
"io"
"net"
"net/http"
"net/http/httputil"
@ -174,12 +173,7 @@ func (h *httpHandler) handleRequest(conn net.Conn, req *http.Request) {
ProtoMinor: 1,
Header: http.Header{},
}
proxyAgent := DefaultProxyAgent
if h.options.ProxyAgent != "" {
proxyAgent = h.options.ProxyAgent
}
resp.Header.Add("Proxy-Agent", proxyAgent)
resp.Header.Add("Proxy-Agent", "gost/"+Version)
if !Can("tcp", host, h.options.Whitelist, h.options.Blacklist) {
log.Logf("[http] %s - %s : Unauthorized to tcp connect to %s",
@ -258,9 +252,7 @@ func (h *httpHandler) handleRequest(conn net.Conn, req *http.Request) {
// forward http request
lastNode := route.LastNode()
if req.Method != http.MethodConnect &&
lastNode.Protocol == "http" &&
!h.options.HTTPTunnel {
if req.Method != http.MethodConnect && lastNode.Protocol == "http" {
err = h.forwardRequest(conn, req, route)
if err == nil {
return
@ -293,65 +285,27 @@ func (h *httpHandler) handleRequest(conn net.Conn, req *http.Request) {
}
defer cc.Close()
if req.Method != http.MethodConnect {
h.handleProxy(conn, cc, req)
return
}
if req.Method == http.MethodConnect {
b := []byte("HTTP/1.1 200 Connection established\r\n" +
"Proxy-Agent: gost/" + Version + "\r\n\r\n")
if Debug {
log.Logf("[http] %s <- %s\n%s", conn.RemoteAddr(), conn.LocalAddr(), string(b))
}
conn.Write(b)
} else {
req.Header.Del("Proxy-Connection")
b := []byte("HTTP/1.1 200 Connection established\r\n" +
"Proxy-Agent: " + proxyAgent + "\r\n\r\n")
if Debug {
log.Logf("[http] %s <- %s\n%s", conn.RemoteAddr(), conn.LocalAddr(), string(b))
if err = req.Write(cc); err != nil {
log.Logf("[http] %s -> %s : %s", conn.RemoteAddr(), conn.LocalAddr(), err)
return
}
}
conn.Write(b)
log.Logf("[http] %s <-> %s", conn.RemoteAddr(), host)
transport(conn, cc)
log.Logf("[http] %s >-< %s", conn.RemoteAddr(), host)
}
func (h *httpHandler) handleProxy(rw, cc io.ReadWriter, req *http.Request) (err error) {
req.Header.Del("Proxy-Connection")
if err = req.Write(cc); err != nil {
return err
}
ch := make(chan error, 1)
go func() {
ch <- copyBuffer(rw, cc)
}()
for {
err := func() error {
req, err := http.ReadRequest(bufio.NewReader(rw))
if err != nil {
return err
}
if Debug {
dump, _ := httputil.DumpRequest(req, false)
log.Log(string(dump))
}
req.Header.Del("Proxy-Connection")
if err = req.Write(cc); err != nil {
return err
}
return nil
}()
ch <- err
if err != nil {
break
}
}
return <-ch
}
func (h *httpHandler) authenticate(conn net.Conn, req *http.Request, resp *http.Response) (ok bool) {
u, p, _ := basicProxyAuth(req.Header.Get("Proxy-Authorization"))
if Debug && (u != "" || p != "") {
@ -418,7 +372,7 @@ func (h *httpHandler) authenticate(conn net.Conn, req *http.Request, resp *http.
} else {
resp.Header = http.Header{}
resp.Header.Set("Server", "nginx/1.14.1")
resp.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat))
resp.Header.Set("Date", time.Now().Format(http.TimeFormat))
if resp.StatusCode == http.StatusOK {
resp.Header.Set("Connection", "keep-alive")
}

View File

@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/http/httputil"
@ -364,11 +365,7 @@ func (h *http2Handler) roundTrip(w http.ResponseWriter, r *http.Request) {
log.Logf("[http2] %s - %s\n%s", r.RemoteAddr, laddr, string(dump))
}
proxyAgent := DefaultProxyAgent
if h.options.ProxyAgent != "" {
proxyAgent = h.options.ProxyAgent
}
w.Header().Set("Proxy-Agent", proxyAgent)
w.Header().Set("Proxy-Agent", "gost/"+Version)
if !Can("tcp", host, h.options.Whitelist, h.options.Blacklist) {
log.Logf("[http2] %s - %s : Unauthorized to tcp connect to %s",
@ -388,7 +385,7 @@ func (h *http2Handler) roundTrip(w http.ResponseWriter, r *http.Request) {
ProtoMajor: 2,
ProtoMinor: 0,
Header: http.Header{},
Body: io.NopCloser(bytes.NewReader([]byte{})),
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
}
if !h.authenticate(w, r, resp) {
@ -538,7 +535,7 @@ func (h *http2Handler) authenticate(w http.ResponseWriter, r *http.Request, resp
} else {
resp.Header = http.Header{}
resp.Header.Set("Server", "nginx/1.14.1")
resp.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat))
resp.Header.Set("Date", time.Now().Format(http.TimeFormat))
if resp.ContentLength > 0 {
resp.Header.Set("Content-Type", "text/html")
}

View File

@ -5,7 +5,7 @@ import (
"crypto/rand"
"crypto/tls"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/http/httptest"
@ -997,7 +997,7 @@ func TestHTTP2ProxyWithWebProbeResist(t *testing.T) {
if err != nil {
t.Error(err)
}
recv, _ := io.ReadAll(conn)
recv, _ := ioutil.ReadAll(conn)
if !bytes.Equal(recv, []byte("Hello World!")) {
t.Error("data not equal")
}
@ -1053,7 +1053,7 @@ func TestHTTP2ProxyWithHostProbeResist(t *testing.T) {
Proto: "HTTP/2.0",
ProtoMajor: 2,
ProtoMinor: 0,
Body: io.NopCloser(bytes.NewReader(sendData)),
Body: ioutil.NopCloser(bytes.NewReader(sendData)),
Host: "github.com:443",
ContentLength: int64(len(sendData)),
}
@ -1068,7 +1068,7 @@ func TestHTTP2ProxyWithHostProbeResist(t *testing.T) {
t.Error("got non-200 status:", resp.Status)
}
recv, _ := io.ReadAll(resp.Body)
recv, _ := ioutil.ReadAll(resp.Body)
if !bytes.Equal(sendData, recv) {
t.Error("data not equal")
}
@ -1105,7 +1105,7 @@ func TestHTTP2ProxyWithFileProbeResist(t *testing.T) {
if err != nil {
t.Error(err)
}
recv, _ := io.ReadAll(conn)
recv, _ := ioutil.ReadAll(conn)
if !bytes.Equal(recv, []byte("Hello World!")) {
t.Error("data not equal")
}

View File

@ -4,7 +4,7 @@ import (
"bytes"
"crypto/rand"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/http/httptest"
@ -249,7 +249,7 @@ func TestHTTPProxyWithWebProbeResist(t *testing.T) {
t.Error("got status:", resp.Status)
}
recv, _ := io.ReadAll(resp.Body)
recv, _ := ioutil.ReadAll(resp.Body)
if !bytes.Equal(recv, []byte("Hello World!")) {
t.Error("data not equal")
}
@ -296,7 +296,7 @@ func TestHTTPProxyWithHostProbeResist(t *testing.T) {
t.Error("got status:", resp.Status)
}
recv, _ := io.ReadAll(resp.Body)
recv, _ := ioutil.ReadAll(resp.Body)
if !bytes.Equal(sendData, recv) {
t.Error("data not equal")
}
@ -332,7 +332,7 @@ func TestHTTPProxyWithFileProbeResist(t *testing.T) {
t.Error("got status:", resp.Status)
}
recv, _ := io.ReadAll(resp.Body)
recv, _ := ioutil.ReadAll(resp.Body)
if !bytes.Equal(recv, []byte("Hello World!")) {
t.Error("data not equal, got:", string(recv))
}

42
kcp.go
View File

@ -15,9 +15,9 @@ import (
"github.com/go-log/log"
"github.com/klauspost/compress/snappy"
"github.com/xtaci/kcp-go/v5"
"github.com/xtaci/smux"
"github.com/xtaci/tcpraw"
"github.com/xtaci/kcp-go"
"github.com/xtaci/smux"
)
var (
@ -43,9 +43,6 @@ type KCPConfig struct {
Resend int `json:"resend"`
NoCongestion int `json:"nc"`
SockBuf int `json:"sockbuf"`
SmuxBuf int `json:"smuxbuf"`
StreamBuf int `json:"streambuf"`
SmuxVer int `json:"smuxver"`
KeepAlive int `json:"keepalive"`
SnmpLog string `json:"snmplog"`
SnmpPeriod int `json:"snmpperiod"`
@ -65,16 +62,6 @@ func (c *KCPConfig) Init() {
case "fast3":
c.NoDelay, c.Interval, c.Resend, c.NoCongestion = 1, 10, 2, 1
}
if c.SmuxVer <= 0 {
c.SmuxVer = 1
}
if c.SmuxBuf <= 0 {
c.SmuxBuf = c.SockBuf
}
if c.StreamBuf <= 0 {
c.StreamBuf = c.SockBuf / 2
}
log.Logf("%#v", c)
}
var (
@ -96,9 +83,6 @@ var (
Resend: 0,
NoCongestion: 0,
SockBuf: 4194304,
SmuxVer: 1,
SmuxBuf: 4194304,
StreamBuf: 2097152,
KeepAlive: 10,
SnmpLog: "",
SnmpPeriod: 60,
@ -247,14 +231,8 @@ func (tr *kcpTransporter) initSession(addr string, conn net.Conn, config *KCPCon
// stream multiplex
smuxConfig := smux.DefaultConfig()
smuxConfig.Version = config.SmuxVer
smuxConfig.MaxReceiveBuffer = config.SmuxBuf
smuxConfig.MaxStreamBuffer = config.StreamBuf
smuxConfig.MaxReceiveBuffer = config.SockBuf
smuxConfig.KeepAliveInterval = time.Duration(config.KeepAlive) * time.Second
if err := smux.VerifyConfig(smuxConfig); err != nil {
return nil, err
}
var cc net.Conn = kcpconn
if !config.NoComp {
cc = newCompStreamConn(kcpconn)
@ -354,9 +332,7 @@ func (l *kcpListener) listenLoop() {
func (l *kcpListener) mux(conn net.Conn) {
smuxConfig := smux.DefaultConfig()
smuxConfig.Version = l.config.SmuxVer
smuxConfig.MaxReceiveBuffer = l.config.SmuxBuf
smuxConfig.MaxStreamBuffer = l.config.StreamBuf
smuxConfig.MaxReceiveBuffer = l.config.SockBuf
smuxConfig.KeepAliveInterval = time.Duration(l.config.KeepAlive) * time.Second
log.Logf("[kcp] %s - %s", conn.RemoteAddr(), l.Addr())
@ -497,13 +473,9 @@ func (c *compStreamConn) Read(b []byte) (n int, err error) {
}
func (c *compStreamConn) Write(b []byte) (n int, err error) {
if _, err = c.w.Write(b); err != nil {
return 0, err
}
if err = c.w.Flush(); err != nil {
return 0, err
}
return len(b), err
n, err = c.w.Write(b)
err = c.w.Flush()
return n, err
}
func (c *compStreamConn) Close() error {

View File

@ -90,7 +90,6 @@ func ParseNode(s string) (node Node, err error) {
case "ftcp": // fake TCP
case "dns":
case "redu", "redirectu": // UDP tproxy
case "vsock":
default:
node.Transport = "tcp"
}

14
obfs.go
View File

@ -20,9 +20,9 @@ import (
"github.com/go-log/log"
pt "git.torproject.org/pluggable-transports/goptlib.git"
dissector "github.com/go-gost/tls-dissector"
"gitlab.com/yawning/obfs4.git/transports/base"
"gitlab.com/yawning/obfs4.git/transports/obfs4"
dissector "github.com/go-gost/tls-dissector"
)
const (
@ -804,16 +804,6 @@ func Obfs4Listener(addr string) (Listener, error) {
return l, nil
}
// TempError satisfies the net.Error interface and presents itself
// as temporary to make sure that it gets retried by the Accept loop
// in server.go.
type TempError struct {
error
}
func (e TempError) Timeout() bool { return false }
func (e TempError) Temporary() bool { return true }
func (l *obfs4Listener) Accept() (net.Conn, error) {
conn, err := l.Listener.Accept()
if err != nil {
@ -822,7 +812,7 @@ func (l *obfs4Listener) Accept() (net.Conn, error) {
cc, err := obfs4ServerConn(l.addr, conn)
if err != nil {
conn.Close()
return nil, TempError{err}
return nil, err
}
return cc, nil
}

135
quic.go
View File

@ -13,11 +13,12 @@ import (
"time"
"github.com/go-log/log"
quic "github.com/quic-go/quic-go"
quic "github.com/lucas-clemente/quic-go"
)
type quicSession struct {
session quic.EarlyConnection
conn net.Conn
session quic.Session
}
func (session *quicSession) GetConn() (*quicConn, error) {
@ -59,71 +60,100 @@ func (tr *quicTransporter) Dial(addr string, options ...DialOption) (conn net.Co
option(opts)
}
udpAddr, err := net.ResolveUDPAddr("udp", addr)
if err != nil {
return nil, err
}
tr.sessionMutex.Lock()
defer tr.sessionMutex.Unlock()
session, ok := tr.sessions[addr]
if !ok {
var pc net.PacketConn
pc, err = net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: 0})
var cc *net.UDPConn
cc, err = net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: 0})
if err != nil {
return
}
conn = cc
if tr.config != nil && tr.config.Key != nil {
pc = &quicCipherConn{PacketConn: pc, key: tr.config.Key}
conn = &quicCipherConn{UDPConn: cc, key: tr.config.Key}
}
session, err = tr.initSession(udpAddr, pc)
if err != nil {
pc.Close()
return nil, err
}
session = &quicSession{conn: conn}
tr.sessions[addr] = session
}
conn, err = session.GetConn()
if err != nil {
session.Close()
delete(tr.sessions, addr)
return nil, err
}
return conn, nil
return session.conn, nil
}
func (tr *quicTransporter) Handshake(conn net.Conn, options ...HandshakeOption) (net.Conn, error) {
return conn, nil
}
func (tr *quicTransporter) initSession(addr net.Addr, conn net.PacketConn) (*quicSession, error) {
opts := &HandshakeOptions{}
for _, option := range options {
option(opts)
}
config := tr.config
if config == nil {
config = &QUICConfig{}
if opts.QUICConfig != nil {
config = opts.QUICConfig
}
if config.TLSConfig == nil {
config.TLSConfig = &tls.Config{InsecureSkipVerify: true}
}
tr.sessionMutex.Lock()
defer tr.sessionMutex.Unlock()
timeout := opts.Timeout
if timeout <= 0 {
timeout = HandshakeTimeout
}
conn.SetDeadline(time.Now().Add(timeout))
defer conn.SetDeadline(time.Time{})
session, ok := tr.sessions[opts.Addr]
if session != nil && session.conn != conn {
conn.Close()
return nil, errors.New("quic: unrecognized connection")
}
if !ok || session.session == nil {
s, err := tr.initSession(opts.Addr, conn, config)
if err != nil {
conn.Close()
delete(tr.sessions, opts.Addr)
return nil, err
}
session = s
tr.sessions[opts.Addr] = session
}
cc, err := session.GetConn()
if err != nil {
session.Close()
delete(tr.sessions, opts.Addr)
return nil, err
}
return cc, nil
}
func (tr *quicTransporter) initSession(addr string, conn net.Conn, config *QUICConfig) (*quicSession, error) {
udpConn, ok := conn.(net.PacketConn)
if !ok {
return nil, errors.New("quic: wrong connection type")
}
udpAddr, err := net.ResolveUDPAddr("udp", addr)
if err != nil {
return nil, err
}
quicConfig := &quic.Config{
HandshakeIdleTimeout: config.Timeout,
MaxIdleTimeout: config.IdleTimeout,
KeepAlivePeriod: config.KeepAlivePeriod,
KeepAlive: config.KeepAlive,
Versions: []quic.VersionNumber{
quic.Version1,
quic.Version2,
quic.VersionDraft29,
},
MaxIdleTimeout: config.IdleTimeout,
}
session, err := quic.DialEarly(context.Background(), conn, addr, tlsConfigQUICALPN(config.TLSConfig), quicConfig)
session, err := quic.Dial(udpConn, udpAddr, addr, tlsConfigQUICALPN(config.TLSConfig), quicConfig)
if err != nil {
log.Logf("quic dial %s: %v", addr, err)
return nil, err
}
return &quicSession{session: session}, nil
return &quicSession{conn: conn, session: session}, nil
}
func (tr *quicTransporter) Multiplex() bool {
@ -132,16 +162,15 @@ func (tr *quicTransporter) Multiplex() bool {
// QUICConfig is the config for QUIC client and server
type QUICConfig struct {
TLSConfig *tls.Config
Timeout time.Duration
KeepAlive bool
KeepAlivePeriod time.Duration
IdleTimeout time.Duration
Key []byte
TLSConfig *tls.Config
Timeout time.Duration
KeepAlive bool
IdleTimeout time.Duration
Key []byte
}
type quicListener struct {
ln quic.EarlyListener
ln quic.Listener
connChan chan net.Conn
errChan chan error
}
@ -153,11 +182,11 @@ func QUICListener(addr string, config *QUICConfig) (Listener, error) {
}
quicConfig := &quic.Config{
HandshakeIdleTimeout: config.Timeout,
KeepAlivePeriod: config.KeepAlivePeriod,
KeepAlive: config.KeepAlive,
MaxIdleTimeout: config.IdleTimeout,
Versions: []quic.VersionNumber{
quic.Version1,
quic.Version2,
quic.VersionDraft29,
},
}
@ -171,22 +200,23 @@ func QUICListener(addr string, config *QUICConfig) (Listener, error) {
if err != nil {
return nil, err
}
conn, err = net.ListenUDP("udp", udpAddr)
lconn, err := net.ListenUDP("udp", udpAddr)
if err != nil {
return nil, err
}
conn = lconn
if config.Key != nil {
conn = &quicCipherConn{PacketConn: conn, key: config.Key}
conn = &quicCipherConn{UDPConn: lconn, key: config.Key}
}
ln, err := quic.ListenEarly(conn, tlsConfigQUICALPN(tlsConfig), quicConfig)
ln, err := quic.Listen(conn, tlsConfigQUICALPN(tlsConfig), quicConfig)
if err != nil {
return nil, err
}
l := &quicListener{
ln: *ln,
ln: ln,
connChan: make(chan net.Conn, 1024),
errChan: make(chan error, 1),
}
@ -208,7 +238,7 @@ func (l *quicListener) listenLoop() {
}
}
func (l *quicListener) sessionLoop(session quic.Connection) {
func (l *quicListener) sessionLoop(session quic.Session) {
log.Logf("[quic] %s <-> %s", session.RemoteAddr(), session.LocalAddr())
defer log.Logf("[quic] %s >-< %s", session.RemoteAddr(), session.LocalAddr())
@ -265,12 +295,12 @@ func (c *quicConn) RemoteAddr() net.Addr {
}
type quicCipherConn struct {
net.PacketConn
*net.UDPConn
key []byte
}
func (conn *quicCipherConn) ReadFrom(data []byte) (n int, addr net.Addr, err error) {
n, addr, err = conn.PacketConn.ReadFrom(data)
n, addr, err = conn.UDPConn.ReadFrom(data)
if err != nil {
return
}
@ -290,7 +320,7 @@ func (conn *quicCipherConn) WriteTo(data []byte, addr net.Addr) (n int, err erro
return
}
_, err = conn.PacketConn.WriteTo(b, addr)
_, err = conn.UDPConn.WriteTo(b, addr)
if err != nil {
return
}
@ -341,7 +371,8 @@ func tlsConfigQUICALPN(tlsConfig *tls.Config) *tls.Config {
if tlsConfig == nil {
panic("quic: tlsconfig is nil")
}
tlsConfigQUIC := tlsConfig.Clone()
tlsConfigQUIC := &tls.Config{}
*tlsConfigQUIC = *tlsConfig
tlsConfigQUIC.NextProtos = []string{"http/3", "quic/v1"}
return tlsConfigQUIC
}

View File

@ -1,4 +1,3 @@
//go:build linux
// +build linux
package gost

View File

@ -1,4 +1,3 @@
//go:build !linux
// +build !linux
package gost
@ -36,7 +35,8 @@ func (h *tcpRedirectHandler) Handle(c net.Conn) {
c.Close()
}
type udpRedirectHandler struct{}
type udpRedirectHandler struct {
}
// UDPRedirectHandler creates a server Handler for UDP transparent server.
func UDPRedirectHandler(opts ...HandlerOption) Handler {

View File

@ -8,6 +8,7 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/url"
@ -262,7 +263,9 @@ func (r *resolver) copyServers() []NameServer {
defer r.mux.RUnlock()
servers := make([]NameServer, len(r.servers))
copy(servers, r.servers)
for i := range r.servers {
servers[i] = r.servers[i]
}
return servers
}
@ -309,28 +312,17 @@ func (r *resolver) resolve(ctx context.Context, ex Exchanger, host string) (ips
r.mux.RUnlock()
if prefer == "ipv6" { // prefer ipv6
if ips, err = r.resolve6(ctx, ex, host); len(ips) > 0 {
mq := &dns.Msg{}
mq.SetQuestion(dns.Fqdn(host), dns.TypeAAAA)
ips, err = r.resolveIPs(ctx, ex, mq)
if err != nil || len(ips) > 0 {
return
}
return r.resolve4(ctx, ex, host)
}
if ips, err = r.resolve4(ctx, ex, host); len(ips) > 0 {
return
}
return r.resolve6(ctx, ex, host)
}
func (r *resolver) resolve4(ctx context.Context, ex Exchanger, host string) (ips []net.IP, err error) {
mq := dns.Msg{}
mq := &dns.Msg{}
mq.SetQuestion(dns.Fqdn(host), dns.TypeA)
return r.resolveIPs(ctx, ex, &mq)
}
func (r *resolver) resolve6(ctx context.Context, ex Exchanger, host string) (ips []net.IP, err error) {
mq := dns.Msg{}
mq.SetQuestion(dns.Fqdn(host), dns.TypeAAAA)
return r.resolveIPs(ctx, ex, &mq)
return r.resolveIPs(ctx, ex, mq)
}
func (r *resolver) resolveIPs(ctx context.Context, ex Exchanger, mq *dns.Msg) (ips []net.IP, err error) {
@ -717,8 +709,7 @@ func (ex *dnsExchanger) Exchange(ctx context.Context, query []byte) ([]byte, err
defer c.Close()
conn := &dns.Conn{
Conn: c,
UDPSize: 1024,
Conn: c,
}
if _, err = conn.Write(query); err != nil {
return nil, err
@ -914,7 +905,7 @@ func (ex *dohExchanger) Exchange(ctx context.Context, query []byte) ([]byte, err
}
// Read wireformat response from the body
buf, err := io.ReadAll(resp.Body)
buf, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read the response body: %s", err)
}

View File

@ -4,18 +4,15 @@ import (
"errors"
"math/rand"
"net"
"sort"
"strconv"
"sync"
"sync/atomic"
"time"
"github.com/go-log/log"
)
var (
// ErrNoneAvailable indicates there is no node available.
ErrNoneAvailable = errors.New("none node available")
ErrNoneAvailable = errors.New("none available")
)
// NodeSelector as a mechanism to pick nodes and mark their status.
@ -208,94 +205,6 @@ func (f *FailFilter) String() string {
return "fail"
}
// FastestFilter filter the fastest node
type FastestFilter struct {
mu sync.Mutex
pinger *net.Dialer
pingResult map[int]int
pingResultTTL map[int]int64
topCount int
}
func NewFastestFilter(pingTimeOut int, topCount int) *FastestFilter {
if pingTimeOut == 0 {
pingTimeOut = 3000 // 3s
}
return &FastestFilter{
mu: sync.Mutex{},
pinger: &net.Dialer{Timeout: time.Millisecond * time.Duration(pingTimeOut)},
pingResult: make(map[int]int, 0),
pingResultTTL: make(map[int]int64, 0),
topCount: topCount,
}
}
func (f *FastestFilter) Filter(nodes []Node) []Node {
// disabled
if f.topCount == 0 {
return nodes
}
// get latency with ttl cache
now := time.Now().Unix()
var getNodeLatency = func(node Node) int {
f.mu.Lock()
defer f.mu.Unlock()
if f.pingResultTTL[node.ID] < now {
f.pingResultTTL[node.ID] = now + 5 // tmp
// get latency
go func(node Node) {
latency := f.doTcpPing(node.Addr)
r := rand.New(rand.NewSource(time.Now().UnixNano()))
ttl := 300 - int64(120*r.Float64())
f.mu.Lock()
defer f.mu.Unlock()
f.pingResult[node.ID] = latency
f.pingResultTTL[node.ID] = now + ttl
}(node)
}
return f.pingResult[node.ID]
}
// sort
sort.Slice(nodes, func(i, j int) bool {
return getNodeLatency(nodes[i]) < getNodeLatency(nodes[j])
})
// split
if len(nodes) <= f.topCount {
return nodes
}
return nodes[0:f.topCount]
}
func (f *FastestFilter) String() string {
return "fastest"
}
// doTcpPing
func (f *FastestFilter) doTcpPing(address string) int {
start := time.Now()
conn, err := f.pinger.Dial("tcp", address)
elapsed := time.Since(start)
if err == nil {
_ = conn.Close()
}
latency := int(elapsed.Milliseconds())
log.Logf("pingDoTCP: %s, latency: %d", address, latency)
return latency
}
// InvalidFilter filters the invalid node.
// A node is invalid if its port is invalid (negative or zero value).
type InvalidFilter struct{}

View File

@ -127,30 +127,6 @@ func TestFailFilter(t *testing.T) {
}
}
func TestFastestFilter(t *testing.T) {
nodes := []Node{
Node{ID: 1, marker: &failMarker{}, Addr: "1.0.0.1:80"},
Node{ID: 2, marker: &failMarker{}, Addr: "1.0.0.2:80"},
Node{ID: 3, marker: &failMarker{}, Addr: "1.0.0.3:80"},
}
filter := NewFastestFilter(0, 2)
var print = func(nodes []Node) []string {
var rows []string
for _, node := range nodes {
rows = append(rows, node.Addr)
}
return rows
}
result1 := filter.Filter(nodes)
t.Logf("result 1: %+v", print(result1))
time.Sleep(time.Second)
result2 := filter.Filter(nodes)
t.Logf("result 2: %+v", print(result2))
}
func TestSelector(t *testing.T) {
nodes := []Node{
Node{ID: 1, marker: &failMarker{}},

View File

@ -112,11 +112,11 @@ func transport(rw1, rw2 io.ReadWriter) error {
errc <- copyBuffer(rw2, rw1)
}()
if err := <-errc; err != nil && err != io.EOF {
return err
err := <-errc
if err != nil && err == io.EOF {
err = nil
}
return nil
return err
}
func copyBuffer(dst io.Writer, src io.Reader) error {

View File

@ -1,4 +1,3 @@
//go:build windows
// +build windows
package gost

View File

@ -1,4 +1,3 @@
//go:build !windows
// +build !windows
package gost
@ -9,7 +8,7 @@ import (
"syscall"
"github.com/go-log/log"
"github.com/xtaci/kcp-go/v5"
"github.com/xtaci/kcp-go"
)
func kcpSigHandler() {

View File

@ -1,34 +0,0 @@
name: gost
base: core20
version: '2.12.0'
summary: A simple security tunnel written in golang
description: |
Project: https://github.com/ginuerzh/gost
Wiki: https://v2.gost.run
icon: gost.png
website: https://v2.gost.run
license: MIT
confinement: strict
grade: stable
parts:
gost:
plugin: go
go-channel: latest/stable
source: https://github.com/ginuerzh/gost
source-subdir: cmd/gost
source-type: git
source-tag: v2.12.0
build-packages:
- gcc
apps:
gost:
command: bin/gost
plugs:
- home
- network
- network-bind

43
snapcraft.yaml Normal file
View File

@ -0,0 +1,43 @@
name: gost
type: app
version: '2.11.2'
title: GO Simple Tunnel
summary: A simple security tunnel written in golang
description: |
https://github.com/ginuerzh/gost
confinement: strict
grade: stable
base: core18
license: MIT
parts:
gost:
plugin: nil
build-snaps: [go/1.18/stable]
source: https://github.com/ginuerzh/gost.git
source-subdir: cmd/gost
source-type: git
source-branch: '2'
build-packages:
- build-essential
override-build: |
set -ex
echo "Starting override-build:"
pwd
cd $SNAPCRAFT_PART_BUILD
GO111MODULE=on CGO_ENABLED=0 go build --ldflags="-s -w"
./gost -V
echo "Installing to ${SNAPCRAFT_PART_INSTALL}..."
install -d $SNAPCRAFT_PART_INSTALL/bin
cp -v gost $SNAPCRAFT_PART_INSTALL/bin/
echo "Override-build done!"
apps:
gost:
command: bin/gost
plugs:
- home
- network
- network-bind

View File

@ -7,7 +7,7 @@ import (
"crypto/tls"
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
@ -69,7 +69,7 @@ func sniRoundtrip(client *Client, server *Server, targetURL string, data []byte)
return errors.New(resp.Status)
}
recv, err := io.ReadAll(resp.Body)
recv, err := ioutil.ReadAll(resp.Body)
if err != nil {
return
}

View File

@ -5,7 +5,3 @@ import "syscall"
func setSocketMark(fd int, value int) (e error) {
return syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_MARK, value)
}
func setSocketInterface(fd int, value string) (e error) {
return syscall.SetsockoptString(fd, syscall.SOL_SOCKET, syscall.SO_BINDTODEVICE, value)
}

View File

@ -1,12 +1,7 @@
//go:build !linux
// +build !linux
package gost
func setSocketMark(fd int, value int) (e error) {
return nil
}
func setSocketInterface(fd int, value string) (e error) {
return nil
}

View File

@ -10,7 +10,6 @@ import (
"net"
"net/url"
"strconv"
"strings"
"sync"
"time"
@ -1125,7 +1124,7 @@ func (h *socks5Handler) handleUDPRelay(conn net.Conn, req *gosocks5.Request) {
return
}
relay, err := net.ListenUDP("udp", &net.UDPAddr{IP: conn.LocalAddr().(*net.TCPAddr).IP, Port: 0}) // use out-going interface's IP
relay, err := net.ListenUDP("udp", nil)
if err != nil {
log.Logf("[socks5-udp] %s -> %s : %s", conn.RemoteAddr(), conn.LocalAddr(), err)
reply := gosocks5.NewReply(gosocks5.Failure, nil)
@ -1138,6 +1137,7 @@ func (h *socks5Handler) handleUDPRelay(conn net.Conn, req *gosocks5.Request) {
defer relay.Close()
socksAddr := toSocksAddr(relay.LocalAddr())
socksAddr.Host, _, _ = net.SplitHostPort(conn.LocalAddr().String()) // replace the IP to the out-going interface's
reply := gosocks5.NewReply(gosocks5.Succeeded, socksAddr)
if err := reply.Write(conn); err != nil {
log.Logf("[socks5-udp] %s <- %s : %s", conn.RemoteAddr(), conn.LocalAddr(), err)
@ -1630,21 +1630,17 @@ func (h *socks5Handler) muxBindOn(conn net.Conn, addr string) {
}
}
// TODO: support domain
// TODO: support ipv6 and domain
func toSocksAddr(addr net.Addr) *gosocks5.Addr {
host := "0.0.0.0"
port := 0
addrType := gosocks5.AddrIPv4
if addr != nil {
h, p, _ := net.SplitHostPort(addr.String())
host = h
port, _ = strconv.Atoi(p)
if strings.Count(host, ":") > 0 {
addrType = gosocks5.AddrIPv6
}
}
return &gosocks5.Addr{
Type: addrType,
Type: gosocks5.AddrIPv4,
Host: host,
Port: uint16(port),
}

18
ssh.go
View File

@ -6,8 +6,8 @@ import (
"encoding/binary"
"errors"
"fmt"
"io/ioutil"
"net"
"os"
"strconv"
"strings"
"sync"
@ -27,11 +27,13 @@ const (
GostSSHTunnelRequest = "gost-tunnel" // extended request type for ssh tunnel
)
var errSessionDead = errors.New("session is dead")
var (
errSessionDead = errors.New("session is dead")
)
// ParseSSHKeyFile parses ssh key file.
func ParseSSHKeyFile(fp string) (ssh.Signer, error) {
key, err := os.ReadFile(fp)
key, err := ioutil.ReadFile(fp)
if err != nil {
return nil, err
}
@ -40,7 +42,7 @@ func ParseSSHKeyFile(fp string) (ssh.Signer, error) {
// ParseSSHAuthorizedKeysFile parses ssh Authorized Keys file.
func ParseSSHAuthorizedKeysFile(fp string) (map[string]bool, error) {
authorizedKeysBytes, err := os.ReadFile(fp)
authorizedKeysBytes, err := ioutil.ReadFile(fp)
if err != nil {
return nil, err
}
@ -57,7 +59,8 @@ func ParseSSHAuthorizedKeysFile(fp string) (map[string]bool, error) {
return authorizedKeysMap, nil
}
type sshDirectForwardConnector struct{}
type sshDirectForwardConnector struct {
}
// SSHDirectForwardConnector creates a Connector for SSH TCP direct port forwarding.
func SSHDirectForwardConnector() Connector {
@ -100,7 +103,8 @@ func (c *sshDirectForwardConnector) ConnectContext(ctx context.Context, conn net
return conn, nil
}
type sshRemoteForwardConnector struct{}
type sshRemoteForwardConnector struct {
}
// SSHRemoteForwardConnector creates a Connector for SSH TCP remote port forwarding.
func SSHRemoteForwardConnector() Connector {
@ -646,7 +650,7 @@ func (h *sshForwardHandler) tcpipForwardRequest(sshConn ssh.Conn, req *ssh.Reque
return
}
ln, err := net.Listen("tcp", addr) // tie to the client connection
ln, err := net.Listen("tcp", addr) //tie to the client connection
if err != nil {
log.Log("[ssh-rtcp]", err)
req.Reply(false, nil)

View File

@ -1,17 +1,19 @@
package gost
import (
"errors"
"fmt"
"net"
"os/exec"
"strings"
"syscall"
"github.com/docker/libcontainer/netlink"
"github.com/go-log/log"
"github.com/milosgajdos/tenus"
"github.com/songgao/water"
)
func createTun(cfg TunConfig) (conn net.Conn, itf *net.Interface, err error) {
ip, _, err := net.ParseCIDR(cfg.Addr)
ip, ipNet, err := net.ParseCIDR(cfg.Addr)
if err != nil {
return
}
@ -26,21 +28,35 @@ func createTun(cfg TunConfig) (conn net.Conn, itf *net.Interface, err error) {
return
}
link, err := tenus.NewLinkFrom(ifce.Name())
if err != nil {
return
}
mtu := cfg.MTU
if mtu <= 0 {
mtu = DefaultMTU
}
if err = exeCmd(fmt.Sprintf("ip link set dev %s mtu %d", ifce.Name(), mtu)); err != nil {
log.Log(err)
cmd := fmt.Sprintf("ip link set dev %s mtu %d", ifce.Name(), mtu)
log.Log("[tun]", cmd)
if er := link.SetLinkMTU(mtu); er != nil {
err = fmt.Errorf("%s: %v", cmd, er)
return
}
if err = exeCmd(fmt.Sprintf("ip address add %s dev %s", cfg.Addr, ifce.Name())); err != nil {
log.Log(err)
cmd = fmt.Sprintf("ip address add %s dev %s", cfg.Addr, ifce.Name())
log.Log("[tun]", cmd)
if er := link.SetLinkIp(ip, ipNet); er != nil {
err = fmt.Errorf("%s: %v", cmd, er)
return
}
if err = exeCmd(fmt.Sprintf("ip link set dev %s up", ifce.Name())); err != nil {
log.Log(err)
cmd = fmt.Sprintf("ip link set dev %s up", ifce.Name())
log.Log("[tun]", cmd)
if er := link.SetLinkUp(); er != nil {
err = fmt.Errorf("%s: %v", cmd, er)
return
}
if err = addTunRoutes(ifce.Name(), cfg.Routes...); err != nil {
@ -61,8 +77,9 @@ func createTun(cfg TunConfig) (conn net.Conn, itf *net.Interface, err error) {
func createTap(cfg TapConfig) (conn net.Conn, itf *net.Interface, err error) {
var ip net.IP
var ipNet *net.IPNet
if cfg.Addr != "" {
ip, _, err = net.ParseCIDR(cfg.Addr)
ip, ipNet, err = net.ParseCIDR(cfg.Addr)
if err != nil {
return
}
@ -78,23 +95,37 @@ func createTap(cfg TapConfig) (conn net.Conn, itf *net.Interface, err error) {
return
}
link, err := tenus.NewLinkFrom(ifce.Name())
if err != nil {
return
}
mtu := cfg.MTU
if mtu <= 0 {
mtu = DefaultMTU
}
if err = exeCmd(fmt.Sprintf("ip link set dev %s mtu %d", ifce.Name(), mtu)); err != nil {
log.Log(err)
cmd := fmt.Sprintf("ip link set dev %s mtu %d", ifce.Name(), mtu)
log.Log("[tap]", cmd)
if er := link.SetLinkMTU(mtu); er != nil {
err = fmt.Errorf("%s: %v", cmd, er)
return
}
if cfg.Addr != "" {
if err = exeCmd(fmt.Sprintf("ip address add %s dev %s", cfg.Addr, ifce.Name())); err != nil {
log.Log(err)
cmd = fmt.Sprintf("ip address add %s dev %s", cfg.Addr, ifce.Name())
log.Log("[tap]", cmd)
if er := link.SetLinkIp(ip, ipNet); er != nil {
err = fmt.Errorf("%s: %v", cmd, er)
return
}
}
if err = exeCmd(fmt.Sprintf("ip link set dev %s up", ifce.Name())); err != nil {
log.Log(err)
cmd = fmt.Sprintf("ip link set dev %s up", ifce.Name())
log.Log("[tap]", cmd)
if er := link.SetLinkUp(); er != nil {
err = fmt.Errorf("%s: %v", cmd, er)
return
}
if err = addTapRoutes(ifce.Name(), cfg.Gateway, cfg.Routes...); err != nil {
@ -120,10 +151,8 @@ func addTunRoutes(ifName string, routes ...IPRoute) error {
}
cmd := fmt.Sprintf("ip route add %s dev %s", route.Dest.String(), ifName)
log.Logf("[tun] %s", cmd)
args := strings.Split(cmd, " ")
if er := exec.Command(args[0], args[1:]...).Run(); er != nil {
log.Logf("[tun] %s: %v", cmd, er)
if err := netlink.AddRoute(route.Dest.String(), "", "", ifName); err != nil && !errors.Is(err, syscall.EEXIST) {
return fmt.Errorf("%s: %v", cmd, err)
}
}
return nil
@ -136,22 +165,9 @@ func addTapRoutes(ifName string, gw string, routes ...string) error {
}
cmd := fmt.Sprintf("ip route add %s via %s dev %s", route, gw, ifName)
log.Logf("[tap] %s", cmd)
args := strings.Split(cmd, " ")
if er := exec.Command(args[0], args[1:]...).Run(); er != nil {
log.Logf("[tap] %s: %v", cmd, er)
if err := netlink.AddRoute(route, "", gw, ifName); err != nil {
return fmt.Errorf("%s: %v", cmd, err)
}
}
return nil
}
func exeCmd(cmd string) error {
log.Log(cmd)
args := strings.Split(cmd, " ")
if err := exec.Command(args[0], args[1:]...).Run(); err != nil {
return fmt.Errorf("%s: %v", cmd, err)
}
return nil
}

View File

@ -1,4 +1,3 @@
//go:build !linux && !windows && !darwin
// +build !linux,!windows,!darwin
package gost

View File

@ -1,76 +0,0 @@
package gost
import (
"net"
"strconv"
"github.com/mdlayher/vsock"
)
// vsockTransporter is a raw VSOCK transporter.
type vsockTransporter struct{}
// VSOCKTransporter creates a raw VSOCK client.
func VSOCKTransporter() Transporter {
return &vsockTransporter{}
}
func (tr *vsockTransporter) Dial(addr string, options ...DialOption) (net.Conn, error) {
opts := &DialOptions{}
for _, option := range options {
option(opts)
}
if opts.Chain == nil {
vAddr, err := parseAddr(addr)
if err != nil {
return nil, err
}
return vsock.Dial(vAddr.ContextID, vAddr.Port, nil)
}
return opts.Chain.Dial(addr)
}
func parseUint32(s string) (uint32, error ) {
n, err := strconv.ParseUint(s, 10, 32)
if err != nil {
return 0, err
}
return uint32(n), nil
}
func parseAddr(addr string) (*vsock.Addr, error) {
hostStr, portStr, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
}
host := uint32(0)
if hostStr != "" {
host, err = parseUint32(hostStr)
if err != nil {
return nil, err
}
}
port, err := parseUint32(portStr)
if err != nil {
return nil, err
}
return &vsock.Addr{ContextID: host, Port: port}, nil
}
func (tr *vsockTransporter) Handshake(conn net.Conn, options ...HandshakeOption) (net.Conn, error) {
return conn, nil
}
func (tr *vsockTransporter) Multiplex() bool {
return false
}
// VSOCKListener creates a Listener for VSOCK proxy server.
func VSOCKListener(addr string) (Listener, error) {
vAddr, err := parseAddr(addr)
if err != nil {
return nil, err
}
return vsock.Listen(vAddr.Port, nil)
}