mirror of
https://github.com/fatedier/frp.git
synced 2025-07-27 15:45:39 +00:00
Compare commits
66 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
b2ae433e18 | ||
|
b26080589b | ||
|
aff979c2b6 | ||
|
46f809d711 | ||
|
72595b2da8 | ||
|
c842558ace | ||
|
ed61049041 | ||
|
abe6f580c0 | ||
|
e940066012 | ||
|
1e846df870 | ||
|
0ab055e946 | ||
|
fca59c71e2 | ||
|
fae2f8768d | ||
|
3d9499f554 | ||
|
7adeeedd55 | ||
|
127a31ea6a | ||
|
a85bd9a4d9 | ||
|
01d551ec8d | ||
|
16cabf4127 | ||
|
968be4a2c2 | ||
|
aa0a41ee4e | ||
|
8a779eb88c | ||
|
0138dbd352 | ||
|
9b45c93c14 | ||
|
191da54980 | ||
|
c3b7575453 | ||
|
1ea1530b36 | ||
|
7f7305fa03 | ||
|
644a0cfdb6 | ||
|
3c2e2bcea5 | ||
|
e0c45a1aca | ||
|
e52dfc4a5c | ||
|
cc003a2570 | ||
|
0f8040b875 | ||
|
ef5ae3e598 | ||
|
3acf1bb6e9 | ||
|
1089eb9d22 | ||
|
edf9596ca8 | ||
|
26e54b901f | ||
|
008933f304 | ||
|
317f901c1c | ||
|
cd5314466c | ||
|
3fbdea0f6b | ||
|
710ecf44f5 | ||
|
04dafd7ff0 | ||
|
c6aa74a2bb | ||
|
813c45f5c2 | ||
|
c0e05bb41e | ||
|
aa74dc4646 | ||
|
1e420cc766 | ||
|
4fff3c7472 | ||
|
48fa618c34 | ||
|
c9fe23eb10 | ||
|
268afb3438 | ||
|
b1181fd17a | ||
|
b23548eeff | ||
|
262317192c | ||
|
8b75b8b837 | ||
|
2170c481ce | ||
|
dfbf9c4542 | ||
|
964a1bbf39 | ||
|
228e225f84 | ||
|
bd6435c982 | ||
|
591023a1f0 | ||
|
1ab23b5e0e | ||
|
d193519329 |
25
.circleci/config.yml
Normal file
25
.circleci/config.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
version: 2
|
||||
jobs:
|
||||
test1:
|
||||
docker:
|
||||
- image: circleci/golang:1.15-node
|
||||
working_directory: /go/src/github.com/fatedier/frp
|
||||
steps:
|
||||
- checkout
|
||||
- run: make
|
||||
- run: make alltest
|
||||
test2:
|
||||
docker:
|
||||
- image: circleci/golang:1.14-node
|
||||
working_directory: /go/src/github.com/fatedier/frp
|
||||
steps:
|
||||
- checkout
|
||||
- run: make
|
||||
- run: make alltest
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
build_and_test:
|
||||
jobs:
|
||||
- test1
|
||||
- test2
|
29
.github/ISSUE_TEMPLATE
vendored
29
.github/ISSUE_TEMPLATE
vendored
@@ -1,29 +0,0 @@
|
||||
Issue is only used for submiting bug report and documents typo. If there are same issues or answers can be found in documents, we will close it directly.
|
||||
|
||||
Use the commands below to provide key information from your environment:
|
||||
You do NOT have to include this information if this is a FEATURE REQUEST
|
||||
|
||||
**What version of frp are you using (./frpc -v or ./frps -v)?**
|
||||
|
||||
|
||||
**What operating system and processor architecture are you using (`go env`)?**
|
||||
|
||||
|
||||
**Configures you used:**
|
||||
|
||||
|
||||
**Steps to reproduce the issue:**
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
**Describe the results you received:**
|
||||
|
||||
|
||||
**Describe the results you expected:**
|
||||
|
||||
|
||||
**Additional information you deem important (e.g. issue happens only occasionally):**
|
||||
|
||||
|
||||
**Can you point out what caused this issue (optional)**
|
44
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
44
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Bug Report for FRP
|
||||
title: ''
|
||||
labels: Requires Testing
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- From Chinese to English by machine translation, welcome to revise and polish. -->
|
||||
|
||||
<!-- ⚠️⚠️ Incomplete reports will be marked as invalid, and closed, with few exceptions ⚠️⚠️ -->
|
||||
<!-- in addition, please use search well so that the same solution can be found in the feedback, we will close it directly -->
|
||||
<!-- for convenience of differentiation, use FRPS or FRPC to refer to the FRP server or client -->
|
||||
|
||||
**[REQUIRED] hat version of frp are you using**
|
||||
<!-- Use ./frpc -v or ./frps -v -->
|
||||
Version:
|
||||
|
||||
**[REQUIRED] What operating system and processor architecture are you using**
|
||||
OS:
|
||||
CPU architecture:
|
||||
|
||||
**[REQUIRED] description of errors**
|
||||
|
||||
**confile**
|
||||
<!-- Please pay attention to hiding the token, server_addr and other privacy information -->
|
||||
|
||||
**log file**
|
||||
<!-- If the file is too large, use Pastebin, for example https://pastebin.ubuntu.com/ -->
|
||||
|
||||
**Steps to reproduce the issue**
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
**Supplementary information**
|
||||
|
||||
**Can you guess what caused this issue**
|
||||
|
||||
**Checklist**:
|
||||
<!--- Make sure you've completed the following steps (put an "X" between of brackets): -->
|
||||
- [] I included all information required in the sections above
|
||||
- [] I made sure there are no duplicates of this report [(Use Search)](https://github.com/fatedier/frp/issues?q=is%3Aissue)
|
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: DOCS
|
||||
url: https://github.com/fatedier/frp
|
||||
about: Here you can find out how to configure frp.
|
22
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
22
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: "[+] Enhancement"
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- From Chinese to English by machine translation, welcome to revise and polish. -->
|
||||
|
||||
**The solution you want**
|
||||
<!--A clear and concise description of the solution you want. -->
|
||||
|
||||
**Alternatives considered**
|
||||
<!--A clear and concise description of any alternative solutions or features you have considered. -->
|
||||
|
||||
**How to implement this function**
|
||||
<!--Implementation steps for the solution you want. -->
|
||||
|
||||
**Application scenarios of this function**
|
||||
<!--Make a clear and concise description of the application scenario of the solution you want. -->
|
115
.github/workflows/build-and-push-image.yml
vendored
Normal file
115
.github/workflows/build-and-push-image.yml
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
name: Build Image and Publish to Dockerhub & GPR
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [ created ]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: 'Image tag'
|
||||
required: true
|
||||
default: 'test'
|
||||
jobs:
|
||||
binary:
|
||||
name: Build Golang project
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Set up Go 1.x
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.15
|
||||
-
|
||||
run: go version
|
||||
-
|
||||
name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Build
|
||||
run: make build
|
||||
-
|
||||
name: Archive artifacts for frpc
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: frpc
|
||||
path: bin/frpc
|
||||
-
|
||||
name: Archive artifacts for frps
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: frps
|
||||
path: bin/frps
|
||||
|
||||
image:
|
||||
name: Build Image from Dockerfile and binaries
|
||||
runs-on: ubuntu-latest
|
||||
needs: binary
|
||||
steps:
|
||||
# environment
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
# download binaries of frpc and frps
|
||||
-
|
||||
name: Download binary of frpc
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: frpc
|
||||
path: bin/frpc
|
||||
-
|
||||
name: Download binary of frps
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: frps
|
||||
path: bin/frps
|
||||
# get image tag name
|
||||
-
|
||||
name: Get Image Tag Name
|
||||
run: |
|
||||
if [ x${{ github.event.inputs.tag }} == x"" ]; then
|
||||
echo "TAG_NAME=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||
else
|
||||
echo "TAG_NAME=${{ github.event.inputs.tag }}" >> $GITHUB_ENV
|
||||
fi
|
||||
# prepare image tags
|
||||
-
|
||||
name: Prepare Image Tags
|
||||
run: |
|
||||
echo "DOCKERFILE_FRPC_PATH=dockerfiles/Dockerfile-for-frpc" >> $GITHUB_ENV
|
||||
echo "DOCKERFILE_FRPS_PATH=dockerfiles/Dockerfile-for-frps" >> $GITHUB_ENV
|
||||
echo "TAG_FRPC=fatedier/frpc:${{ env.TAG_NAME }}" >> $GITHUB_ENV
|
||||
echo "TAG_FRPS=fatedier/frps:${{ env.TAG_NAME }}" >> $GITHUB_ENV
|
||||
echo "TAG_FRPC_GPR=ghcr.io/fatedier/frpc:${{ env.TAG_NAME }}" >> $GITHUB_ENV
|
||||
echo "TAG_FRPS_GPR=ghcr.io/fatedier/frps:${{ env.TAG_NAME }}" >> $GITHUB_ENV
|
||||
# build images
|
||||
-
|
||||
name: Build Images
|
||||
run: |
|
||||
# for Docker hub
|
||||
docker build --file ${{ env.DOCKERFILE_FRPC_PATH }} --tag ${{ env.TAG_FRPC }} .
|
||||
docker build --file ${{ env.DOCKERFILE_FRPS_PATH }} --tag ${{ env.TAG_FRPS }} .
|
||||
# for GPR
|
||||
docker build --file ${{ env.DOCKERFILE_FRPC_PATH }} --tag ${{ env.TAG_FRPC_GPR }} .
|
||||
docker build --file ${{ env.DOCKERFILE_FRPS_PATH }} --tag ${{ env.TAG_FRPS_GPR }} .
|
||||
# push to dockerhub
|
||||
-
|
||||
name: Publish to Dockerhub
|
||||
run: |
|
||||
echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login --username ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin
|
||||
docker push ${{ env.TAG_FRPC }}
|
||||
docker push ${{ env.TAG_FRPS }}
|
||||
# push to gpr
|
||||
-
|
||||
name: Publish to GPR
|
||||
run: |
|
||||
echo ${{ secrets.GPR_TOKEN }} | docker login ghcr.io --username ${{ github.repository_owner }} --password-stdin
|
||||
docker push ${{ env.TAG_FRPC_GPR }}
|
||||
docker push ${{ env.TAG_FRPS_GPR }}
|
30
.github/workflows/goreleaser.yml
vendored
Normal file
30
.github/workflows/goreleaser.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
name: goreleaser
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
goreleaser:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.15
|
||||
|
||||
- name: Make All
|
||||
run: |
|
||||
./package.sh
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
with:
|
||||
version: latest
|
||||
args: release --rm-dist --release-notes=./Release.md
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GPR_TOKEN }}
|
26
.github/workflows/stale.yml
vendored
Normal file
26
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: "Close stale issues"
|
||||
on:
|
||||
schedule:
|
||||
- cron: "20 0 * * *"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
debug-only:
|
||||
description: 'In debug mod'
|
||||
required: false
|
||||
default: 'false'
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v3
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: 'Issues go stale after 45d of inactivity. Stale issues rot after an additional 10d of inactivity and eventually close.'
|
||||
stale-pr-message: 'Issues go stale after 45d of inactivity. Stale issues rot after an additional 10d of inactivity and eventually close.'
|
||||
stale-issue-label: 'lifecycle/stale'
|
||||
exempt-issue-labels: 'bug,doc,enhancement,future,proposal,question,testing,todo,easy,help wanted,assigned'
|
||||
stale-pr-label: 'lifecycle/stale'
|
||||
exempt-pr-labels: 'bug,doc,enhancement,future,proposal,question,testing,todo,easy,help wanted,assigned'
|
||||
days-before-stale: 45
|
||||
days-before-close: 10
|
||||
debug-only: ${{ github.event.inputs.debug-only }}
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -29,6 +29,7 @@ packages/
|
||||
release/
|
||||
test/bin/
|
||||
vendor/
|
||||
dist/
|
||||
|
||||
# Cache
|
||||
*.swp
|
||||
|
19
.goreleaser.yml
Normal file
19
.goreleaser.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
builds:
|
||||
- skip: true
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
release:
|
||||
# Same as for github
|
||||
# Note: it can only be one: either github, gitlab or gitea
|
||||
github:
|
||||
owner: fatedier
|
||||
name: frp
|
||||
|
||||
draft: false
|
||||
|
||||
# You can add extra pre-existing files to the release.
|
||||
# The filename on the release will be the last part of the path (base). If
|
||||
# another file with the same name exists, the latest one found will be used.
|
||||
# Defaults to empty.
|
||||
extra_files:
|
||||
- glob: ./release/packages/*
|
12
.travis.yml
12
.travis.yml
@@ -1,12 +0,0 @@
|
||||
sudo: false
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.13.x
|
||||
- 1.14.x
|
||||
|
||||
install:
|
||||
- make
|
||||
|
||||
script:
|
||||
- make alltest
|
15
Makefile
15
Makefile
@@ -1,5 +1,6 @@
|
||||
export PATH := $(GOPATH)/bin:$(PATH)
|
||||
export GO111MODULE=on
|
||||
LDFLAGS := -s -w
|
||||
|
||||
all: fmt build
|
||||
|
||||
@@ -19,25 +20,27 @@ fmt:
|
||||
go fmt ./...
|
||||
|
||||
frps:
|
||||
go build -o bin/frps ./cmd/frps
|
||||
env CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o bin/frps ./cmd/frps
|
||||
|
||||
frpc:
|
||||
go build -o bin/frpc ./cmd/frpc
|
||||
env CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o bin/frpc ./cmd/frpc
|
||||
|
||||
test: gotest
|
||||
|
||||
gotest:
|
||||
go test -v --cover ./assets/...
|
||||
go test -v --cover ./client/...
|
||||
go test -v --cover ./cmd/...
|
||||
go test -v --cover ./models/...
|
||||
go test -v --cover ./client/...
|
||||
go test -v --cover ./server/...
|
||||
go test -v --cover ./utils/...
|
||||
go test -v --cover ./pkg/...
|
||||
|
||||
ci:
|
||||
go test -count=1 -p=1 -v ./tests/...
|
||||
|
||||
alltest: gotest ci
|
||||
e2e:
|
||||
./hack/run-e2e.sh
|
||||
|
||||
alltest: gotest ci e2e
|
||||
|
||||
clean:
|
||||
rm -f ./bin/frpc
|
||||
|
@@ -7,32 +7,29 @@ all: build
|
||||
build: app
|
||||
|
||||
app:
|
||||
env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o ./release/frpc_darwin_amd64 ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o ./release/frps_darwin_amd64 ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=freebsd GOARCH=386 go build -ldflags "$(LDFLAGS)" -o ./release/frpc_freebsd_386 ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=freebsd GOARCH=386 go build -ldflags "$(LDFLAGS)" -o ./release/frps_freebsd_386 ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=freebsd GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o ./release/frpc_freebsd_amd64 ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=freebsd GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o ./release/frps_freebsd_amd64 ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=386 go build -ldflags "$(LDFLAGS)" -o ./release/frpc_linux_386 ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=386 go build -ldflags "$(LDFLAGS)" -o ./release/frps_linux_386 ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o ./release/frpc_linux_amd64 ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o ./release/frps_linux_amd64 ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=arm go build -ldflags "$(LDFLAGS)" -o ./release/frpc_linux_arm ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=arm go build -ldflags "$(LDFLAGS)" -o ./release/frps_linux_arm ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags "$(LDFLAGS)" -o ./release/frpc_linux_arm64 ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags "$(LDFLAGS)" -o ./release/frps_linux_arm64 ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=windows GOARCH=386 go build -ldflags "$(LDFLAGS)" -o ./release/frpc_windows_386.exe ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=windows GOARCH=386 go build -ldflags "$(LDFLAGS)" -o ./release/frps_windows_386.exe ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o ./release/frpc_windows_amd64.exe ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o ./release/frps_windows_amd64.exe ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mips64 go build -ldflags "$(LDFLAGS)" -o ./release/frpc_linux_mips64 ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mips64 go build -ldflags "$(LDFLAGS)" -o ./release/frps_linux_mips64 ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mips64le go build -ldflags "$(LDFLAGS)" -o ./release/frpc_linux_mips64le ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mips64le go build -ldflags "$(LDFLAGS)" -o ./release/frps_linux_mips64le ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mips GOMIPS=softfloat go build -ldflags "$(LDFLAGS)" -o ./release/frpc_linux_mips ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mips GOMIPS=softfloat go build -ldflags "$(LDFLAGS)" -o ./release/frps_linux_mips ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build -ldflags "$(LDFLAGS)" -o ./release/frpc_linux_mipsle ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build -ldflags "$(LDFLAGS)" -o ./release/frps_linux_mipsle ./cmd/frps
|
||||
|
||||
temp:
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o ./frps_linux_amd64 ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frpc_darwin_amd64 ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frps_darwin_amd64 ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=freebsd GOARCH=386 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frpc_freebsd_386 ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=freebsd GOARCH=386 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frps_freebsd_386 ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=freebsd GOARCH=amd64 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frpc_freebsd_amd64 ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=freebsd GOARCH=amd64 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frps_freebsd_amd64 ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=386 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frpc_linux_386 ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=386 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frps_linux_386 ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frpc_linux_amd64 ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frps_linux_amd64 ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=arm go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frpc_linux_arm ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=arm go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frps_linux_arm ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frpc_linux_arm64 ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frps_linux_arm64 ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=windows GOARCH=386 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frpc_windows_386.exe ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=windows GOARCH=386 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frps_windows_386.exe ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frpc_windows_amd64.exe ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frps_windows_amd64.exe ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mips64 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frpc_linux_mips64 ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mips64 go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frps_linux_mips64 ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mips64le go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frpc_linux_mips64le ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mips64le go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frps_linux_mips64le ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mips GOMIPS=softfloat go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frpc_linux_mips ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mips GOMIPS=softfloat go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frps_linux_mips ./cmd/frps
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frpc_linux_mipsle ./cmd/frpc
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build -trimpath -ldflags "$(LDFLAGS)" -o ./release/frps_linux_mipsle ./cmd/frps
|
||||
|
@@ -1,6 +1,7 @@
|
||||
# frp
|
||||
|
||||
[](https://travis-ci.org/fatedier/frp)
|
||||
[](https://circleci.com/gh/fatedier/frp)
|
||||
[](https://github.com/fatedier/frp/releases)
|
||||
|
||||
[README](README.md) | [中文文档](README_zh.md)
|
||||
|
||||
|
997
README_zh.md
997
README_zh.md
File diff suppressed because it is too large
Load Diff
8
Release.md
Normal file
8
Release.md
Normal file
@@ -0,0 +1,8 @@
|
||||
### New
|
||||
|
||||
* Server Plugin supports HTTPS.
|
||||
|
||||
### Fix
|
||||
|
||||
* Fix IPv6 address parse problem.
|
||||
* HTTP type proxy can't handle websocket protocol due to error `Connection` header value.
|
File diff suppressed because one or more lines are too long
Binary file not shown.
1
assets/frps/static/css/app.808290ae.css
Normal file
1
assets/frps/static/css/app.808290ae.css
Normal file
@@ -0,0 +1 @@
|
||||
.el-form-item span{margin-left:15px}.demo-table-expand{font-size:0}.demo-table-expand label{width:90px;color:#99a9bf}.demo-table-expand .el-form-item{margin-right:0;margin-bottom:0;width:50%}body{background-color:#fafafa;margin:0;font-family:-apple-system,BlinkMacSystemFont,Helvetica Neue,sans-serif}header{width:100%;height:60px}.header-color{background:#58b7ff}#content{margin-top:20px;padding-right:40px}.brand{color:#fff;background-color:transparent;margin-left:20px;float:left;line-height:25px;font-size:25px;padding:15px 15px;height:30px;text-decoration:none}.source{border:1px solid #eaeefb;border-radius:4px;transition:.2s;padding:24px}.server_info{margin-left:40px;font-size:0}.server_info label{width:150px;color:#99a9bf}.server_info .el-form-item{margin-right:0;margin-bottom:0;width:100%}
|
1
assets/frps/static/css/chunk-vendors.84bb20f7.css
Normal file
1
assets/frps/static/css/chunk-vendors.84bb20f7.css
Normal file
File diff suppressed because one or more lines are too long
BIN
assets/frps/static/fonts/element-icons.535877f5.woff
Normal file
BIN
assets/frps/static/fonts/element-icons.535877f5.woff
Normal file
Binary file not shown.
BIN
assets/frps/static/fonts/element-icons.732389de.ttf
Normal file
BIN
assets/frps/static/fonts/element-icons.732389de.ttf
Normal file
Binary file not shown.
@@ -1 +1 @@
|
||||
<!DOCTYPE html> <html lang=en> <head> <meta charset=utf-8> <title>frps dashboard</title> <link rel="shortcut icon" href="favicon.ico"></head> <body> <div id=app></div> <script type="text/javascript" src="manifest.js?14bea8276eef86cc7c61"></script><script type="text/javascript" src="vendor.js?51925ec1a77936b64d61"></script></body> </html>
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>frps-dashboard</title><link href="css/app.808290ae.css" rel="preload" as="style"><link href="css/chunk-vendors.84bb20f7.css" rel="preload" as="style"><link href="js/app.bb942a48.js" rel="preload" as="script"><link href="js/chunk-vendors.4421b07d.js" rel="preload" as="script"><link href="css/chunk-vendors.84bb20f7.css" rel="stylesheet"><link href="css/app.808290ae.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but frps-dashboard doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.4421b07d.js"></script><script src="js/app.bb942a48.js"></script></body></html>
|
2
assets/frps/static/js/app.bb942a48.js
Normal file
2
assets/frps/static/js/app.bb942a48.js
Normal file
File diff suppressed because one or more lines are too long
1
assets/frps/static/js/app.bb942a48.js.map
Normal file
1
assets/frps/static/js/app.bb942a48.js.map
Normal file
File diff suppressed because one or more lines are too long
34
assets/frps/static/js/chunk-vendors.4421b07d.js
Normal file
34
assets/frps/static/js/chunk-vendors.4421b07d.js
Normal file
File diff suppressed because one or more lines are too long
1
assets/frps/static/js/chunk-vendors.4421b07d.js.map
Normal file
1
assets/frps/static/js/chunk-vendors.4421b07d.js.map
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,u){for(var i,a,f,l=0,s=[];l<t.length;l++)a=t[l],o[a]&&s.push(o[a][0]),o[a]=0;for(i in c)Object.prototype.hasOwnProperty.call(c,i)&&(e[i]=c[i]);for(r&&r(t,c,u);s.length;)s.shift()();if(u)for(l=0;l<u.length;l++)f=n(n.s=u[l]);return f};var t={},o={1:0};n.e=function(e){function r(){i.onerror=i.onload=null,clearTimeout(a);var n=o[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),o[e]=void 0)}var t=o[e];if(0===t)return new Promise(function(e){e()});if(t)return t[2];var c=new Promise(function(n,r){t=o[e]=[n,r]});t[2]=c;var u=document.getElementsByTagName("head")[0],i=document.createElement("script");i.type="text/javascript",i.charset="utf-8",i.async=!0,i.timeout=12e4,n.nc&&i.setAttribute("nonce",n.nc),i.src=n.p+""+e+".js?"+{0:"51925ec1a77936b64d61"}[e];var a=setTimeout(r,12e4);return i.onerror=i.onload=r,u.appendChild(i),c},n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,r,t){n.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,"a",r),r},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n.oe=function(e){throw console.error(e),e}}([]);
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -21,7 +21,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/assets"
|
||||
frpNet "github.com/fatedier/frp/utils/net"
|
||||
frpNet "github.com/fatedier/frp/pkg/util/net"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
@@ -36,7 +36,7 @@ func (svr *Service) RunAdminServer(addr string, port int) (err error) {
|
||||
router := mux.NewRouter()
|
||||
|
||||
user, passwd := svr.cfg.AdminUser, svr.cfg.AdminPwd
|
||||
router.Use(frpNet.NewHttpAuthMiddleware(user, passwd).Middleware)
|
||||
router.Use(frpNet.NewHTTPAuthMiddleware(user, passwd).Middleware)
|
||||
|
||||
// api, see dashboard_api.go
|
||||
router.HandleFunc("/api/reload", svr.apiReload).Methods("GET")
|
||||
@@ -46,7 +46,7 @@ func (svr *Service) RunAdminServer(addr string, port int) (err error) {
|
||||
|
||||
// view
|
||||
router.Handle("/favicon.ico", http.FileServer(assets.FileSystem)).Methods("GET")
|
||||
router.PathPrefix("/static/").Handler(frpNet.MakeHttpGzipHandler(http.StripPrefix("/static/", http.FileServer(assets.FileSystem)))).Methods("GET")
|
||||
router.PathPrefix("/static/").Handler(frpNet.MakeHTTPGzipHandler(http.StripPrefix("/static/", http.FileServer(assets.FileSystem)))).Methods("GET")
|
||||
router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, "/static/", http.StatusMovedPermanently)
|
||||
})
|
||||
|
@@ -23,8 +23,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/fatedier/frp/client/proxy"
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/utils/log"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/util/log"
|
||||
)
|
||||
|
||||
type GeneralResponse struct {
|
||||
@@ -82,13 +82,13 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
type StatusResp struct {
|
||||
Tcp []ProxyStatusResp `json:"tcp"`
|
||||
Udp []ProxyStatusResp `json:"udp"`
|
||||
Http []ProxyStatusResp `json:"http"`
|
||||
Https []ProxyStatusResp `json:"https"`
|
||||
Stcp []ProxyStatusResp `json:"stcp"`
|
||||
Xtcp []ProxyStatusResp `json:"xtcp"`
|
||||
Sudp []ProxyStatusResp `json:"sudp"`
|
||||
TCP []ProxyStatusResp `json:"tcp"`
|
||||
UDP []ProxyStatusResp `json:"udp"`
|
||||
HTTP []ProxyStatusResp `json:"http"`
|
||||
HTTPS []ProxyStatusResp `json:"https"`
|
||||
STCP []ProxyStatusResp `json:"stcp"`
|
||||
XTCP []ProxyStatusResp `json:"xtcp"`
|
||||
SUDP []ProxyStatusResp `json:"sudp"`
|
||||
}
|
||||
|
||||
type ProxyStatusResp struct {
|
||||
@@ -107,17 +107,17 @@ func (a ByProxyStatusResp) Len() int { return len(a) }
|
||||
func (a ByProxyStatusResp) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a ByProxyStatusResp) Less(i, j int) bool { return strings.Compare(a[i].Name, a[j].Name) < 0 }
|
||||
|
||||
func NewProxyStatusResp(status *proxy.ProxyStatus, serverAddr string) ProxyStatusResp {
|
||||
func NewProxyStatusResp(status *proxy.WorkingStatus, serverAddr string) ProxyStatusResp {
|
||||
psr := ProxyStatusResp{
|
||||
Name: status.Name,
|
||||
Type: status.Type,
|
||||
Status: status.Status,
|
||||
Status: status.Phase,
|
||||
Err: status.Err,
|
||||
}
|
||||
switch cfg := status.Cfg.(type) {
|
||||
case *config.TcpProxyConf:
|
||||
case *config.TCPProxyConf:
|
||||
if cfg.LocalPort != 0 {
|
||||
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort)
|
||||
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIP, cfg.LocalPort)
|
||||
}
|
||||
psr.Plugin = cfg.Plugin
|
||||
if status.Err != "" {
|
||||
@@ -125,40 +125,40 @@ func NewProxyStatusResp(status *proxy.ProxyStatus, serverAddr string) ProxyStatu
|
||||
} else {
|
||||
psr.RemoteAddr = serverAddr + status.RemoteAddr
|
||||
}
|
||||
case *config.UdpProxyConf:
|
||||
case *config.UDPProxyConf:
|
||||
if cfg.LocalPort != 0 {
|
||||
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort)
|
||||
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIP, cfg.LocalPort)
|
||||
}
|
||||
if status.Err != "" {
|
||||
psr.RemoteAddr = fmt.Sprintf("%s:%d", serverAddr, cfg.RemotePort)
|
||||
} else {
|
||||
psr.RemoteAddr = serverAddr + status.RemoteAddr
|
||||
}
|
||||
case *config.HttpProxyConf:
|
||||
case *config.HTTPProxyConf:
|
||||
if cfg.LocalPort != 0 {
|
||||
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort)
|
||||
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIP, cfg.LocalPort)
|
||||
}
|
||||
psr.Plugin = cfg.Plugin
|
||||
psr.RemoteAddr = status.RemoteAddr
|
||||
case *config.HttpsProxyConf:
|
||||
case *config.HTTPSProxyConf:
|
||||
if cfg.LocalPort != 0 {
|
||||
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort)
|
||||
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIP, cfg.LocalPort)
|
||||
}
|
||||
psr.Plugin = cfg.Plugin
|
||||
psr.RemoteAddr = status.RemoteAddr
|
||||
case *config.StcpProxyConf:
|
||||
case *config.STCPProxyConf:
|
||||
if cfg.LocalPort != 0 {
|
||||
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort)
|
||||
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIP, cfg.LocalPort)
|
||||
}
|
||||
psr.Plugin = cfg.Plugin
|
||||
case *config.XtcpProxyConf:
|
||||
case *config.XTCPProxyConf:
|
||||
if cfg.LocalPort != 0 {
|
||||
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort)
|
||||
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIP, cfg.LocalPort)
|
||||
}
|
||||
psr.Plugin = cfg.Plugin
|
||||
case *config.SudpProxyConf:
|
||||
case *config.SUDPProxyConf:
|
||||
if cfg.LocalPort != 0 {
|
||||
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort)
|
||||
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIP, cfg.LocalPort)
|
||||
}
|
||||
psr.Plugin = cfg.Plugin
|
||||
}
|
||||
@@ -171,13 +171,13 @@ func (svr *Service) apiStatus(w http.ResponseWriter, r *http.Request) {
|
||||
buf []byte
|
||||
res StatusResp
|
||||
)
|
||||
res.Tcp = make([]ProxyStatusResp, 0)
|
||||
res.Udp = make([]ProxyStatusResp, 0)
|
||||
res.Http = make([]ProxyStatusResp, 0)
|
||||
res.Https = make([]ProxyStatusResp, 0)
|
||||
res.Stcp = make([]ProxyStatusResp, 0)
|
||||
res.Xtcp = make([]ProxyStatusResp, 0)
|
||||
res.Sudp = make([]ProxyStatusResp, 0)
|
||||
res.TCP = make([]ProxyStatusResp, 0)
|
||||
res.UDP = make([]ProxyStatusResp, 0)
|
||||
res.HTTP = make([]ProxyStatusResp, 0)
|
||||
res.HTTPS = make([]ProxyStatusResp, 0)
|
||||
res.STCP = make([]ProxyStatusResp, 0)
|
||||
res.XTCP = make([]ProxyStatusResp, 0)
|
||||
res.SUDP = make([]ProxyStatusResp, 0)
|
||||
|
||||
log.Info("Http request [/api/status]")
|
||||
defer func() {
|
||||
@@ -190,28 +190,28 @@ func (svr *Service) apiStatus(w http.ResponseWriter, r *http.Request) {
|
||||
for _, status := range ps {
|
||||
switch status.Type {
|
||||
case "tcp":
|
||||
res.Tcp = append(res.Tcp, NewProxyStatusResp(status, svr.cfg.ServerAddr))
|
||||
res.TCP = append(res.TCP, NewProxyStatusResp(status, svr.cfg.ServerAddr))
|
||||
case "udp":
|
||||
res.Udp = append(res.Udp, NewProxyStatusResp(status, svr.cfg.ServerAddr))
|
||||
res.UDP = append(res.UDP, NewProxyStatusResp(status, svr.cfg.ServerAddr))
|
||||
case "http":
|
||||
res.Http = append(res.Http, NewProxyStatusResp(status, svr.cfg.ServerAddr))
|
||||
res.HTTP = append(res.HTTP, NewProxyStatusResp(status, svr.cfg.ServerAddr))
|
||||
case "https":
|
||||
res.Https = append(res.Https, NewProxyStatusResp(status, svr.cfg.ServerAddr))
|
||||
res.HTTPS = append(res.HTTPS, NewProxyStatusResp(status, svr.cfg.ServerAddr))
|
||||
case "stcp":
|
||||
res.Stcp = append(res.Stcp, NewProxyStatusResp(status, svr.cfg.ServerAddr))
|
||||
res.STCP = append(res.STCP, NewProxyStatusResp(status, svr.cfg.ServerAddr))
|
||||
case "xtcp":
|
||||
res.Xtcp = append(res.Xtcp, NewProxyStatusResp(status, svr.cfg.ServerAddr))
|
||||
res.XTCP = append(res.XTCP, NewProxyStatusResp(status, svr.cfg.ServerAddr))
|
||||
case "sudp":
|
||||
res.Sudp = append(res.Sudp, NewProxyStatusResp(status, svr.cfg.ServerAddr))
|
||||
res.SUDP = append(res.SUDP, NewProxyStatusResp(status, svr.cfg.ServerAddr))
|
||||
}
|
||||
}
|
||||
sort.Sort(ByProxyStatusResp(res.Tcp))
|
||||
sort.Sort(ByProxyStatusResp(res.Udp))
|
||||
sort.Sort(ByProxyStatusResp(res.Http))
|
||||
sort.Sort(ByProxyStatusResp(res.Https))
|
||||
sort.Sort(ByProxyStatusResp(res.Stcp))
|
||||
sort.Sort(ByProxyStatusResp(res.Xtcp))
|
||||
sort.Sort(ByProxyStatusResp(res.Sudp))
|
||||
sort.Sort(ByProxyStatusResp(res.TCP))
|
||||
sort.Sort(ByProxyStatusResp(res.UDP))
|
||||
sort.Sort(ByProxyStatusResp(res.HTTP))
|
||||
sort.Sort(ByProxyStatusResp(res.HTTPS))
|
||||
sort.Sort(ByProxyStatusResp(res.STCP))
|
||||
sort.Sort(ByProxyStatusResp(res.XTCP))
|
||||
sort.Sort(ByProxyStatusResp(res.SUDP))
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -17,19 +17,20 @@ package client
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/client/proxy"
|
||||
"github.com/fatedier/frp/models/auth"
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/models/msg"
|
||||
frpNet "github.com/fatedier/frp/utils/net"
|
||||
"github.com/fatedier/frp/utils/xlog"
|
||||
"github.com/fatedier/frp/pkg/auth"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
"github.com/fatedier/frp/pkg/transport"
|
||||
frpNet "github.com/fatedier/frp/pkg/util/net"
|
||||
"github.com/fatedier/frp/pkg/util/xlog"
|
||||
|
||||
"github.com/fatedier/golib/control/shutdown"
|
||||
"github.com/fatedier/golib/crypto"
|
||||
@@ -38,11 +39,11 @@ import (
|
||||
|
||||
type Control struct {
|
||||
// uniq id got from frps, attach it in loginMsg
|
||||
runId string
|
||||
runID string
|
||||
|
||||
// manage all proxies
|
||||
pxyCfgs map[string]config.ProxyConf
|
||||
pm *proxy.ProxyManager
|
||||
pm *proxy.Manager
|
||||
|
||||
// manage all visitors
|
||||
vm *VisitorManager
|
||||
@@ -88,7 +89,7 @@ type Control struct {
|
||||
authSetter auth.Setter
|
||||
}
|
||||
|
||||
func NewControl(ctx context.Context, runId string, conn net.Conn, session *fmux.Session,
|
||||
func NewControl(ctx context.Context, runID string, conn net.Conn, session *fmux.Session,
|
||||
clientCfg config.ClientCommonConf,
|
||||
pxyCfgs map[string]config.ProxyConf,
|
||||
visitorCfgs map[string]config.VisitorConf,
|
||||
@@ -97,7 +98,7 @@ func NewControl(ctx context.Context, runId string, conn net.Conn, session *fmux.
|
||||
|
||||
// new xlog instance
|
||||
ctl := &Control{
|
||||
runId: runId,
|
||||
runID: runID,
|
||||
conn: conn,
|
||||
session: session,
|
||||
pxyCfgs: pxyCfgs,
|
||||
@@ -114,7 +115,7 @@ func NewControl(ctx context.Context, runId string, conn net.Conn, session *fmux.
|
||||
ctx: ctx,
|
||||
authSetter: authSetter,
|
||||
}
|
||||
ctl.pm = proxy.NewProxyManager(ctl.ctx, ctl.sendCh, clientCfg, serverUDPPort)
|
||||
ctl.pm = proxy.NewManager(ctl.ctx, ctl.sendCh, clientCfg, serverUDPPort)
|
||||
|
||||
ctl.vm = NewVisitorManager(ctl.ctx, ctl)
|
||||
ctl.vm.Reload(visitorCfgs)
|
||||
@@ -140,7 +141,7 @@ func (ctl *Control) HandleReqWorkConn(inMsg *msg.ReqWorkConn) {
|
||||
}
|
||||
|
||||
m := &msg.NewWorkConn{
|
||||
RunId: ctl.runId,
|
||||
RunID: ctl.runID,
|
||||
}
|
||||
if err = ctl.authSetter.SetNewWorkConn(m); err != nil {
|
||||
xl.Warn("error during NewWorkConn authentication: %v", err)
|
||||
@@ -198,7 +199,7 @@ func (ctl *Control) ClosedDoneCh() <-chan struct{} {
|
||||
// connectServer return a new connection to frps
|
||||
func (ctl *Control) connectServer() (conn net.Conn, err error) {
|
||||
xl := ctl.xl
|
||||
if ctl.clientCfg.TcpMux {
|
||||
if ctl.clientCfg.TCPMux {
|
||||
stream, errRet := ctl.session.OpenStream()
|
||||
if errRet != nil {
|
||||
err = errRet
|
||||
@@ -208,13 +209,23 @@ func (ctl *Control) connectServer() (conn net.Conn, err error) {
|
||||
conn = stream
|
||||
} else {
|
||||
var tlsConfig *tls.Config
|
||||
|
||||
if ctl.clientCfg.TLSEnable {
|
||||
tlsConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
tlsConfig, err = transport.NewClientTLSConfig(
|
||||
ctl.clientCfg.TLSCertFile,
|
||||
ctl.clientCfg.TLSKeyFile,
|
||||
ctl.clientCfg.TLSTrustedCaFile,
|
||||
ctl.clientCfg.ServerAddr)
|
||||
|
||||
if err != nil {
|
||||
xl.Warn("fail to build tls configuration when connecting to server, err: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
conn, err = frpNet.ConnectServerByProxyWithTLS(ctl.clientCfg.HttpProxy, ctl.clientCfg.Protocol,
|
||||
fmt.Sprintf("%s:%d", ctl.clientCfg.ServerAddr, ctl.clientCfg.ServerPort), tlsConfig)
|
||||
|
||||
address := net.JoinHostPort(ctl.clientCfg.ServerAddr, strconv.Itoa(ctl.clientCfg.ServerPort))
|
||||
conn, err = frpNet.ConnectServerByProxyWithTLS(ctl.clientCfg.HTTPProxy, ctl.clientCfg.Protocol, address, tlsConfig)
|
||||
|
||||
if err != nil {
|
||||
xl.Warn("start new connection to server error: %v", err)
|
||||
return
|
||||
@@ -237,18 +248,17 @@ func (ctl *Control) reader() {
|
||||
|
||||
encReader := crypto.NewReader(ctl.conn, []byte(ctl.clientCfg.Token))
|
||||
for {
|
||||
if m, err := msg.ReadMsg(encReader); err != nil {
|
||||
m, err := msg.ReadMsg(encReader)
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
xl.Debug("read from control connection EOF")
|
||||
return
|
||||
} else {
|
||||
xl.Warn("read error: %v", err)
|
||||
ctl.conn.Close()
|
||||
return
|
||||
}
|
||||
} else {
|
||||
ctl.readCh <- m
|
||||
xl.Warn("read error: %v", err)
|
||||
ctl.conn.Close()
|
||||
return
|
||||
}
|
||||
ctl.readCh <- m
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,14 +273,15 @@ func (ctl *Control) writer() {
|
||||
return
|
||||
}
|
||||
for {
|
||||
if m, ok := <-ctl.sendCh; !ok {
|
||||
m, ok := <-ctl.sendCh
|
||||
if !ok {
|
||||
xl.Info("control writer is closing")
|
||||
return
|
||||
} else {
|
||||
if err := msg.WriteMsg(encWriter, m); err != nil {
|
||||
xl.Warn("write message to control connection error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err := msg.WriteMsg(encWriter, m); err != nil {
|
||||
xl.Warn("write message to control connection error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -286,7 +297,7 @@ func (ctl *Control) msgHandler() {
|
||||
}()
|
||||
defer ctl.msgHandlerShutdown.Done()
|
||||
|
||||
hbSend := time.NewTicker(time.Duration(ctl.clientCfg.HeartBeatInterval) * time.Second)
|
||||
hbSend := time.NewTicker(time.Duration(ctl.clientCfg.HeartbeatInterval) * time.Second)
|
||||
defer hbSend.Stop()
|
||||
hbCheck := time.NewTicker(time.Second)
|
||||
defer hbCheck.Stop()
|
||||
@@ -305,7 +316,7 @@ func (ctl *Control) msgHandler() {
|
||||
}
|
||||
ctl.sendCh <- pingMsg
|
||||
case <-hbCheck.C:
|
||||
if time.Since(ctl.lastPong) > time.Duration(ctl.clientCfg.HeartBeatTimeout)*time.Second {
|
||||
if time.Since(ctl.lastPong) > time.Duration(ctl.clientCfg.HeartbeatTimeout)*time.Second {
|
||||
xl.Warn("heartbeat timeout")
|
||||
// let reader() stop
|
||||
ctl.conn.Close()
|
||||
|
@@ -3,13 +3,13 @@ package event
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/fatedier/frp/models/msg"
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
)
|
||||
|
||||
type EventType int
|
||||
type Type int
|
||||
|
||||
const (
|
||||
EvStartProxy EventType = iota
|
||||
EvStartProxy Type = iota
|
||||
EvCloseProxy
|
||||
)
|
||||
|
||||
@@ -17,7 +17,7 @@ var (
|
||||
ErrPayloadType = errors.New("error payload type")
|
||||
)
|
||||
|
||||
type EventHandler func(evType EventType, payload interface{}) error
|
||||
type Handler func(evType Type, payload interface{}) error
|
||||
|
||||
type StartProxyPayload struct {
|
||||
NewProxyMsg *msg.NewProxy
|
||||
|
@@ -24,14 +24,14 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/utils/xlog"
|
||||
"github.com/fatedier/frp/pkg/util/xlog"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrHealthCheckType = errors.New("error health check type")
|
||||
)
|
||||
|
||||
type HealthCheckMonitor struct {
|
||||
type Monitor struct {
|
||||
checkType string
|
||||
interval time.Duration
|
||||
timeout time.Duration
|
||||
@@ -52,10 +52,10 @@ type HealthCheckMonitor struct {
|
||||
cancel context.CancelFunc
|
||||
}
|
||||
|
||||
func NewHealthCheckMonitor(ctx context.Context, checkType string,
|
||||
func NewMonitor(ctx context.Context, checkType string,
|
||||
intervalS int, timeoutS int, maxFailedTimes int,
|
||||
addr string, url string,
|
||||
statusNormalFn func(), statusFailedFn func()) *HealthCheckMonitor {
|
||||
statusNormalFn func(), statusFailedFn func()) *Monitor {
|
||||
|
||||
if intervalS <= 0 {
|
||||
intervalS = 10
|
||||
@@ -67,7 +67,7 @@ func NewHealthCheckMonitor(ctx context.Context, checkType string,
|
||||
maxFailedTimes = 1
|
||||
}
|
||||
newctx, cancel := context.WithCancel(ctx)
|
||||
return &HealthCheckMonitor{
|
||||
return &Monitor{
|
||||
checkType: checkType,
|
||||
interval: time.Duration(intervalS) * time.Second,
|
||||
timeout: time.Duration(timeoutS) * time.Second,
|
||||
@@ -82,15 +82,15 @@ func NewHealthCheckMonitor(ctx context.Context, checkType string,
|
||||
}
|
||||
}
|
||||
|
||||
func (monitor *HealthCheckMonitor) Start() {
|
||||
func (monitor *Monitor) Start() {
|
||||
go monitor.checkWorker()
|
||||
}
|
||||
|
||||
func (monitor *HealthCheckMonitor) Stop() {
|
||||
func (monitor *Monitor) Stop() {
|
||||
monitor.cancel()
|
||||
}
|
||||
|
||||
func (monitor *HealthCheckMonitor) checkWorker() {
|
||||
func (monitor *Monitor) checkWorker() {
|
||||
xl := xlog.FromContextSafe(monitor.ctx)
|
||||
for {
|
||||
doCtx, cancel := context.WithDeadline(monitor.ctx, time.Now().Add(monitor.timeout))
|
||||
@@ -126,18 +126,18 @@ func (monitor *HealthCheckMonitor) checkWorker() {
|
||||
}
|
||||
}
|
||||
|
||||
func (monitor *HealthCheckMonitor) doCheck(ctx context.Context) error {
|
||||
func (monitor *Monitor) doCheck(ctx context.Context) error {
|
||||
switch monitor.checkType {
|
||||
case "tcp":
|
||||
return monitor.doTcpCheck(ctx)
|
||||
return monitor.doTCPCheck(ctx)
|
||||
case "http":
|
||||
return monitor.doHttpCheck(ctx)
|
||||
return monitor.doHTTPCheck(ctx)
|
||||
default:
|
||||
return ErrHealthCheckType
|
||||
}
|
||||
}
|
||||
|
||||
func (monitor *HealthCheckMonitor) doTcpCheck(ctx context.Context) error {
|
||||
func (monitor *Monitor) doTCPCheck(ctx context.Context) error {
|
||||
// if tcp address is not specified, always return nil
|
||||
if monitor.addr == "" {
|
||||
return nil
|
||||
@@ -152,7 +152,7 @@ func (monitor *HealthCheckMonitor) doTcpCheck(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (monitor *HealthCheckMonitor) doHttpCheck(ctx context.Context) error {
|
||||
func (monitor *Monitor) doHTTPCheck(ctx context.Context) error {
|
||||
req, err := http.NewRequest("GET", monitor.url, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -26,13 +26,13 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/models/msg"
|
||||
plugin "github.com/fatedier/frp/models/plugin/client"
|
||||
"github.com/fatedier/frp/models/proto/udp"
|
||||
"github.com/fatedier/frp/utils/limit"
|
||||
frpNet "github.com/fatedier/frp/utils/net"
|
||||
"github.com/fatedier/frp/utils/xlog"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
plugin "github.com/fatedier/frp/pkg/plugin/client"
|
||||
"github.com/fatedier/frp/pkg/proto/udp"
|
||||
"github.com/fatedier/frp/pkg/util/limit"
|
||||
frpNet "github.com/fatedier/frp/pkg/util/net"
|
||||
"github.com/fatedier/frp/pkg/util/xlog"
|
||||
|
||||
"github.com/fatedier/golib/errors"
|
||||
frpIo "github.com/fatedier/golib/io"
|
||||
@@ -67,43 +67,43 @@ func NewProxy(ctx context.Context, pxyConf config.ProxyConf, clientCfg config.Cl
|
||||
ctx: ctx,
|
||||
}
|
||||
switch cfg := pxyConf.(type) {
|
||||
case *config.TcpProxyConf:
|
||||
pxy = &TcpProxy{
|
||||
case *config.TCPProxyConf:
|
||||
pxy = &TCPProxy{
|
||||
BaseProxy: &baseProxy,
|
||||
cfg: cfg,
|
||||
}
|
||||
case *config.TcpMuxProxyConf:
|
||||
pxy = &TcpMuxProxy{
|
||||
case *config.TCPMuxProxyConf:
|
||||
pxy = &TCPMuxProxy{
|
||||
BaseProxy: &baseProxy,
|
||||
cfg: cfg,
|
||||
}
|
||||
case *config.UdpProxyConf:
|
||||
pxy = &UdpProxy{
|
||||
case *config.UDPProxyConf:
|
||||
pxy = &UDPProxy{
|
||||
BaseProxy: &baseProxy,
|
||||
cfg: cfg,
|
||||
}
|
||||
case *config.HttpProxyConf:
|
||||
pxy = &HttpProxy{
|
||||
case *config.HTTPProxyConf:
|
||||
pxy = &HTTPProxy{
|
||||
BaseProxy: &baseProxy,
|
||||
cfg: cfg,
|
||||
}
|
||||
case *config.HttpsProxyConf:
|
||||
pxy = &HttpsProxy{
|
||||
case *config.HTTPSProxyConf:
|
||||
pxy = &HTTPSProxy{
|
||||
BaseProxy: &baseProxy,
|
||||
cfg: cfg,
|
||||
}
|
||||
case *config.StcpProxyConf:
|
||||
pxy = &StcpProxy{
|
||||
case *config.STCPProxyConf:
|
||||
pxy = &STCPProxy{
|
||||
BaseProxy: &baseProxy,
|
||||
cfg: cfg,
|
||||
}
|
||||
case *config.XtcpProxyConf:
|
||||
pxy = &XtcpProxy{
|
||||
case *config.XTCPProxyConf:
|
||||
pxy = &XTCPProxy{
|
||||
BaseProxy: &baseProxy,
|
||||
cfg: cfg,
|
||||
}
|
||||
case *config.SudpProxyConf:
|
||||
pxy = &SudpProxy{
|
||||
case *config.SUDPProxyConf:
|
||||
pxy = &SUDPProxy{
|
||||
BaseProxy: &baseProxy,
|
||||
cfg: cfg,
|
||||
closeCh: make(chan struct{}),
|
||||
@@ -124,14 +124,14 @@ type BaseProxy struct {
|
||||
}
|
||||
|
||||
// TCP
|
||||
type TcpProxy struct {
|
||||
type TCPProxy struct {
|
||||
*BaseProxy
|
||||
|
||||
cfg *config.TcpProxyConf
|
||||
cfg *config.TCPProxyConf
|
||||
proxyPlugin plugin.Plugin
|
||||
}
|
||||
|
||||
func (pxy *TcpProxy) Run() (err error) {
|
||||
func (pxy *TCPProxy) Run() (err error) {
|
||||
if pxy.cfg.Plugin != "" {
|
||||
pxy.proxyPlugin, err = plugin.Create(pxy.cfg.Plugin, pxy.cfg.PluginParams)
|
||||
if err != nil {
|
||||
@@ -141,26 +141,26 @@ func (pxy *TcpProxy) Run() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (pxy *TcpProxy) Close() {
|
||||
func (pxy *TCPProxy) Close() {
|
||||
if pxy.proxyPlugin != nil {
|
||||
pxy.proxyPlugin.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (pxy *TcpProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
HandleTcpWorkConnection(pxy.ctx, &pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, pxy.limiter,
|
||||
func (pxy *TCPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
HandleTCPWorkConnection(pxy.ctx, &pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, pxy.limiter,
|
||||
conn, []byte(pxy.clientCfg.Token), m)
|
||||
}
|
||||
|
||||
// TCP Multiplexer
|
||||
type TcpMuxProxy struct {
|
||||
type TCPMuxProxy struct {
|
||||
*BaseProxy
|
||||
|
||||
cfg *config.TcpMuxProxyConf
|
||||
cfg *config.TCPMuxProxyConf
|
||||
proxyPlugin plugin.Plugin
|
||||
}
|
||||
|
||||
func (pxy *TcpMuxProxy) Run() (err error) {
|
||||
func (pxy *TCPMuxProxy) Run() (err error) {
|
||||
if pxy.cfg.Plugin != "" {
|
||||
pxy.proxyPlugin, err = plugin.Create(pxy.cfg.Plugin, pxy.cfg.PluginParams)
|
||||
if err != nil {
|
||||
@@ -170,26 +170,26 @@ func (pxy *TcpMuxProxy) Run() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (pxy *TcpMuxProxy) Close() {
|
||||
func (pxy *TCPMuxProxy) Close() {
|
||||
if pxy.proxyPlugin != nil {
|
||||
pxy.proxyPlugin.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (pxy *TcpMuxProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
HandleTcpWorkConnection(pxy.ctx, &pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, pxy.limiter,
|
||||
func (pxy *TCPMuxProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
HandleTCPWorkConnection(pxy.ctx, &pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, pxy.limiter,
|
||||
conn, []byte(pxy.clientCfg.Token), m)
|
||||
}
|
||||
|
||||
// HTTP
|
||||
type HttpProxy struct {
|
||||
type HTTPProxy struct {
|
||||
*BaseProxy
|
||||
|
||||
cfg *config.HttpProxyConf
|
||||
cfg *config.HTTPProxyConf
|
||||
proxyPlugin plugin.Plugin
|
||||
}
|
||||
|
||||
func (pxy *HttpProxy) Run() (err error) {
|
||||
func (pxy *HTTPProxy) Run() (err error) {
|
||||
if pxy.cfg.Plugin != "" {
|
||||
pxy.proxyPlugin, err = plugin.Create(pxy.cfg.Plugin, pxy.cfg.PluginParams)
|
||||
if err != nil {
|
||||
@@ -199,26 +199,26 @@ func (pxy *HttpProxy) Run() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (pxy *HttpProxy) Close() {
|
||||
func (pxy *HTTPProxy) Close() {
|
||||
if pxy.proxyPlugin != nil {
|
||||
pxy.proxyPlugin.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (pxy *HttpProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
HandleTcpWorkConnection(pxy.ctx, &pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, pxy.limiter,
|
||||
func (pxy *HTTPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
HandleTCPWorkConnection(pxy.ctx, &pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, pxy.limiter,
|
||||
conn, []byte(pxy.clientCfg.Token), m)
|
||||
}
|
||||
|
||||
// HTTPS
|
||||
type HttpsProxy struct {
|
||||
type HTTPSProxy struct {
|
||||
*BaseProxy
|
||||
|
||||
cfg *config.HttpsProxyConf
|
||||
cfg *config.HTTPSProxyConf
|
||||
proxyPlugin plugin.Plugin
|
||||
}
|
||||
|
||||
func (pxy *HttpsProxy) Run() (err error) {
|
||||
func (pxy *HTTPSProxy) Run() (err error) {
|
||||
if pxy.cfg.Plugin != "" {
|
||||
pxy.proxyPlugin, err = plugin.Create(pxy.cfg.Plugin, pxy.cfg.PluginParams)
|
||||
if err != nil {
|
||||
@@ -228,26 +228,26 @@ func (pxy *HttpsProxy) Run() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (pxy *HttpsProxy) Close() {
|
||||
func (pxy *HTTPSProxy) Close() {
|
||||
if pxy.proxyPlugin != nil {
|
||||
pxy.proxyPlugin.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (pxy *HttpsProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
HandleTcpWorkConnection(pxy.ctx, &pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, pxy.limiter,
|
||||
func (pxy *HTTPSProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
HandleTCPWorkConnection(pxy.ctx, &pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, pxy.limiter,
|
||||
conn, []byte(pxy.clientCfg.Token), m)
|
||||
}
|
||||
|
||||
// STCP
|
||||
type StcpProxy struct {
|
||||
type STCPProxy struct {
|
||||
*BaseProxy
|
||||
|
||||
cfg *config.StcpProxyConf
|
||||
cfg *config.STCPProxyConf
|
||||
proxyPlugin plugin.Plugin
|
||||
}
|
||||
|
||||
func (pxy *StcpProxy) Run() (err error) {
|
||||
func (pxy *STCPProxy) Run() (err error) {
|
||||
if pxy.cfg.Plugin != "" {
|
||||
pxy.proxyPlugin, err = plugin.Create(pxy.cfg.Plugin, pxy.cfg.PluginParams)
|
||||
if err != nil {
|
||||
@@ -257,26 +257,26 @@ func (pxy *StcpProxy) Run() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (pxy *StcpProxy) Close() {
|
||||
func (pxy *STCPProxy) Close() {
|
||||
if pxy.proxyPlugin != nil {
|
||||
pxy.proxyPlugin.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (pxy *StcpProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
HandleTcpWorkConnection(pxy.ctx, &pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, pxy.limiter,
|
||||
func (pxy *STCPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
HandleTCPWorkConnection(pxy.ctx, &pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, pxy.limiter,
|
||||
conn, []byte(pxy.clientCfg.Token), m)
|
||||
}
|
||||
|
||||
// XTCP
|
||||
type XtcpProxy struct {
|
||||
type XTCPProxy struct {
|
||||
*BaseProxy
|
||||
|
||||
cfg *config.XtcpProxyConf
|
||||
cfg *config.XTCPProxyConf
|
||||
proxyPlugin plugin.Plugin
|
||||
}
|
||||
|
||||
func (pxy *XtcpProxy) Run() (err error) {
|
||||
func (pxy *XTCPProxy) Run() (err error) {
|
||||
if pxy.cfg.Plugin != "" {
|
||||
pxy.proxyPlugin, err = plugin.Create(pxy.cfg.Plugin, pxy.cfg.PluginParams)
|
||||
if err != nil {
|
||||
@@ -286,13 +286,13 @@ func (pxy *XtcpProxy) Run() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (pxy *XtcpProxy) Close() {
|
||||
func (pxy *XTCPProxy) Close() {
|
||||
if pxy.proxyPlugin != nil {
|
||||
pxy.proxyPlugin.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (pxy *XtcpProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
func (pxy *XTCPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
xl := pxy.xl
|
||||
defer conn.Close()
|
||||
var natHoleSidMsg msg.NatHoleSid
|
||||
@@ -389,7 +389,7 @@ func (pxy *XtcpProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
|
||||
lConn.WriteToUDP(sidBuf[:n], uAddr)
|
||||
|
||||
kcpConn, err := frpNet.NewKcpConnFromUdp(lConn, false, uAddr.String())
|
||||
kcpConn, err := frpNet.NewKCPConnFromUDP(lConn, false, uAddr.String())
|
||||
if err != nil {
|
||||
xl.Error("create kcp connection from udp connection error: %v", err)
|
||||
return
|
||||
@@ -410,11 +410,11 @@ func (pxy *XtcpProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
return
|
||||
}
|
||||
|
||||
HandleTcpWorkConnection(pxy.ctx, &pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, pxy.limiter,
|
||||
HandleTCPWorkConnection(pxy.ctx, &pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, pxy.limiter,
|
||||
muxConn, []byte(pxy.cfg.Sk), m)
|
||||
}
|
||||
|
||||
func (pxy *XtcpProxy) sendDetectMsg(addr string, port int, laddr *net.UDPAddr, content []byte) (err error) {
|
||||
func (pxy *XTCPProxy) sendDetectMsg(addr string, port int, laddr *net.UDPAddr, content []byte) (err error) {
|
||||
daddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", addr, port))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -434,28 +434,28 @@ func (pxy *XtcpProxy) sendDetectMsg(addr string, port int, laddr *net.UDPAddr, c
|
||||
}
|
||||
|
||||
// UDP
|
||||
type UdpProxy struct {
|
||||
type UDPProxy struct {
|
||||
*BaseProxy
|
||||
|
||||
cfg *config.UdpProxyConf
|
||||
cfg *config.UDPProxyConf
|
||||
|
||||
localAddr *net.UDPAddr
|
||||
readCh chan *msg.UdpPacket
|
||||
readCh chan *msg.UDPPacket
|
||||
|
||||
// include msg.UdpPacket and msg.Ping
|
||||
// include msg.UDPPacket and msg.Ping
|
||||
sendCh chan msg.Message
|
||||
workConn net.Conn
|
||||
}
|
||||
|
||||
func (pxy *UdpProxy) Run() (err error) {
|
||||
pxy.localAddr, err = net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", pxy.cfg.LocalIp, pxy.cfg.LocalPort))
|
||||
func (pxy *UDPProxy) Run() (err error) {
|
||||
pxy.localAddr, err = net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", pxy.cfg.LocalIP, pxy.cfg.LocalPort))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (pxy *UdpProxy) Close() {
|
||||
func (pxy *UDPProxy) Close() {
|
||||
pxy.mu.Lock()
|
||||
defer pxy.mu.Unlock()
|
||||
|
||||
@@ -473,29 +473,42 @@ func (pxy *UdpProxy) Close() {
|
||||
}
|
||||
}
|
||||
|
||||
func (pxy *UdpProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
func (pxy *UDPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
xl := pxy.xl
|
||||
xl.Info("incoming a new work connection for udp proxy, %s", conn.RemoteAddr().String())
|
||||
// close resources releated with old workConn
|
||||
pxy.Close()
|
||||
|
||||
var rwc io.ReadWriteCloser = conn
|
||||
var err error
|
||||
if pxy.limiter != nil {
|
||||
rwc := frpIo.WrapReadWriteCloser(limit.NewReader(conn, pxy.limiter), limit.NewWriter(conn, pxy.limiter), func() error {
|
||||
rwc = frpIo.WrapReadWriteCloser(limit.NewReader(conn, pxy.limiter), limit.NewWriter(conn, pxy.limiter), func() error {
|
||||
return conn.Close()
|
||||
})
|
||||
conn = frpNet.WrapReadWriteCloserToConn(rwc, conn)
|
||||
}
|
||||
if pxy.cfg.UseEncryption {
|
||||
rwc, err = frpIo.WithEncryption(rwc, []byte(pxy.clientCfg.Token))
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
xl.Error("create encryption stream error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if pxy.cfg.UseCompression {
|
||||
rwc = frpIo.WithCompression(rwc)
|
||||
}
|
||||
conn = frpNet.WrapReadWriteCloserToConn(rwc, conn)
|
||||
|
||||
pxy.mu.Lock()
|
||||
pxy.workConn = conn
|
||||
pxy.readCh = make(chan *msg.UdpPacket, 1024)
|
||||
pxy.readCh = make(chan *msg.UDPPacket, 1024)
|
||||
pxy.sendCh = make(chan msg.Message, 1024)
|
||||
pxy.closed = false
|
||||
pxy.mu.Unlock()
|
||||
|
||||
workConnReaderFn := func(conn net.Conn, readCh chan *msg.UdpPacket) {
|
||||
workConnReaderFn := func(conn net.Conn, readCh chan *msg.UDPPacket) {
|
||||
for {
|
||||
var udpMsg msg.UdpPacket
|
||||
var udpMsg msg.UDPPacket
|
||||
if errRet := msg.ReadMsgInto(conn, &udpMsg); errRet != nil {
|
||||
xl.Warn("read from workConn for udp error: %v", errRet)
|
||||
return
|
||||
@@ -516,7 +529,7 @@ func (pxy *UdpProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
var errRet error
|
||||
for rawMsg := range sendCh {
|
||||
switch m := rawMsg.(type) {
|
||||
case *msg.UdpPacket:
|
||||
case *msg.UDPPacket:
|
||||
xl.Trace("send udp package to workConn: %s", m.Content)
|
||||
case *msg.Ping:
|
||||
xl.Trace("send ping message to udp workConn")
|
||||
@@ -543,28 +556,28 @@ func (pxy *UdpProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
go workConnSenderFn(pxy.workConn, pxy.sendCh)
|
||||
go workConnReaderFn(pxy.workConn, pxy.readCh)
|
||||
go heartbeatFn(pxy.workConn, pxy.sendCh)
|
||||
udp.Forwarder(pxy.localAddr, pxy.readCh, pxy.sendCh)
|
||||
udp.Forwarder(pxy.localAddr, pxy.readCh, pxy.sendCh, int(pxy.clientCfg.UDPPacketSize))
|
||||
}
|
||||
|
||||
type SudpProxy struct {
|
||||
type SUDPProxy struct {
|
||||
*BaseProxy
|
||||
|
||||
cfg *config.SudpProxyConf
|
||||
cfg *config.SUDPProxyConf
|
||||
|
||||
localAddr *net.UDPAddr
|
||||
|
||||
closeCh chan struct{}
|
||||
}
|
||||
|
||||
func (pxy *SudpProxy) Run() (err error) {
|
||||
pxy.localAddr, err = net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", pxy.cfg.LocalIp, pxy.cfg.LocalPort))
|
||||
func (pxy *SUDPProxy) Run() (err error) {
|
||||
pxy.localAddr, err = net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", pxy.cfg.LocalIP, pxy.cfg.LocalPort))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (pxy *SudpProxy) Close() {
|
||||
func (pxy *SUDPProxy) Close() {
|
||||
pxy.mu.Lock()
|
||||
defer pxy.mu.Unlock()
|
||||
select {
|
||||
@@ -575,19 +588,32 @@ func (pxy *SudpProxy) Close() {
|
||||
}
|
||||
}
|
||||
|
||||
func (pxy *SudpProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
func (pxy *SUDPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
xl := pxy.xl
|
||||
xl.Info("incoming a new work connection for sudp proxy, %s", conn.RemoteAddr().String())
|
||||
|
||||
var rwc io.ReadWriteCloser = conn
|
||||
var err error
|
||||
if pxy.limiter != nil {
|
||||
rwc := frpIo.WrapReadWriteCloser(limit.NewReader(conn, pxy.limiter), limit.NewWriter(conn, pxy.limiter), func() error {
|
||||
rwc = frpIo.WrapReadWriteCloser(limit.NewReader(conn, pxy.limiter), limit.NewWriter(conn, pxy.limiter), func() error {
|
||||
return conn.Close()
|
||||
})
|
||||
conn = frpNet.WrapReadWriteCloserToConn(rwc, conn)
|
||||
}
|
||||
if pxy.cfg.UseEncryption {
|
||||
rwc, err = frpIo.WithEncryption(rwc, []byte(pxy.clientCfg.Token))
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
xl.Error("create encryption stream error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if pxy.cfg.UseCompression {
|
||||
rwc = frpIo.WithCompression(rwc)
|
||||
}
|
||||
conn = frpNet.WrapReadWriteCloserToConn(rwc, conn)
|
||||
|
||||
workConn := conn
|
||||
readCh := make(chan *msg.UdpPacket, 1024)
|
||||
readCh := make(chan *msg.UDPPacket, 1024)
|
||||
sendCh := make(chan msg.Message, 1024)
|
||||
isClose := false
|
||||
|
||||
@@ -609,7 +635,7 @@ func (pxy *SudpProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
}
|
||||
|
||||
// udp service <- frpc <- frps <- frpc visitor <- user
|
||||
workConnReaderFn := func(conn net.Conn, readCh chan *msg.UdpPacket) {
|
||||
workConnReaderFn := func(conn net.Conn, readCh chan *msg.UDPPacket) {
|
||||
defer closeFn()
|
||||
|
||||
for {
|
||||
@@ -621,7 +647,7 @@ func (pxy *SudpProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
default:
|
||||
}
|
||||
|
||||
var udpMsg msg.UdpPacket
|
||||
var udpMsg msg.UDPPacket
|
||||
if errRet := msg.ReadMsgInto(conn, &udpMsg); errRet != nil {
|
||||
xl.Warn("read from workConn for sudp error: %v", errRet)
|
||||
return
|
||||
@@ -646,7 +672,7 @@ func (pxy *SudpProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
var errRet error
|
||||
for rawMsg := range sendCh {
|
||||
switch m := rawMsg.(type) {
|
||||
case *msg.UdpPacket:
|
||||
case *msg.UDPPacket:
|
||||
xl.Trace("frpc send udp package to frpc visitor, [udp local: %v, remote: %v], [tcp work conn local: %v, remote: %v]",
|
||||
m.LocalAddr.String(), m.RemoteAddr.String(), conn.LocalAddr().String(), conn.RemoteAddr().String())
|
||||
case *msg.Ping:
|
||||
@@ -688,11 +714,11 @@ func (pxy *SudpProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
||||
go workConnReaderFn(workConn, readCh)
|
||||
go heartbeatFn(workConn, sendCh)
|
||||
|
||||
udp.Forwarder(pxy.localAddr, readCh, sendCh)
|
||||
udp.Forwarder(pxy.localAddr, readCh, sendCh, int(pxy.clientCfg.UDPPacketSize))
|
||||
}
|
||||
|
||||
// Common handler for tcp work connections.
|
||||
func HandleTcpWorkConnection(ctx context.Context, localInfo *config.LocalSvrConf, proxyPlugin plugin.Plugin,
|
||||
func HandleTCPWorkConnection(ctx context.Context, localInfo *config.LocalSvrConf, proxyPlugin plugin.Plugin,
|
||||
baseInfo *config.BaseProxyConf, limiter *rate.Limiter, workConn net.Conn, encKey []byte, m *msg.StartWorkConn) {
|
||||
xl := xlog.FromContextSafe(ctx)
|
||||
var (
|
||||
@@ -759,22 +785,22 @@ func HandleTcpWorkConnection(ctx context.Context, localInfo *config.LocalSvrConf
|
||||
proxyPlugin.Handle(remote, workConn, extraInfo)
|
||||
xl.Debug("handle by plugin finished")
|
||||
return
|
||||
} else {
|
||||
localConn, err := frpNet.ConnectServer("tcp", fmt.Sprintf("%s:%d", localInfo.LocalIp, localInfo.LocalPort))
|
||||
if err != nil {
|
||||
workConn.Close()
|
||||
xl.Error("connect to local service [%s:%d] error: %v", localInfo.LocalIp, localInfo.LocalPort, err)
|
||||
return
|
||||
}
|
||||
|
||||
xl.Debug("join connections, localConn(l[%s] r[%s]) workConn(l[%s] r[%s])", localConn.LocalAddr().String(),
|
||||
localConn.RemoteAddr().String(), workConn.LocalAddr().String(), workConn.RemoteAddr().String())
|
||||
|
||||
if len(extraInfo) > 0 {
|
||||
localConn.Write(extraInfo)
|
||||
}
|
||||
|
||||
frpIo.Join(localConn, remote)
|
||||
xl.Debug("join connections closed")
|
||||
}
|
||||
|
||||
localConn, err := frpNet.ConnectServer("tcp", fmt.Sprintf("%s:%d", localInfo.LocalIP, localInfo.LocalPort))
|
||||
if err != nil {
|
||||
workConn.Close()
|
||||
xl.Error("connect to local service [%s:%d] error: %v", localInfo.LocalIP, localInfo.LocalPort, err)
|
||||
return
|
||||
}
|
||||
|
||||
xl.Debug("join connections, localConn(l[%s] r[%s]) workConn(l[%s] r[%s])", localConn.LocalAddr().String(),
|
||||
localConn.RemoteAddr().String(), workConn.LocalAddr().String(), workConn.RemoteAddr().String())
|
||||
|
||||
if len(extraInfo) > 0 {
|
||||
localConn.Write(extraInfo)
|
||||
}
|
||||
|
||||
frpIo.Join(localConn, remote)
|
||||
xl.Debug("join connections closed")
|
||||
}
|
||||
|
@@ -7,16 +7,16 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/fatedier/frp/client/event"
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/models/msg"
|
||||
"github.com/fatedier/frp/utils/xlog"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
"github.com/fatedier/frp/pkg/util/xlog"
|
||||
|
||||
"github.com/fatedier/golib/errors"
|
||||
)
|
||||
|
||||
type ProxyManager struct {
|
||||
type Manager struct {
|
||||
sendCh chan (msg.Message)
|
||||
proxies map[string]*ProxyWrapper
|
||||
proxies map[string]*Wrapper
|
||||
|
||||
closed bool
|
||||
mu sync.RWMutex
|
||||
@@ -29,10 +29,10 @@ type ProxyManager struct {
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func NewProxyManager(ctx context.Context, msgSendCh chan (msg.Message), clientCfg config.ClientCommonConf, serverUDPPort int) *ProxyManager {
|
||||
return &ProxyManager{
|
||||
func NewManager(ctx context.Context, msgSendCh chan (msg.Message), clientCfg config.ClientCommonConf, serverUDPPort int) *Manager {
|
||||
return &Manager{
|
||||
sendCh: msgSendCh,
|
||||
proxies: make(map[string]*ProxyWrapper),
|
||||
proxies: make(map[string]*Wrapper),
|
||||
closed: false,
|
||||
clientCfg: clientCfg,
|
||||
serverUDPPort: serverUDPPort,
|
||||
@@ -40,7 +40,7 @@ func NewProxyManager(ctx context.Context, msgSendCh chan (msg.Message), clientCf
|
||||
}
|
||||
}
|
||||
|
||||
func (pm *ProxyManager) StartProxy(name string, remoteAddr string, serverRespErr string) error {
|
||||
func (pm *Manager) StartProxy(name string, remoteAddr string, serverRespErr string) error {
|
||||
pm.mu.RLock()
|
||||
pxy, ok := pm.proxies[name]
|
||||
pm.mu.RUnlock()
|
||||
@@ -55,16 +55,16 @@ func (pm *ProxyManager) StartProxy(name string, remoteAddr string, serverRespErr
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pm *ProxyManager) Close() {
|
||||
func (pm *Manager) Close() {
|
||||
pm.mu.Lock()
|
||||
defer pm.mu.Unlock()
|
||||
for _, pxy := range pm.proxies {
|
||||
pxy.Stop()
|
||||
}
|
||||
pm.proxies = make(map[string]*ProxyWrapper)
|
||||
pm.proxies = make(map[string]*Wrapper)
|
||||
}
|
||||
|
||||
func (pm *ProxyManager) HandleWorkConn(name string, workConn net.Conn, m *msg.StartWorkConn) {
|
||||
func (pm *Manager) HandleWorkConn(name string, workConn net.Conn, m *msg.StartWorkConn) {
|
||||
pm.mu.RLock()
|
||||
pw, ok := pm.proxies[name]
|
||||
pm.mu.RUnlock()
|
||||
@@ -75,7 +75,7 @@ func (pm *ProxyManager) HandleWorkConn(name string, workConn net.Conn, m *msg.St
|
||||
}
|
||||
}
|
||||
|
||||
func (pm *ProxyManager) HandleEvent(evType event.EventType, payload interface{}) error {
|
||||
func (pm *Manager) HandleEvent(evType event.Type, payload interface{}) error {
|
||||
var m msg.Message
|
||||
switch e := payload.(type) {
|
||||
case *event.StartProxyPayload:
|
||||
@@ -92,8 +92,8 @@ func (pm *ProxyManager) HandleEvent(evType event.EventType, payload interface{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (pm *ProxyManager) GetAllProxyStatus() []*ProxyStatus {
|
||||
ps := make([]*ProxyStatus, 0)
|
||||
func (pm *Manager) GetAllProxyStatus() []*WorkingStatus {
|
||||
ps := make([]*WorkingStatus, 0)
|
||||
pm.mu.RLock()
|
||||
defer pm.mu.RUnlock()
|
||||
for _, pxy := range pm.proxies {
|
||||
@@ -102,7 +102,7 @@ func (pm *ProxyManager) GetAllProxyStatus() []*ProxyStatus {
|
||||
return ps
|
||||
}
|
||||
|
||||
func (pm *ProxyManager) Reload(pxyCfgs map[string]config.ProxyConf) {
|
||||
func (pm *Manager) Reload(pxyCfgs map[string]config.ProxyConf) {
|
||||
xl := xlog.FromContextSafe(pm.ctx)
|
||||
pm.mu.Lock()
|
||||
defer pm.mu.Unlock()
|
||||
@@ -133,7 +133,7 @@ func (pm *ProxyManager) Reload(pxyCfgs map[string]config.ProxyConf) {
|
||||
addPxyNames := make([]string, 0)
|
||||
for name, cfg := range pxyCfgs {
|
||||
if _, ok := pm.proxies[name]; !ok {
|
||||
pxy := NewProxyWrapper(pm.ctx, cfg, pm.clientCfg, pm.HandleEvent, pm.serverUDPPort)
|
||||
pxy := NewWrapper(pm.ctx, cfg, pm.clientCfg, pm.HandleEvent, pm.serverUDPPort)
|
||||
pm.proxies[name] = pxy
|
||||
addPxyNames = append(addPxyNames, name)
|
||||
|
||||
|
@@ -10,20 +10,20 @@ import (
|
||||
|
||||
"github.com/fatedier/frp/client/event"
|
||||
"github.com/fatedier/frp/client/health"
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/models/msg"
|
||||
"github.com/fatedier/frp/utils/xlog"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
"github.com/fatedier/frp/pkg/util/xlog"
|
||||
|
||||
"github.com/fatedier/golib/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
ProxyStatusNew = "new"
|
||||
ProxyStatusWaitStart = "wait start"
|
||||
ProxyStatusStartErr = "start error"
|
||||
ProxyStatusRunning = "running"
|
||||
ProxyStatusCheckFailed = "check failed"
|
||||
ProxyStatusClosed = "closed"
|
||||
ProxyPhaseNew = "new"
|
||||
ProxyPhaseWaitStart = "wait start"
|
||||
ProxyPhaseStartErr = "start error"
|
||||
ProxyPhaseRunning = "running"
|
||||
ProxyPhaseCheckFailed = "check failed"
|
||||
ProxyPhaseClosed = "closed"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -32,29 +32,29 @@ var (
|
||||
startErrTimeout = 30 * time.Second
|
||||
)
|
||||
|
||||
type ProxyStatus struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Status string `json:"status"`
|
||||
Err string `json:"err"`
|
||||
Cfg config.ProxyConf `json:"cfg"`
|
||||
type WorkingStatus struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Phase string `json:"status"`
|
||||
Err string `json:"err"`
|
||||
Cfg config.ProxyConf `json:"cfg"`
|
||||
|
||||
// Got from server.
|
||||
RemoteAddr string `json:"remote_addr"`
|
||||
}
|
||||
|
||||
type ProxyWrapper struct {
|
||||
ProxyStatus
|
||||
type Wrapper struct {
|
||||
WorkingStatus
|
||||
|
||||
// underlying proxy
|
||||
pxy Proxy
|
||||
|
||||
// if ProxyConf has healcheck config
|
||||
// monitor will watch if it is alive
|
||||
monitor *health.HealthCheckMonitor
|
||||
monitor *health.Monitor
|
||||
|
||||
// event handler
|
||||
handler event.EventHandler
|
||||
handler event.Handler
|
||||
|
||||
health uint32
|
||||
lastSendStartMsg time.Time
|
||||
@@ -67,15 +67,15 @@ type ProxyWrapper struct {
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func NewProxyWrapper(ctx context.Context, cfg config.ProxyConf, clientCfg config.ClientCommonConf, eventHandler event.EventHandler, serverUDPPort int) *ProxyWrapper {
|
||||
func NewWrapper(ctx context.Context, cfg config.ProxyConf, clientCfg config.ClientCommonConf, eventHandler event.Handler, serverUDPPort int) *Wrapper {
|
||||
baseInfo := cfg.GetBaseInfo()
|
||||
xl := xlog.FromContextSafe(ctx).Spawn().AppendPrefix(baseInfo.ProxyName)
|
||||
pw := &ProxyWrapper{
|
||||
ProxyStatus: ProxyStatus{
|
||||
Name: baseInfo.ProxyName,
|
||||
Type: baseInfo.ProxyType,
|
||||
Status: ProxyStatusNew,
|
||||
Cfg: cfg,
|
||||
pw := &Wrapper{
|
||||
WorkingStatus: WorkingStatus{
|
||||
Name: baseInfo.ProxyName,
|
||||
Type: baseInfo.ProxyType,
|
||||
Phase: ProxyPhaseNew,
|
||||
Cfg: cfg,
|
||||
},
|
||||
closeCh: make(chan struct{}),
|
||||
healthNotifyCh: make(chan struct{}),
|
||||
@@ -86,9 +86,9 @@ func NewProxyWrapper(ctx context.Context, cfg config.ProxyConf, clientCfg config
|
||||
|
||||
if baseInfo.HealthCheckType != "" {
|
||||
pw.health = 1 // means failed
|
||||
pw.monitor = health.NewHealthCheckMonitor(pw.ctx, baseInfo.HealthCheckType, baseInfo.HealthCheckIntervalS,
|
||||
pw.monitor = health.NewMonitor(pw.ctx, baseInfo.HealthCheckType, baseInfo.HealthCheckIntervalS,
|
||||
baseInfo.HealthCheckTimeoutS, baseInfo.HealthCheckMaxFailed, baseInfo.HealthCheckAddr,
|
||||
baseInfo.HealthCheckUrl, pw.statusNormalCallback, pw.statusFailedCallback)
|
||||
baseInfo.HealthCheckURL, pw.statusNormalCallback, pw.statusFailedCallback)
|
||||
xl.Trace("enable health check monitor")
|
||||
}
|
||||
|
||||
@@ -96,16 +96,16 @@ func NewProxyWrapper(ctx context.Context, cfg config.ProxyConf, clientCfg config
|
||||
return pw
|
||||
}
|
||||
|
||||
func (pw *ProxyWrapper) SetRunningStatus(remoteAddr string, respErr string) error {
|
||||
func (pw *Wrapper) SetRunningStatus(remoteAddr string, respErr string) error {
|
||||
pw.mu.Lock()
|
||||
defer pw.mu.Unlock()
|
||||
if pw.Status != ProxyStatusWaitStart {
|
||||
if pw.Phase != ProxyPhaseWaitStart {
|
||||
return fmt.Errorf("status not wait start, ignore start message")
|
||||
}
|
||||
|
||||
pw.RemoteAddr = remoteAddr
|
||||
if respErr != "" {
|
||||
pw.Status = ProxyStatusStartErr
|
||||
pw.Phase = ProxyPhaseStartErr
|
||||
pw.Err = respErr
|
||||
pw.lastStartErr = time.Now()
|
||||
return fmt.Errorf(pw.Err)
|
||||
@@ -113,25 +113,25 @@ func (pw *ProxyWrapper) SetRunningStatus(remoteAddr string, respErr string) erro
|
||||
|
||||
if err := pw.pxy.Run(); err != nil {
|
||||
pw.close()
|
||||
pw.Status = ProxyStatusStartErr
|
||||
pw.Phase = ProxyPhaseStartErr
|
||||
pw.Err = err.Error()
|
||||
pw.lastStartErr = time.Now()
|
||||
return err
|
||||
}
|
||||
|
||||
pw.Status = ProxyStatusRunning
|
||||
pw.Phase = ProxyPhaseRunning
|
||||
pw.Err = ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pw *ProxyWrapper) Start() {
|
||||
func (pw *Wrapper) Start() {
|
||||
go pw.checkWorker()
|
||||
if pw.monitor != nil {
|
||||
go pw.monitor.Start()
|
||||
}
|
||||
}
|
||||
|
||||
func (pw *ProxyWrapper) Stop() {
|
||||
func (pw *Wrapper) Stop() {
|
||||
pw.mu.Lock()
|
||||
defer pw.mu.Unlock()
|
||||
close(pw.closeCh)
|
||||
@@ -140,11 +140,11 @@ func (pw *ProxyWrapper) Stop() {
|
||||
if pw.monitor != nil {
|
||||
pw.monitor.Stop()
|
||||
}
|
||||
pw.Status = ProxyStatusClosed
|
||||
pw.Phase = ProxyPhaseClosed
|
||||
pw.close()
|
||||
}
|
||||
|
||||
func (pw *ProxyWrapper) close() {
|
||||
func (pw *Wrapper) close() {
|
||||
pw.handler(event.EvCloseProxy, &event.CloseProxyPayload{
|
||||
CloseProxyMsg: &msg.CloseProxy{
|
||||
ProxyName: pw.Name,
|
||||
@@ -152,7 +152,7 @@ func (pw *ProxyWrapper) close() {
|
||||
})
|
||||
}
|
||||
|
||||
func (pw *ProxyWrapper) checkWorker() {
|
||||
func (pw *Wrapper) checkWorker() {
|
||||
xl := pw.xl
|
||||
if pw.monitor != nil {
|
||||
// let monitor do check request first
|
||||
@@ -163,13 +163,13 @@ func (pw *ProxyWrapper) checkWorker() {
|
||||
now := time.Now()
|
||||
if atomic.LoadUint32(&pw.health) == 0 {
|
||||
pw.mu.Lock()
|
||||
if pw.Status == ProxyStatusNew ||
|
||||
pw.Status == ProxyStatusCheckFailed ||
|
||||
(pw.Status == ProxyStatusWaitStart && now.After(pw.lastSendStartMsg.Add(waitResponseTimeout))) ||
|
||||
(pw.Status == ProxyStatusStartErr && now.After(pw.lastStartErr.Add(startErrTimeout))) {
|
||||
if pw.Phase == ProxyPhaseNew ||
|
||||
pw.Phase == ProxyPhaseCheckFailed ||
|
||||
(pw.Phase == ProxyPhaseWaitStart && now.After(pw.lastSendStartMsg.Add(waitResponseTimeout))) ||
|
||||
(pw.Phase == ProxyPhaseStartErr && now.After(pw.lastStartErr.Add(startErrTimeout))) {
|
||||
|
||||
xl.Trace("change status from [%s] to [%s]", pw.Status, ProxyStatusWaitStart)
|
||||
pw.Status = ProxyStatusWaitStart
|
||||
xl.Trace("change status from [%s] to [%s]", pw.Phase, ProxyPhaseWaitStart)
|
||||
pw.Phase = ProxyPhaseWaitStart
|
||||
|
||||
var newProxyMsg msg.NewProxy
|
||||
pw.Cfg.MarshalToMsg(&newProxyMsg)
|
||||
@@ -181,10 +181,10 @@ func (pw *ProxyWrapper) checkWorker() {
|
||||
pw.mu.Unlock()
|
||||
} else {
|
||||
pw.mu.Lock()
|
||||
if pw.Status == ProxyStatusRunning || pw.Status == ProxyStatusWaitStart {
|
||||
if pw.Phase == ProxyPhaseRunning || pw.Phase == ProxyPhaseWaitStart {
|
||||
pw.close()
|
||||
xl.Trace("change status from [%s] to [%s]", pw.Status, ProxyStatusCheckFailed)
|
||||
pw.Status = ProxyStatusCheckFailed
|
||||
xl.Trace("change status from [%s] to [%s]", pw.Phase, ProxyPhaseCheckFailed)
|
||||
pw.Phase = ProxyPhaseCheckFailed
|
||||
}
|
||||
pw.mu.Unlock()
|
||||
}
|
||||
@@ -198,7 +198,7 @@ func (pw *ProxyWrapper) checkWorker() {
|
||||
}
|
||||
}
|
||||
|
||||
func (pw *ProxyWrapper) statusNormalCallback() {
|
||||
func (pw *Wrapper) statusNormalCallback() {
|
||||
xl := pw.xl
|
||||
atomic.StoreUint32(&pw.health, 0)
|
||||
errors.PanicToError(func() {
|
||||
@@ -210,7 +210,7 @@ func (pw *ProxyWrapper) statusNormalCallback() {
|
||||
xl.Info("health check success")
|
||||
}
|
||||
|
||||
func (pw *ProxyWrapper) statusFailedCallback() {
|
||||
func (pw *Wrapper) statusFailedCallback() {
|
||||
xl := pw.xl
|
||||
atomic.StoreUint32(&pw.health, 1)
|
||||
errors.PanicToError(func() {
|
||||
@@ -222,7 +222,7 @@ func (pw *ProxyWrapper) statusFailedCallback() {
|
||||
xl.Info("health check failed")
|
||||
}
|
||||
|
||||
func (pw *ProxyWrapper) InWorkConn(workConn net.Conn, m *msg.StartWorkConn) {
|
||||
func (pw *Wrapper) InWorkConn(workConn net.Conn, m *msg.StartWorkConn) {
|
||||
xl := pw.xl
|
||||
pw.mu.RLock()
|
||||
pxy := pw.pxy
|
||||
@@ -235,13 +235,13 @@ func (pw *ProxyWrapper) InWorkConn(workConn net.Conn, m *msg.StartWorkConn) {
|
||||
}
|
||||
}
|
||||
|
||||
func (pw *ProxyWrapper) GetStatus() *ProxyStatus {
|
||||
func (pw *Wrapper) GetStatus() *WorkingStatus {
|
||||
pw.mu.RLock()
|
||||
defer pw.mu.RUnlock()
|
||||
ps := &ProxyStatus{
|
||||
ps := &WorkingStatus{
|
||||
Name: pw.Name,
|
||||
Type: pw.Type,
|
||||
Status: pw.Status,
|
||||
Phase: pw.Phase,
|
||||
Err: pw.Err,
|
||||
Cfg: pw.Cfg,
|
||||
RemoteAddr: pw.RemoteAddr,
|
||||
|
@@ -21,18 +21,20 @@ import (
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/assets"
|
||||
"github.com/fatedier/frp/models/auth"
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/models/msg"
|
||||
"github.com/fatedier/frp/utils/log"
|
||||
frpNet "github.com/fatedier/frp/utils/net"
|
||||
"github.com/fatedier/frp/utils/version"
|
||||
"github.com/fatedier/frp/utils/xlog"
|
||||
"github.com/fatedier/frp/pkg/auth"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
"github.com/fatedier/frp/pkg/transport"
|
||||
"github.com/fatedier/frp/pkg/util/log"
|
||||
frpNet "github.com/fatedier/frp/pkg/util/net"
|
||||
"github.com/fatedier/frp/pkg/util/version"
|
||||
"github.com/fatedier/frp/pkg/util/xlog"
|
||||
|
||||
fmux "github.com/hashicorp/yamux"
|
||||
)
|
||||
@@ -40,7 +42,7 @@ import (
|
||||
// Service is a client service.
|
||||
type Service struct {
|
||||
// uniq id got from frps, attach it in loginMsg
|
||||
runId string
|
||||
runID string
|
||||
|
||||
// manager control connection with server
|
||||
ctl *Control
|
||||
@@ -73,7 +75,7 @@ func NewService(cfg config.ClientCommonConf, pxyCfgs map[string]config.ProxyConf
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
svr = &Service{
|
||||
authSetter: auth.NewAuthSetter(cfg.AuthClientConfig),
|
||||
authSetter: auth.NewAuthSetter(cfg.ClientConfig),
|
||||
cfg: cfg,
|
||||
cfgFile: cfgFile,
|
||||
pxyCfgs: pxyCfgs,
|
||||
@@ -104,12 +106,11 @@ func (svr *Service) Run() error {
|
||||
// otherwise sleep a while and try again to connect to server
|
||||
if svr.cfg.LoginFailExit {
|
||||
return err
|
||||
} else {
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
||||
time.Sleep(10 * time.Second)
|
||||
} else {
|
||||
// login success
|
||||
ctl := NewControl(svr.ctx, svr.runId, conn, session, svr.cfg, svr.pxyCfgs, svr.visitorCfgs, svr.serverUDPPort, svr.authSetter)
|
||||
ctl := NewControl(svr.ctx, svr.runID, conn, session, svr.cfg, svr.pxyCfgs, svr.visitorCfgs, svr.serverUDPPort, svr.authSetter)
|
||||
ctl.Run()
|
||||
svr.ctlMu.Lock()
|
||||
svr.ctl = ctl
|
||||
@@ -185,7 +186,7 @@ func (svr *Service) keepControllerWorking() {
|
||||
// reconnect success, init delayTime
|
||||
delayTime = time.Second
|
||||
|
||||
ctl := NewControl(svr.ctx, svr.runId, conn, session, svr.cfg, svr.pxyCfgs, svr.visitorCfgs, svr.serverUDPPort, svr.authSetter)
|
||||
ctl := NewControl(svr.ctx, svr.runID, conn, session, svr.cfg, svr.pxyCfgs, svr.visitorCfgs, svr.serverUDPPort, svr.authSetter)
|
||||
ctl.Run()
|
||||
svr.ctlMu.Lock()
|
||||
if svr.ctl != nil {
|
||||
@@ -205,12 +206,19 @@ func (svr *Service) login() (conn net.Conn, session *fmux.Session, err error) {
|
||||
xl := xlog.FromContextSafe(svr.ctx)
|
||||
var tlsConfig *tls.Config
|
||||
if svr.cfg.TLSEnable {
|
||||
tlsConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
tlsConfig, err = transport.NewClientTLSConfig(
|
||||
svr.cfg.TLSCertFile,
|
||||
svr.cfg.TLSKeyFile,
|
||||
svr.cfg.TLSTrustedCaFile,
|
||||
svr.cfg.ServerAddr)
|
||||
if err != nil {
|
||||
xl.Warn("fail to build tls configuration when service login, err: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
conn, err = frpNet.ConnectServerByProxyWithTLS(svr.cfg.HttpProxy, svr.cfg.Protocol,
|
||||
fmt.Sprintf("%s:%d", svr.cfg.ServerAddr, svr.cfg.ServerPort), tlsConfig)
|
||||
|
||||
address := net.JoinHostPort(svr.cfg.ServerAddr, strconv.Itoa(svr.cfg.ServerPort))
|
||||
conn, err = frpNet.ConnectServerByProxyWithTLS(svr.cfg.HTTPProxy, svr.cfg.Protocol, address, tlsConfig)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -224,7 +232,7 @@ func (svr *Service) login() (conn net.Conn, session *fmux.Session, err error) {
|
||||
}
|
||||
}()
|
||||
|
||||
if svr.cfg.TcpMux {
|
||||
if svr.cfg.TCPMux {
|
||||
fmuxCfg := fmux.DefaultConfig()
|
||||
fmuxCfg.KeepAliveInterval = 20 * time.Second
|
||||
fmuxCfg.LogOutput = ioutil.Discard
|
||||
@@ -248,7 +256,7 @@ func (svr *Service) login() (conn net.Conn, session *fmux.Session, err error) {
|
||||
User: svr.cfg.User,
|
||||
Version: version.Full(),
|
||||
Timestamp: time.Now().Unix(),
|
||||
RunId: svr.runId,
|
||||
RunID: svr.runID,
|
||||
Metas: svr.cfg.Metas,
|
||||
}
|
||||
|
||||
@@ -274,12 +282,12 @@ func (svr *Service) login() (conn net.Conn, session *fmux.Session, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
svr.runId = loginRespMsg.RunId
|
||||
svr.runID = loginRespMsg.RunID
|
||||
xl.ResetPrefixes()
|
||||
xl.AppendPrefix(svr.runId)
|
||||
xl.AppendPrefix(svr.runID)
|
||||
|
||||
svr.serverUDPPort = loginRespMsg.ServerUdpPort
|
||||
xl.Info("login to server success, get run id [%s], server udp port [%d]", loginRespMsg.RunId, loginRespMsg.ServerUdpPort)
|
||||
svr.serverUDPPort = loginRespMsg.ServerUDPPort
|
||||
xl.Info("login to server success, get run id [%s], server udp port [%d]", loginRespMsg.RunID, loginRespMsg.ServerUDPPort)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -294,6 +302,8 @@ func (svr *Service) ReloadConf(pxyCfgs map[string]config.ProxyConf, visitorCfgs
|
||||
|
||||
func (svr *Service) Close() {
|
||||
atomic.StoreUint32(&svr.exit, 1)
|
||||
svr.ctl.Close()
|
||||
if svr.ctl != nil {
|
||||
svr.ctl.Close()
|
||||
}
|
||||
svr.cancel()
|
||||
}
|
||||
|
@@ -24,12 +24,12 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/models/msg"
|
||||
"github.com/fatedier/frp/models/proto/udp"
|
||||
frpNet "github.com/fatedier/frp/utils/net"
|
||||
"github.com/fatedier/frp/utils/util"
|
||||
"github.com/fatedier/frp/utils/xlog"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
"github.com/fatedier/frp/pkg/proto/udp"
|
||||
frpNet "github.com/fatedier/frp/pkg/util/net"
|
||||
"github.com/fatedier/frp/pkg/util/util"
|
||||
"github.com/fatedier/frp/pkg/util/xlog"
|
||||
|
||||
"github.com/fatedier/golib/errors"
|
||||
frpIo "github.com/fatedier/golib/io"
|
||||
@@ -50,18 +50,18 @@ func NewVisitor(ctx context.Context, ctl *Control, cfg config.VisitorConf) (visi
|
||||
ctx: xlog.NewContext(ctx, xl),
|
||||
}
|
||||
switch cfg := cfg.(type) {
|
||||
case *config.StcpVisitorConf:
|
||||
visitor = &StcpVisitor{
|
||||
case *config.STCPVisitorConf:
|
||||
visitor = &STCPVisitor{
|
||||
BaseVisitor: &baseVisitor,
|
||||
cfg: cfg,
|
||||
}
|
||||
case *config.XtcpVisitorConf:
|
||||
visitor = &XtcpVisitor{
|
||||
case *config.XTCPVisitorConf:
|
||||
visitor = &XTCPVisitor{
|
||||
BaseVisitor: &baseVisitor,
|
||||
cfg: cfg,
|
||||
}
|
||||
case *config.SudpVisitorConf:
|
||||
visitor = &SudpVisitor{
|
||||
case *config.SUDPVisitorConf:
|
||||
visitor = &SUDPVisitor{
|
||||
BaseVisitor: &baseVisitor,
|
||||
cfg: cfg,
|
||||
checkCloseCh: make(chan struct{}),
|
||||
@@ -79,13 +79,13 @@ type BaseVisitor struct {
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
type StcpVisitor struct {
|
||||
type STCPVisitor struct {
|
||||
*BaseVisitor
|
||||
|
||||
cfg *config.StcpVisitorConf
|
||||
cfg *config.STCPVisitorConf
|
||||
}
|
||||
|
||||
func (sv *StcpVisitor) Run() (err error) {
|
||||
func (sv *STCPVisitor) Run() (err error) {
|
||||
sv.l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", sv.cfg.BindAddr, sv.cfg.BindPort))
|
||||
if err != nil {
|
||||
return
|
||||
@@ -95,11 +95,11 @@ func (sv *StcpVisitor) Run() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (sv *StcpVisitor) Close() {
|
||||
func (sv *STCPVisitor) Close() {
|
||||
sv.l.Close()
|
||||
}
|
||||
|
||||
func (sv *StcpVisitor) worker() {
|
||||
func (sv *STCPVisitor) worker() {
|
||||
xl := xlog.FromContextSafe(sv.ctx)
|
||||
for {
|
||||
conn, err := sv.l.Accept()
|
||||
@@ -112,7 +112,7 @@ func (sv *StcpVisitor) worker() {
|
||||
}
|
||||
}
|
||||
|
||||
func (sv *StcpVisitor) handleConn(userConn net.Conn) {
|
||||
func (sv *STCPVisitor) handleConn(userConn net.Conn) {
|
||||
xl := xlog.FromContextSafe(sv.ctx)
|
||||
defer userConn.Close()
|
||||
|
||||
@@ -168,13 +168,13 @@ func (sv *StcpVisitor) handleConn(userConn net.Conn) {
|
||||
frpIo.Join(userConn, remote)
|
||||
}
|
||||
|
||||
type XtcpVisitor struct {
|
||||
type XTCPVisitor struct {
|
||||
*BaseVisitor
|
||||
|
||||
cfg *config.XtcpVisitorConf
|
||||
cfg *config.XTCPVisitorConf
|
||||
}
|
||||
|
||||
func (sv *XtcpVisitor) Run() (err error) {
|
||||
func (sv *XTCPVisitor) Run() (err error) {
|
||||
sv.l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", sv.cfg.BindAddr, sv.cfg.BindPort))
|
||||
if err != nil {
|
||||
return
|
||||
@@ -184,11 +184,11 @@ func (sv *XtcpVisitor) Run() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (sv *XtcpVisitor) Close() {
|
||||
func (sv *XTCPVisitor) Close() {
|
||||
sv.l.Close()
|
||||
}
|
||||
|
||||
func (sv *XtcpVisitor) worker() {
|
||||
func (sv *XTCPVisitor) worker() {
|
||||
xl := xlog.FromContextSafe(sv.ctx)
|
||||
for {
|
||||
conn, err := sv.l.Accept()
|
||||
@@ -201,7 +201,7 @@ func (sv *XtcpVisitor) worker() {
|
||||
}
|
||||
}
|
||||
|
||||
func (sv *XtcpVisitor) handleConn(userConn net.Conn) {
|
||||
func (sv *XTCPVisitor) handleConn(userConn net.Conn) {
|
||||
xl := xlog.FromContextSafe(sv.ctx)
|
||||
defer userConn.Close()
|
||||
|
||||
@@ -300,7 +300,7 @@ func (sv *XtcpVisitor) handleConn(userConn net.Conn) {
|
||||
|
||||
// wrap kcp connection
|
||||
var remote io.ReadWriteCloser
|
||||
remote, err = frpNet.NewKcpConnFromUdp(lConn, true, natHoleRespMsg.ClientAddr)
|
||||
remote, err = frpNet.NewKCPConnFromUDP(lConn, true, natHoleRespMsg.ClientAddr)
|
||||
if err != nil {
|
||||
xl.Error("create kcp connection from udp connection error: %v", err)
|
||||
return
|
||||
@@ -337,20 +337,20 @@ func (sv *XtcpVisitor) handleConn(userConn net.Conn) {
|
||||
xl.Debug("join connections closed")
|
||||
}
|
||||
|
||||
type SudpVisitor struct {
|
||||
type SUDPVisitor struct {
|
||||
*BaseVisitor
|
||||
|
||||
checkCloseCh chan struct{}
|
||||
// udpConn is the listener of udp packet
|
||||
udpConn *net.UDPConn
|
||||
readCh chan *msg.UdpPacket
|
||||
sendCh chan *msg.UdpPacket
|
||||
readCh chan *msg.UDPPacket
|
||||
sendCh chan *msg.UDPPacket
|
||||
|
||||
cfg *config.SudpVisitorConf
|
||||
cfg *config.SUDPVisitorConf
|
||||
}
|
||||
|
||||
// SUDP Run start listen a udp port
|
||||
func (sv *SudpVisitor) Run() (err error) {
|
||||
func (sv *SUDPVisitor) Run() (err error) {
|
||||
xl := xlog.FromContextSafe(sv.ctx)
|
||||
|
||||
addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", sv.cfg.BindAddr, sv.cfg.BindPort))
|
||||
@@ -363,18 +363,18 @@ func (sv *SudpVisitor) Run() (err error) {
|
||||
return fmt.Errorf("listen udp port %s error: %v", addr.String(), err)
|
||||
}
|
||||
|
||||
sv.sendCh = make(chan *msg.UdpPacket, 1024)
|
||||
sv.readCh = make(chan *msg.UdpPacket, 1024)
|
||||
sv.sendCh = make(chan *msg.UDPPacket, 1024)
|
||||
sv.readCh = make(chan *msg.UDPPacket, 1024)
|
||||
|
||||
xl.Info("sudp start to work")
|
||||
|
||||
go sv.dispatcher()
|
||||
go udp.ForwardUserConn(sv.udpConn, sv.readCh, sv.sendCh)
|
||||
go udp.ForwardUserConn(sv.udpConn, sv.readCh, sv.sendCh, int(sv.ctl.clientCfg.UDPPacketSize))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (sv *SudpVisitor) dispatcher() {
|
||||
func (sv *SUDPVisitor) dispatcher() {
|
||||
xl := xlog.FromContextSafe(sv.ctx)
|
||||
|
||||
for {
|
||||
@@ -409,7 +409,7 @@ func (sv *SudpVisitor) dispatcher() {
|
||||
}
|
||||
}
|
||||
|
||||
func (sv *SudpVisitor) worker(workConn net.Conn) {
|
||||
func (sv *SUDPVisitor) worker(workConn net.Conn) {
|
||||
xl := xlog.FromContextSafe(sv.ctx)
|
||||
xl.Debug("starting sudp proxy worker")
|
||||
|
||||
@@ -443,7 +443,7 @@ func (sv *SudpVisitor) worker(workConn net.Conn) {
|
||||
case *msg.Ping:
|
||||
xl.Debug("frpc visitor get ping message from frpc")
|
||||
continue
|
||||
case *msg.UdpPacket:
|
||||
case *msg.UDPPacket:
|
||||
if errRet := errors.PanicToError(func() {
|
||||
sv.readCh <- m
|
||||
xl.Trace("frpc visitor get udp packet from frpc")
|
||||
@@ -488,8 +488,9 @@ func (sv *SudpVisitor) worker(workConn net.Conn) {
|
||||
xl.Info("sudp worker is closed")
|
||||
}
|
||||
|
||||
func (sv *SudpVisitor) getNewVisitorConn() (visitorConn net.Conn, err error) {
|
||||
visitorConn, err = sv.ctl.connectServer()
|
||||
func (sv *SUDPVisitor) getNewVisitorConn() (net.Conn, error) {
|
||||
xl := xlog.FromContextSafe(sv.ctx)
|
||||
visitorConn, err := sv.ctl.connectServer()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("frpc connect frps error: %v", err)
|
||||
}
|
||||
@@ -518,10 +519,23 @@ func (sv *SudpVisitor) getNewVisitorConn() (visitorConn net.Conn, err error) {
|
||||
if newVisitorConnRespMsg.Error != "" {
|
||||
return nil, fmt.Errorf("start new visitor connection error: %s", newVisitorConnRespMsg.Error)
|
||||
}
|
||||
return
|
||||
|
||||
var remote io.ReadWriteCloser
|
||||
remote = visitorConn
|
||||
if sv.cfg.UseEncryption {
|
||||
remote, err = frpIo.WithEncryption(remote, []byte(sv.cfg.Sk))
|
||||
if err != nil {
|
||||
xl.Error("create encryption stream error: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if sv.cfg.UseCompression {
|
||||
remote = frpIo.WithCompression(remote)
|
||||
}
|
||||
return frpNet.WrapReadWriteCloserToConn(remote, visitorConn), nil
|
||||
}
|
||||
|
||||
func (sv *SudpVisitor) Close() {
|
||||
func (sv *SUDPVisitor) Close() {
|
||||
sv.mu.Lock()
|
||||
defer sv.mu.Unlock()
|
||||
|
||||
|
@@ -19,8 +19,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/utils/xlog"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/util/xlog"
|
||||
)
|
||||
|
||||
type VisitorManager struct {
|
||||
|
@@ -19,24 +19,17 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/consts"
|
||||
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/models/consts"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
httpCmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address")
|
||||
httpCmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user")
|
||||
httpCmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp or kcp or websocket")
|
||||
httpCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
|
||||
httpCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||
httpCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
|
||||
httpCmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
|
||||
httpCmd.PersistentFlags().BoolVarP(&disableLogColor, "disable_log_color", "", false, "disable log color in console")
|
||||
RegisterCommonFlags(httpCmd)
|
||||
|
||||
httpCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name")
|
||||
httpCmd.PersistentFlags().StringVarP(&localIp, "local_ip", "i", "127.0.0.1", "local ip")
|
||||
httpCmd.PersistentFlags().StringVarP(&localIP, "local_ip", "i", "127.0.0.1", "local ip")
|
||||
httpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port")
|
||||
httpCmd.PersistentFlags().StringVarP(&customDomains, "custom_domain", "d", "", "custom domain")
|
||||
httpCmd.PersistentFlags().StringVarP(&subDomain, "sd", "", "", "sub domain")
|
||||
@@ -60,20 +53,20 @@ var httpCmd = &cobra.Command{
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
cfg := &config.HttpProxyConf{}
|
||||
cfg := &config.HTTPProxyConf{}
|
||||
var prefix string
|
||||
if user != "" {
|
||||
prefix = user + "."
|
||||
}
|
||||
cfg.ProxyName = prefix + proxyName
|
||||
cfg.ProxyType = consts.HttpProxy
|
||||
cfg.LocalIp = localIp
|
||||
cfg.ProxyType = consts.HTTPProxy
|
||||
cfg.LocalIP = localIP
|
||||
cfg.LocalPort = localPort
|
||||
cfg.CustomDomains = strings.Split(customDomains, ",")
|
||||
cfg.SubDomain = subDomain
|
||||
cfg.Locations = strings.Split(locations, ",")
|
||||
cfg.HttpUser = httpUser
|
||||
cfg.HttpPwd = httpPwd
|
||||
cfg.HTTPUser = httpUser
|
||||
cfg.HTTPPwd = httpPwd
|
||||
cfg.HostHeaderRewrite = hostHeaderRewrite
|
||||
cfg.UseEncryption = useEncryption
|
||||
cfg.UseCompression = useCompression
|
||||
|
@@ -21,22 +21,15 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/models/consts"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/consts"
|
||||
)
|
||||
|
||||
func init() {
|
||||
httpsCmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address")
|
||||
httpsCmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user")
|
||||
httpsCmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp or kcp or websocket")
|
||||
httpsCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
|
||||
httpsCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||
httpsCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
|
||||
httpsCmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
|
||||
httpsCmd.PersistentFlags().BoolVarP(&disableLogColor, "disable_log_color", "", false, "disable log color in console")
|
||||
RegisterCommonFlags(httpsCmd)
|
||||
|
||||
httpsCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name")
|
||||
httpsCmd.PersistentFlags().StringVarP(&localIp, "local_ip", "i", "127.0.0.1", "local ip")
|
||||
httpsCmd.PersistentFlags().StringVarP(&localIP, "local_ip", "i", "127.0.0.1", "local ip")
|
||||
httpsCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port")
|
||||
httpsCmd.PersistentFlags().StringVarP(&customDomains, "custom_domain", "d", "", "custom domain")
|
||||
httpsCmd.PersistentFlags().StringVarP(&subDomain, "sd", "", "", "sub domain")
|
||||
@@ -56,14 +49,14 @@ var httpsCmd = &cobra.Command{
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
cfg := &config.HttpsProxyConf{}
|
||||
cfg := &config.HTTPSProxyConf{}
|
||||
var prefix string
|
||||
if user != "" {
|
||||
prefix = user + "."
|
||||
}
|
||||
cfg.ProxyName = prefix + proxyName
|
||||
cfg.ProxyType = consts.HttpsProxy
|
||||
cfg.LocalIp = localIp
|
||||
cfg.ProxyType = consts.HTTPSProxy
|
||||
cfg.LocalIP = localIP
|
||||
cfg.LocalPort = localPort
|
||||
cfg.CustomDomains = strings.Split(customDomains, ",")
|
||||
cfg.SubDomain = subDomain
|
||||
|
@@ -22,9 +22,9 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@@ -25,13 +25,13 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/fatedier/frp/client"
|
||||
"github.com/fatedier/frp/models/auth"
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/utils/log"
|
||||
"github.com/fatedier/frp/utils/version"
|
||||
"github.com/fatedier/frp/pkg/auth"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/util/log"
|
||||
"github.com/fatedier/frp/pkg/util/version"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -53,7 +53,7 @@ var (
|
||||
disableLogColor bool
|
||||
|
||||
proxyName string
|
||||
localIp string
|
||||
localIP string
|
||||
localPort int
|
||||
remotePort int
|
||||
useEncryption bool
|
||||
@@ -71,6 +71,8 @@ var (
|
||||
bindAddr string
|
||||
bindPort int
|
||||
|
||||
tlsEnable bool
|
||||
|
||||
kcpDoneCh chan struct{}
|
||||
)
|
||||
|
||||
@@ -81,6 +83,18 @@ func init() {
|
||||
kcpDoneCh = make(chan struct{})
|
||||
}
|
||||
|
||||
func RegisterCommonFlags(cmd *cobra.Command) {
|
||||
cmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address")
|
||||
cmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user")
|
||||
cmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp or kcp or websocket")
|
||||
cmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
|
||||
cmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||
cmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
|
||||
cmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
|
||||
cmd.PersistentFlags().BoolVarP(&disableLogColor, "disable_log_color", "", false, "disable log color in console")
|
||||
cmd.PersistentFlags().BoolVarP(&tlsEnable, "tls_enable", "", false, "enable frpc tls")
|
||||
}
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "frpc",
|
||||
Short: "frpc is the client of frp (https://github.com/fatedier/frp)",
|
||||
@@ -143,17 +157,16 @@ func parseClientCommonCfgFromIni(content string) (config.ClientCommonConf, error
|
||||
func parseClientCommonCfgFromCmd() (cfg config.ClientCommonConf, err error) {
|
||||
cfg = config.GetDefaultClientConf()
|
||||
|
||||
strs := strings.Split(serverAddr, ":")
|
||||
if len(strs) < 2 {
|
||||
err = fmt.Errorf("invalid server_addr")
|
||||
ipStr, portStr, err := net.SplitHostPort(serverAddr)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("invalid server_addr: %v", err)
|
||||
return
|
||||
}
|
||||
if strs[0] != "" {
|
||||
cfg.ServerAddr = strs[0]
|
||||
}
|
||||
cfg.ServerPort, err = strconv.Atoi(strs[1])
|
||||
|
||||
cfg.ServerAddr = ipStr
|
||||
cfg.ServerPort, err = strconv.Atoi(portStr)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("invalid server_addr")
|
||||
err = fmt.Errorf("invalid server_addr: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -170,8 +183,9 @@ func parseClientCommonCfgFromCmd() (cfg config.ClientCommonConf, err error) {
|
||||
cfg.DisableLogColor = disableLogColor
|
||||
|
||||
// Only token authentication is supported in cmd mode
|
||||
cfg.AuthClientConfig = auth.GetDefaultAuthClientConf()
|
||||
cfg.ClientConfig = auth.GetDefaultClientConf()
|
||||
cfg.Token = token
|
||||
cfg.TLSEnable = tlsEnable
|
||||
|
||||
return
|
||||
}
|
||||
@@ -197,12 +211,18 @@ func runClient(cfgFilePath string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func startService(cfg config.ClientCommonConf, pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf, cfgFile string) (err error) {
|
||||
func startService(
|
||||
cfg config.ClientCommonConf,
|
||||
pxyCfgs map[string]config.ProxyConf,
|
||||
visitorCfgs map[string]config.VisitorConf,
|
||||
cfgFile string,
|
||||
) (err error) {
|
||||
|
||||
log.InitLog(cfg.LogWay, cfg.LogFile, cfg.LogLevel,
|
||||
cfg.LogMaxDays, cfg.DisableLogColor)
|
||||
|
||||
if cfg.DnsServer != "" {
|
||||
s := cfg.DnsServer
|
||||
if cfg.DNSServer != "" {
|
||||
s := cfg.DNSServer
|
||||
if !strings.Contains(s, ":") {
|
||||
s += ":53"
|
||||
}
|
||||
|
@@ -23,11 +23,11 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/fatedier/frp/client"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
|
||||
"github.com/rodaine/table"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/fatedier/frp/client"
|
||||
"github.com/fatedier/frp/models/config"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -95,55 +95,55 @@ func status(clientCfg config.ClientCommonConf) error {
|
||||
}
|
||||
|
||||
fmt.Println("Proxy Status...")
|
||||
if len(res.Tcp) > 0 {
|
||||
if len(res.TCP) > 0 {
|
||||
fmt.Printf("TCP")
|
||||
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
||||
for _, ps := range res.Tcp {
|
||||
for _, ps := range res.TCP {
|
||||
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
||||
}
|
||||
tbl.Print()
|
||||
fmt.Println("")
|
||||
}
|
||||
if len(res.Udp) > 0 {
|
||||
if len(res.UDP) > 0 {
|
||||
fmt.Printf("UDP")
|
||||
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
||||
for _, ps := range res.Udp {
|
||||
for _, ps := range res.UDP {
|
||||
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
||||
}
|
||||
tbl.Print()
|
||||
fmt.Println("")
|
||||
}
|
||||
if len(res.Http) > 0 {
|
||||
if len(res.HTTP) > 0 {
|
||||
fmt.Printf("HTTP")
|
||||
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
||||
for _, ps := range res.Http {
|
||||
for _, ps := range res.HTTP {
|
||||
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
||||
}
|
||||
tbl.Print()
|
||||
fmt.Println("")
|
||||
}
|
||||
if len(res.Https) > 0 {
|
||||
if len(res.HTTPS) > 0 {
|
||||
fmt.Printf("HTTPS")
|
||||
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
||||
for _, ps := range res.Https {
|
||||
for _, ps := range res.HTTPS {
|
||||
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
||||
}
|
||||
tbl.Print()
|
||||
fmt.Println("")
|
||||
}
|
||||
if len(res.Stcp) > 0 {
|
||||
if len(res.STCP) > 0 {
|
||||
fmt.Printf("STCP")
|
||||
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
||||
for _, ps := range res.Stcp {
|
||||
for _, ps := range res.STCP {
|
||||
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
||||
}
|
||||
tbl.Print()
|
||||
fmt.Println("")
|
||||
}
|
||||
if len(res.Xtcp) > 0 {
|
||||
if len(res.XTCP) > 0 {
|
||||
fmt.Printf("XTCP")
|
||||
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
||||
for _, ps := range res.Xtcp {
|
||||
for _, ps := range res.XTCP {
|
||||
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
||||
}
|
||||
tbl.Print()
|
||||
|
@@ -18,27 +18,20 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/consts"
|
||||
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/models/consts"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
stcpCmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address")
|
||||
stcpCmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user")
|
||||
stcpCmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp or kcp or websocket")
|
||||
stcpCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
|
||||
stcpCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||
stcpCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
|
||||
stcpCmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
|
||||
stcpCmd.PersistentFlags().BoolVarP(&disableLogColor, "disable_log_color", "", false, "disable log color in console")
|
||||
RegisterCommonFlags(stcpCmd)
|
||||
|
||||
stcpCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name")
|
||||
stcpCmd.PersistentFlags().StringVarP(&role, "role", "", "server", "role")
|
||||
stcpCmd.PersistentFlags().StringVarP(&sk, "sk", "", "", "secret key")
|
||||
stcpCmd.PersistentFlags().StringVarP(&serverName, "server_name", "", "", "server name")
|
||||
stcpCmd.PersistentFlags().StringVarP(&localIp, "local_ip", "i", "127.0.0.1", "local ip")
|
||||
stcpCmd.PersistentFlags().StringVarP(&localIP, "local_ip", "i", "127.0.0.1", "local ip")
|
||||
stcpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port")
|
||||
stcpCmd.PersistentFlags().StringVarP(&bindAddr, "bind_addr", "", "", "bind addr")
|
||||
stcpCmd.PersistentFlags().IntVarP(&bindPort, "bind_port", "", 0, "bind port")
|
||||
@@ -67,14 +60,14 @@ var stcpCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
if role == "server" {
|
||||
cfg := &config.StcpProxyConf{}
|
||||
cfg := &config.STCPProxyConf{}
|
||||
cfg.ProxyName = prefix + proxyName
|
||||
cfg.ProxyType = consts.StcpProxy
|
||||
cfg.ProxyType = consts.STCPProxy
|
||||
cfg.UseEncryption = useEncryption
|
||||
cfg.UseCompression = useCompression
|
||||
cfg.Role = role
|
||||
cfg.Sk = sk
|
||||
cfg.LocalIp = localIp
|
||||
cfg.LocalIP = localIP
|
||||
cfg.LocalPort = localPort
|
||||
err = cfg.CheckForCli()
|
||||
if err != nil {
|
||||
@@ -83,9 +76,9 @@ var stcpCmd = &cobra.Command{
|
||||
}
|
||||
proxyConfs[cfg.ProxyName] = cfg
|
||||
} else if role == "visitor" {
|
||||
cfg := &config.StcpVisitorConf{}
|
||||
cfg := &config.STCPVisitorConf{}
|
||||
cfg.ProxyName = prefix + proxyName
|
||||
cfg.ProxyType = consts.StcpProxy
|
||||
cfg.ProxyType = consts.STCPProxy
|
||||
cfg.UseEncryption = useEncryption
|
||||
cfg.UseCompression = useCompression
|
||||
cfg.Role = role
|
||||
|
@@ -18,27 +18,20 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/consts"
|
||||
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/models/consts"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
sudpCmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address")
|
||||
sudpCmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user")
|
||||
sudpCmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp or kcp or websocket")
|
||||
sudpCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
|
||||
sudpCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||
sudpCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
|
||||
sudpCmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
|
||||
sudpCmd.PersistentFlags().BoolVarP(&disableLogColor, "disable_log_color", "", false, "disable log color in console")
|
||||
RegisterCommonFlags(sudpCmd)
|
||||
|
||||
sudpCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name")
|
||||
sudpCmd.PersistentFlags().StringVarP(&role, "role", "", "server", "role")
|
||||
sudpCmd.PersistentFlags().StringVarP(&sk, "sk", "", "", "secret key")
|
||||
sudpCmd.PersistentFlags().StringVarP(&serverName, "server_name", "", "", "server name")
|
||||
sudpCmd.PersistentFlags().StringVarP(&localIp, "local_ip", "i", "127.0.0.1", "local ip")
|
||||
sudpCmd.PersistentFlags().StringVarP(&localIP, "local_ip", "i", "127.0.0.1", "local ip")
|
||||
sudpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port")
|
||||
sudpCmd.PersistentFlags().StringVarP(&bindAddr, "bind_addr", "", "", "bind addr")
|
||||
sudpCmd.PersistentFlags().IntVarP(&bindPort, "bind_port", "", 0, "bind port")
|
||||
@@ -67,14 +60,14 @@ var sudpCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
if role == "server" {
|
||||
cfg := &config.SudpProxyConf{}
|
||||
cfg := &config.SUDPProxyConf{}
|
||||
cfg.ProxyName = prefix + proxyName
|
||||
cfg.ProxyType = consts.SudpProxy
|
||||
cfg.ProxyType = consts.SUDPProxy
|
||||
cfg.UseEncryption = useEncryption
|
||||
cfg.UseCompression = useCompression
|
||||
cfg.Role = role
|
||||
cfg.Sk = sk
|
||||
cfg.LocalIp = localIp
|
||||
cfg.LocalIP = localIP
|
||||
cfg.LocalPort = localPort
|
||||
err = cfg.CheckForCli()
|
||||
if err != nil {
|
||||
@@ -83,9 +76,9 @@ var sudpCmd = &cobra.Command{
|
||||
}
|
||||
proxyConfs[cfg.ProxyName] = cfg
|
||||
} else if role == "visitor" {
|
||||
cfg := &config.SudpVisitorConf{}
|
||||
cfg := &config.SUDPVisitorConf{}
|
||||
cfg.ProxyName = prefix + proxyName
|
||||
cfg.ProxyType = consts.SudpProxy
|
||||
cfg.ProxyType = consts.SUDPProxy
|
||||
cfg.UseEncryption = useEncryption
|
||||
cfg.UseCompression = useCompression
|
||||
cfg.Role = role
|
||||
|
@@ -20,22 +20,15 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/models/consts"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/consts"
|
||||
)
|
||||
|
||||
func init() {
|
||||
tcpCmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address")
|
||||
tcpCmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user")
|
||||
tcpCmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp or kcp")
|
||||
tcpCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
|
||||
tcpCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||
tcpCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
|
||||
tcpCmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
|
||||
tcpCmd.PersistentFlags().BoolVarP(&disableLogColor, "disable_log_color", "", false, "disable log color in console")
|
||||
RegisterCommonFlags(tcpCmd)
|
||||
|
||||
tcpCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name")
|
||||
tcpCmd.PersistentFlags().StringVarP(&localIp, "local_ip", "i", "127.0.0.1", "local ip")
|
||||
tcpCmd.PersistentFlags().StringVarP(&localIP, "local_ip", "i", "127.0.0.1", "local ip")
|
||||
tcpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port")
|
||||
tcpCmd.PersistentFlags().IntVarP(&remotePort, "remote_port", "r", 0, "remote port")
|
||||
tcpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
|
||||
@@ -54,14 +47,14 @@ var tcpCmd = &cobra.Command{
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
cfg := &config.TcpProxyConf{}
|
||||
cfg := &config.TCPProxyConf{}
|
||||
var prefix string
|
||||
if user != "" {
|
||||
prefix = user + "."
|
||||
}
|
||||
cfg.ProxyName = prefix + proxyName
|
||||
cfg.ProxyType = consts.TcpProxy
|
||||
cfg.LocalIp = localIp
|
||||
cfg.ProxyType = consts.TCPProxy
|
||||
cfg.LocalIP = localIP
|
||||
cfg.LocalPort = localPort
|
||||
cfg.RemotePort = remotePort
|
||||
cfg.UseEncryption = useEncryption
|
||||
|
@@ -21,22 +21,15 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/models/consts"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/consts"
|
||||
)
|
||||
|
||||
func init() {
|
||||
tcpMuxCmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address")
|
||||
tcpMuxCmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user")
|
||||
tcpMuxCmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp or kcp or websocket")
|
||||
tcpMuxCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
|
||||
tcpMuxCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||
tcpMuxCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
|
||||
tcpMuxCmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
|
||||
tcpMuxCmd.PersistentFlags().BoolVarP(&disableLogColor, "disable_log_color", "", false, "disable log color in console")
|
||||
RegisterCommonFlags(tcpMuxCmd)
|
||||
|
||||
tcpMuxCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name")
|
||||
tcpMuxCmd.PersistentFlags().StringVarP(&localIp, "local_ip", "i", "127.0.0.1", "local ip")
|
||||
tcpMuxCmd.PersistentFlags().StringVarP(&localIP, "local_ip", "i", "127.0.0.1", "local ip")
|
||||
tcpMuxCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port")
|
||||
tcpMuxCmd.PersistentFlags().StringVarP(&customDomains, "custom_domain", "d", "", "custom domain")
|
||||
tcpMuxCmd.PersistentFlags().StringVarP(&subDomain, "sd", "", "", "sub domain")
|
||||
@@ -57,14 +50,14 @@ var tcpMuxCmd = &cobra.Command{
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
cfg := &config.TcpMuxProxyConf{}
|
||||
cfg := &config.TCPMuxProxyConf{}
|
||||
var prefix string
|
||||
if user != "" {
|
||||
prefix = user + "."
|
||||
}
|
||||
cfg.ProxyName = prefix + proxyName
|
||||
cfg.ProxyType = consts.TcpMuxProxy
|
||||
cfg.LocalIp = localIp
|
||||
cfg.ProxyType = consts.TCPMuxProxy
|
||||
cfg.LocalIP = localIP
|
||||
cfg.LocalPort = localPort
|
||||
cfg.CustomDomains = strings.Split(customDomains, ",")
|
||||
cfg.SubDomain = subDomain
|
||||
|
@@ -18,24 +18,17 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/consts"
|
||||
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/models/consts"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
udpCmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address")
|
||||
udpCmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user")
|
||||
udpCmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp or kcp or websocket")
|
||||
udpCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
|
||||
udpCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||
udpCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
|
||||
udpCmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
|
||||
udpCmd.PersistentFlags().BoolVarP(&disableLogColor, "disable_log_color", "", false, "disable log color in console")
|
||||
RegisterCommonFlags(udpCmd)
|
||||
|
||||
udpCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name")
|
||||
udpCmd.PersistentFlags().StringVarP(&localIp, "local_ip", "i", "127.0.0.1", "local ip")
|
||||
udpCmd.PersistentFlags().StringVarP(&localIP, "local_ip", "i", "127.0.0.1", "local ip")
|
||||
udpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port")
|
||||
udpCmd.PersistentFlags().IntVarP(&remotePort, "remote_port", "r", 0, "remote port")
|
||||
udpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
|
||||
@@ -54,14 +47,14 @@ var udpCmd = &cobra.Command{
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
cfg := &config.UdpProxyConf{}
|
||||
cfg := &config.UDPProxyConf{}
|
||||
var prefix string
|
||||
if user != "" {
|
||||
prefix = user + "."
|
||||
}
|
||||
cfg.ProxyName = prefix + proxyName
|
||||
cfg.ProxyType = consts.UdpProxy
|
||||
cfg.LocalIp = localIp
|
||||
cfg.ProxyType = consts.UDPProxy
|
||||
cfg.LocalIP = localIP
|
||||
cfg.LocalPort = localPort
|
||||
cfg.RemotePort = remotePort
|
||||
cfg.UseEncryption = useEncryption
|
||||
|
@@ -18,27 +18,20 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/consts"
|
||||
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/models/consts"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
xtcpCmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address")
|
||||
xtcpCmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user")
|
||||
xtcpCmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp or kcp or websocket")
|
||||
xtcpCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
|
||||
xtcpCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||
xtcpCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
|
||||
xtcpCmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
|
||||
xtcpCmd.PersistentFlags().BoolVarP(&disableLogColor, "disable_log_color", "", false, "disable log color in console")
|
||||
RegisterCommonFlags(xtcpCmd)
|
||||
|
||||
xtcpCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name")
|
||||
xtcpCmd.PersistentFlags().StringVarP(&role, "role", "", "server", "role")
|
||||
xtcpCmd.PersistentFlags().StringVarP(&sk, "sk", "", "", "secret key")
|
||||
xtcpCmd.PersistentFlags().StringVarP(&serverName, "server_name", "", "", "server name")
|
||||
xtcpCmd.PersistentFlags().StringVarP(&localIp, "local_ip", "i", "127.0.0.1", "local ip")
|
||||
xtcpCmd.PersistentFlags().StringVarP(&localIP, "local_ip", "i", "127.0.0.1", "local ip")
|
||||
xtcpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port")
|
||||
xtcpCmd.PersistentFlags().StringVarP(&bindAddr, "bind_addr", "", "", "bind addr")
|
||||
xtcpCmd.PersistentFlags().IntVarP(&bindPort, "bind_port", "", 0, "bind port")
|
||||
@@ -67,14 +60,14 @@ var xtcpCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
if role == "server" {
|
||||
cfg := &config.XtcpProxyConf{}
|
||||
cfg := &config.XTCPProxyConf{}
|
||||
cfg.ProxyName = prefix + proxyName
|
||||
cfg.ProxyType = consts.XtcpProxy
|
||||
cfg.ProxyType = consts.XTCPProxy
|
||||
cfg.UseEncryption = useEncryption
|
||||
cfg.UseCompression = useCompression
|
||||
cfg.Role = role
|
||||
cfg.Sk = sk
|
||||
cfg.LocalIp = localIp
|
||||
cfg.LocalIP = localIP
|
||||
cfg.LocalPort = localPort
|
||||
err = cfg.CheckForCli()
|
||||
if err != nil {
|
||||
@@ -83,9 +76,9 @@ var xtcpCmd = &cobra.Command{
|
||||
}
|
||||
proxyConfs[cfg.ProxyName] = cfg
|
||||
} else if role == "visitor" {
|
||||
cfg := &config.XtcpVisitorConf{}
|
||||
cfg := &config.XTCPVisitorConf{}
|
||||
cfg.ProxyName = prefix + proxyName
|
||||
cfg.ProxyType = consts.XtcpProxy
|
||||
cfg.ProxyType = consts.XTCPProxy
|
||||
cfg.UseEncryption = useEncryption
|
||||
cfg.UseCompression = useCompression
|
||||
cfg.Role = role
|
||||
|
@@ -21,7 +21,7 @@ import (
|
||||
"github.com/fatedier/golib/crypto"
|
||||
|
||||
_ "github.com/fatedier/frp/assets/frps/statik"
|
||||
_ "github.com/fatedier/frp/models/metrics"
|
||||
_ "github.com/fatedier/frp/pkg/metrics"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@@ -18,14 +18,14 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/fatedier/frp/models/auth"
|
||||
"github.com/fatedier/frp/models/config"
|
||||
"github.com/fatedier/frp/pkg/auth"
|
||||
"github.com/fatedier/frp/pkg/config"
|
||||
"github.com/fatedier/frp/pkg/util/log"
|
||||
"github.com/fatedier/frp/pkg/util/util"
|
||||
"github.com/fatedier/frp/pkg/util/version"
|
||||
"github.com/fatedier/frp/server"
|
||||
"github.com/fatedier/frp/utils/log"
|
||||
"github.com/fatedier/frp/utils/util"
|
||||
"github.com/fatedier/frp/utils/version"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -39,16 +39,17 @@ var (
|
||||
|
||||
bindAddr string
|
||||
bindPort int
|
||||
bindUdpPort int
|
||||
bindUDPPort int
|
||||
kcpBindPort int
|
||||
proxyBindAddr string
|
||||
vhostHttpPort int
|
||||
vhostHttpsPort int
|
||||
vhostHttpTimeout int64
|
||||
vhostHTTPPort int
|
||||
vhostHTTPSPort int
|
||||
vhostHTTPTimeout int64
|
||||
dashboardAddr string
|
||||
dashboardPort int
|
||||
dashboardUser string
|
||||
dashboardPwd string
|
||||
enablePrometheus bool
|
||||
assetsDir string
|
||||
logFile string
|
||||
logLevel string
|
||||
@@ -60,24 +61,26 @@ var (
|
||||
allowPorts string
|
||||
maxPoolCount int64
|
||||
maxPortsPerClient int64
|
||||
tlsOnly bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file of frps")
|
||||
rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frpc")
|
||||
rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frps")
|
||||
|
||||
rootCmd.PersistentFlags().StringVarP(&bindAddr, "bind_addr", "", "0.0.0.0", "bind address")
|
||||
rootCmd.PersistentFlags().IntVarP(&bindPort, "bind_port", "p", 7000, "bind port")
|
||||
rootCmd.PersistentFlags().IntVarP(&bindUdpPort, "bind_udp_port", "", 0, "bind udp port")
|
||||
rootCmd.PersistentFlags().IntVarP(&bindUDPPort, "bind_udp_port", "", 0, "bind udp port")
|
||||
rootCmd.PersistentFlags().IntVarP(&kcpBindPort, "kcp_bind_port", "", 0, "kcp bind udp port")
|
||||
rootCmd.PersistentFlags().StringVarP(&proxyBindAddr, "proxy_bind_addr", "", "0.0.0.0", "proxy bind address")
|
||||
rootCmd.PersistentFlags().IntVarP(&vhostHttpPort, "vhost_http_port", "", 0, "vhost http port")
|
||||
rootCmd.PersistentFlags().IntVarP(&vhostHttpsPort, "vhost_https_port", "", 0, "vhost https port")
|
||||
rootCmd.PersistentFlags().Int64VarP(&vhostHttpTimeout, "vhost_http_timeout", "", 60, "vhost http response header timeout")
|
||||
rootCmd.PersistentFlags().IntVarP(&vhostHTTPPort, "vhost_http_port", "", 0, "vhost http port")
|
||||
rootCmd.PersistentFlags().IntVarP(&vhostHTTPSPort, "vhost_https_port", "", 0, "vhost https port")
|
||||
rootCmd.PersistentFlags().Int64VarP(&vhostHTTPTimeout, "vhost_http_timeout", "", 60, "vhost http response header timeout")
|
||||
rootCmd.PersistentFlags().StringVarP(&dashboardAddr, "dashboard_addr", "", "0.0.0.0", "dasboard address")
|
||||
rootCmd.PersistentFlags().IntVarP(&dashboardPort, "dashboard_port", "", 0, "dashboard port")
|
||||
rootCmd.PersistentFlags().StringVarP(&dashboardUser, "dashboard_user", "", "admin", "dashboard user")
|
||||
rootCmd.PersistentFlags().StringVarP(&dashboardPwd, "dashboard_pwd", "", "admin", "dashboard password")
|
||||
rootCmd.PersistentFlags().BoolVarP(&enablePrometheus, "enable_prometheus", "", false, "enable prometheus dashboard")
|
||||
rootCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "log file")
|
||||
rootCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||
rootCmd.PersistentFlags().Int64VarP(&logMaxDays, "log_max_days", "", 3, "log max days")
|
||||
@@ -87,6 +90,7 @@ func init() {
|
||||
rootCmd.PersistentFlags().StringVarP(&subDomainHost, "subdomain_host", "", "", "subdomain host")
|
||||
rootCmd.PersistentFlags().StringVarP(&allowPorts, "allow_ports", "", "", "allow ports")
|
||||
rootCmd.PersistentFlags().Int64VarP(&maxPortsPerClient, "max_ports_per_client", "", 0, "max ports per client")
|
||||
rootCmd.PersistentFlags().BoolVarP(&tlsOnly, "tls_only", "", false, "frps tls only")
|
||||
}
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
@@ -101,6 +105,7 @@ var rootCmd = &cobra.Command{
|
||||
var cfg config.ServerCommonConf
|
||||
var err error
|
||||
if cfgFile != "" {
|
||||
log.Info("frps uses config file: %s", cfgFile)
|
||||
var content string
|
||||
content, err = config.GetRenderedConfFromFile(cfgFile)
|
||||
if err != nil {
|
||||
@@ -108,6 +113,7 @@ var rootCmd = &cobra.Command{
|
||||
}
|
||||
cfg, err = parseServerCommonCfg(CfgFileTypeIni, content)
|
||||
} else {
|
||||
log.Info("frps uses command line arguments for config")
|
||||
cfg, err = parseServerCommonCfg(CfgFileTypeCmd, "")
|
||||
}
|
||||
if err != nil {
|
||||
@@ -159,23 +165,25 @@ func parseServerCommonCfgFromCmd() (cfg config.ServerCommonConf, err error) {
|
||||
|
||||
cfg.BindAddr = bindAddr
|
||||
cfg.BindPort = bindPort
|
||||
cfg.BindUdpPort = bindUdpPort
|
||||
cfg.KcpBindPort = kcpBindPort
|
||||
cfg.BindUDPPort = bindUDPPort
|
||||
cfg.KCPBindPort = kcpBindPort
|
||||
cfg.ProxyBindAddr = proxyBindAddr
|
||||
cfg.VhostHttpPort = vhostHttpPort
|
||||
cfg.VhostHttpsPort = vhostHttpsPort
|
||||
cfg.VhostHttpTimeout = vhostHttpTimeout
|
||||
cfg.VhostHTTPPort = vhostHTTPPort
|
||||
cfg.VhostHTTPSPort = vhostHTTPSPort
|
||||
cfg.VhostHTTPTimeout = vhostHTTPTimeout
|
||||
cfg.DashboardAddr = dashboardAddr
|
||||
cfg.DashboardPort = dashboardPort
|
||||
cfg.DashboardUser = dashboardUser
|
||||
cfg.DashboardPwd = dashboardPwd
|
||||
cfg.EnablePrometheus = enablePrometheus
|
||||
cfg.LogFile = logFile
|
||||
cfg.LogLevel = logLevel
|
||||
cfg.LogMaxDays = logMaxDays
|
||||
cfg.SubDomainHost = subDomainHost
|
||||
cfg.TLSOnly = tlsOnly
|
||||
|
||||
// Only token authentication is supported in cmd mode
|
||||
cfg.AuthServerConfig = auth.GetDefaultAuthServerConf()
|
||||
cfg.ServerConfig = auth.GetDefaultServerConf()
|
||||
cfg.Token = token
|
||||
if len(allowPorts) > 0 {
|
||||
// e.g. 1000-2000,2001,2002,3000-4000
|
||||
@@ -206,7 +214,7 @@ func runServer(cfg config.ServerCommonConf) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info("start frps success")
|
||||
log.Info("frps started successfully")
|
||||
svr.Run()
|
||||
return
|
||||
}
|
||||
|
@@ -5,10 +5,11 @@
|
||||
server_addr = 0.0.0.0
|
||||
server_port = 7000
|
||||
|
||||
# if you want to connect frps by http proxy or socks5 proxy, you can set http_proxy here or in global environment variables
|
||||
# if you want to connect frps by http proxy or socks5 proxy or ntlm proxy, you can set http_proxy here or in global environment variables
|
||||
# it only works when protocol is tcp
|
||||
# http_proxy = http://user:passwd@192.168.1.128:8080
|
||||
# http_proxy = socks5://user:passwd@192.168.1.128:1080
|
||||
# http_proxy = ntlm://user:passwd@192.168.1.128:2080
|
||||
|
||||
# console or real logFile path like ./frpc.log
|
||||
log_file = ./frpc.log
|
||||
@@ -21,9 +22,31 @@ log_max_days = 3
|
||||
# disable log colors when log_file is console, default is false
|
||||
disable_log_color = false
|
||||
|
||||
# for authentication
|
||||
# for authentication, should be same as your frps.ini
|
||||
# authenticate_heartbeats specifies whether to include authentication token in heartbeats sent to frps. By default, this value is false.
|
||||
authenticate_heartbeats = false
|
||||
|
||||
# authenticate_new_work_conns specifies whether to include authentication token in new work connections sent to frps. By default, this value is false.
|
||||
authenticate_new_work_conns = false
|
||||
|
||||
# auth token
|
||||
token = 12345678
|
||||
|
||||
# oidc_client_id specifies the client ID to use to get a token in OIDC authentication if AuthenticationMethod == "oidc".
|
||||
# By default, this value is "".
|
||||
oidc_client_id =
|
||||
|
||||
# oidc_client_secret specifies the client secret to use to get a token in OIDC authentication if AuthenticationMethod == "oidc".
|
||||
# By default, this value is "".
|
||||
oidc_client_secret =
|
||||
|
||||
# oidc_audience specifies the audience of the token in OIDC authentication if AuthenticationMethod == "oidc". By default, this value is "".
|
||||
oidc_audience =
|
||||
|
||||
# oidc_token_endpoint_url specifies the URL which implements OIDC Token Endpoint.
|
||||
# It will be used to get an OIDC token if AuthenticationMethod == "oidc". By default, this value is "".
|
||||
oidc_token_endpoint_url =
|
||||
|
||||
# set admin address for control frpc's action by http api such as reload
|
||||
admin_addr = 127.0.0.1
|
||||
admin_port = 7400
|
||||
@@ -46,12 +69,16 @@ user = your_name
|
||||
login_fail_exit = true
|
||||
|
||||
# communication protocol used to connect to server
|
||||
# now it supports tcp and kcp and websocket, default is tcp
|
||||
# now it supports tcp, kcp and websocket, default is tcp
|
||||
protocol = tcp
|
||||
|
||||
# if tls_enable is true, frpc will connect frps by tls
|
||||
tls_enable = true
|
||||
|
||||
# tls_cert_file = client.crt
|
||||
# tls_key_file = client.key
|
||||
# tls_trusted_ca_file = ca.crt
|
||||
|
||||
# specify a dns server, so frpc will use this instead of default one
|
||||
# dns_server = 8.8.8.8
|
||||
|
||||
@@ -68,6 +95,11 @@ tls_enable = true
|
||||
meta_var1 = 123
|
||||
meta_var2 = 234
|
||||
|
||||
# specify udp packet size, unit is byte. If not set, the default value is 1500.
|
||||
# This parameter should be same between client and server.
|
||||
# It affects the udp and sudp proxy.
|
||||
udp_packet_size = 1500
|
||||
|
||||
# 'ssh' is the unique proxy name
|
||||
# if user in [common] section is not empty, it will be changed to {user}.{proxy} such as 'your_name.ssh'
|
||||
[ssh]
|
||||
|
@@ -23,7 +23,7 @@ vhost_https_port = 443
|
||||
# response header timeout(seconds) for vhost http server, default is 60s
|
||||
# vhost_http_timeout = 60
|
||||
|
||||
# TcpMuxHttpConnectPort specifies the port that the server listens for TCP
|
||||
# tcpmux_httpconnect_port specifies the port that the server listens for TCP
|
||||
# HTTP CONNECT requests. If the value is 0, the server will not multiplex TCP
|
||||
# requests on one single port. If it's not - it will listen on this value for
|
||||
# HTTP CONNECT requests. By default, this value is 0.
|
||||
@@ -44,6 +44,7 @@ enable_prometheus = true
|
||||
|
||||
# dashboard assets directory(only for debug mode)
|
||||
# assets_dir = ./static
|
||||
|
||||
# console or real logFile path like ./frps.log
|
||||
log_file = ./frps.log
|
||||
|
||||
@@ -58,12 +59,12 @@ disable_log_color = false
|
||||
# DetailedErrorsToClient defines whether to send the specific error (with debug info) to frpc. By default, this value is true.
|
||||
detailed_errors_to_client = true
|
||||
|
||||
# AuthenticationMethod specifies what authentication method to use authenticate frpc with frps.
|
||||
# authentication_method specifies what authentication method to use authenticate frpc with frps.
|
||||
# If "token" is specified - token will be read into login message.
|
||||
# If "oidc" is specified - OIDC (Open ID Connect) token will be issued using OIDC settings. By default, this value is "token".
|
||||
authentication_method = token
|
||||
|
||||
# AuthenticateHeartBeats specifies whether to include authentication token in heartbeats sent to frps. By default, this value is false.
|
||||
# authenticate_heartbeats specifies whether to include authentication token in heartbeats sent to frps. By default, this value is false.
|
||||
authenticate_heartbeats = false
|
||||
|
||||
# AuthenticateNewWorkConns specifies whether to include authentication token in new work connections sent to frps. By default, this value is false.
|
||||
@@ -72,25 +73,31 @@ authenticate_new_work_conns = false
|
||||
# auth token
|
||||
token = 12345678
|
||||
|
||||
# OidcClientId specifies the client ID to use to get a token in OIDC authentication if AuthenticationMethod == "oidc".
|
||||
# oidc_issuer specifies the issuer to verify OIDC tokens with.
|
||||
# By default, this value is "".
|
||||
oidc_client_id =
|
||||
oidc_issuer =
|
||||
|
||||
# OidcClientSecret specifies the client secret to use to get a token in OIDC authentication if AuthenticationMethod == "oidc".
|
||||
# oidc_audience specifies the audience OIDC tokens should contain when validated.
|
||||
# By default, this value is "".
|
||||
oidc_client_secret =
|
||||
oidc_audience =
|
||||
|
||||
# OidcAudience specifies the audience of the token in OIDC authentication if AuthenticationMethod == "oidc". By default, this value is "".
|
||||
oidc_audience =
|
||||
# oidc_skip_expiry_check specifies whether to skip checking if the OIDC token is expired.
|
||||
# By default, this value is false.
|
||||
oidc_skip_expiry_check = false
|
||||
|
||||
# OidcTokenEndpointUrl specifies the URL which implements OIDC Token Endpoint.
|
||||
# It will be used to get an OIDC token if AuthenticationMethod == "oidc". By default, this value is "".
|
||||
oidc_token_endpoint_url =
|
||||
|
||||
# oidc_skip_issuer_check specifies whether to skip checking if the OIDC token's issuer claim matches the issuer specified in OidcIssuer.
|
||||
# By default, this value is false.
|
||||
oidc_skip_issuer_check = false
|
||||
|
||||
# heartbeat configure, it's not recommended to modify the default value
|
||||
# the default value of heartbeat_timeout is 90
|
||||
# heartbeat_timeout = 90
|
||||
|
||||
# user_conn_timeout configure, it's not recommended to modify the default value
|
||||
# the default value of user_conn_timeout is 10
|
||||
# user_conn_timeout = 10
|
||||
|
||||
# only allow frpc to bind ports you list, if you set nothing, there won't be any limit
|
||||
allow_ports = 2000-3000,3001,3003,4000-50000
|
||||
|
||||
@@ -100,9 +107,13 @@ max_pool_count = 5
|
||||
# max ports can be used for each client, default value is 0 means no limit
|
||||
max_ports_per_client = 0
|
||||
|
||||
# TlsOnly specifies whether to only accept TLS-encrypted connections. By default, the value is false.
|
||||
# tls_only specifies whether to only accept TLS-encrypted connections. By default, the value is false.
|
||||
tls_only = false
|
||||
|
||||
# tls_cert_file = server.crt
|
||||
# tls_key_file = server.key
|
||||
# tls_trusted_ca_file = ca.crt
|
||||
|
||||
# if subdomain_host is not empty, you can set subdomain when type is http or https in frpc's configure file
|
||||
# when subdomain is test, the host used by routing is test.frps.com
|
||||
subdomain_host = frps.com
|
||||
@@ -113,6 +124,11 @@ tcp_mux = true
|
||||
# custom 404 page for HTTP requests
|
||||
# custom_404_page = /path/to/404.html
|
||||
|
||||
# specify udp packet size, unit is byte. If not set, the default value is 1500.
|
||||
# This parameter should be same between client and server.
|
||||
# It affects the udp and sudp proxy.
|
||||
udp_packet_size = 1500
|
||||
|
||||
[plugin.user-manager]
|
||||
addr = 127.0.0.1:9000
|
||||
path = /handler
|
||||
|
@@ -209,9 +209,10 @@ path = /handler
|
||||
ops = NewProxy
|
||||
```
|
||||
|
||||
addr: the address where the external RPC service listens on.
|
||||
path: http request url path for the POST request.
|
||||
ops: operations plugin needs to handle (e.g. "Login", "NewProxy", ...).
|
||||
- addr: the address where the external RPC service listens. Defaults to http. For https, specify the schema: `addr = https://127.0.0.1:9001`.
|
||||
- path: http request url path for the POST request.
|
||||
- ops: operations plugin needs to handle (e.g. "Login", "NewProxy", ...).
|
||||
- tls_verify: When the schema is https, we verify by default. Set this value to false if you want to skip verification.
|
||||
|
||||
### Metadata
|
||||
|
||||
|
14
dockerfiles/Dockerfile-for-frpc
Normal file
14
dockerfiles/Dockerfile-for-frpc
Normal file
@@ -0,0 +1,14 @@
|
||||
FROM alpine:3.12.0 AS temp
|
||||
|
||||
COPY bin/frpc /tmp
|
||||
|
||||
RUN chmod -R 777 /tmp/frpc
|
||||
|
||||
|
||||
FROM alpine:3.12.0
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=temp /tmp/frpc /usr/bin
|
||||
|
||||
ENTRYPOINT ["/usr/bin/frpc"]
|
14
dockerfiles/Dockerfile-for-frps
Normal file
14
dockerfiles/Dockerfile-for-frps
Normal file
@@ -0,0 +1,14 @@
|
||||
FROM alpine:3.12.0 AS temp
|
||||
|
||||
COPY bin/frps /tmp
|
||||
|
||||
RUN chmod -R 777 /tmp/frps
|
||||
|
||||
|
||||
FROM alpine:3.12.0
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=temp /tmp/frps /usr/bin
|
||||
|
||||
ENTRYPOINT ["/usr/bin/frps"]
|
14
go.mod
14
go.mod
@@ -1,14 +1,14 @@
|
||||
module github.com/fatedier/frp
|
||||
|
||||
go 1.12
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible
|
||||
github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb
|
||||
github.com/fatedier/golib v0.0.0-20181107124048-ff8cd814b049
|
||||
github.com/fatedier/golib v0.1.1-0.20200901083111-1f870741e185
|
||||
github.com/fatedier/kcp-go v2.0.4-0.20190803094908-fe8645b0a904+incompatible
|
||||
github.com/golang/snappy v0.0.0-20170215233205-553a64147049 // indirect
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/gorilla/mux v1.7.3
|
||||
github.com/gorilla/websocket v1.4.0
|
||||
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d
|
||||
@@ -16,22 +16,24 @@ require (
|
||||
github.com/klauspost/cpuid v1.2.0 // indirect
|
||||
github.com/klauspost/reedsolomon v1.9.1 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.4 // indirect
|
||||
github.com/onsi/ginkgo v1.12.3
|
||||
github.com/onsi/gomega v1.10.1
|
||||
github.com/pires/go-proxyproto v0.0.0-20190111085350-4d51b51e3bfc
|
||||
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
|
||||
github.com/prometheus/client_golang v1.4.1
|
||||
github.com/rakyll/statik v0.1.1
|
||||
github.com/rodaine/table v1.0.0
|
||||
github.com/spf13/cobra v0.0.3
|
||||
github.com/spf13/pflag v1.0.1 // indirect
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/templexxx/cpufeat v0.0.0-20170927014610-3794dfbfb047 // indirect
|
||||
github.com/templexxx/xor v0.0.0-20170926022130-0af8e873c554 // indirect
|
||||
github.com/tjfoc/gmsm v0.0.0-20171124023159-98aa888b79d8 // indirect
|
||||
github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec
|
||||
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae // indirect
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
golang.org/x/text v0.3.2 // indirect
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 // indirect
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
|
||||
gopkg.in/square/go-jose.v2 v2.4.1 // indirect
|
||||
k8s.io/apimachinery v0.18.3
|
||||
)
|
||||
|
117
go.sum
117
go.sum
@@ -1,4 +1,9 @@
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
@@ -16,39 +21,73 @@ github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHo
|
||||
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/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb h1:wCrNShQidLmvVWn/0PikGmpdP0vtQmnvyRg3ZBEhczw=
|
||||
github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb/go.mod h1:wx3gB6dbIfBRcucp94PI9Bt3I0F2c/MyNEWuhzpWiwk=
|
||||
github.com/fatedier/golib v0.0.0-20181107124048-ff8cd814b049 h1:teH578mf2ii42NHhIp3PhgvjU5bv+NFMq9fSQR8NaG8=
|
||||
github.com/fatedier/golib v0.0.0-20181107124048-ff8cd814b049/go.mod h1:DqIrnl0rp3Zybg9zbJmozTy1n8fYJoX+QoAj9slIkKM=
|
||||
github.com/fatedier/golib v0.1.1-0.20200901083111-1f870741e185 h1:2p4W5xYizIYwhiGQgeHOQcRD2O84j0tjD40P6gUCRrk=
|
||||
github.com/fatedier/golib v0.1.1-0.20200901083111-1f870741e185/go.mod h1:MUs+IH/MGJNz5Cj2JVJBPZBKw2exON7LzO3HrJHmGiQ=
|
||||
github.com/fatedier/kcp-go v2.0.4-0.20190803094908-fe8645b0a904+incompatible h1:ssXat9YXFvigNge/IkkZvFMn8yeYKFX+uI6wn2mLJ74=
|
||||
github.com/fatedier/kcp-go v2.0.4-0.20190803094908-fe8645b0a904+incompatible/go.mod h1:YpCOaxj7vvMThhIQ9AfTOPW2sfztQR5WDfs7AflSy4s=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
||||
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
||||
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
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 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20170215233205-553a64147049 h1:K9KHZbXKpGydfDN0aZrsoHpLJlZsBrGMFWbgLDGnPZk=
|
||||
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
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 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
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 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ=
|
||||
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
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/reedsolomon v1.9.1 h1:kYrT1MlR4JH6PqOpC+okdb9CDTcwEC/BqpzK4WFyXL8=
|
||||
@@ -60,6 +99,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
@@ -68,7 +108,22 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.12.3 h1:+RYp9QczoWz9zfUyLP/5SLXQVhfr6gZOoKGfQqHuLZQ=
|
||||
github.com/onsi/ginkgo v1.12.3/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/pires/go-proxyproto v0.0.0-20190111085350-4d51b51e3bfc h1:lNOt1SMsgHXTdpuGw+RpnJtzUcCb/oRKZP65pBy9pr8=
|
||||
github.com/pires/go-proxyproto v0.0.0-20190111085350-4d51b51e3bfc/go.mod h1:6/gX3+E/IYGa0wMORlSMla999awQFdbaeQCHjSMKIzY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -101,8 +156,9 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
@@ -120,43 +176,88 @@ github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec/go.mod h1:owBmyHYM
|
||||
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
|
||||
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/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-20181114220301-adae6a3d119a/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-20190228165749-92fc7df08ae7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
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-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/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-20181116152217-5ac8a444bdc5/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-20190422165155-953cdadca894/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-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/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 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 h1:OjiUf46hAmXblsZdnoSXsEUSKU8r1UEzcL5RVZ4gO9Y=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
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 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
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/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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/square/go-jose.v2 v2.4.1 h1:H0TmLt7/KmzlrDOpa1F+zr0Tk90PbJYBfsVUmRLrf9Y=
|
||||
gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
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.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
k8s.io/apimachinery v0.18.3 h1:pOGcbVAhxADgUYnjS08EFXs9QMl8qaH5U4fr5LGUrSk=
|
||||
k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
|
||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
|
15
hack/run-e2e.sh
Executable file
15
hack/run-e2e.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
ROOT=$(unset CDPATH && cd $(dirname "${BASH_SOURCE[0]}")/.. && pwd)
|
||||
|
||||
which ginkgo &> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ginkgo not found, try to install..."
|
||||
go get -u github.com/onsi/ginkgo/ginkgo
|
||||
fi
|
||||
|
||||
debug=false
|
||||
if [ x${DEBUG} == x"true" ]; then
|
||||
debug=true
|
||||
fi
|
||||
ginkgo -nodes=4 ${ROOT}/test/e2e -- -frpc-path=${ROOT}/bin/frpc -frps-path=${ROOT}/bin/frps -log-level=debug -debug=${debug}
|
@@ -17,8 +17,8 @@ package auth
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/fatedier/frp/models/consts"
|
||||
"github.com/fatedier/frp/models/msg"
|
||||
"github.com/fatedier/frp/pkg/consts"
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
|
||||
"github.com/vaughan0/go-ini"
|
||||
)
|
||||
@@ -72,42 +72,42 @@ func unmarshalBaseConfFromIni(conf ini.File) baseConfig {
|
||||
return cfg
|
||||
}
|
||||
|
||||
type AuthClientConfig struct {
|
||||
type ClientConfig struct {
|
||||
baseConfig
|
||||
oidcClientConfig
|
||||
tokenConfig
|
||||
}
|
||||
|
||||
func GetDefaultAuthClientConf() AuthClientConfig {
|
||||
return AuthClientConfig{
|
||||
func GetDefaultClientConf() ClientConfig {
|
||||
return ClientConfig{
|
||||
baseConfig: getDefaultBaseConf(),
|
||||
oidcClientConfig: getDefaultOidcClientConf(),
|
||||
tokenConfig: getDefaultTokenConf(),
|
||||
}
|
||||
}
|
||||
|
||||
func UnmarshalAuthClientConfFromIni(conf ini.File) (cfg AuthClientConfig) {
|
||||
func UnmarshalClientConfFromIni(conf ini.File) (cfg ClientConfig) {
|
||||
cfg.baseConfig = unmarshalBaseConfFromIni(conf)
|
||||
cfg.oidcClientConfig = unmarshalOidcClientConfFromIni(conf)
|
||||
cfg.tokenConfig = unmarshalTokenConfFromIni(conf)
|
||||
return cfg
|
||||
}
|
||||
|
||||
type AuthServerConfig struct {
|
||||
type ServerConfig struct {
|
||||
baseConfig
|
||||
oidcServerConfig
|
||||
tokenConfig
|
||||
}
|
||||
|
||||
func GetDefaultAuthServerConf() AuthServerConfig {
|
||||
return AuthServerConfig{
|
||||
func GetDefaultServerConf() ServerConfig {
|
||||
return ServerConfig{
|
||||
baseConfig: getDefaultBaseConf(),
|
||||
oidcServerConfig: getDefaultOidcServerConf(),
|
||||
tokenConfig: getDefaultTokenConf(),
|
||||
}
|
||||
}
|
||||
|
||||
func UnmarshalAuthServerConfFromIni(conf ini.File) (cfg AuthServerConfig) {
|
||||
func UnmarshalServerConfFromIni(conf ini.File) (cfg ServerConfig) {
|
||||
cfg.baseConfig = unmarshalBaseConfFromIni(conf)
|
||||
cfg.oidcServerConfig = unmarshalOidcServerConfFromIni(conf)
|
||||
cfg.tokenConfig = unmarshalTokenConfFromIni(conf)
|
||||
@@ -120,7 +120,7 @@ type Setter interface {
|
||||
SetNewWorkConn(*msg.NewWorkConn) error
|
||||
}
|
||||
|
||||
func NewAuthSetter(cfg AuthClientConfig) (authProvider Setter) {
|
||||
func NewAuthSetter(cfg ClientConfig) (authProvider Setter) {
|
||||
switch cfg.AuthenticationMethod {
|
||||
case consts.TokenAuthMethod:
|
||||
authProvider = NewTokenAuth(cfg.baseConfig, cfg.tokenConfig)
|
||||
@@ -139,7 +139,7 @@ type Verifier interface {
|
||||
VerifyNewWorkConn(*msg.NewWorkConn) error
|
||||
}
|
||||
|
||||
func NewAuthVerifier(cfg AuthServerConfig) (authVerifier Verifier) {
|
||||
func NewAuthVerifier(cfg ServerConfig) (authVerifier Verifier) {
|
||||
switch cfg.AuthenticationMethod {
|
||||
case consts.TokenAuthMethod:
|
||||
authVerifier = NewTokenAuth(cfg.baseConfig, cfg.tokenConfig)
|
@@ -18,7 +18,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/fatedier/frp/models/msg"
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
|
||||
"github.com/coreos/go-oidc"
|
||||
"github.com/vaughan0/go-ini"
|
||||
@@ -26,10 +26,10 @@ import (
|
||||
)
|
||||
|
||||
type oidcClientConfig struct {
|
||||
// OidcClientId specifies the client ID to use to get a token in OIDC
|
||||
// OidcClientID specifies the client ID to use to get a token in OIDC
|
||||
// authentication if AuthenticationMethod == "oidc". By default, this value
|
||||
// is "".
|
||||
OidcClientId string `json:"oidc_client_id"`
|
||||
OidcClientID string `json:"oidc_client_id"`
|
||||
// OidcClientSecret specifies the client secret to use to get a token in OIDC
|
||||
// authentication if AuthenticationMethod == "oidc". By default, this value
|
||||
// is "".
|
||||
@@ -37,18 +37,18 @@ type oidcClientConfig struct {
|
||||
// OidcAudience specifies the audience of the token in OIDC authentication
|
||||
//if AuthenticationMethod == "oidc". By default, this value is "".
|
||||
OidcAudience string `json:"oidc_audience"`
|
||||
// OidcTokenEndpointUrl specifies the URL which implements OIDC Token Endpoint.
|
||||
// OidcTokenEndpointURL specifies the URL which implements OIDC Token Endpoint.
|
||||
// It will be used to get an OIDC token if AuthenticationMethod == "oidc".
|
||||
// By default, this value is "".
|
||||
OidcTokenEndpointUrl string `json:"oidc_token_endpoint_url"`
|
||||
OidcTokenEndpointURL string `json:"oidc_token_endpoint_url"`
|
||||
}
|
||||
|
||||
func getDefaultOidcClientConf() oidcClientConfig {
|
||||
return oidcClientConfig{
|
||||
OidcClientId: "",
|
||||
OidcClientID: "",
|
||||
OidcClientSecret: "",
|
||||
OidcAudience: "",
|
||||
OidcTokenEndpointUrl: "",
|
||||
OidcTokenEndpointURL: "",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ func unmarshalOidcClientConfFromIni(conf ini.File) oidcClientConfig {
|
||||
cfg := getDefaultOidcClientConf()
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "oidc_client_id"); ok {
|
||||
cfg.OidcClientId = tmpStr
|
||||
cfg.OidcClientID = tmpStr
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "oidc_client_secret"); ok {
|
||||
@@ -73,7 +73,7 @@ func unmarshalOidcClientConfFromIni(conf ini.File) oidcClientConfig {
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "oidc_token_endpoint_url"); ok {
|
||||
cfg.OidcTokenEndpointUrl = tmpStr
|
||||
cfg.OidcTokenEndpointURL = tmpStr
|
||||
}
|
||||
|
||||
return cfg
|
||||
@@ -148,10 +148,10 @@ type OidcAuthProvider struct {
|
||||
|
||||
func NewOidcAuthSetter(baseCfg baseConfig, cfg oidcClientConfig) *OidcAuthProvider {
|
||||
tokenGenerator := &clientcredentials.Config{
|
||||
ClientID: cfg.OidcClientId,
|
||||
ClientID: cfg.OidcClientID,
|
||||
ClientSecret: cfg.OidcClientSecret,
|
||||
Scopes: []string{cfg.OidcAudience},
|
||||
TokenURL: cfg.OidcTokenEndpointUrl,
|
||||
TokenURL: cfg.OidcTokenEndpointURL,
|
||||
}
|
||||
|
||||
return &OidcAuthProvider{
|
@@ -18,8 +18,8 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/models/msg"
|
||||
"github.com/fatedier/frp/utils/util"
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
"github.com/fatedier/frp/pkg/util/util"
|
||||
|
||||
"github.com/vaughan0/go-ini"
|
||||
)
|
@@ -20,26 +20,26 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
ini "github.com/vaughan0/go-ini"
|
||||
"github.com/fatedier/frp/pkg/auth"
|
||||
|
||||
"github.com/fatedier/frp/models/auth"
|
||||
ini "github.com/vaughan0/go-ini"
|
||||
)
|
||||
|
||||
// ClientCommonConf contains information for a client service. It is
|
||||
// recommended to use GetDefaultClientConf instead of creating this object
|
||||
// directly, so that all unspecified fields have reasonable default values.
|
||||
type ClientCommonConf struct {
|
||||
auth.AuthClientConfig
|
||||
auth.ClientConfig
|
||||
// ServerAddr specifies the address of the server to connect to. By
|
||||
// default, this value is "0.0.0.0".
|
||||
ServerAddr string `json:"server_addr"`
|
||||
// ServerPort specifies the port to connect to the server on. By default,
|
||||
// this value is 7000.
|
||||
ServerPort int `json:"server_port"`
|
||||
// HttpProxy specifies a proxy address to connect to the server through. If
|
||||
// HTTPProxy specifies a proxy address to connect to the server through. If
|
||||
// this value is "", the server will be connected to directly. By default,
|
||||
// this value is read from the "http_proxy" environment variable.
|
||||
HttpProxy string `json:"http_proxy"`
|
||||
HTTPProxy string `json:"http_proxy"`
|
||||
// LogFile specifies a file where logs will be written to. This value will
|
||||
// only be used if LogWay is set appropriately. By default, this value is
|
||||
// "console".
|
||||
@@ -79,18 +79,18 @@ type ClientCommonConf struct {
|
||||
// PoolCount specifies the number of connections the client will make to
|
||||
// the server in advance. By default, this value is 0.
|
||||
PoolCount int `json:"pool_count"`
|
||||
// TcpMux toggles TCP stream multiplexing. This allows multiple requests
|
||||
// TCPMux toggles TCP stream multiplexing. This allows multiple requests
|
||||
// from a client to share a single TCP connection. If this value is true,
|
||||
// the server must have TCP multiplexing enabled as well. By default, this
|
||||
// value is true.
|
||||
TcpMux bool `json:"tcp_mux"`
|
||||
TCPMux bool `json:"tcp_mux"`
|
||||
// User specifies a prefix for proxy names to distinguish them from other
|
||||
// clients. If this value is not "", proxy names will automatically be
|
||||
// changed to "{user}.{proxy_name}". By default, this value is "".
|
||||
User string `json:"user"`
|
||||
// DnsServer specifies a DNS server address for FRPC to use. If this value
|
||||
// DNSServer specifies a DNS server address for FRPC to use. If this value
|
||||
// is "", the default DNS will be used. By default, this value is "".
|
||||
DnsServer string `json:"dns_server"`
|
||||
DNSServer string `json:"dns_server"`
|
||||
// LoginFailExit controls whether or not the client should exit after a
|
||||
// failed login attempt. If false, the client will retry until a login
|
||||
// attempt succeeds. By default, this value is true.
|
||||
@@ -100,22 +100,37 @@ type ClientCommonConf struct {
|
||||
// set.
|
||||
Start map[string]struct{} `json:"start"`
|
||||
// Protocol specifies the protocol to use when interacting with the server.
|
||||
// Valid values are "tcp", "kcp", and "websocket". By default, this value
|
||||
// Valid values are "tcp", "kcp" and "websocket". By default, this value
|
||||
// is "tcp".
|
||||
Protocol string `json:"protocol"`
|
||||
// TLSEnable specifies whether or not TLS should be used when communicating
|
||||
// with the server.
|
||||
// with the server. If "tls_cert_file" and "tls_key_file" are valid,
|
||||
// client will load the supplied tls configuration.
|
||||
TLSEnable bool `json:"tls_enable"`
|
||||
// ClientTLSCertPath specifies the path of the cert file that client will
|
||||
// load. It only works when "tls_enable" is true and "tls_key_file" is valid.
|
||||
TLSCertFile string `json:"tls_cert_file"`
|
||||
// ClientTLSKeyPath specifies the path of the secret key file that client
|
||||
// will load. It only works when "tls_enable" is true and "tls_cert_file"
|
||||
// are valid.
|
||||
TLSKeyFile string `json:"tls_key_file"`
|
||||
// TrustedCaFile specifies the path of the trusted ca file that will load.
|
||||
// It only works when "tls_enable" is valid and tls configuration of server
|
||||
// has been specified.
|
||||
TLSTrustedCaFile string `json:"tls_trusted_ca_file"`
|
||||
// HeartBeatInterval specifies at what interval heartbeats are sent to the
|
||||
// server, in seconds. It is not recommended to change this value. By
|
||||
// default, this value is 30.
|
||||
HeartBeatInterval int64 `json:"heartbeat_interval"`
|
||||
HeartbeatInterval int64 `json:"heartbeat_interval"`
|
||||
// HeartBeatTimeout specifies the maximum allowed heartbeat response delay
|
||||
// before the connection is terminated, in seconds. It is not recommended
|
||||
// to change this value. By default, this value is 90.
|
||||
HeartBeatTimeout int64 `json:"heartbeat_timeout"`
|
||||
HeartbeatTimeout int64 `json:"heartbeat_timeout"`
|
||||
// Client meta info
|
||||
Metas map[string]string `json:"metas"`
|
||||
// UDPPacketSize specifies the udp packet size
|
||||
// By default, this value is 1500
|
||||
UDPPacketSize int64 `json:"udp_packet_size"`
|
||||
}
|
||||
|
||||
// GetDefaultClientConf returns a client configuration with default values.
|
||||
@@ -123,7 +138,7 @@ func GetDefaultClientConf() ClientCommonConf {
|
||||
return ClientCommonConf{
|
||||
ServerAddr: "0.0.0.0",
|
||||
ServerPort: 7000,
|
||||
HttpProxy: os.Getenv("http_proxy"),
|
||||
HTTPProxy: os.Getenv("http_proxy"),
|
||||
LogFile: "console",
|
||||
LogWay: "console",
|
||||
LogLevel: "info",
|
||||
@@ -135,16 +150,20 @@ func GetDefaultClientConf() ClientCommonConf {
|
||||
AdminPwd: "",
|
||||
AssetsDir: "",
|
||||
PoolCount: 1,
|
||||
TcpMux: true,
|
||||
TCPMux: true,
|
||||
User: "",
|
||||
DnsServer: "",
|
||||
DNSServer: "",
|
||||
LoginFailExit: true,
|
||||
Start: make(map[string]struct{}),
|
||||
Protocol: "tcp",
|
||||
TLSEnable: false,
|
||||
HeartBeatInterval: 30,
|
||||
HeartBeatTimeout: 90,
|
||||
TLSCertFile: "",
|
||||
TLSKeyFile: "",
|
||||
TLSTrustedCaFile: "",
|
||||
HeartbeatInterval: 30,
|
||||
HeartbeatTimeout: 90,
|
||||
Metas: make(map[string]string),
|
||||
UDPPacketSize: 1500,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +175,7 @@ func UnmarshalClientConfFromIni(content string) (cfg ClientCommonConf, err error
|
||||
return ClientCommonConf{}, fmt.Errorf("parse ini conf file error: %v", err)
|
||||
}
|
||||
|
||||
cfg.AuthClientConfig = auth.UnmarshalAuthClientConfFromIni(conf)
|
||||
cfg.ClientConfig = auth.UnmarshalClientConfFromIni(conf)
|
||||
|
||||
var (
|
||||
tmpStr string
|
||||
@@ -181,7 +200,7 @@ func UnmarshalClientConfFromIni(content string) (cfg ClientCommonConf, err error
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "http_proxy"); ok {
|
||||
cfg.HttpProxy = tmpStr
|
||||
cfg.HTTPProxy = tmpStr
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "log_file"); ok {
|
||||
@@ -235,9 +254,9 @@ func UnmarshalClientConfFromIni(content string) (cfg ClientCommonConf, err error
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "tcp_mux"); ok && tmpStr == "false" {
|
||||
cfg.TcpMux = false
|
||||
cfg.TCPMux = false
|
||||
} else {
|
||||
cfg.TcpMux = true
|
||||
cfg.TCPMux = true
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "user"); ok {
|
||||
@@ -245,7 +264,7 @@ func UnmarshalClientConfFromIni(content string) (cfg ClientCommonConf, err error
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "dns_server"); ok {
|
||||
cfg.DnsServer = tmpStr
|
||||
cfg.DNSServer = tmpStr
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "start"); ok {
|
||||
@@ -276,40 +295,71 @@ func UnmarshalClientConfFromIni(content string) (cfg ClientCommonConf, err error
|
||||
cfg.TLSEnable = false
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "tls_cert_file"); ok {
|
||||
cfg.TLSCertFile = tmpStr
|
||||
}
|
||||
|
||||
if tmpStr, ok := conf.Get("common", "tls_key_file"); ok {
|
||||
cfg.TLSKeyFile = tmpStr
|
||||
}
|
||||
|
||||
if tmpStr, ok := conf.Get("common", "tls_trusted_ca_file"); ok {
|
||||
cfg.TLSTrustedCaFile = tmpStr
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "heartbeat_timeout"); ok {
|
||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||
err = fmt.Errorf("Parse conf error: invalid heartbeat_timeout")
|
||||
return
|
||||
} else {
|
||||
cfg.HeartBeatTimeout = v
|
||||
}
|
||||
cfg.HeartbeatTimeout = v
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "heartbeat_interval"); ok {
|
||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||
err = fmt.Errorf("Parse conf error: invalid heartbeat_interval")
|
||||
return
|
||||
} else {
|
||||
cfg.HeartBeatInterval = v
|
||||
}
|
||||
cfg.HeartbeatInterval = v
|
||||
}
|
||||
for k, v := range conf.Section("common") {
|
||||
if strings.HasPrefix(k, "meta_") {
|
||||
cfg.Metas[strings.TrimPrefix(k, "meta_")] = v
|
||||
}
|
||||
}
|
||||
if tmpStr, ok = conf.Get("common", "udp_packet_size"); ok {
|
||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||
err = fmt.Errorf("Parse conf error: invalid udp_packet_size")
|
||||
return
|
||||
}
|
||||
cfg.UDPPacketSize = v
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *ClientCommonConf) Check() (err error) {
|
||||
if cfg.HeartBeatInterval <= 0 {
|
||||
if cfg.HeartbeatInterval <= 0 {
|
||||
err = fmt.Errorf("Parse conf error: invalid heartbeat_interval")
|
||||
return
|
||||
}
|
||||
|
||||
if cfg.HeartBeatTimeout < cfg.HeartBeatInterval {
|
||||
if cfg.HeartbeatTimeout < cfg.HeartbeatInterval {
|
||||
err = fmt.Errorf("Parse conf error: invalid heartbeat_timeout, heartbeat_timeout is less than heartbeat_interval")
|
||||
return
|
||||
}
|
||||
|
||||
if cfg.TLSEnable == false {
|
||||
if cfg.TLSCertFile != "" {
|
||||
fmt.Println("WARNING! tls_cert_file is invalid when tls_enable is false")
|
||||
}
|
||||
|
||||
if cfg.TLSKeyFile != "" {
|
||||
fmt.Println("WARNING! tls_key_file is invalid when tls_enable is false")
|
||||
}
|
||||
|
||||
if cfg.TLSTrustedCaFile != "" {
|
||||
fmt.Println("WARNING! tls_trusted_ca_file is invalid when tls_enable is false")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
@@ -20,9 +20,9 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/fatedier/frp/models/consts"
|
||||
"github.com/fatedier/frp/models/msg"
|
||||
"github.com/fatedier/frp/utils/util"
|
||||
"github.com/fatedier/frp/pkg/consts"
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
"github.com/fatedier/frp/pkg/util/util"
|
||||
|
||||
ini "github.com/vaughan0/go-ini"
|
||||
)
|
||||
@@ -33,14 +33,14 @@ var (
|
||||
|
||||
func init() {
|
||||
proxyConfTypeMap = make(map[string]reflect.Type)
|
||||
proxyConfTypeMap[consts.TcpProxy] = reflect.TypeOf(TcpProxyConf{})
|
||||
proxyConfTypeMap[consts.TcpMuxProxy] = reflect.TypeOf(TcpMuxProxyConf{})
|
||||
proxyConfTypeMap[consts.UdpProxy] = reflect.TypeOf(UdpProxyConf{})
|
||||
proxyConfTypeMap[consts.HttpProxy] = reflect.TypeOf(HttpProxyConf{})
|
||||
proxyConfTypeMap[consts.HttpsProxy] = reflect.TypeOf(HttpsProxyConf{})
|
||||
proxyConfTypeMap[consts.StcpProxy] = reflect.TypeOf(StcpProxyConf{})
|
||||
proxyConfTypeMap[consts.XtcpProxy] = reflect.TypeOf(XtcpProxyConf{})
|
||||
proxyConfTypeMap[consts.SudpProxy] = reflect.TypeOf(SudpProxyConf{})
|
||||
proxyConfTypeMap[consts.TCPProxy] = reflect.TypeOf(TCPProxyConf{})
|
||||
proxyConfTypeMap[consts.TCPMuxProxy] = reflect.TypeOf(TCPMuxProxyConf{})
|
||||
proxyConfTypeMap[consts.UDPProxy] = reflect.TypeOf(UDPProxyConf{})
|
||||
proxyConfTypeMap[consts.HTTPProxy] = reflect.TypeOf(HTTPProxyConf{})
|
||||
proxyConfTypeMap[consts.HTTPSProxy] = reflect.TypeOf(HTTPSProxyConf{})
|
||||
proxyConfTypeMap[consts.STCPProxy] = reflect.TypeOf(STCPProxyConf{})
|
||||
proxyConfTypeMap[consts.XTCPProxy] = reflect.TypeOf(XTCPProxyConf{})
|
||||
proxyConfTypeMap[consts.SUDPProxy] = reflect.TypeOf(SUDPProxyConf{})
|
||||
}
|
||||
|
||||
// NewConfByType creates a empty ProxyConf object by proxyType.
|
||||
@@ -66,7 +66,7 @@ type ProxyConf interface {
|
||||
|
||||
func NewProxyConfFromMsg(pMsg *msg.NewProxy, serverCfg ServerCommonConf) (cfg ProxyConf, err error) {
|
||||
if pMsg.ProxyType == "" {
|
||||
pMsg.ProxyType = consts.TcpProxy
|
||||
pMsg.ProxyType = consts.TCPProxy
|
||||
}
|
||||
|
||||
cfg = NewConfByType(pMsg.ProxyType)
|
||||
@@ -82,8 +82,8 @@ func NewProxyConfFromMsg(pMsg *msg.NewProxy, serverCfg ServerCommonConf) (cfg Pr
|
||||
func NewProxyConfFromIni(prefix string, name string, section ini.Section) (cfg ProxyConf, err error) {
|
||||
proxyType := section["type"]
|
||||
if proxyType == "" {
|
||||
proxyType = consts.TcpProxy
|
||||
section["type"] = consts.TcpProxy
|
||||
proxyType = consts.TCPProxy
|
||||
section["type"] = consts.TCPProxy
|
||||
}
|
||||
cfg = NewConfByType(proxyType)
|
||||
if cfg == nil {
|
||||
@@ -210,14 +210,14 @@ func (cfg *BaseProxyConf) UnmarshalFromIni(prefix string, name string, section i
|
||||
}
|
||||
|
||||
if cfg.HealthCheckType == "tcp" && cfg.Plugin == "" {
|
||||
cfg.HealthCheckAddr = cfg.LocalIp + fmt.Sprintf(":%d", cfg.LocalPort)
|
||||
cfg.HealthCheckAddr = cfg.LocalIP + fmt.Sprintf(":%d", cfg.LocalPort)
|
||||
}
|
||||
if cfg.HealthCheckType == "http" && cfg.Plugin == "" && cfg.HealthCheckUrl != "" {
|
||||
s := fmt.Sprintf("http://%s:%d", cfg.LocalIp, cfg.LocalPort)
|
||||
if !strings.HasPrefix(cfg.HealthCheckUrl, "/") {
|
||||
if cfg.HealthCheckType == "http" && cfg.Plugin == "" && cfg.HealthCheckURL != "" {
|
||||
s := fmt.Sprintf("http://%s:%d", cfg.LocalIP, cfg.LocalPort)
|
||||
if !strings.HasPrefix(cfg.HealthCheckURL, "/") {
|
||||
s += "/"
|
||||
}
|
||||
cfg.HealthCheckUrl = s + cfg.HealthCheckUrl
|
||||
cfg.HealthCheckURL = s + cfg.HealthCheckURL
|
||||
}
|
||||
|
||||
cfg.Metas = make(map[string]string)
|
||||
@@ -280,9 +280,8 @@ func (cfg *BindInfoConf) UnmarshalFromIni(prefix string, name string, section in
|
||||
if tmpStr, ok = section["remote_port"]; ok {
|
||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||
return fmt.Errorf("Parse conf error: proxy [%s] remote_port error", name)
|
||||
} else {
|
||||
cfg.RemotePort = int(v)
|
||||
}
|
||||
cfg.RemotePort = int(v)
|
||||
} else {
|
||||
return fmt.Errorf("Parse conf error: proxy [%s] remote_port not found", name)
|
||||
}
|
||||
@@ -377,8 +376,8 @@ func (cfg *DomainConf) checkForSvr(serverCfg ServerCommonConf) (err error) {
|
||||
// LocalSvrConf configures what location the client will proxy to, or what
|
||||
// plugin will be used.
|
||||
type LocalSvrConf struct {
|
||||
// LocalIp specifies the IP address or host name to proxy to.
|
||||
LocalIp string `json:"local_ip"`
|
||||
// LocalIP specifies the IP address or host name to proxy to.
|
||||
LocalIP string `json:"local_ip"`
|
||||
// LocalPort specifies the port to proxy to.
|
||||
LocalPort int `json:"local_port"`
|
||||
|
||||
@@ -392,7 +391,7 @@ type LocalSvrConf struct {
|
||||
}
|
||||
|
||||
func (cfg *LocalSvrConf) compare(cmp *LocalSvrConf) bool {
|
||||
if cfg.LocalIp != cmp.LocalIp ||
|
||||
if cfg.LocalIP != cmp.LocalIP ||
|
||||
cfg.LocalPort != cmp.LocalPort {
|
||||
return false
|
||||
}
|
||||
@@ -420,8 +419,8 @@ func (cfg *LocalSvrConf) UnmarshalFromIni(prefix string, name string, section in
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if cfg.LocalIp = section["local_ip"]; cfg.LocalIp == "" {
|
||||
cfg.LocalIp = "127.0.0.1"
|
||||
if cfg.LocalIP = section["local_ip"]; cfg.LocalIP == "" {
|
||||
cfg.LocalIP = "127.0.0.1"
|
||||
}
|
||||
|
||||
if tmpStr, ok := section["local_port"]; ok {
|
||||
@@ -437,7 +436,7 @@ func (cfg *LocalSvrConf) UnmarshalFromIni(prefix string, name string, section in
|
||||
|
||||
func (cfg *LocalSvrConf) checkForCli() (err error) {
|
||||
if cfg.Plugin == "" {
|
||||
if cfg.LocalIp == "" {
|
||||
if cfg.LocalIP == "" {
|
||||
err = fmt.Errorf("local ip or plugin is required")
|
||||
return
|
||||
}
|
||||
@@ -460,7 +459,7 @@ type HealthCheckConf struct {
|
||||
// server. If a connection cannot be established, the health check fails.
|
||||
//
|
||||
// If the type is "http", a GET request will be made to the endpoint
|
||||
// specified by HealthCheckUrl. If the response is not a 200, the health
|
||||
// specified by HealthCheckURL. If the response is not a 200, the health
|
||||
// check fails.
|
||||
HealthCheckType string `json:"health_check_type"` // tcp | http
|
||||
// HealthCheckTimeoutS specifies the number of seconds to wait for a health
|
||||
@@ -473,9 +472,9 @@ type HealthCheckConf struct {
|
||||
// HealthCheckIntervalS specifies the time in seconds between health
|
||||
// checks. By default, this value is 10.
|
||||
HealthCheckIntervalS int `json:"health_check_interval_s"`
|
||||
// HealthCheckUrl specifies the address to send health checks to if the
|
||||
// HealthCheckURL specifies the address to send health checks to if the
|
||||
// health check type is "http".
|
||||
HealthCheckUrl string `json:"health_check_url"`
|
||||
HealthCheckURL string `json:"health_check_url"`
|
||||
// HealthCheckAddr specifies the address to connect to if the health check
|
||||
// type is "tcp".
|
||||
HealthCheckAddr string `json:"-"`
|
||||
@@ -486,7 +485,7 @@ func (cfg *HealthCheckConf) compare(cmp *HealthCheckConf) bool {
|
||||
cfg.HealthCheckTimeoutS != cmp.HealthCheckTimeoutS ||
|
||||
cfg.HealthCheckMaxFailed != cmp.HealthCheckMaxFailed ||
|
||||
cfg.HealthCheckIntervalS != cmp.HealthCheckIntervalS ||
|
||||
cfg.HealthCheckUrl != cmp.HealthCheckUrl {
|
||||
cfg.HealthCheckURL != cmp.HealthCheckURL {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@@ -494,7 +493,7 @@ func (cfg *HealthCheckConf) compare(cmp *HealthCheckConf) bool {
|
||||
|
||||
func (cfg *HealthCheckConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
cfg.HealthCheckType = section["health_check_type"]
|
||||
cfg.HealthCheckUrl = section["health_check_url"]
|
||||
cfg.HealthCheckURL = section["health_check_url"]
|
||||
|
||||
if tmpStr, ok := section["health_check_timeout_s"]; ok {
|
||||
if cfg.HealthCheckTimeoutS, err = strconv.Atoi(tmpStr); err != nil {
|
||||
@@ -521,7 +520,7 @@ func (cfg *HealthCheckConf) checkForCli() error {
|
||||
return fmt.Errorf("unsupport health check type")
|
||||
}
|
||||
if cfg.HealthCheckType != "" {
|
||||
if cfg.HealthCheckType == "http" && cfg.HealthCheckUrl == "" {
|
||||
if cfg.HealthCheckType == "http" && cfg.HealthCheckURL == "" {
|
||||
return fmt.Errorf("health_check_url is required for health check type 'http'")
|
||||
}
|
||||
}
|
||||
@@ -529,13 +528,13 @@ func (cfg *HealthCheckConf) checkForCli() error {
|
||||
}
|
||||
|
||||
// TCP
|
||||
type TcpProxyConf struct {
|
||||
type TCPProxyConf struct {
|
||||
BaseProxyConf
|
||||
BindInfoConf
|
||||
}
|
||||
|
||||
func (cfg *TcpProxyConf) Compare(cmp ProxyConf) bool {
|
||||
cmpConf, ok := cmp.(*TcpProxyConf)
|
||||
func (cfg *TCPProxyConf) Compare(cmp ProxyConf) bool {
|
||||
cmpConf, ok := cmp.(*TCPProxyConf)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -547,12 +546,12 @@ func (cfg *TcpProxyConf) Compare(cmp ProxyConf) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (cfg *TcpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||
func (cfg *TCPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
|
||||
cfg.BindInfoConf.UnmarshalFromMsg(pMsg)
|
||||
}
|
||||
|
||||
func (cfg *TcpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
func (cfg *TCPProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -562,30 +561,30 @@ func (cfg *TcpProxyConf) UnmarshalFromIni(prefix string, name string, section in
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *TcpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||
func (cfg *TCPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||
cfg.BaseProxyConf.MarshalToMsg(pMsg)
|
||||
cfg.BindInfoConf.MarshalToMsg(pMsg)
|
||||
}
|
||||
|
||||
func (cfg *TcpProxyConf) CheckForCli() (err error) {
|
||||
func (cfg *TCPProxyConf) CheckForCli() (err error) {
|
||||
if err = cfg.BaseProxyConf.checkForCli(); err != nil {
|
||||
return err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *TcpProxyConf) CheckForSvr(serverCfg ServerCommonConf) error { return nil }
|
||||
func (cfg *TCPProxyConf) CheckForSvr(serverCfg ServerCommonConf) error { return nil }
|
||||
|
||||
// TCP Multiplexer
|
||||
type TcpMuxProxyConf struct {
|
||||
type TCPMuxProxyConf struct {
|
||||
BaseProxyConf
|
||||
DomainConf
|
||||
|
||||
Multiplexer string `json:"multiplexer"`
|
||||
}
|
||||
|
||||
func (cfg *TcpMuxProxyConf) Compare(cmp ProxyConf) bool {
|
||||
cmpConf, ok := cmp.(*TcpMuxProxyConf)
|
||||
func (cfg *TCPMuxProxyConf) Compare(cmp ProxyConf) bool {
|
||||
cmpConf, ok := cmp.(*TCPMuxProxyConf)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -598,13 +597,13 @@ func (cfg *TcpMuxProxyConf) Compare(cmp ProxyConf) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (cfg *TcpMuxProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||
func (cfg *TCPMuxProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
|
||||
cfg.DomainConf.UnmarshalFromMsg(pMsg)
|
||||
cfg.Multiplexer = pMsg.Multiplexer
|
||||
}
|
||||
|
||||
func (cfg *TcpMuxProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
func (cfg *TCPMuxProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -613,37 +612,37 @@ func (cfg *TcpMuxProxyConf) UnmarshalFromIni(prefix string, name string, section
|
||||
}
|
||||
|
||||
cfg.Multiplexer = section["multiplexer"]
|
||||
if cfg.Multiplexer != consts.HttpConnectTcpMultiplexer {
|
||||
if cfg.Multiplexer != consts.HTTPConnectTCPMultiplexer {
|
||||
return fmt.Errorf("parse conf error: proxy [%s] incorrect multiplexer [%s]", name, cfg.Multiplexer)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *TcpMuxProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||
func (cfg *TCPMuxProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||
cfg.BaseProxyConf.MarshalToMsg(pMsg)
|
||||
cfg.DomainConf.MarshalToMsg(pMsg)
|
||||
pMsg.Multiplexer = cfg.Multiplexer
|
||||
}
|
||||
|
||||
func (cfg *TcpMuxProxyConf) CheckForCli() (err error) {
|
||||
func (cfg *TCPMuxProxyConf) CheckForCli() (err error) {
|
||||
if err = cfg.BaseProxyConf.checkForCli(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = cfg.DomainConf.checkForCli(); err != nil {
|
||||
return err
|
||||
}
|
||||
if cfg.Multiplexer != consts.HttpConnectTcpMultiplexer {
|
||||
if cfg.Multiplexer != consts.HTTPConnectTCPMultiplexer {
|
||||
return fmt.Errorf("parse conf error: incorrect multiplexer [%s]", cfg.Multiplexer)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *TcpMuxProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
|
||||
if cfg.Multiplexer != consts.HttpConnectTcpMultiplexer {
|
||||
func (cfg *TCPMuxProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
|
||||
if cfg.Multiplexer != consts.HTTPConnectTCPMultiplexer {
|
||||
return fmt.Errorf("proxy [%s] incorrect multiplexer [%s]", cfg.ProxyName, cfg.Multiplexer)
|
||||
}
|
||||
|
||||
if cfg.Multiplexer == consts.HttpConnectTcpMultiplexer && serverCfg.TcpMuxHttpConnectPort == 0 {
|
||||
if cfg.Multiplexer == consts.HTTPConnectTCPMultiplexer && serverCfg.TCPMuxHTTPConnectPort == 0 {
|
||||
return fmt.Errorf("proxy [%s] type [tcpmux] with multiplexer [httpconnect] requires tcpmux_httpconnect_port configuration", cfg.ProxyName)
|
||||
}
|
||||
|
||||
@@ -655,13 +654,13 @@ func (cfg *TcpMuxProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error)
|
||||
}
|
||||
|
||||
// UDP
|
||||
type UdpProxyConf struct {
|
||||
type UDPProxyConf struct {
|
||||
BaseProxyConf
|
||||
BindInfoConf
|
||||
}
|
||||
|
||||
func (cfg *UdpProxyConf) Compare(cmp ProxyConf) bool {
|
||||
cmpConf, ok := cmp.(*UdpProxyConf)
|
||||
func (cfg *UDPProxyConf) Compare(cmp ProxyConf) bool {
|
||||
cmpConf, ok := cmp.(*UDPProxyConf)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -673,12 +672,12 @@ func (cfg *UdpProxyConf) Compare(cmp ProxyConf) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (cfg *UdpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||
func (cfg *UDPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
|
||||
cfg.BindInfoConf.UnmarshalFromMsg(pMsg)
|
||||
}
|
||||
|
||||
func (cfg *UdpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
func (cfg *UDPProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -688,34 +687,34 @@ func (cfg *UdpProxyConf) UnmarshalFromIni(prefix string, name string, section in
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *UdpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||
func (cfg *UDPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||
cfg.BaseProxyConf.MarshalToMsg(pMsg)
|
||||
cfg.BindInfoConf.MarshalToMsg(pMsg)
|
||||
}
|
||||
|
||||
func (cfg *UdpProxyConf) CheckForCli() (err error) {
|
||||
func (cfg *UDPProxyConf) CheckForCli() (err error) {
|
||||
if err = cfg.BaseProxyConf.checkForCli(); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *UdpProxyConf) CheckForSvr(serverCfg ServerCommonConf) error { return nil }
|
||||
func (cfg *UDPProxyConf) CheckForSvr(serverCfg ServerCommonConf) error { return nil }
|
||||
|
||||
// HTTP
|
||||
type HttpProxyConf struct {
|
||||
type HTTPProxyConf struct {
|
||||
BaseProxyConf
|
||||
DomainConf
|
||||
|
||||
Locations []string `json:"locations"`
|
||||
HttpUser string `json:"http_user"`
|
||||
HttpPwd string `json:"http_pwd"`
|
||||
HTTPUser string `json:"http_user"`
|
||||
HTTPPwd string `json:"http_pwd"`
|
||||
HostHeaderRewrite string `json:"host_header_rewrite"`
|
||||
Headers map[string]string `json:"headers"`
|
||||
}
|
||||
|
||||
func (cfg *HttpProxyConf) Compare(cmp ProxyConf) bool {
|
||||
cmpConf, ok := cmp.(*HttpProxyConf)
|
||||
func (cfg *HTTPProxyConf) Compare(cmp ProxyConf) bool {
|
||||
cmpConf, ok := cmp.(*HTTPProxyConf)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -724,36 +723,36 @@ func (cfg *HttpProxyConf) Compare(cmp ProxyConf) bool {
|
||||
!cfg.DomainConf.compare(&cmpConf.DomainConf) ||
|
||||
strings.Join(cfg.Locations, " ") != strings.Join(cmpConf.Locations, " ") ||
|
||||
cfg.HostHeaderRewrite != cmpConf.HostHeaderRewrite ||
|
||||
cfg.HttpUser != cmpConf.HttpUser ||
|
||||
cfg.HttpPwd != cmpConf.HttpPwd ||
|
||||
cfg.HTTPUser != cmpConf.HTTPUser ||
|
||||
cfg.HTTPPwd != cmpConf.HTTPPwd ||
|
||||
len(cfg.Headers) != len(cmpConf.Headers) {
|
||||
return false
|
||||
}
|
||||
|
||||
for k, v := range cfg.Headers {
|
||||
if v2, ok := cmpConf.Headers[k]; !ok {
|
||||
v2, ok := cmpConf.Headers[k]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if v != v2 {
|
||||
return false
|
||||
} else {
|
||||
if v != v2 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (cfg *HttpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||
func (cfg *HTTPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
|
||||
cfg.DomainConf.UnmarshalFromMsg(pMsg)
|
||||
|
||||
cfg.Locations = pMsg.Locations
|
||||
cfg.HostHeaderRewrite = pMsg.HostHeaderRewrite
|
||||
cfg.HttpUser = pMsg.HttpUser
|
||||
cfg.HttpPwd = pMsg.HttpPwd
|
||||
cfg.HTTPUser = pMsg.HTTPUser
|
||||
cfg.HTTPPwd = pMsg.HTTPPwd
|
||||
cfg.Headers = pMsg.Headers
|
||||
}
|
||||
|
||||
func (cfg *HttpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
func (cfg *HTTPProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -772,8 +771,8 @@ func (cfg *HttpProxyConf) UnmarshalFromIni(prefix string, name string, section i
|
||||
}
|
||||
|
||||
cfg.HostHeaderRewrite = section["host_header_rewrite"]
|
||||
cfg.HttpUser = section["http_user"]
|
||||
cfg.HttpPwd = section["http_pwd"]
|
||||
cfg.HTTPUser = section["http_user"]
|
||||
cfg.HTTPPwd = section["http_pwd"]
|
||||
cfg.Headers = make(map[string]string)
|
||||
|
||||
for k, v := range section {
|
||||
@@ -784,18 +783,18 @@ func (cfg *HttpProxyConf) UnmarshalFromIni(prefix string, name string, section i
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *HttpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||
func (cfg *HTTPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||
cfg.BaseProxyConf.MarshalToMsg(pMsg)
|
||||
cfg.DomainConf.MarshalToMsg(pMsg)
|
||||
|
||||
pMsg.Locations = cfg.Locations
|
||||
pMsg.HostHeaderRewrite = cfg.HostHeaderRewrite
|
||||
pMsg.HttpUser = cfg.HttpUser
|
||||
pMsg.HttpPwd = cfg.HttpPwd
|
||||
pMsg.HTTPUser = cfg.HTTPUser
|
||||
pMsg.HTTPPwd = cfg.HTTPPwd
|
||||
pMsg.Headers = cfg.Headers
|
||||
}
|
||||
|
||||
func (cfg *HttpProxyConf) CheckForCli() (err error) {
|
||||
func (cfg *HTTPProxyConf) CheckForCli() (err error) {
|
||||
if err = cfg.BaseProxyConf.checkForCli(); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -805,8 +804,8 @@ func (cfg *HttpProxyConf) CheckForCli() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *HttpProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
|
||||
if serverCfg.VhostHttpPort == 0 {
|
||||
func (cfg *HTTPProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
|
||||
if serverCfg.VhostHTTPPort == 0 {
|
||||
return fmt.Errorf("type [http] not support when vhost_http_port is not set")
|
||||
}
|
||||
if err = cfg.DomainConf.checkForSvr(serverCfg); err != nil {
|
||||
@@ -817,13 +816,13 @@ func (cfg *HttpProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
|
||||
}
|
||||
|
||||
// HTTPS
|
||||
type HttpsProxyConf struct {
|
||||
type HTTPSProxyConf struct {
|
||||
BaseProxyConf
|
||||
DomainConf
|
||||
}
|
||||
|
||||
func (cfg *HttpsProxyConf) Compare(cmp ProxyConf) bool {
|
||||
cmpConf, ok := cmp.(*HttpsProxyConf)
|
||||
func (cfg *HTTPSProxyConf) Compare(cmp ProxyConf) bool {
|
||||
cmpConf, ok := cmp.(*HTTPSProxyConf)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -835,12 +834,12 @@ func (cfg *HttpsProxyConf) Compare(cmp ProxyConf) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (cfg *HttpsProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||
func (cfg *HTTPSProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
|
||||
cfg.DomainConf.UnmarshalFromMsg(pMsg)
|
||||
}
|
||||
|
||||
func (cfg *HttpsProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
func (cfg *HTTPSProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -850,12 +849,12 @@ func (cfg *HttpsProxyConf) UnmarshalFromIni(prefix string, name string, section
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *HttpsProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||
func (cfg *HTTPSProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||
cfg.BaseProxyConf.MarshalToMsg(pMsg)
|
||||
cfg.DomainConf.MarshalToMsg(pMsg)
|
||||
}
|
||||
|
||||
func (cfg *HttpsProxyConf) CheckForCli() (err error) {
|
||||
func (cfg *HTTPSProxyConf) CheckForCli() (err error) {
|
||||
if err = cfg.BaseProxyConf.checkForCli(); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -865,8 +864,8 @@ func (cfg *HttpsProxyConf) CheckForCli() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *HttpsProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
|
||||
if serverCfg.VhostHttpsPort == 0 {
|
||||
func (cfg *HTTPSProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
|
||||
if serverCfg.VhostHTTPSPort == 0 {
|
||||
return fmt.Errorf("type [https] not support when vhost_https_port is not set")
|
||||
}
|
||||
if err = cfg.DomainConf.checkForSvr(serverCfg); err != nil {
|
||||
@@ -877,15 +876,15 @@ func (cfg *HttpsProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
|
||||
}
|
||||
|
||||
// SUDP
|
||||
type SudpProxyConf struct {
|
||||
type SUDPProxyConf struct {
|
||||
BaseProxyConf
|
||||
|
||||
Role string `json:"role"`
|
||||
Sk string `json:"sk"`
|
||||
}
|
||||
|
||||
func (cfg *SudpProxyConf) Compare(cmp ProxyConf) bool {
|
||||
cmpConf, ok := cmp.(*SudpProxyConf)
|
||||
func (cfg *SUDPProxyConf) Compare(cmp ProxyConf) bool {
|
||||
cmpConf, ok := cmp.(*SUDPProxyConf)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -898,7 +897,7 @@ func (cfg *SudpProxyConf) Compare(cmp ProxyConf) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (cfg *SudpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
func (cfg *SUDPProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -916,12 +915,12 @@ func (cfg *SudpProxyConf) UnmarshalFromIni(prefix string, name string, section i
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *SudpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||
func (cfg *SUDPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||
cfg.BaseProxyConf.MarshalToMsg(pMsg)
|
||||
pMsg.Sk = cfg.Sk
|
||||
}
|
||||
|
||||
func (cfg *SudpProxyConf) CheckForCli() (err error) {
|
||||
func (cfg *SUDPProxyConf) CheckForCli() (err error) {
|
||||
if err = cfg.BaseProxyConf.checkForCli(); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -932,26 +931,26 @@ func (cfg *SudpProxyConf) CheckForCli() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *SudpProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
|
||||
func (cfg *SUDPProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Only for role server.
|
||||
func (cfg *SudpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||
func (cfg *SUDPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
|
||||
cfg.Sk = pMsg.Sk
|
||||
}
|
||||
|
||||
// STCP
|
||||
type StcpProxyConf struct {
|
||||
type STCPProxyConf struct {
|
||||
BaseProxyConf
|
||||
|
||||
Role string `json:"role"`
|
||||
Sk string `json:"sk"`
|
||||
}
|
||||
|
||||
func (cfg *StcpProxyConf) Compare(cmp ProxyConf) bool {
|
||||
cmpConf, ok := cmp.(*StcpProxyConf)
|
||||
func (cfg *STCPProxyConf) Compare(cmp ProxyConf) bool {
|
||||
cmpConf, ok := cmp.(*STCPProxyConf)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -965,12 +964,12 @@ func (cfg *StcpProxyConf) Compare(cmp ProxyConf) bool {
|
||||
}
|
||||
|
||||
// Only for role server.
|
||||
func (cfg *StcpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||
func (cfg *STCPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
|
||||
cfg.Sk = pMsg.Sk
|
||||
}
|
||||
|
||||
func (cfg *StcpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
func (cfg *STCPProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -988,12 +987,12 @@ func (cfg *StcpProxyConf) UnmarshalFromIni(prefix string, name string, section i
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *StcpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||
func (cfg *STCPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||
cfg.BaseProxyConf.MarshalToMsg(pMsg)
|
||||
pMsg.Sk = cfg.Sk
|
||||
}
|
||||
|
||||
func (cfg *StcpProxyConf) CheckForCli() (err error) {
|
||||
func (cfg *STCPProxyConf) CheckForCli() (err error) {
|
||||
if err = cfg.BaseProxyConf.checkForCli(); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -1004,20 +1003,20 @@ func (cfg *StcpProxyConf) CheckForCli() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *StcpProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
|
||||
func (cfg *STCPProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// XTCP
|
||||
type XtcpProxyConf struct {
|
||||
type XTCPProxyConf struct {
|
||||
BaseProxyConf
|
||||
|
||||
Role string `json:"role"`
|
||||
Sk string `json:"sk"`
|
||||
}
|
||||
|
||||
func (cfg *XtcpProxyConf) Compare(cmp ProxyConf) bool {
|
||||
cmpConf, ok := cmp.(*XtcpProxyConf)
|
||||
func (cfg *XTCPProxyConf) Compare(cmp ProxyConf) bool {
|
||||
cmpConf, ok := cmp.(*XTCPProxyConf)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -1032,12 +1031,12 @@ func (cfg *XtcpProxyConf) Compare(cmp ProxyConf) bool {
|
||||
}
|
||||
|
||||
// Only for role server.
|
||||
func (cfg *XtcpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||
func (cfg *XTCPProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
|
||||
cfg.Sk = pMsg.Sk
|
||||
}
|
||||
|
||||
func (cfg *XtcpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
func (cfg *XTCPProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -1055,12 +1054,12 @@ func (cfg *XtcpProxyConf) UnmarshalFromIni(prefix string, name string, section i
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *XtcpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||
func (cfg *XTCPProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||
cfg.BaseProxyConf.MarshalToMsg(pMsg)
|
||||
pMsg.Sk = cfg.Sk
|
||||
}
|
||||
|
||||
func (cfg *XtcpProxyConf) CheckForCli() (err error) {
|
||||
func (cfg *XTCPProxyConf) CheckForCli() (err error) {
|
||||
if err = cfg.BaseProxyConf.checkForCli(); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -1071,7 +1070,7 @@ func (cfg *XtcpProxyConf) CheckForCli() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *XtcpProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
|
||||
func (cfg *XTCPProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
|
||||
return
|
||||
}
|
||||
|
@@ -19,51 +19,51 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
ini "github.com/vaughan0/go-ini"
|
||||
"github.com/fatedier/frp/pkg/auth"
|
||||
plugin "github.com/fatedier/frp/pkg/plugin/server"
|
||||
"github.com/fatedier/frp/pkg/util/util"
|
||||
|
||||
"github.com/fatedier/frp/models/auth"
|
||||
plugin "github.com/fatedier/frp/models/plugin/server"
|
||||
"github.com/fatedier/frp/utils/util"
|
||||
ini "github.com/vaughan0/go-ini"
|
||||
)
|
||||
|
||||
// ServerCommonConf contains information for a server service. It is
|
||||
// recommended to use GetDefaultServerConf instead of creating this object
|
||||
// directly, so that all unspecified fields have reasonable default values.
|
||||
type ServerCommonConf struct {
|
||||
auth.AuthServerConfig
|
||||
auth.ServerConfig
|
||||
// BindAddr specifies the address that the server binds to. By default,
|
||||
// this value is "0.0.0.0".
|
||||
BindAddr string `json:"bind_addr"`
|
||||
// BindPort specifies the port that the server listens on. By default, this
|
||||
// value is 7000.
|
||||
BindPort int `json:"bind_port"`
|
||||
// BindUdpPort specifies the UDP port that the server listens on. If this
|
||||
// BindUDPPort specifies the UDP port that the server listens on. If this
|
||||
// value is 0, the server will not listen for UDP connections. By default,
|
||||
// this value is 0
|
||||
BindUdpPort int `json:"bind_udp_port"`
|
||||
// BindKcpPort specifies the KCP port that the server listens on. If this
|
||||
BindUDPPort int `json:"bind_udp_port"`
|
||||
// KCPBindPort specifies the KCP port that the server listens on. If this
|
||||
// value is 0, the server will not listen for KCP connections. By default,
|
||||
// this value is 0.
|
||||
KcpBindPort int `json:"kcp_bind_port"`
|
||||
KCPBindPort int `json:"kcp_bind_port"`
|
||||
// ProxyBindAddr specifies the address that the proxy binds to. This value
|
||||
// may be the same as BindAddr. By default, this value is "0.0.0.0".
|
||||
ProxyBindAddr string `json:"proxy_bind_addr"`
|
||||
// VhostHttpPort specifies the port that the server listens for HTTP Vhost
|
||||
// VhostHTTPPort specifies the port that the server listens for HTTP Vhost
|
||||
// requests. If this value is 0, the server will not listen for HTTP
|
||||
// requests. By default, this value is 0.
|
||||
VhostHttpPort int `json:"vhost_http_port"`
|
||||
// VhostHttpsPort specifies the port that the server listens for HTTPS
|
||||
VhostHTTPPort int `json:"vhost_http_port"`
|
||||
// VhostHTTPSPort specifies the port that the server listens for HTTPS
|
||||
// Vhost requests. If this value is 0, the server will not listen for HTTPS
|
||||
// requests. By default, this value is 0.
|
||||
VhostHttpsPort int `json:"vhost_https_port"`
|
||||
// TcpMuxHttpConnectPort specifies the port that the server listens for TCP
|
||||
VhostHTTPSPort int `json:"vhost_https_port"`
|
||||
// TCPMuxHTTPConnectPort specifies the port that the server listens for TCP
|
||||
// HTTP CONNECT requests. If the value is 0, the server will not multiplex TCP
|
||||
// requests on one single port. If it's not - it will listen on this value for
|
||||
// HTTP CONNECT requests. By default, this value is 0.
|
||||
TcpMuxHttpConnectPort int `json:"tcpmux_httpconnect_port"`
|
||||
// VhostHttpTimeout specifies the response header timeout for the Vhost
|
||||
TCPMuxHTTPConnectPort int `json:"tcpmux_httpconnect_port"`
|
||||
// VhostHTTPTimeout specifies the response header timeout for the Vhost
|
||||
// HTTP server, in seconds. By default, this value is 60.
|
||||
VhostHttpTimeout int64 `json:"vhost_http_timeout"`
|
||||
VhostHTTPTimeout int64 `json:"vhost_http_timeout"`
|
||||
// DashboardAddr specifies the address that the dashboard binds to. By
|
||||
// default, this value is "0.0.0.0".
|
||||
DashboardAddr string `json:"dashboard_addr"`
|
||||
@@ -83,7 +83,7 @@ type ServerCommonConf struct {
|
||||
// AssetsDir specifies the local directory that the dashboard will load
|
||||
// resources from. If this value is "", assets will be loaded from the
|
||||
// bundled executable using statik. By default, this value is "".
|
||||
AssetsDir string `json:"asserts_dir"`
|
||||
AssetsDir string `json:"assets_dir"`
|
||||
// LogFile specifies a file where logs will be written to. This value will
|
||||
// only be used if LogWay is set appropriately. By default, this value is
|
||||
// "console".
|
||||
@@ -113,10 +113,10 @@ type ServerCommonConf struct {
|
||||
// "test", the resulting URL would be "test.frps.com". By default, this
|
||||
// value is "".
|
||||
SubDomainHost string `json:"subdomain_host"`
|
||||
// TcpMux toggles TCP stream multiplexing. This allows multiple requests
|
||||
// TCPMux toggles TCP stream multiplexing. This allows multiple requests
|
||||
// from a client to share a single TCP connection. By default, this value
|
||||
// is true.
|
||||
TcpMux bool `json:"tcp_mux"`
|
||||
TCPMux bool `json:"tcp_mux"`
|
||||
// Custom404Page specifies a path to a custom 404 page to display. If this
|
||||
// value is "", a default page will be displayed. By default, this value is
|
||||
// "".
|
||||
@@ -133,18 +133,36 @@ type ServerCommonConf struct {
|
||||
// may proxy to. If this value is 0, no limit will be applied. By default,
|
||||
// this value is 0.
|
||||
MaxPortsPerClient int64 `json:"max_ports_per_client"`
|
||||
// TlsOnly specifies whether to only accept TLS-encrypted connections. By
|
||||
// default, the value is false.
|
||||
TlsOnly bool `json:"tls_only"`
|
||||
// TLSOnly specifies whether to only accept TLS-encrypted connections.
|
||||
// By default, the value is false.
|
||||
TLSOnly bool `json:"tls_only"`
|
||||
// TLSCertFile specifies the path of the cert file that the server will
|
||||
// load. If "tls_cert_file", "tls_key_file" are valid, the server will use this
|
||||
// supplied tls configuration. Otherwise, the server will use the tls
|
||||
// configuration generated by itself.
|
||||
TLSCertFile string `json:"tls_cert_file"`
|
||||
// TLSKeyFile specifies the path of the secret key that the server will
|
||||
// load. If "tls_cert_file", "tls_key_file" are valid, the server will use this
|
||||
// supplied tls configuration. Otherwise, the server will use the tls
|
||||
// configuration generated by itself.
|
||||
TLSKeyFile string `json:"tls_key_file"`
|
||||
// TLSTrustedCaFile specifies the paths of the client cert files that the
|
||||
// server will load. It only works when "tls_only" is true. If
|
||||
// "tls_trusted_ca_file" is valid, the server will verify each client's
|
||||
// certificate.
|
||||
TLSTrustedCaFile string `json:"tls_trusted_ca_file"`
|
||||
// HeartBeatTimeout specifies the maximum time to wait for a heartbeat
|
||||
// before terminating the connection. It is not recommended to change this
|
||||
// value. By default, this value is 90.
|
||||
HeartBeatTimeout int64 `json:"heart_beat_timeout"`
|
||||
HeartbeatTimeout int64 `json:"heartbeat_timeout"`
|
||||
// UserConnTimeout specifies the maximum time to wait for a work
|
||||
// connection. By default, this value is 10.
|
||||
UserConnTimeout int64 `json:"user_conn_timeout"`
|
||||
// HTTPPlugins specify the server plugins support HTTP protocol.
|
||||
HTTPPlugins map[string]plugin.HTTPPluginOptions `json:"http_plugins"`
|
||||
// UDPPacketSize specifies the UDP packet size
|
||||
// By default, this value is 1500
|
||||
UDPPacketSize int64 `json:"udp_packet_size"`
|
||||
}
|
||||
|
||||
// GetDefaultServerConf returns a server configuration with reasonable
|
||||
@@ -153,13 +171,13 @@ func GetDefaultServerConf() ServerCommonConf {
|
||||
return ServerCommonConf{
|
||||
BindAddr: "0.0.0.0",
|
||||
BindPort: 7000,
|
||||
BindUdpPort: 0,
|
||||
KcpBindPort: 0,
|
||||
BindUDPPort: 0,
|
||||
KCPBindPort: 0,
|
||||
ProxyBindAddr: "0.0.0.0",
|
||||
VhostHttpPort: 0,
|
||||
VhostHttpsPort: 0,
|
||||
TcpMuxHttpConnectPort: 0,
|
||||
VhostHttpTimeout: 60,
|
||||
VhostHTTPPort: 0,
|
||||
VhostHTTPSPort: 0,
|
||||
TCPMuxHTTPConnectPort: 0,
|
||||
VhostHTTPTimeout: 60,
|
||||
DashboardAddr: "0.0.0.0",
|
||||
DashboardPort: 0,
|
||||
DashboardUser: "admin",
|
||||
@@ -173,15 +191,19 @@ func GetDefaultServerConf() ServerCommonConf {
|
||||
DisableLogColor: false,
|
||||
DetailedErrorsToClient: true,
|
||||
SubDomainHost: "",
|
||||
TcpMux: true,
|
||||
TCPMux: true,
|
||||
AllowPorts: make(map[int]struct{}),
|
||||
MaxPoolCount: 5,
|
||||
MaxPortsPerClient: 0,
|
||||
TlsOnly: false,
|
||||
HeartBeatTimeout: 90,
|
||||
TLSOnly: false,
|
||||
TLSCertFile: "",
|
||||
TLSKeyFile: "",
|
||||
TLSTrustedCaFile: "",
|
||||
HeartbeatTimeout: 90,
|
||||
UserConnTimeout: 10,
|
||||
Custom404Page: "",
|
||||
HTTPPlugins: make(map[string]plugin.HTTPPluginOptions),
|
||||
UDPPacketSize: 1500,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,7 +220,7 @@ func UnmarshalServerConfFromIni(content string) (cfg ServerCommonConf, err error
|
||||
|
||||
UnmarshalPluginsFromIni(conf, &cfg)
|
||||
|
||||
cfg.AuthServerConfig = auth.UnmarshalAuthServerConfFromIni(conf)
|
||||
cfg.ServerConfig = auth.UnmarshalServerConfFromIni(conf)
|
||||
|
||||
var (
|
||||
tmpStr string
|
||||
@@ -213,27 +235,24 @@ func UnmarshalServerConfFromIni(content string) (cfg ServerCommonConf, err error
|
||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||
err = fmt.Errorf("Parse conf error: invalid bind_port")
|
||||
return
|
||||
} else {
|
||||
cfg.BindPort = int(v)
|
||||
}
|
||||
cfg.BindPort = int(v)
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "bind_udp_port"); ok {
|
||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||
err = fmt.Errorf("Parse conf error: invalid bind_udp_port")
|
||||
return
|
||||
} else {
|
||||
cfg.BindUdpPort = int(v)
|
||||
}
|
||||
cfg.BindUDPPort = int(v)
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "kcp_bind_port"); ok {
|
||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||
err = fmt.Errorf("Parse conf error: invalid kcp_bind_port")
|
||||
return
|
||||
} else {
|
||||
cfg.KcpBindPort = int(v)
|
||||
}
|
||||
cfg.KCPBindPort = int(v)
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "proxy_bind_addr"); ok {
|
||||
@@ -246,33 +265,30 @@ func UnmarshalServerConfFromIni(content string) (cfg ServerCommonConf, err error
|
||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||
err = fmt.Errorf("Parse conf error: invalid vhost_http_port")
|
||||
return
|
||||
} else {
|
||||
cfg.VhostHttpPort = int(v)
|
||||
}
|
||||
cfg.VhostHTTPPort = int(v)
|
||||
} else {
|
||||
cfg.VhostHttpPort = 0
|
||||
cfg.VhostHTTPPort = 0
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "vhost_https_port"); ok {
|
||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||
err = fmt.Errorf("Parse conf error: invalid vhost_https_port")
|
||||
return
|
||||
} else {
|
||||
cfg.VhostHttpsPort = int(v)
|
||||
}
|
||||
cfg.VhostHTTPSPort = int(v)
|
||||
} else {
|
||||
cfg.VhostHttpsPort = 0
|
||||
cfg.VhostHTTPSPort = 0
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "tcpmux_httpconnect_port"); ok {
|
||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||
err = fmt.Errorf("Parse conf error: invalid tcpmux_httpconnect_port")
|
||||
return
|
||||
} else {
|
||||
cfg.TcpMuxHttpConnectPort = int(v)
|
||||
}
|
||||
cfg.TCPMuxHTTPConnectPort = int(v)
|
||||
} else {
|
||||
cfg.TcpMuxHttpConnectPort = 0
|
||||
cfg.TCPMuxHTTPConnectPort = 0
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "vhost_http_timeout"); ok {
|
||||
@@ -280,9 +296,8 @@ func UnmarshalServerConfFromIni(content string) (cfg ServerCommonConf, err error
|
||||
if errRet != nil || v < 0 {
|
||||
err = fmt.Errorf("Parse conf error: invalid vhost_http_timeout")
|
||||
return
|
||||
} else {
|
||||
cfg.VhostHttpTimeout = v
|
||||
}
|
||||
cfg.VhostHTTPTimeout = v
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "dashboard_addr"); ok {
|
||||
@@ -295,9 +310,8 @@ func UnmarshalServerConfFromIni(content string) (cfg ServerCommonConf, err error
|
||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||
err = fmt.Errorf("Parse conf error: invalid dashboard_port")
|
||||
return
|
||||
} else {
|
||||
cfg.DashboardPort = int(v)
|
||||
}
|
||||
cfg.DashboardPort = int(v)
|
||||
} else {
|
||||
cfg.DashboardPort = 0
|
||||
}
|
||||
@@ -365,26 +379,26 @@ func UnmarshalServerConfFromIni(content string) (cfg ServerCommonConf, err error
|
||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||
err = fmt.Errorf("Parse conf error: invalid max_pool_count")
|
||||
return
|
||||
} else {
|
||||
if v < 0 {
|
||||
err = fmt.Errorf("Parse conf error: invalid max_pool_count")
|
||||
return
|
||||
}
|
||||
cfg.MaxPoolCount = v
|
||||
}
|
||||
|
||||
if v < 0 {
|
||||
err = fmt.Errorf("Parse conf error: invalid max_pool_count")
|
||||
return
|
||||
}
|
||||
cfg.MaxPoolCount = v
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "max_ports_per_client"); ok {
|
||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||
err = fmt.Errorf("Parse conf error: invalid max_ports_per_client")
|
||||
return
|
||||
} else {
|
||||
if v < 0 {
|
||||
err = fmt.Errorf("Parse conf error: invalid max_ports_per_client")
|
||||
return
|
||||
}
|
||||
cfg.MaxPortsPerClient = v
|
||||
}
|
||||
|
||||
if v < 0 {
|
||||
err = fmt.Errorf("Parse conf error: invalid max_ports_per_client")
|
||||
return
|
||||
}
|
||||
cfg.MaxPortsPerClient = v
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "subdomain_host"); ok {
|
||||
@@ -392,9 +406,9 @@ func UnmarshalServerConfFromIni(content string) (cfg ServerCommonConf, err error
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "tcp_mux"); ok && tmpStr == "false" {
|
||||
cfg.TcpMux = false
|
||||
cfg.TCPMux = false
|
||||
} else {
|
||||
cfg.TcpMux = true
|
||||
cfg.TCPMux = true
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "custom_404_page"); ok {
|
||||
@@ -406,16 +420,37 @@ func UnmarshalServerConfFromIni(content string) (cfg ServerCommonConf, err error
|
||||
if errRet != nil {
|
||||
err = fmt.Errorf("Parse conf error: heartbeat_timeout is incorrect")
|
||||
return
|
||||
} else {
|
||||
cfg.HeartBeatTimeout = v
|
||||
}
|
||||
cfg.HeartbeatTimeout = v
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "tls_only"); ok && tmpStr == "true" {
|
||||
cfg.TlsOnly = true
|
||||
cfg.TLSOnly = true
|
||||
} else {
|
||||
cfg.TlsOnly = false
|
||||
cfg.TLSOnly = false
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "udp_packet_size"); ok {
|
||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||
err = fmt.Errorf("Parse conf error: invalid udp_packet_size")
|
||||
return
|
||||
}
|
||||
cfg.UDPPacketSize = v
|
||||
}
|
||||
|
||||
if tmpStr, ok := conf.Get("common", "tls_cert_file"); ok {
|
||||
cfg.TLSCertFile = tmpStr
|
||||
}
|
||||
|
||||
if tmpStr, ok := conf.Get("common", "tls_key_file"); ok {
|
||||
cfg.TLSKeyFile = tmpStr
|
||||
}
|
||||
|
||||
if tmpStr, ok := conf.Get("common", "tls_trusted_ca_file"); ok {
|
||||
cfg.TLSTrustedCaFile = tmpStr
|
||||
cfg.TLSOnly = true
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -423,13 +458,18 @@ func UnmarshalPluginsFromIni(sections ini.File, cfg *ServerCommonConf) {
|
||||
for name, section := range sections {
|
||||
if strings.HasPrefix(name, "plugin.") {
|
||||
name = strings.TrimSpace(strings.TrimPrefix(name, "plugin."))
|
||||
options := plugin.HTTPPluginOptions{
|
||||
Name: name,
|
||||
Addr: section["addr"],
|
||||
Path: section["path"],
|
||||
Ops: strings.Split(section["ops"], ","),
|
||||
var tls_verify, err = strconv.ParseBool(section["tls_verify"])
|
||||
if err != nil {
|
||||
tls_verify = true
|
||||
}
|
||||
for i, _ := range options.Ops {
|
||||
options := plugin.HTTPPluginOptions{
|
||||
Name: name,
|
||||
Addr: section["addr"],
|
||||
Path: section["path"],
|
||||
Ops: strings.Split(section["ops"], ","),
|
||||
TLSVerify: tls_verify,
|
||||
}
|
||||
for i := range options.Ops {
|
||||
options.Ops[i] = strings.TrimSpace(options.Ops[i])
|
||||
}
|
||||
cfg.HTTPPlugins[name] = options
|
||||
@@ -437,6 +477,6 @@ func UnmarshalPluginsFromIni(sections ini.File, cfg *ServerCommonConf) {
|
||||
}
|
||||
}
|
||||
|
||||
func (cfg *ServerCommonConf) Check() (err error) {
|
||||
return
|
||||
func (cfg *ServerCommonConf) Check() error {
|
||||
return nil
|
||||
}
|
@@ -19,7 +19,7 @@ import (
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"github.com/fatedier/frp/models/consts"
|
||||
"github.com/fatedier/frp/pkg/consts"
|
||||
|
||||
ini "github.com/vaughan0/go-ini"
|
||||
)
|
||||
@@ -30,9 +30,9 @@ var (
|
||||
|
||||
func init() {
|
||||
visitorConfTypeMap = make(map[string]reflect.Type)
|
||||
visitorConfTypeMap[consts.StcpProxy] = reflect.TypeOf(StcpVisitorConf{})
|
||||
visitorConfTypeMap[consts.XtcpProxy] = reflect.TypeOf(XtcpVisitorConf{})
|
||||
visitorConfTypeMap[consts.SudpProxy] = reflect.TypeOf(SudpVisitorConf{})
|
||||
visitorConfTypeMap[consts.STCPProxy] = reflect.TypeOf(STCPVisitorConf{})
|
||||
visitorConfTypeMap[consts.XTCPProxy] = reflect.TypeOf(XTCPVisitorConf{})
|
||||
visitorConfTypeMap[consts.SUDPProxy] = reflect.TypeOf(SUDPVisitorConf{})
|
||||
}
|
||||
|
||||
type VisitorConf interface {
|
||||
@@ -153,12 +153,12 @@ func (cfg *BaseVisitorConf) UnmarshalFromIni(prefix string, name string, section
|
||||
return nil
|
||||
}
|
||||
|
||||
type SudpVisitorConf struct {
|
||||
type SUDPVisitorConf struct {
|
||||
BaseVisitorConf
|
||||
}
|
||||
|
||||
func (cfg *SudpVisitorConf) Compare(cmp VisitorConf) bool {
|
||||
cmpConf, ok := cmp.(*SudpVisitorConf)
|
||||
func (cfg *SUDPVisitorConf) Compare(cmp VisitorConf) bool {
|
||||
cmpConf, ok := cmp.(*SUDPVisitorConf)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -169,26 +169,26 @@ func (cfg *SudpVisitorConf) Compare(cmp VisitorConf) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (cfg *SudpVisitorConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
func (cfg *SUDPVisitorConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
if err = cfg.BaseVisitorConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *SudpVisitorConf) Check() (err error) {
|
||||
func (cfg *SUDPVisitorConf) Check() (err error) {
|
||||
if err = cfg.BaseVisitorConf.check(); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type StcpVisitorConf struct {
|
||||
type STCPVisitorConf struct {
|
||||
BaseVisitorConf
|
||||
}
|
||||
|
||||
func (cfg *StcpVisitorConf) Compare(cmp VisitorConf) bool {
|
||||
cmpConf, ok := cmp.(*StcpVisitorConf)
|
||||
func (cfg *STCPVisitorConf) Compare(cmp VisitorConf) bool {
|
||||
cmpConf, ok := cmp.(*STCPVisitorConf)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -199,26 +199,26 @@ func (cfg *StcpVisitorConf) Compare(cmp VisitorConf) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (cfg *StcpVisitorConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
func (cfg *STCPVisitorConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
if err = cfg.BaseVisitorConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *StcpVisitorConf) Check() (err error) {
|
||||
func (cfg *STCPVisitorConf) Check() (err error) {
|
||||
if err = cfg.BaseVisitorConf.check(); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type XtcpVisitorConf struct {
|
||||
type XTCPVisitorConf struct {
|
||||
BaseVisitorConf
|
||||
}
|
||||
|
||||
func (cfg *XtcpVisitorConf) Compare(cmp VisitorConf) bool {
|
||||
cmpConf, ok := cmp.(*XtcpVisitorConf)
|
||||
func (cfg *XTCPVisitorConf) Compare(cmp VisitorConf) bool {
|
||||
cmpConf, ok := cmp.(*XTCPVisitorConf)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
@@ -229,14 +229,14 @@ func (cfg *XtcpVisitorConf) Compare(cmp VisitorConf) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (cfg *XtcpVisitorConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
func (cfg *XTCPVisitorConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||
if err = cfg.BaseVisitorConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *XtcpVisitorConf) Check() (err error) {
|
||||
func (cfg *XTCPVisitorConf) Check() (err error) {
|
||||
if err = cfg.BaseVisitorConf.check(); err != nil {
|
||||
return
|
||||
}
|
@@ -23,19 +23,19 @@ var (
|
||||
Offline string = "offline"
|
||||
|
||||
// proxy type
|
||||
TcpProxy string = "tcp"
|
||||
UdpProxy string = "udp"
|
||||
TcpMuxProxy string = "tcpmux"
|
||||
HttpProxy string = "http"
|
||||
HttpsProxy string = "https"
|
||||
StcpProxy string = "stcp"
|
||||
XtcpProxy string = "xtcp"
|
||||
SudpProxy string = "sudp"
|
||||
TCPProxy string = "tcp"
|
||||
UDPProxy string = "udp"
|
||||
TCPMuxProxy string = "tcpmux"
|
||||
HTTPProxy string = "http"
|
||||
HTTPSProxy string = "https"
|
||||
STCPProxy string = "stcp"
|
||||
XTCPProxy string = "xtcp"
|
||||
SUDPProxy string = "sudp"
|
||||
|
||||
// authentication method
|
||||
TokenAuthMethod string = "token"
|
||||
OidcAuthMethod string = "oidc"
|
||||
|
||||
// tcp multiplexer
|
||||
HttpConnectTcpMultiplexer string = "httpconnect"
|
||||
// TCP multiplexer
|
||||
HTTPConnectTCPMultiplexer string = "httpconnect"
|
||||
)
|
@@ -15,8 +15,8 @@
|
||||
package aggregate
|
||||
|
||||
import (
|
||||
"github.com/fatedier/frp/models/metrics/mem"
|
||||
"github.com/fatedier/frp/models/metrics/prometheus"
|
||||
"github.com/fatedier/frp/pkg/metrics/mem"
|
||||
"github.com/fatedier/frp/pkg/metrics/prometheus"
|
||||
"github.com/fatedier/frp/server/metrics"
|
||||
)
|
||||
|
@@ -18,9 +18,9 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/pkg/util/log"
|
||||
"github.com/fatedier/frp/pkg/util/metric"
|
||||
server "github.com/fatedier/frp/server/metrics"
|
||||
"github.com/fatedier/frp/utils/log"
|
||||
"github.com/fatedier/frp/utils/metric"
|
||||
)
|
||||
|
||||
var sm *serverMetrics = newServerMetrics()
|
||||
@@ -69,7 +69,9 @@ func (m *serverMetrics) clearUselessInfo() {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
for name, data := range m.info.ProxyStatistics {
|
||||
if !data.LastCloseTime.IsZero() && time.Since(data.LastCloseTime) > time.Duration(7*24)*time.Hour {
|
||||
if !data.LastCloseTime.IsZero() &&
|
||||
data.LastStartTime.Before(data.LastCloseTime) &&
|
||||
time.Since(data.LastCloseTime) > time.Duration(7*24)*time.Hour {
|
||||
delete(m.info.ProxyStatistics, name)
|
||||
log.Trace("clear proxy [%s]'s statistics data, lastCloseTime: [%s]", name, data.LastCloseTime.String())
|
||||
}
|
||||
@@ -177,12 +179,12 @@ func (m *serverMetrics) GetServer() *ServerStats {
|
||||
s := &ServerStats{
|
||||
TotalTrafficIn: m.info.TotalTrafficIn.TodayCount(),
|
||||
TotalTrafficOut: m.info.TotalTrafficOut.TodayCount(),
|
||||
CurConns: m.info.CurConns.Count(),
|
||||
ClientCounts: m.info.ClientCounts.Count(),
|
||||
CurConns: int64(m.info.CurConns.Count()),
|
||||
ClientCounts: int64(m.info.ClientCounts.Count()),
|
||||
ProxyTypeCounts: make(map[string]int64),
|
||||
}
|
||||
for k, v := range m.info.ProxyTypeCounts {
|
||||
s.ProxyTypeCounts[k] = v.Count()
|
||||
s.ProxyTypeCounts[k] = int64(v.Count())
|
||||
}
|
||||
return s
|
||||
}
|
||||
@@ -202,7 +204,7 @@ func (m *serverMetrics) GetProxiesByType(proxyType string) []*ProxyStats {
|
||||
Type: proxyStats.ProxyType,
|
||||
TodayTrafficIn: proxyStats.TrafficIn.TodayCount(),
|
||||
TodayTrafficOut: proxyStats.TrafficOut.TodayCount(),
|
||||
CurConns: proxyStats.CurConns.Count(),
|
||||
CurConns: int64(proxyStats.CurConns.Count()),
|
||||
}
|
||||
if !proxyStats.LastStartTime.IsZero() {
|
||||
ps.LastStartTime = proxyStats.LastStartTime.Format("01-02 15:04:05")
|
||||
@@ -233,7 +235,7 @@ func (m *serverMetrics) GetProxiesByTypeAndName(proxyType string, proxyName stri
|
||||
Type: proxyStats.ProxyType,
|
||||
TodayTrafficIn: proxyStats.TrafficIn.TodayCount(),
|
||||
TodayTrafficOut: proxyStats.TrafficOut.TodayCount(),
|
||||
CurConns: proxyStats.CurConns.Count(),
|
||||
CurConns: int64(proxyStats.CurConns.Count()),
|
||||
}
|
||||
if !proxyStats.LastStartTime.IsZero() {
|
||||
res.LastStartTime = proxyStats.LastStartTime.Format("01-02 15:04:05")
|
@@ -17,7 +17,7 @@ package mem
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/utils/metric"
|
||||
"github.com/fatedier/frp/pkg/util/metric"
|
||||
)
|
||||
|
||||
const (
|
@@ -1,7 +1,7 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"github.com/fatedier/frp/models/metrics/aggregate"
|
||||
"github.com/fatedier/frp/pkg/metrics/aggregate"
|
||||
)
|
||||
|
||||
var EnableMem = aggregate.EnableMem
|
@@ -29,7 +29,7 @@ const (
|
||||
TypeNewVisitorConnResp = '3'
|
||||
TypePing = 'h'
|
||||
TypePong = '4'
|
||||
TypeUdpPacket = 'u'
|
||||
TypeUDPPacket = 'u'
|
||||
TypeNatHoleVisitor = 'i'
|
||||
TypeNatHoleClient = 'n'
|
||||
TypeNatHoleResp = 'm'
|
||||
@@ -51,7 +51,7 @@ var (
|
||||
TypeNewVisitorConnResp: NewVisitorConnResp{},
|
||||
TypePing: Ping{},
|
||||
TypePong: Pong{},
|
||||
TypeUdpPacket: UdpPacket{},
|
||||
TypeUDPPacket: UDPPacket{},
|
||||
TypeNatHoleVisitor: NatHoleVisitor{},
|
||||
TypeNatHoleClient: NatHoleClient{},
|
||||
TypeNatHoleResp: NatHoleResp{},
|
||||
@@ -69,7 +69,7 @@ type Login struct {
|
||||
User string `json:"user"`
|
||||
PrivilegeKey string `json:"privilege_key"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
RunId string `json:"run_id"`
|
||||
RunID string `json:"run_id"`
|
||||
Metas map[string]string `json:"metas"`
|
||||
|
||||
// Some global configures.
|
||||
@@ -78,8 +78,8 @@ type Login struct {
|
||||
|
||||
type LoginResp struct {
|
||||
Version string `json:"version"`
|
||||
RunId string `json:"run_id"`
|
||||
ServerUdpPort int `json:"server_udp_port"`
|
||||
RunID string `json:"run_id"`
|
||||
ServerUDPPort int `json:"server_udp_port"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
@@ -100,8 +100,8 @@ type NewProxy struct {
|
||||
CustomDomains []string `json:"custom_domains"`
|
||||
SubDomain string `json:"subdomain"`
|
||||
Locations []string `json:"locations"`
|
||||
HttpUser string `json:"http_user"`
|
||||
HttpPwd string `json:"http_pwd"`
|
||||
HTTPUser string `json:"http_user"`
|
||||
HTTPPwd string `json:"http_pwd"`
|
||||
HostHeaderRewrite string `json:"host_header_rewrite"`
|
||||
Headers map[string]string `json:"headers"`
|
||||
|
||||
@@ -123,7 +123,7 @@ type CloseProxy struct {
|
||||
}
|
||||
|
||||
type NewWorkConn struct {
|
||||
RunId string `json:"run_id"`
|
||||
RunID string `json:"run_id"`
|
||||
PrivilegeKey string `json:"privilege_key"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
}
|
||||
@@ -162,7 +162,7 @@ type Pong struct {
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
type UdpPacket struct {
|
||||
type UDPPacket struct {
|
||||
Content string `json:"c"`
|
||||
LocalAddr *net.UDPAddr `json:"l"`
|
||||
RemoteAddr *net.UDPAddr `json:"r"`
|
@@ -7,9 +7,9 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/models/msg"
|
||||
"github.com/fatedier/frp/utils/log"
|
||||
"github.com/fatedier/frp/utils/util"
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
"github.com/fatedier/frp/pkg/util/log"
|
||||
"github.com/fatedier/frp/pkg/util/util"
|
||||
|
||||
"github.com/fatedier/golib/errors"
|
||||
"github.com/fatedier/golib/pool"
|
||||
@@ -23,16 +23,16 @@ type SidRequest struct {
|
||||
NotifyCh chan struct{}
|
||||
}
|
||||
|
||||
type NatHoleController struct {
|
||||
type Controller struct {
|
||||
listener *net.UDPConn
|
||||
|
||||
clientCfgs map[string]*NatHoleClientCfg
|
||||
sessions map[string]*NatHoleSession
|
||||
clientCfgs map[string]*ClientCfg
|
||||
sessions map[string]*Session
|
||||
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
func NewNatHoleController(udpBindAddr string) (nc *NatHoleController, err error) {
|
||||
func NewController(udpBindAddr string) (nc *Controller, err error) {
|
||||
addr, err := net.ResolveUDPAddr("udp", udpBindAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -41,16 +41,16 @@ func NewNatHoleController(udpBindAddr string) (nc *NatHoleController, err error)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nc = &NatHoleController{
|
||||
nc = &Controller{
|
||||
listener: lconn,
|
||||
clientCfgs: make(map[string]*NatHoleClientCfg),
|
||||
sessions: make(map[string]*NatHoleSession),
|
||||
clientCfgs: make(map[string]*ClientCfg),
|
||||
sessions: make(map[string]*Session),
|
||||
}
|
||||
return nc, nil
|
||||
}
|
||||
|
||||
func (nc *NatHoleController) ListenClient(name string, sk string) (sidCh chan *SidRequest) {
|
||||
clientCfg := &NatHoleClientCfg{
|
||||
func (nc *Controller) ListenClient(name string, sk string) (sidCh chan *SidRequest) {
|
||||
clientCfg := &ClientCfg{
|
||||
Name: name,
|
||||
Sk: sk,
|
||||
SidCh: make(chan *SidRequest),
|
||||
@@ -61,13 +61,13 @@ func (nc *NatHoleController) ListenClient(name string, sk string) (sidCh chan *S
|
||||
return clientCfg.SidCh
|
||||
}
|
||||
|
||||
func (nc *NatHoleController) CloseClient(name string) {
|
||||
func (nc *Controller) CloseClient(name string) {
|
||||
nc.mu.Lock()
|
||||
defer nc.mu.Unlock()
|
||||
delete(nc.clientCfgs, name)
|
||||
}
|
||||
|
||||
func (nc *NatHoleController) Run() {
|
||||
func (nc *Controller) Run() {
|
||||
for {
|
||||
buf := pool.GetBuf(1024)
|
||||
n, raddr, err := nc.listener.ReadFromUDP(buf)
|
||||
@@ -96,15 +96,15 @@ func (nc *NatHoleController) Run() {
|
||||
}
|
||||
}
|
||||
|
||||
func (nc *NatHoleController) GenSid() string {
|
||||
func (nc *Controller) GenSid() string {
|
||||
t := time.Now().Unix()
|
||||
id, _ := util.RandId()
|
||||
id, _ := util.RandID()
|
||||
return fmt.Sprintf("%d%s", t, id)
|
||||
}
|
||||
|
||||
func (nc *NatHoleController) HandleVisitor(m *msg.NatHoleVisitor, raddr *net.UDPAddr) {
|
||||
func (nc *Controller) HandleVisitor(m *msg.NatHoleVisitor, raddr *net.UDPAddr) {
|
||||
sid := nc.GenSid()
|
||||
session := &NatHoleSession{
|
||||
session := &Session{
|
||||
Sid: sid,
|
||||
VisitorAddr: raddr,
|
||||
NotifyCh: make(chan struct{}, 0),
|
||||
@@ -157,7 +157,7 @@ func (nc *NatHoleController) HandleVisitor(m *msg.NatHoleVisitor, raddr *net.UDP
|
||||
}
|
||||
}
|
||||
|
||||
func (nc *NatHoleController) HandleClient(m *msg.NatHoleClient, raddr *net.UDPAddr) {
|
||||
func (nc *Controller) HandleClient(m *msg.NatHoleClient, raddr *net.UDPAddr) {
|
||||
nc.mu.RLock()
|
||||
session, ok := nc.sessions[m.Sid]
|
||||
nc.mu.RUnlock()
|
||||
@@ -172,7 +172,7 @@ func (nc *NatHoleController) HandleClient(m *msg.NatHoleClient, raddr *net.UDPAd
|
||||
nc.listener.WriteToUDP(resp, raddr)
|
||||
}
|
||||
|
||||
func (nc *NatHoleController) GenNatHoleResponse(session *NatHoleSession, errInfo string) []byte {
|
||||
func (nc *Controller) GenNatHoleResponse(session *Session, errInfo string) []byte {
|
||||
var (
|
||||
sid string
|
||||
visitorAddr string
|
||||
@@ -197,7 +197,7 @@ func (nc *NatHoleController) GenNatHoleResponse(session *NatHoleSession, errInfo
|
||||
return b.Bytes()
|
||||
}
|
||||
|
||||
type NatHoleSession struct {
|
||||
type Session struct {
|
||||
Sid string
|
||||
VisitorAddr *net.UDPAddr
|
||||
ClientAddr *net.UDPAddr
|
||||
@@ -205,7 +205,7 @@ type NatHoleSession struct {
|
||||
NotifyCh chan struct{}
|
||||
}
|
||||
|
||||
type NatHoleClientCfg struct {
|
||||
type ClientCfg struct {
|
||||
Name string
|
||||
Sk string
|
||||
SidCh chan *SidRequest
|
@@ -23,7 +23,7 @@ import (
|
||||
"net/http/httputil"
|
||||
"strings"
|
||||
|
||||
frpNet "github.com/fatedier/frp/utils/net"
|
||||
frpNet "github.com/fatedier/frp/pkg/util/net"
|
||||
)
|
||||
|
||||
const PluginHTTP2HTTPS = "http2https"
|
@@ -22,31 +22,31 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
frpNet "github.com/fatedier/frp/utils/net"
|
||||
frpNet "github.com/fatedier/frp/pkg/util/net"
|
||||
|
||||
frpIo "github.com/fatedier/golib/io"
|
||||
gnet "github.com/fatedier/golib/net"
|
||||
)
|
||||
|
||||
const PluginHttpProxy = "http_proxy"
|
||||
const PluginHTTPProxy = "http_proxy"
|
||||
|
||||
func init() {
|
||||
Register(PluginHttpProxy, NewHttpProxyPlugin)
|
||||
Register(PluginHTTPProxy, NewHTTPProxyPlugin)
|
||||
}
|
||||
|
||||
type HttpProxy struct {
|
||||
type HTTPProxy struct {
|
||||
l *Listener
|
||||
s *http.Server
|
||||
AuthUser string
|
||||
AuthPasswd string
|
||||
}
|
||||
|
||||
func NewHttpProxyPlugin(params map[string]string) (Plugin, error) {
|
||||
func NewHTTPProxyPlugin(params map[string]string) (Plugin, error) {
|
||||
user := params["plugin_http_user"]
|
||||
passwd := params["plugin_http_passwd"]
|
||||
listener := NewProxyListener()
|
||||
|
||||
hp := &HttpProxy{
|
||||
hp := &HTTPProxy{
|
||||
l: listener,
|
||||
AuthUser: user,
|
||||
AuthPasswd: passwd,
|
||||
@@ -60,11 +60,11 @@ func NewHttpProxyPlugin(params map[string]string) (Plugin, error) {
|
||||
return hp, nil
|
||||
}
|
||||
|
||||
func (hp *HttpProxy) Name() string {
|
||||
return PluginHttpProxy
|
||||
func (hp *HTTPProxy) Name() string {
|
||||
return PluginHTTPProxy
|
||||
}
|
||||
|
||||
func (hp *HttpProxy) Handle(conn io.ReadWriteCloser, realConn net.Conn, extraBufToLocal []byte) {
|
||||
func (hp *HTTPProxy) Handle(conn io.ReadWriteCloser, realConn net.Conn, extraBufToLocal []byte) {
|
||||
wrapConn := frpNet.WrapReadWriteCloserToConn(conn, realConn)
|
||||
|
||||
sc, rd := gnet.NewSharedConn(wrapConn)
|
||||
@@ -90,13 +90,13 @@ func (hp *HttpProxy) Handle(conn io.ReadWriteCloser, realConn net.Conn, extraBuf
|
||||
return
|
||||
}
|
||||
|
||||
func (hp *HttpProxy) Close() error {
|
||||
func (hp *HTTPProxy) Close() error {
|
||||
hp.s.Close()
|
||||
hp.l.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hp *HttpProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
func (hp *HTTPProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
if ok := hp.Auth(req); !ok {
|
||||
rw.Header().Set("Proxy-Authenticate", "Basic")
|
||||
rw.WriteHeader(http.StatusProxyAuthRequired)
|
||||
@@ -108,11 +108,11 @@ func (hp *HttpProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
// Connect request is handled in Handle function.
|
||||
hp.ConnectHandler(rw, req)
|
||||
} else {
|
||||
hp.HttpHandler(rw, req)
|
||||
hp.HTTPHandler(rw, req)
|
||||
}
|
||||
}
|
||||
|
||||
func (hp *HttpProxy) HttpHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
func (hp *HTTPProxy) HTTPHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
removeProxyHeaders(req)
|
||||
|
||||
resp, err := http.DefaultTransport.RoundTrip(req)
|
||||
@@ -134,7 +134,7 @@ func (hp *HttpProxy) HttpHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
// deprecated
|
||||
// Hijack needs to SetReadDeadline on the Conn of the request, but if we use stream compression here,
|
||||
// we may always get i/o timeout error.
|
||||
func (hp *HttpProxy) ConnectHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
func (hp *HTTPProxy) ConnectHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
hj, ok := rw.(http.Hijacker)
|
||||
if !ok {
|
||||
rw.WriteHeader(http.StatusInternalServerError)
|
||||
@@ -158,7 +158,7 @@ func (hp *HttpProxy) ConnectHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
go frpIo.Join(remote, client)
|
||||
}
|
||||
|
||||
func (hp *HttpProxy) Auth(req *http.Request) bool {
|
||||
func (hp *HTTPProxy) Auth(req *http.Request) bool {
|
||||
if hp.AuthUser == "" && hp.AuthPasswd == "" {
|
||||
return true
|
||||
}
|
||||
@@ -184,7 +184,7 @@ func (hp *HttpProxy) Auth(req *http.Request) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (hp *HttpProxy) handleConnectReq(req *http.Request, rwc io.ReadWriteCloser) {
|
||||
func (hp *HTTPProxy) handleConnectReq(req *http.Request, rwc io.ReadWriteCloser) {
|
||||
defer rwc.Close()
|
||||
if ok := hp.Auth(req); !ok {
|
||||
res := getBadResponse()
|
||||
@@ -231,6 +231,7 @@ func removeProxyHeaders(req *http.Request) {
|
||||
func getBadResponse() *http.Response {
|
||||
header := make(map[string][]string)
|
||||
header["Proxy-Authenticate"] = []string{"Basic"}
|
||||
header["Connection"] = []string{"close"}
|
||||
res := &http.Response{
|
||||
Status: "407 Not authorized",
|
||||
StatusCode: 407,
|
@@ -23,7 +23,7 @@ import (
|
||||
"net/http/httputil"
|
||||
"strings"
|
||||
|
||||
frpNet "github.com/fatedier/frp/utils/net"
|
||||
frpNet "github.com/fatedier/frp/pkg/util/net"
|
||||
)
|
||||
|
||||
const PluginHTTPS2HTTP = "https2http"
|
@@ -20,7 +20,7 @@ import (
|
||||
"log"
|
||||
"net"
|
||||
|
||||
frpNet "github.com/fatedier/frp/utils/net"
|
||||
frpNet "github.com/fatedier/frp/pkg/util/net"
|
||||
|
||||
gosocks5 "github.com/armon/go-socks5"
|
||||
)
|
@@ -19,7 +19,7 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
frpNet "github.com/fatedier/frp/utils/net"
|
||||
frpNet "github.com/fatedier/frp/pkg/util/net"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
@@ -64,8 +64,8 @@ func NewStaticFilePlugin(params map[string]string) (Plugin, error) {
|
||||
}
|
||||
|
||||
router := mux.NewRouter()
|
||||
router.Use(frpNet.NewHttpAuthMiddleware(httpUser, httpPasswd).Middleware)
|
||||
router.PathPrefix(prefix).Handler(frpNet.MakeHttpGzipHandler(http.StripPrefix(prefix, http.FileServer(http.Dir(localPath))))).Methods("GET")
|
||||
router.Use(frpNet.NewHTTPAuthMiddleware(httpUser, httpPasswd).Middleware)
|
||||
router.PathPrefix(prefix).Handler(frpNet.MakeHTTPGzipHandler(http.StripPrefix(prefix, http.FileServer(http.Dir(localPath))))).Methods("GET")
|
||||
sp.s = &http.Server{
|
||||
Handler: router,
|
||||
}
|
@@ -17,19 +17,22 @@ package plugin
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type HTTPPluginOptions struct {
|
||||
Name string
|
||||
Addr string
|
||||
Path string
|
||||
Ops []string
|
||||
Name string
|
||||
Addr string
|
||||
Path string
|
||||
Ops []string
|
||||
TLSVerify bool
|
||||
}
|
||||
|
||||
type httpPlugin struct {
|
||||
@@ -40,10 +43,25 @@ type httpPlugin struct {
|
||||
}
|
||||
|
||||
func NewHTTPPluginOptions(options HTTPPluginOptions) Plugin {
|
||||
var url = fmt.Sprintf("%s%s", options.Addr, options.Path)
|
||||
|
||||
var client *http.Client
|
||||
if strings.HasPrefix(url, "https://") {
|
||||
tr := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: options.TLSVerify == false},
|
||||
}
|
||||
client = &http.Client{Transport: tr}
|
||||
} else {
|
||||
client = &http.Client{}
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(url, "https://") && !strings.HasPrefix(url, "http://") {
|
||||
url = "http://" + url
|
||||
}
|
||||
return &httpPlugin{
|
||||
options: options,
|
||||
url: fmt.Sprintf("http://%s%s", options.Addr, options.Path),
|
||||
client: &http.Client{},
|
||||
url: url,
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
@@ -19,8 +19,8 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/fatedier/frp/utils/util"
|
||||
"github.com/fatedier/frp/utils/xlog"
|
||||
"github.com/fatedier/frp/pkg/util/util"
|
||||
"github.com/fatedier/frp/pkg/util/xlog"
|
||||
)
|
||||
|
||||
type Manager struct {
|
||||
@@ -52,7 +52,7 @@ func (m *Manager) Register(p Plugin) {
|
||||
m.pingPlugins = append(m.pingPlugins, p)
|
||||
}
|
||||
if p.IsSupport(OpNewWorkConn) {
|
||||
m.pingPlugins = append(m.pingPlugins, p)
|
||||
m.newWorkConnPlugins = append(m.newWorkConnPlugins, p)
|
||||
}
|
||||
if p.IsSupport(OpNewUserConn) {
|
||||
m.newUserConnPlugins = append(m.newUserConnPlugins, p)
|
||||
@@ -72,7 +72,7 @@ func (m *Manager) Login(content *LoginContent) (*LoginContent, error) {
|
||||
retContent interface{}
|
||||
err error
|
||||
)
|
||||
reqid, _ := util.RandId()
|
||||
reqid, _ := util.RandID()
|
||||
xl := xlog.New().AppendPrefix("reqid: " + reqid)
|
||||
ctx := xlog.NewContext(context.Background(), xl)
|
||||
ctx = NewReqidContext(ctx, reqid)
|
||||
@@ -106,7 +106,7 @@ func (m *Manager) NewProxy(content *NewProxyContent) (*NewProxyContent, error) {
|
||||
retContent interface{}
|
||||
err error
|
||||
)
|
||||
reqid, _ := util.RandId()
|
||||
reqid, _ := util.RandID()
|
||||
xl := xlog.New().AppendPrefix("reqid: " + reqid)
|
||||
ctx := xlog.NewContext(context.Background(), xl)
|
||||
ctx = NewReqidContext(ctx, reqid)
|
||||
@@ -140,7 +140,7 @@ func (m *Manager) Ping(content *PingContent) (*PingContent, error) {
|
||||
retContent interface{}
|
||||
err error
|
||||
)
|
||||
reqid, _ := util.RandId()
|
||||
reqid, _ := util.RandID()
|
||||
xl := xlog.New().AppendPrefix("reqid: " + reqid)
|
||||
ctx := xlog.NewContext(context.Background(), xl)
|
||||
ctx = NewReqidContext(ctx, reqid)
|
||||
@@ -174,7 +174,7 @@ func (m *Manager) NewWorkConn(content *NewWorkConnContent) (*NewWorkConnContent,
|
||||
retContent interface{}
|
||||
err error
|
||||
)
|
||||
reqid, _ := util.RandId()
|
||||
reqid, _ := util.RandID()
|
||||
xl := xlog.New().AppendPrefix("reqid: " + reqid)
|
||||
ctx := xlog.NewContext(context.Background(), xl)
|
||||
ctx = NewReqidContext(ctx, reqid)
|
||||
@@ -208,7 +208,7 @@ func (m *Manager) NewUserConn(content *NewUserConnContent) (*NewUserConnContent,
|
||||
retContent interface{}
|
||||
err error
|
||||
)
|
||||
reqid, _ := util.RandId()
|
||||
reqid, _ := util.RandID()
|
||||
xl := xlog.New().AppendPrefix("reqid: " + reqid)
|
||||
ctx := xlog.NewContext(context.Background(), xl)
|
||||
ctx = NewReqidContext(ctx, reqid)
|
@@ -15,7 +15,7 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"github.com/fatedier/frp/models/msg"
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
)
|
||||
|
||||
type Request struct {
|
||||
@@ -38,7 +38,7 @@ type LoginContent struct {
|
||||
type UserInfo struct {
|
||||
User string `json:"user"`
|
||||
Metas map[string]string `json:"metas"`
|
||||
RunId string `json:"run_id"`
|
||||
RunID string `json:"run_id"`
|
||||
}
|
||||
|
||||
type NewProxyContent struct {
|
@@ -20,26 +20,26 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fatedier/frp/models/msg"
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
|
||||
"github.com/fatedier/golib/errors"
|
||||
"github.com/fatedier/golib/pool"
|
||||
)
|
||||
|
||||
func NewUdpPacket(buf []byte, laddr, raddr *net.UDPAddr) *msg.UdpPacket {
|
||||
return &msg.UdpPacket{
|
||||
func NewUDPPacket(buf []byte, laddr, raddr *net.UDPAddr) *msg.UDPPacket {
|
||||
return &msg.UDPPacket{
|
||||
Content: base64.StdEncoding.EncodeToString(buf),
|
||||
LocalAddr: laddr,
|
||||
RemoteAddr: raddr,
|
||||
}
|
||||
}
|
||||
|
||||
func GetContent(m *msg.UdpPacket) (buf []byte, err error) {
|
||||
func GetContent(m *msg.UDPPacket) (buf []byte, err error) {
|
||||
buf, err = base64.StdEncoding.DecodeString(m.Content)
|
||||
return
|
||||
}
|
||||
|
||||
func ForwardUserConn(udpConn *net.UDPConn, readCh <-chan *msg.UdpPacket, sendCh chan<- *msg.UdpPacket) {
|
||||
func ForwardUserConn(udpConn *net.UDPConn, readCh <-chan *msg.UDPPacket, sendCh chan<- *msg.UDPPacket, bufSize int) {
|
||||
// read
|
||||
go func() {
|
||||
for udpMsg := range readCh {
|
||||
@@ -52,7 +52,7 @@ func ForwardUserConn(udpConn *net.UDPConn, readCh <-chan *msg.UdpPacket, sendCh
|
||||
}()
|
||||
|
||||
// write
|
||||
buf := pool.GetBuf(1500)
|
||||
buf := pool.GetBuf(bufSize)
|
||||
defer pool.PutBuf(buf)
|
||||
for {
|
||||
n, remoteAddr, err := udpConn.ReadFromUDP(buf)
|
||||
@@ -60,7 +60,7 @@ func ForwardUserConn(udpConn *net.UDPConn, readCh <-chan *msg.UdpPacket, sendCh
|
||||
return
|
||||
}
|
||||
// buf[:n] will be encoded to string, so the bytes can be reused
|
||||
udpMsg := NewUdpPacket(buf[:n], nil, remoteAddr)
|
||||
udpMsg := NewUDPPacket(buf[:n], nil, remoteAddr)
|
||||
|
||||
select {
|
||||
case sendCh <- udpMsg:
|
||||
@@ -69,7 +69,7 @@ func ForwardUserConn(udpConn *net.UDPConn, readCh <-chan *msg.UdpPacket, sendCh
|
||||
}
|
||||
}
|
||||
|
||||
func Forwarder(dstAddr *net.UDPAddr, readCh <-chan *msg.UdpPacket, sendCh chan<- msg.Message) {
|
||||
func Forwarder(dstAddr *net.UDPAddr, readCh <-chan *msg.UDPPacket, sendCh chan<- msg.Message, bufSize int) {
|
||||
var (
|
||||
mu sync.RWMutex
|
||||
)
|
||||
@@ -85,7 +85,7 @@ func Forwarder(dstAddr *net.UDPAddr, readCh <-chan *msg.UdpPacket, sendCh chan<-
|
||||
udpConn.Close()
|
||||
}()
|
||||
|
||||
buf := pool.GetBuf(1500)
|
||||
buf := pool.GetBuf(bufSize)
|
||||
for {
|
||||
udpConn.SetReadDeadline(time.Now().Add(30 * time.Second))
|
||||
n, _, err := udpConn.ReadFromUDP(buf)
|
||||
@@ -93,7 +93,7 @@ func Forwarder(dstAddr *net.UDPAddr, readCh <-chan *msg.UdpPacket, sendCh chan<-
|
||||
return
|
||||
}
|
||||
|
||||
udpMsg := NewUdpPacket(buf[:n], nil, raddr)
|
||||
udpMsg := NewUDPPacket(buf[:n], nil, raddr)
|
||||
if err = errors.PanicToError(func() {
|
||||
select {
|
||||
case sendCh <- udpMsg:
|
@@ -10,7 +10,7 @@ func TestUdpPacket(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
buf := []byte("hello world")
|
||||
udpMsg := NewUdpPacket(buf, nil, nil)
|
||||
udpMsg := NewUDPPacket(buf, nil, nil)
|
||||
|
||||
newBuf, err := GetContent(udpMsg)
|
||||
assert.NoError(err)
|
117
pkg/transport/tls.go
Normal file
117
pkg/transport/tls.go
Normal file
@@ -0,0 +1,117 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
func newCustomTLSKeyPair(certfile, keyfile string) (*tls.Certificate, error) {
|
||||
tlsCert, err := tls.LoadX509KeyPair(certfile, keyfile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &tlsCert, nil
|
||||
}
|
||||
|
||||
func newRandomTLSKeyPair() *tls.Certificate {
|
||||
key, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
template := x509.Certificate{SerialNumber: big.NewInt(1)}
|
||||
certDER, err := x509.CreateCertificate(
|
||||
rand.Reader,
|
||||
&template,
|
||||
&template,
|
||||
&key.PublicKey,
|
||||
key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)})
|
||||
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
|
||||
|
||||
tlsCert, err := tls.X509KeyPair(certPEM, keyPEM)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &tlsCert
|
||||
}
|
||||
|
||||
// Only supprt one ca file to add
|
||||
func newCertPool(caPath string) (*x509.CertPool, error) {
|
||||
pool := x509.NewCertPool()
|
||||
|
||||
caCrt, err := ioutil.ReadFile(caPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pool.AppendCertsFromPEM(caCrt)
|
||||
|
||||
return pool, nil
|
||||
}
|
||||
|
||||
func NewServerTLSConfig(certPath, keyPath, caPath string) (*tls.Config, error) {
|
||||
var base = &tls.Config{}
|
||||
|
||||
if certPath == "" || keyPath == "" {
|
||||
// server will generate tls conf by itself
|
||||
cert := newRandomTLSKeyPair()
|
||||
base.Certificates = []tls.Certificate{*cert}
|
||||
} else {
|
||||
cert, err := newCustomTLSKeyPair(certPath, keyPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
base.Certificates = []tls.Certificate{*cert}
|
||||
}
|
||||
|
||||
if caPath != "" {
|
||||
pool, err := newCertPool(caPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
base.ClientAuth = tls.RequireAndVerifyClientCert
|
||||
base.ClientCAs = pool
|
||||
}
|
||||
|
||||
return base, nil
|
||||
}
|
||||
|
||||
func NewClientTLSConfig(certPath, keyPath, caPath, servearName string) (*tls.Config, error) {
|
||||
var base = &tls.Config{}
|
||||
|
||||
if certPath == "" || keyPath == "" {
|
||||
// client will not generate tls conf by itself
|
||||
} else {
|
||||
cert, err := newCustomTLSKeyPair(certPath, keyPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
base.Certificates = []tls.Certificate{*cert}
|
||||
}
|
||||
|
||||
if caPath != "" {
|
||||
pool, err := newCertPool(caPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
base.RootCAs = pool
|
||||
base.ServerName = servearName
|
||||
base.InsecureSkipVerify = false
|
||||
} else {
|
||||
base.InsecureSkipVerify = true
|
||||
}
|
||||
|
||||
return base, nil
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user