forked from ms/transocks
Compare commits
No commits in common. "master" and "v0.1" have entirely different histories.
@ -1,80 +0,0 @@
|
|||||||
name: build
|
|
||||||
|
|
||||||
run-name: ${{ gitea.actor }} build Transocks
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- "**"
|
|
||||||
tags-ignore:
|
|
||||||
- "v*"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: check-out
|
|
||||||
uses: https://git.mousesoft.ru/actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
fetch-tags: true
|
|
||||||
|
|
||||||
- name: set-up go
|
|
||||||
uses: https://git.mousesoft.ru/actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: ">=1.22"
|
|
||||||
|
|
||||||
- name: set-up dependencies
|
|
||||||
run: |
|
|
||||||
go install github.com/kisielk/errcheck@latest
|
|
||||||
go install honnef.co/go/tools/cmd/staticcheck@latest
|
|
||||||
go install github.com/sashamelentyev/usestdlibvars@latest
|
|
||||||
go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latest
|
|
||||||
make vendor
|
|
||||||
|
|
||||||
- name: lint
|
|
||||||
run: make lint
|
|
||||||
|
|
||||||
- name: golangci-lint
|
|
||||||
uses: https://github.com/golangci/golangci-lint-action@v6
|
|
||||||
with:
|
|
||||||
version: v1.60
|
|
||||||
|
|
||||||
- name: build linux amd64
|
|
||||||
id: build-amd64
|
|
||||||
run: |
|
|
||||||
echo "ARTIFACT=transocks-$(make version)_$(go env GOOS)-amd64" >> $GITHUB_OUTPUT
|
|
||||||
GOARCH=amd64 make clean build
|
|
||||||
|
|
||||||
- name: upload linux amd64
|
|
||||||
uses: https://git.mousesoft.ru/actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: ${{ steps.build-amd64.outputs.ARTIFACT }}
|
|
||||||
path: out/bin/*
|
|
||||||
overwrite: true
|
|
||||||
|
|
||||||
- name: build linux arm64
|
|
||||||
id: build-arm64
|
|
||||||
run: |
|
|
||||||
echo "ARTIFACT=transocks-$(make version)_$(go env GOOS)-arm64" >> $GITHUB_OUTPUT
|
|
||||||
GOARCH=arm64 make clean build
|
|
||||||
|
|
||||||
- name: upload linux arm64
|
|
||||||
uses: https://git.mousesoft.ru/actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: ${{ steps.build-arm64.outputs.ARTIFACT }}
|
|
||||||
path: out/bin/*
|
|
||||||
overwrite: true
|
|
||||||
|
|
||||||
- name: build linux arm32
|
|
||||||
id: build-arm32
|
|
||||||
run: |
|
|
||||||
echo "ARTIFACT=transocks-$(make version)_$(go env GOOS)-arm32" >> $GITHUB_OUTPUT
|
|
||||||
GOARCH=arm make clean build
|
|
||||||
|
|
||||||
- name: upload linux arm32
|
|
||||||
uses: https://git.mousesoft.ru/actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: ${{ steps.build-arm32.outputs.ARTIFACT }}
|
|
||||||
path: out/bin/*
|
|
||||||
overwrite: true
|
|
@ -1,7 +1,5 @@
|
|||||||
name: release
|
name: release
|
||||||
|
|
||||||
run-name: ${{ gitea.actor }} release Transocks
|
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
@ -12,81 +10,44 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: check-out
|
- name: check-out
|
||||||
uses: https://git.mousesoft.ru/actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: set-up qemu
|
||||||
|
uses: https://git.mousesoft.ru/ms/gitea-action-setup-qemu@v3
|
||||||
|
|
||||||
|
- name: set-up docker buildx
|
||||||
|
uses: https://git.mousesoft.ru/ms/gitea-action-docker-setup-buildx@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
buildkitd-flags: --debug
|
||||||
fetch-tags: true
|
|
||||||
|
|
||||||
- name: set-up go
|
- name: login to docker hub
|
||||||
uses: https://git.mousesoft.ru/actions/setup-go@v3
|
uses: https://git.mousesoft.ru/ms/gitea-action-docker-login@v3
|
||||||
with:
|
with:
|
||||||
go-version: ">=1.22"
|
registry: git.mousesoft.ru
|
||||||
|
username: ${{ secrets.API_USER }}
|
||||||
- name: set-up dependencies
|
password: ${{ secrets.API_TOKEN }}
|
||||||
run: |
|
|
||||||
go install github.com/kisielk/errcheck@latest
|
|
||||||
go install honnef.co/go/tools/cmd/staticcheck@latest
|
|
||||||
go install github.com/sashamelentyev/usestdlibvars@latest
|
|
||||||
go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latest
|
|
||||||
make vendor
|
|
||||||
|
|
||||||
- name: lint
|
|
||||||
run: make lint
|
|
||||||
|
|
||||||
- name: golangci-lint
|
|
||||||
uses: https://github.com/golangci/golangci-lint-action@v6
|
|
||||||
with:
|
|
||||||
version: v1.60
|
|
||||||
|
|
||||||
- name: build linux amd64
|
|
||||||
run: GOARCH=amd64 make build pkg-deb
|
|
||||||
|
|
||||||
- name: build linux arm64
|
|
||||||
run: GOARCH=arm64 make build pkg-deb
|
|
||||||
|
|
||||||
- name: build linux arm32
|
|
||||||
run: GOARCH=arm make build pkg-deb
|
|
||||||
|
|
||||||
- name: meta
|
- name: meta
|
||||||
id: meta
|
id: meta
|
||||||
env:
|
|
||||||
SSH_HOST: ${{ secrets.DEB_SSH_HOST }}
|
|
||||||
run: |
|
run: |
|
||||||
echo "VERSION=$(make version)" >> $GITHUB_OUTPUT
|
echo IMAGE_CREATED=$(date -u +'%Y-%m-%dT%H:%M:%SZ') | tee -a $GITHUB_OUTPUT
|
||||||
echo 'CHANGES<<EOF' >> $GITHUB_OUTPUT
|
echo IMAGE_VERSION=$(./version.sh n) | tee -a $GITHUB_OUTPUT
|
||||||
gawk -f scripts/changes.awk -v version=$(make version-number) CHANGELOG.md >> $GITHUB_OUTPUT
|
echo IMAGE_REVISION=$(git rev-parse HEAD) | tee -a $GITHUB_OUTPUT
|
||||||
echo EOF >> $GITHUB_OUTPUT
|
|
||||||
mkdir -p out
|
|
||||||
sed -e "s/DEB_SSH_HOST/$SSH_HOST/g" deploy/dput/mousesoft.json.tpl > out/mousesoft.json
|
|
||||||
mkdir -p /etc/dput.d/profiles
|
|
||||||
cp out/mousesoft.json /etc/dput.d/profiles/
|
|
||||||
|
|
||||||
- name: deploy packages
|
- name: build and push
|
||||||
env:
|
uses: https://git.mousesoft.ru/ms/gitea-action-docker-build-push@v6
|
||||||
SSH_HOST: ${{ secrets.DEB_SSH_HOST }}
|
|
||||||
SSH_PORT: ${{ secrets.DEB_SSH_PORT }}
|
|
||||||
SSH_USER: ${{ secrets.DEB_SSH_USER }}
|
|
||||||
SSH_KEY: ${{ secrets.DEB_SSH_KEY }}
|
|
||||||
run: |
|
|
||||||
mkdir -p ~/.ssh/
|
|
||||||
echo "$SSH_KEY" | tr -d '\r' > ~/.ssh/key
|
|
||||||
chmod 0600 ~/.ssh/key
|
|
||||||
cat >>~/.ssh/config <<END
|
|
||||||
Host $SSH_HOST
|
|
||||||
IdentitiesOnly yes
|
|
||||||
User $SSH_USER
|
|
||||||
IdentityFile ~/.ssh/key
|
|
||||||
Port $SSH_PORT
|
|
||||||
StrictHostKeyChecking no
|
|
||||||
END
|
|
||||||
find -O1 out -name '*.changes' -exec dput mousesoft \{\} \;
|
|
||||||
|
|
||||||
- name: release
|
|
||||||
uses: https://git.mousesoft.ru/actions/gitea-release-action@v1
|
|
||||||
with:
|
with:
|
||||||
title: "Transocks ${{ steps.meta.outputs.VERSION }}"
|
context: .
|
||||||
body: "${{ steps.meta.outputs.CHANGES }}"
|
file: Dockerfile
|
||||||
files: "out/*.deb"
|
platforms: |
|
||||||
sha256sum: true
|
linux/amd64
|
||||||
prerelease: true
|
linux/arm64
|
||||||
draft: true
|
pull: true
|
||||||
|
push: true
|
||||||
|
no-cache: true
|
||||||
|
build-args: |
|
||||||
|
IMAGE_VERSION=${{ steps.meta.outputs.IMAGE_VERSION }}
|
||||||
|
IMAGE_CREATED=${{ steps.meta.outputs.IMAGE_CREATED }}
|
||||||
|
tags: |
|
||||||
|
git.mousesoft.ru/alexey/transocks:${{ steps.meta.outputs.IMAGE_VERSION }}
|
||||||
|
git.mousesoft.ru/alexey/transocks:latest
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -12,8 +12,6 @@
|
|||||||
# Folders
|
# Folders
|
||||||
_obj
|
_obj
|
||||||
_test
|
_test
|
||||||
out
|
|
||||||
tmp
|
|
||||||
|
|
||||||
# Architecture specific extensions/prefixes
|
# Architecture specific extensions/prefixes
|
||||||
*.[568vq]
|
*.[568vq]
|
||||||
|
@ -3,5 +3,6 @@ linters:
|
|||||||
- dupl
|
- dupl
|
||||||
- goconst
|
- goconst
|
||||||
- gofmt
|
- gofmt
|
||||||
|
- golint
|
||||||
- typecheck
|
- typecheck
|
||||||
- unparam
|
- unparam
|
||||||
|
39
CHANGELOG.md
39
CHANGELOG.md
@ -2,44 +2,33 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## [1.1.4](https://git.mousesoft.ru/alexey/transocks/releases/tag/v1.1.4) - 2024-11-05
|
## [Unreleased]
|
||||||
|
|
||||||
- **Fixed**
|
|
||||||
- Bug in method `Server.handleConnection`.
|
|
||||||
|
|
||||||
## [1.1.3](https://git.mousesoft.ru/alexey/transocks/releases/tag/v1.1.3) - 2024-11-03
|
|
||||||
|
|
||||||
- **Added**
|
|
||||||
- Build linux-arm32 package.
|
|
||||||
|
|
||||||
## [1.1.2](https://git.mousesoft.ru/alexey/transocks/releases/tag/v1.1.2) - 2024-11-02
|
|
||||||
|
|
||||||
- **Added**
|
|
||||||
- Build debian packages.
|
|
||||||
|
|
||||||
## [1.1.1] - 2019-03-16
|
## [1.1.1] - 2019-03-16
|
||||||
|
|
||||||
- **Changed**
|
### Changed
|
||||||
- Replace `syscall` with `golang.org/x/sys/unix`, contributed by @otariidae (#14).
|
- Replace `syscall` with `golang.org/x/sys/unix`, contriubted by @otariidae (#14).
|
||||||
|
|
||||||
## [1.1.0] - 2018-11-13
|
## [1.1.0] - 2018-11-13
|
||||||
|
|
||||||
- **Changed**
|
### Changed
|
||||||
- Update `github.com/cybozu-go/cmd` to `github.com/cybozu-go/well` (#7, #9).
|
- Update `github.com/cybozu-go/cmd` to `github.com/cybozu-go/well` (#7, #9).
|
||||||
- Replace TravisCI with CircleCI.
|
- Replace TravisCI with CircleCI.
|
||||||
|
|
||||||
## [1.0.0] - 2016-09-01
|
## [1.0.0] - 2016-09-01
|
||||||
|
|
||||||
- **Added**
|
### Added
|
||||||
- transocks now adopts [github.com/cybozu-go/well][well] framework.
|
- transocks now adopts [github.com/cybozu-go/well][well] framework.
|
||||||
As a result, it implements [the common spec][spec] including graceful restart.
|
As a result, it implements [the common spec][spec] including graceful restart.
|
||||||
- **Changed**
|
|
||||||
- The default configuration file path is now `/etc/transocks.toml`.
|
### Changed
|
||||||
- "listen" config option becomes optional. Default is "localhost:1081".
|
- The default configuration file path is now `/etc/transocks.toml`.
|
||||||
- Configuration items for logging is changed.
|
- "listen" config option becomes optional. Default is "localhost:1081".
|
||||||
|
- Configuration items for logging is changed.
|
||||||
|
|
||||||
[well]: https://github.com/cybozu-go/well
|
[well]: https://github.com/cybozu-go/well
|
||||||
[spec]: https://github.com/cybozu-go/well/blob/master/README.md#specifications
|
[spec]: https://github.com/cybozu-go/well/blob/master/README.md#specifications
|
||||||
|
[Unreleased]: https://github.com/cybozu-go/transocks/compare/v1.1.1...HEAD
|
||||||
[1.1.1]: https://github.com/cybozu-go/transocks/compare/v1.1.0...v1.1.1
|
[1.1.1]: https://github.com/cybozu-go/transocks/compare/v1.1.0...v1.1.1
|
||||||
[1.1.0]: https://github.com/cybozu-go/transocks/compare/v1.0.0...v1.1.0
|
[1.1.0]: https://github.com/cybozu-go/transocks/compare/v1.0.0...v1.1.0
|
||||||
[1.0.0]: https://github.com/cybozu-go/transocks/compare/v0.1...v1.0.0
|
[1.0.0]: https://github.com/cybozu-go/transocks/compare/v0.1...v1.0.0
|
||||||
|
31
Dockerfile
Normal file
31
Dockerfile
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Start by building the application.
|
||||||
|
FROM docker.io/golang:1.22 AS build
|
||||||
|
|
||||||
|
WORKDIR /usr/src/transocks
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN CGO_ENABLED=0 go build -trimpath -o transocks ./cmd/transocks
|
||||||
|
|
||||||
|
# Now copy it into our base image.
|
||||||
|
FROM gcr.io/distroless/static-debian12:nonroot
|
||||||
|
|
||||||
|
COPY --from=build /usr/src/transocks/transocks /usr/bin/transocks
|
||||||
|
|
||||||
|
VOLUME [ "/etc/transocks" ]
|
||||||
|
ENTRYPOINT [ "/usr/bin/transocks" ]
|
||||||
|
|
||||||
|
ARG IMAGE_CREATED
|
||||||
|
ARG IMAGE_VERSION
|
||||||
|
ARG IMAGE_REVISION
|
||||||
|
|
||||||
|
LABEL org.opencontainers.image.created="${IMAGE_CREATED}" \
|
||||||
|
org.opencontainers.image.authors="MouseSoft" \
|
||||||
|
org.opencontainers.image.url="https://git.mousesoft.ru/alexey/transocks" \
|
||||||
|
org.opencontainers.image.documentation="https://git.mousesoft.ru/alexey/transocks/src/branch/master/README.md" \
|
||||||
|
org.opencontainers.image.source="https://git.mousesoft.ru/alexey/transocks" \
|
||||||
|
org.opencontainers.image.version="${IMAGE_VERSION}" \
|
||||||
|
org.opencontainers.image.revision="${IMAGE_REVISION}" \
|
||||||
|
org.opencontainers.image.vendor="MouseSoft" \
|
||||||
|
org.opencontainers.image.licenses="MIT" \
|
||||||
|
org.opencontainers.image.title="transocks - a transparent SOCKS5/HTTP proxy" \
|
||||||
|
org.opencontainers.image.description="transocks is a background service to redirect TCP connections transparently to a SOCKS5 server or a HTTP proxy server like Squid."
|
@ -1,5 +0,0 @@
|
|||||||
transocks (VERSION) mousesoft-stable; urgency=low
|
|
||||||
|
|
||||||
* Initial Release.
|
|
||||||
|
|
||||||
-- Aleksei Badiaev <aleksei.badiaev@mousesoft.ru> Sun, 9 Apr 2023 21:45:22 +0700
|
|
@ -1,8 +0,0 @@
|
|||||||
Source: transocks
|
|
||||||
Maintainer: Aleksei Badiaev <aleksei.badiaev@mousesoft.ru>
|
|
||||||
|
|
||||||
Package: transocks
|
|
||||||
Section: network
|
|
||||||
Priority: optional
|
|
||||||
Architecture: ARCH
|
|
||||||
Description: transocks - a transparent SOCKS5/HTTP proxy
|
|
@ -75,10 +75,10 @@ func NewConfig() *Config {
|
|||||||
// It returns non-nil error if the configuration is not valid.
|
// It returns non-nil error if the configuration is not valid.
|
||||||
func (c *Config) validate() error {
|
func (c *Config) validate() error {
|
||||||
if c.ProxyURL == nil {
|
if c.ProxyURL == nil {
|
||||||
return errors.New("proxy URL is nil")
|
return errors.New("ProxyURL is nil")
|
||||||
}
|
}
|
||||||
if c.Mode != ModeNAT {
|
if c.Mode != ModeNAT {
|
||||||
return fmt.Errorf("unknown mode: %s", c.Mode)
|
return fmt.Errorf("Unknown mode: %s", c.Mode)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
# listening address of transocks.
|
|
||||||
listen = "localhost:1081" # default is "localhost:1081"
|
|
||||||
|
|
||||||
#proxy_url = "socks5://10.20.30.40:1080" # for SOCKS5 server
|
|
||||||
#proxy_url = "http://10.20.30.40:3128" # for HTTP proxy server
|
|
||||||
|
|
||||||
[log]
|
|
||||||
#filename = "/path/to/file" # default to stderr
|
|
||||||
level = "info" # critical", error, warning, info, debug
|
|
||||||
#format = "json" # plain, logfmt, json
|
|
@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"allow_unsigned_uploads": true,
|
|
||||||
"full_upload_log": false,
|
|
||||||
"fqdn": "DEB_SSH_HOST",
|
|
||||||
"hash": "sha1",
|
|
||||||
"interface": "cli",
|
|
||||||
"incoming": "mini-dinstall/incoming/",
|
|
||||||
"login": "mini-dinstall",
|
|
||||||
"meta": "boring",
|
|
||||||
"method": "scp",
|
|
||||||
"scp_compress": true
|
|
||||||
}
|
|
@ -12,6 +12,7 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -50,7 +51,7 @@ func httpDialType(u *url.URL, forward proxy.Dialer) (proxy.Dialer, error) {
|
|||||||
|
|
||||||
func (d *httpDialer) Dial(network, addr string) (c net.Conn, err error) {
|
func (d *httpDialer) Dial(network, addr string) (c net.Conn, err error) {
|
||||||
req := &http.Request{
|
req := &http.Request{
|
||||||
Method: http.MethodConnect,
|
Method: "CONNECT",
|
||||||
URL: &url.URL{Opaque: addr},
|
URL: &url.URL{Opaque: addr},
|
||||||
Host: addr,
|
Host: addr,
|
||||||
Header: d.header,
|
Header: d.header,
|
||||||
@ -59,24 +60,20 @@ func (d *httpDialer) Dial(network, addr string) (c net.Conn, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = req.Write(c); err != nil {
|
req.Write(c)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read response until "\r\n\r\n".
|
// Read response until "\r\n\r\n".
|
||||||
// bufio cannot be used as the connected server may not be
|
// bufio cannot be used as the connected server may not be
|
||||||
// a HTTP(S) server.
|
// a HTTP(S) server.
|
||||||
if err = c.SetReadDeadline(time.Now().Add(10 * time.Second)); err != nil {
|
c.SetReadDeadline(time.Now().Add(10 * time.Second))
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
buf := make([]byte, 0, 4096)
|
buf := make([]byte, 0, 4096)
|
||||||
b := make([]byte, 1)
|
b := make([]byte, 1)
|
||||||
state := 0
|
state := 0
|
||||||
for {
|
for {
|
||||||
if _, err = c.Read(b); err != nil {
|
_, e := c.Read(b)
|
||||||
_ = c.Close()
|
if e != nil {
|
||||||
return nil, fmt.Errorf("reset proxy connection: %w", err)
|
c.Close()
|
||||||
|
return nil, errors.New("reset proxy connection")
|
||||||
}
|
}
|
||||||
buf = append(buf, b[0])
|
buf = append(buf, b[0])
|
||||||
switch state {
|
switch state {
|
||||||
@ -110,21 +107,15 @@ func (d *httpDialer) Dial(network, addr string) (c net.Conn, err error) {
|
|||||||
|
|
||||||
PARSE:
|
PARSE:
|
||||||
var zero time.Time
|
var zero time.Time
|
||||||
|
c.SetReadDeadline(zero)
|
||||||
if err = c.SetReadDeadline(zero); err != nil {
|
resp, e := http.ReadResponse(bufio.NewReader(bytes.NewBuffer(buf)), req)
|
||||||
return nil, err
|
if e != nil {
|
||||||
|
c.Close()
|
||||||
|
return nil, e
|
||||||
}
|
}
|
||||||
|
resp.Body.Close()
|
||||||
resp, err := http.ReadResponse(bufio.NewReader(bytes.NewBuffer(buf)), req)
|
if resp.StatusCode != 200 {
|
||||||
if err != nil {
|
c.Close()
|
||||||
_ = c.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
_ = resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
_ = c.Close()
|
|
||||||
return nil, fmt.Errorf("proxy returns %s", resp.Status)
|
return nil, fmt.Errorf("proxy returns %s", resp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,9 +23,8 @@ func TestHTTPDialer(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
defer func() { _ = conn.Close() }()
|
conn.Write([]byte("GET / HTTP/1.1\r\nHost: www.yahoo.com:80\r\nConnection: close\r\n\r\n"))
|
||||||
|
io.Copy(os.Stdout, conn)
|
||||||
_, _ = conn.Write([]byte("GET / HTTP/1.1\r\nHost: www.yahoo.com:80\r\nConnection: close\r\n\r\n"))
|
|
||||||
_, _ = io.Copy(os.Stdout, conn)
|
|
||||||
}
|
}
|
||||||
|
167
makefile
167
makefile
@ -1,167 +0,0 @@
|
|||||||
# transocks makefile
|
|
||||||
# ==================
|
|
||||||
|
|
||||||
SHELL := /usr/bin/env bash
|
|
||||||
|
|
||||||
PROJECT_ID := transocks
|
|
||||||
PROJECT_NAME ?= Transocks
|
|
||||||
BIN_SUFFIX :=
|
|
||||||
|
|
||||||
TMPDIR ?= $(CURDIR)/tmp
|
|
||||||
OUTDIR ?= $(CURDIR)/out
|
|
||||||
BINDIR ?= $(OUTDIR)/bin
|
|
||||||
|
|
||||||
VERSION ?= $(strip $(shell ./scripts/version.sh))
|
|
||||||
VERSION_NUMBER := $(strip $(shell ./scripts/version.sh number))
|
|
||||||
|
|
||||||
GOOS ?= $(shell go env GOOS)
|
|
||||||
GOARCH ?= $(shell go env GOARCH)
|
|
||||||
|
|
||||||
GO_LDFLAGS ?=
|
|
||||||
GO_OPT_V := -X "main.version=$(VERSION)"
|
|
||||||
GO_OPT_APP := -X "main.appname=$(PROJECT_NAME)"
|
|
||||||
GO_OPT_BASE := -ldflags '$(GO_OPT_V) $(GO_OPT_APP) $(GO_LDFLAGS)'
|
|
||||||
GO_OPT ?=
|
|
||||||
EXPORT_RESULT ?= false # for CI please set EXPORT_RESULT to true
|
|
||||||
|
|
||||||
GOCMD := go
|
|
||||||
GOTEST := $(GOCMD) test
|
|
||||||
GOVET := $(GOCMD) vet
|
|
||||||
ECHO_CMD := echo -e
|
|
||||||
|
|
||||||
DIST_EXT := .tar.gz
|
|
||||||
DIST_OPTS := -czf
|
|
||||||
PKG_NAME := $(PROJECT_ID)_$(VERSION)_$(GOOS)-$(GOARCH)
|
|
||||||
DIST_FILE := $(PKG_NAME)$(DIST_EXT)
|
|
||||||
PKG_ARCH := $(GOARCH)
|
|
||||||
|
|
||||||
ifeq ($(PKG_ARCH),arm)
|
|
||||||
PKG_ARCH = armhf
|
|
||||||
endif
|
|
||||||
|
|
||||||
GREEN := $(shell tput -Txterm setaf 2)
|
|
||||||
YELLOW := $(shell tput -Txterm setaf 3)
|
|
||||||
WHITE := $(shell tput -Txterm setaf 7)
|
|
||||||
CYAN := $(shell tput -Txterm setaf 6)
|
|
||||||
RESET := $(shell tput -Txterm sgr0)
|
|
||||||
|
|
||||||
.DEFAULT_GOAL := all
|
|
||||||
|
|
||||||
version: ## Version of the project to be built
|
|
||||||
@echo $(VERSION)
|
|
||||||
.PHONY:version
|
|
||||||
|
|
||||||
version-number: ## Version number of the project to be built
|
|
||||||
@echo $(VERSION_NUMBER)
|
|
||||||
.PHONY:version-number
|
|
||||||
|
|
||||||
## Build
|
|
||||||
|
|
||||||
all: clean vendor build ## Build binary
|
|
||||||
.PHONY:all
|
|
||||||
|
|
||||||
clean: ## Remove build related files
|
|
||||||
@rm -fr $(TMPDIR)
|
|
||||||
@rm -fr $(OUTDIR)
|
|
||||||
@$(ECHO_CMD) "Clean\t\t${GREEN}[OK]${RESET}"
|
|
||||||
.PHONY:clean
|
|
||||||
|
|
||||||
vendor: ## Copy of all packages needed to support builds and tests in the vendor directory
|
|
||||||
$(GOCMD) mod vendor
|
|
||||||
@$(ECHO_CMD) "Vendor\t\t${GREEN}[OK]${RESET}"
|
|
||||||
.PHONY:vendor
|
|
||||||
|
|
||||||
APPS := $(patsubst cmd/%/, %, $(dir $(wildcard cmd/*/main.go)))
|
|
||||||
|
|
||||||
build: $(addprefix $(BINDIR)/, $(APPS)) ## Build your project and put the output binary in out/bin/
|
|
||||||
@mkdir -p $(BINDIR)
|
|
||||||
@$(ECHO_CMD) "Build\t\t${GREEN}[OK]${RESET}"
|
|
||||||
.PHONY:build
|
|
||||||
|
|
||||||
$(BINDIR)/%: cmd/%/main.go $(patsubst cmd/%/main.go,cmd/%/*.go,$<)
|
|
||||||
@rm -f "$(BINDIR)/$(BIN_PREFIX)$(patsubst cmd/%/main.go,%,$<)$(BIN_SUFFIX)"
|
|
||||||
$(GOCMD) build $(GO_OPT_BASE) $(GO_OPT) \
|
|
||||||
-o "$(BINDIR)/$(BIN_PREFIX)$(patsubst cmd/%/main.go,%,$<)$(BIN_SUFFIX)" \
|
|
||||||
$(patsubst %/main.go,./%,$<)
|
|
||||||
|
|
||||||
dist: ## Create binary distro package
|
|
||||||
@rm -f "$(OUTDIR)/$(DIST_FILE)"
|
|
||||||
tar $(DIST_OPTS) "$(OUTDIR)/$(DIST_FILE)" -C "$(OUTDIR)" bin
|
|
||||||
@$(ECHO_CMD) "Dist\t\t${GREEN}[OK]${RESET}"
|
|
||||||
.PHONY:dist
|
|
||||||
|
|
||||||
DEB_NAME := $(PROJECT_ID)_$(VERSION_NUMBER)-1_$(PKG_ARCH)
|
|
||||||
|
|
||||||
pkg-deb: ## Build debian package
|
|
||||||
@rm -rf $(TMPDIR)
|
|
||||||
@mkdir -p $(TMPDIR)/$(DEB_NAME)/DEBIAN
|
|
||||||
@mkdir -p $(TMPDIR)/$(DEB_NAME)/etc
|
|
||||||
@mkdir -p $(TMPDIR)/$(DEB_NAME)/usr/bin
|
|
||||||
@cp $(CURDIR)/configs/transocks.example.toml $(TMPDIR)/$(DEB_NAME)/etc/transocks.toml
|
|
||||||
@cp -a $(BINDIR)/* $(TMPDIR)/$(DEB_NAME)/usr/bin/
|
|
||||||
@sed -e "s/VERSION/$(VERSION_NUMBER)/g" \
|
|
||||||
$(CURDIR)/build/package/debian/changelog.tpl \
|
|
||||||
> $(TMPDIR)/changelog
|
|
||||||
@sed -e "s/ARCH/$(PKG_ARCH)/g" $(CURDIR)/build/package/debian/control.tpl \
|
|
||||||
> $(TMPDIR)/control
|
|
||||||
DEB_HOST_ARCH=$(PKG_ARCH) dpkg-gencontrol -v$(VERSION_NUMBER)-1 \
|
|
||||||
-c$(TMPDIR)/control \
|
|
||||||
-l$(TMPDIR)/changelog \
|
|
||||||
-f$(TMPDIR)/$(DEB_NAME)/DEBIAN/files -Ptmp/$(DEB_NAME)
|
|
||||||
dpkg-deb --build --root-owner-group $(TMPDIR)/$(DEB_NAME)
|
|
||||||
dpkg-genchanges --build=binary \
|
|
||||||
-c$(TMPDIR)/control \
|
|
||||||
-l$(TMPDIR)/changelog \
|
|
||||||
-f$(TMPDIR)/$(DEB_NAME)/DEBIAN/files \
|
|
||||||
-u$(TMPDIR) -O$(OUTDIR)/$(DEB_NAME).changes
|
|
||||||
@mv $(TMPDIR)/*.deb $(OUTDIR)/
|
|
||||||
@$(ECHO_CMD) "pkg-deb\t\t${GREEN}[OK]${RESET}"
|
|
||||||
.PHONY:pkg-deb
|
|
||||||
|
|
||||||
## Deploy
|
|
||||||
|
|
||||||
deploy-deb: ## Deploy debian packages
|
|
||||||
find -O1 $(OUT_DIR) -name '*.changes' -exec dput mousesoft \{\} \;
|
|
||||||
.PHONY:deploy-deb
|
|
||||||
|
|
||||||
## Test
|
|
||||||
|
|
||||||
test: ## Run the tests of the project
|
|
||||||
ifeq ($(EXPORT_RESULT), true)
|
|
||||||
@mkdir -p $(OUTDIR)
|
|
||||||
$(eval OUTPUT_OPTIONS = | go-junit-report -set-exit-code > $(OUTDIR)/junit-report.xml)
|
|
||||||
endif
|
|
||||||
$(GOTEST) -v $(GO_OPT) ./... $(OUTPUT_OPTIONS)
|
|
||||||
@$(ECHO_CMD) "Test\t\t${GREEN}[OK]${RESET}"
|
|
||||||
.PHONY:test
|
|
||||||
|
|
||||||
|
|
||||||
## Lint
|
|
||||||
|
|
||||||
lint: ## Run all available linters.
|
|
||||||
go vet ./...
|
|
||||||
errcheck ./...
|
|
||||||
staticcheck ./...
|
|
||||||
usestdlibvars ./...
|
|
||||||
shadow ./...
|
|
||||||
@$(ECHO_CMD) "Lint\t\t${GREEN}[OK]${RESET}"
|
|
||||||
.PHONY:lint
|
|
||||||
|
|
||||||
golangci-lint: ## Run golangci-lint linter
|
|
||||||
@golangci-lint run
|
|
||||||
@$(ECHO_CMD) "GolangCI Lint\t${GREEN}[OK]${RESET}"
|
|
||||||
.PHONY:golangci-lint
|
|
||||||
|
|
||||||
## Help
|
|
||||||
|
|
||||||
help: ## Show this help.
|
|
||||||
@$(ECHO_CMD) ''
|
|
||||||
@$(ECHO_CMD) 'Usage:'
|
|
||||||
@$(ECHO_CMD) ' ${YELLOW}make${RESET} ${GREEN}<target>${RESET}'
|
|
||||||
@$(ECHO_CMD) ''
|
|
||||||
@$(ECHO_CMD) 'Targets:'
|
|
||||||
@awk 'BEGIN {FS = ":.*?## "} { \
|
|
||||||
if (/^[a-zA-Z_-]+:.*?##.*$$/) {printf " ${YELLOW}%-20s${GREEN}%s${RESET}\n", $$1, $$2} \
|
|
||||||
else if (/^## .*$$/) {printf " ${CYAN}%s${RESET}\n", substr($$1,4)} \
|
|
||||||
}' $(MAKEFILE_LIST)
|
|
||||||
.PHONY:help
|
|
@ -1,14 +1,12 @@
|
|||||||
//go:build linux
|
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
package transocks
|
package transocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
syscall "golang.org/x/sys/unix"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
syscall "golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func getsockopt(s int, level int, optname int, optval unsafe.Pointer, optlen *uint32) (err error) {
|
func getsockopt(s int, level int, optname int, optval unsafe.Pointer, optlen *uint32) (err error) {
|
||||||
@ -33,7 +31,7 @@ func GetOriginalDST(conn *net.TCPConn) (*net.TCPAddr, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer func() { _ = f.Close() }()
|
defer f.Close()
|
||||||
|
|
||||||
fd := int(f.Fd())
|
fd := int(f.Fd())
|
||||||
// revert to non-blocking mode.
|
// revert to non-blocking mode.
|
||||||
@ -45,14 +43,17 @@ func GetOriginalDST(conn *net.TCPConn) (*net.TCPAddr, error) {
|
|||||||
v6 := conn.LocalAddr().(*net.TCPAddr).IP.To4() == nil
|
v6 := conn.LocalAddr().(*net.TCPAddr).IP.To4() == nil
|
||||||
if v6 {
|
if v6 {
|
||||||
var addr syscall.RawSockaddrInet6
|
var addr syscall.RawSockaddrInet6
|
||||||
len := uint32(unsafe.Sizeof(addr))
|
var len uint32
|
||||||
|
len = uint32(unsafe.Sizeof(addr))
|
||||||
err = getsockopt(fd, syscall.IPPROTO_IPV6, IP6T_SO_ORIGINAL_DST,
|
err = getsockopt(fd, syscall.IPPROTO_IPV6, IP6T_SO_ORIGINAL_DST,
|
||||||
unsafe.Pointer(&addr), &len)
|
unsafe.Pointer(&addr), &len)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, os.NewSyscallError("getsockopt", err)
|
return nil, os.NewSyscallError("getsockopt", err)
|
||||||
}
|
}
|
||||||
ip := make([]byte, 16)
|
ip := make([]byte, 16)
|
||||||
copy(ip, addr.Addr[:])
|
for i, b := range addr.Addr {
|
||||||
|
ip[i] = b
|
||||||
|
}
|
||||||
pb := *(*[2]byte)(unsafe.Pointer(&addr.Port))
|
pb := *(*[2]byte)(unsafe.Pointer(&addr.Port))
|
||||||
return &net.TCPAddr{
|
return &net.TCPAddr{
|
||||||
IP: ip,
|
IP: ip,
|
||||||
@ -62,14 +63,17 @@ func GetOriginalDST(conn *net.TCPConn) (*net.TCPAddr, error) {
|
|||||||
|
|
||||||
// IPv4
|
// IPv4
|
||||||
var addr syscall.RawSockaddrInet4
|
var addr syscall.RawSockaddrInet4
|
||||||
len := uint32(unsafe.Sizeof(addr))
|
var len uint32
|
||||||
|
len = uint32(unsafe.Sizeof(addr))
|
||||||
err = getsockopt(fd, syscall.IPPROTO_IP, SO_ORIGINAL_DST,
|
err = getsockopt(fd, syscall.IPPROTO_IP, SO_ORIGINAL_DST,
|
||||||
unsafe.Pointer(&addr), &len)
|
unsafe.Pointer(&addr), &len)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, os.NewSyscallError("getsockopt", err)
|
return nil, os.NewSyscallError("getsockopt", err)
|
||||||
}
|
}
|
||||||
ip := make([]byte, 4)
|
ip := make([]byte, 4)
|
||||||
copy(ip, addr.Addr[:])
|
for i, b := range addr.Addr {
|
||||||
|
ip[i] = b
|
||||||
|
}
|
||||||
pb := *(*[2]byte)(unsafe.Pointer(&addr.Port))
|
pb := *(*[2]byte)(unsafe.Pointer(&addr.Port))
|
||||||
return &net.TCPAddr{
|
return &net.TCPAddr{
|
||||||
IP: ip,
|
IP: ip,
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
//go:build linux
|
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
package transocks
|
package transocks
|
||||||
@ -15,14 +14,13 @@ func TestGetOriginalDST(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
defer l.Close()
|
||||||
defer func() { _ = l.Close() }()
|
|
||||||
|
|
||||||
c, err := l.Accept()
|
c, err := l.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
defer func() { _ = c.Close() }()
|
defer c.Close()
|
||||||
|
|
||||||
origAddr, err := GetOriginalDST(c.(*net.TCPConn))
|
origAddr, err := GetOriginalDST(c.(*net.TCPConn))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
# Get changes of given version number.
|
|
||||||
{
|
|
||||||
while (index($0, "## [" version "]") <= 0) {
|
|
||||||
if (getline <= 0) {
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (getline <= 0 ) {
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
if (getline <= 0 ) {
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
while (index($0, "## [") <= 0) {
|
|
||||||
print $0
|
|
||||||
if (getline <= 0) {
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
if [ -z ${TAG_NAME+x} ]; then
|
|
||||||
if [ -z ${BRANCH_NAME+x} ]; then
|
|
||||||
BRANCH_NAME=$(echo $(git branch --show-current) || \
|
|
||||||
echo $(git name-rev --name-only HEAD))
|
|
||||||
fi
|
|
||||||
GIT_VERSION=$(echo ${BRANCH_NAME} | grep -q 'release/' \
|
|
||||||
&& echo ${BRANCH_NAME} | sed -e 's|release/|v|' -e 's/$/-RC/' || \
|
|
||||||
echo $(git describe --always --tags --dirty 2>/dev/null) || echo v0)
|
|
||||||
else
|
|
||||||
GIT_VERSION=${TAG_NAME}
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z ${VERSION+x} ]; then
|
|
||||||
VERSION=$(echo ${GIT_VERSION} | sed -e 's|^origin/||')
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z $1 ]; then
|
|
||||||
echo "${VERSION}"
|
|
||||||
else
|
|
||||||
echo ${VERSION} | sed -e 's/^v//'
|
|
||||||
fi
|
|
55
server.go
55
server.go
@ -85,7 +85,7 @@ func NewServer(c *Config) (*Server, error) {
|
|||||||
func (s *Server) handleConnection(ctx context.Context, conn net.Conn) {
|
func (s *Server) handleConnection(ctx context.Context, conn net.Conn) {
|
||||||
tc, ok := conn.(*net.TCPConn)
|
tc, ok := conn.(*net.TCPConn)
|
||||||
if !ok {
|
if !ok {
|
||||||
_ = s.logger.Error("non-TCP connection", map[string]interface{}{
|
s.logger.Error("non-TCP connection", map[string]interface{}{
|
||||||
"conn": conn,
|
"conn": conn,
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@ -101,7 +101,7 @@ func (s *Server) handleConnection(ctx context.Context, conn net.Conn) {
|
|||||||
origAddr, err := GetOriginalDST(tc)
|
origAddr, err := GetOriginalDST(tc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fields[log.FnError] = err.Error()
|
fields[log.FnError] = err.Error()
|
||||||
_ = s.logger.Error("GetOriginalDST failed", fields)
|
s.logger.Error("GetOriginalDST failed", fields)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addr = origAddr.String()
|
addr = origAddr.String()
|
||||||
@ -109,20 +109,14 @@ func (s *Server) handleConnection(ctx context.Context, conn net.Conn) {
|
|||||||
addr = tc.LocalAddr().String()
|
addr = tc.LocalAddr().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var reader io.Reader = tc
|
||||||
reader io.Reader = tc
|
|
||||||
isTLS bool
|
|
||||||
reader_n io.Reader
|
|
||||||
)
|
|
||||||
|
|
||||||
// Check if TLS
|
// Check if TLS
|
||||||
if isTLSloc, reader_nloc, err := peekSSL(tc); err != nil {
|
isTLS, reader_n, err := peekSSL(tc)
|
||||||
|
if err != nil {
|
||||||
fields[log.FnError] = err.Error()
|
fields[log.FnError] = err.Error()
|
||||||
_ = s.logger.Error("peekSSL failed", fields)
|
s.logger.Error("peekSSL failed", fields)
|
||||||
return
|
return
|
||||||
} else {
|
|
||||||
isTLS = isTLSloc
|
|
||||||
reader_n = reader_nloc
|
|
||||||
}
|
}
|
||||||
reader = reader_n
|
reader = reader_n
|
||||||
fields["is_tls"] = isTLS
|
fields["is_tls"] = isTLS
|
||||||
@ -132,7 +126,7 @@ func (s *Server) handleConnection(ctx context.Context, conn net.Conn) {
|
|||||||
hello, reader_n2, err := peekClientHello(reader)
|
hello, reader_n2, err := peekClientHello(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fields[log.FnError] = err.Error()
|
fields[log.FnError] = err.Error()
|
||||||
_ = s.logger.Warn("peekClientHello failed", fields)
|
s.logger.Warn("peekClientHello failed", fields)
|
||||||
}
|
}
|
||||||
if err == nil && hello.ServerName != "" {
|
if err == nil && hello.ServerName != "" {
|
||||||
addr = hello.ServerName + addr[strings.Index(addr, ":"):]
|
addr = hello.ServerName + addr[strings.Index(addr, ":"):]
|
||||||
@ -143,12 +137,11 @@ func (s *Server) handleConnection(ctx context.Context, conn net.Conn) {
|
|||||||
host, reader_n3, err := peekHTTP(reader)
|
host, reader_n3, err := peekHTTP(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fields[log.FnError] = err.Error()
|
fields[log.FnError] = err.Error()
|
||||||
_ = s.logger.Warn("peekHTTP failed", fields)
|
s.logger.Warn("peekHTTP failed", fields)
|
||||||
} else if host != "" {
|
} else {
|
||||||
if strings.Contains(host, ":") {
|
if err == nil && host != "" {
|
||||||
host = host[:strings.Index(host, ":")]
|
addr = host + addr[strings.Index(addr, ":"):]
|
||||||
}
|
}
|
||||||
addr = host + addr[strings.Index(addr, ":"):]
|
|
||||||
}
|
}
|
||||||
reader = reader_n3
|
reader = reader_n3
|
||||||
}
|
}
|
||||||
@ -158,33 +151,33 @@ func (s *Server) handleConnection(ctx context.Context, conn net.Conn) {
|
|||||||
destConn, err := s.dialer.Dial("tcp", addr)
|
destConn, err := s.dialer.Dial("tcp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fields[log.FnError] = err.Error()
|
fields[log.FnError] = err.Error()
|
||||||
_ = s.logger.Error("failed to connect to proxy server", fields)
|
s.logger.Error("failed to connect to proxy server", fields)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer func() { _ = destConn.Close() }()
|
defer destConn.Close()
|
||||||
|
|
||||||
_ = s.logger.Info("proxy starts", fields)
|
s.logger.Info("proxy starts", fields)
|
||||||
|
|
||||||
// do proxy
|
// do proxy
|
||||||
st := time.Now()
|
st := time.Now()
|
||||||
env := well.NewEnvironment(ctx)
|
env := well.NewEnvironment(ctx)
|
||||||
env.Go(func(ctx context.Context) error {
|
env.Go(func(ctx context.Context) error {
|
||||||
buf := s.pool.Get().([]byte)
|
buf := s.pool.Get().([]byte)
|
||||||
_, err = io.CopyBuffer(destConn, reader, buf)
|
_, err := io.CopyBuffer(destConn, reader, buf)
|
||||||
s.pool.Put(&buf)
|
s.pool.Put(buf)
|
||||||
if hc, ok := destConn.(netutil.HalfCloser); ok {
|
if hc, ok := destConn.(netutil.HalfCloser); ok {
|
||||||
_ = hc.CloseWrite()
|
hc.CloseWrite()
|
||||||
}
|
}
|
||||||
_ = tc.CloseRead()
|
tc.CloseRead()
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
env.Go(func(ctx context.Context) error {
|
env.Go(func(ctx context.Context) error {
|
||||||
buf := s.pool.Get().([]byte)
|
buf := s.pool.Get().([]byte)
|
||||||
_, err = io.CopyBuffer(tc, destConn, buf)
|
_, err := io.CopyBuffer(tc, destConn, buf)
|
||||||
s.pool.Put(&buf)
|
s.pool.Put(buf)
|
||||||
_ = tc.CloseWrite()
|
tc.CloseWrite()
|
||||||
if hc, ok := destConn.(netutil.HalfCloser); ok {
|
if hc, ok := destConn.(netutil.HalfCloser); ok {
|
||||||
_ = hc.CloseRead()
|
hc.CloseRead()
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
@ -195,10 +188,10 @@ func (s *Server) handleConnection(ctx context.Context, conn net.Conn) {
|
|||||||
fields["elapsed"] = time.Since(st).Seconds()
|
fields["elapsed"] = time.Since(st).Seconds()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fields[log.FnError] = err.Error()
|
fields[log.FnError] = err.Error()
|
||||||
_ = s.logger.Error("proxy ends with an error", fields)
|
s.logger.Error("proxy ends with an error", fields)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_ = s.logger.Info("proxy ends", fields)
|
s.logger.Info("proxy ends", fields)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Peek ClientHello message from conn and returns SNI.
|
// Peek ClientHello message from conn and returns SNI.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user