Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c586e2b78 | ||
|
|
6917ff3347 | ||
|
|
284bb83d64 | ||
|
|
1b29112a2c | ||
|
|
b9afc98230 | ||
|
|
20761d2183 | ||
|
|
1ab07c81ab | ||
|
|
07efc2c8de | ||
|
|
ef8737063b | ||
|
|
b5e0fa4895 | ||
|
|
02513a9449 | ||
|
|
0859452475 | ||
|
|
42d18ca1d3 | ||
|
|
08b3715bda | ||
|
|
253783573a | ||
|
|
56dc3fdc07 | ||
|
|
af20893551 | ||
|
|
85178223e0 | ||
|
|
e116bf8897 | ||
|
|
0fffedebd7 | ||
|
|
1e259b5c6f | ||
|
|
7bb5bb86dc | ||
|
|
18716cb3a2 | ||
|
|
1aca777c6d | ||
|
|
3a5b47b84a | ||
|
|
8bda30c4cf | ||
|
|
03ef384c48 | ||
|
|
5ace1eef1d | ||
|
|
d270b4a468 | ||
|
|
6154d4173a | ||
|
|
70067d67b9 | ||
|
|
8befdbc89c | ||
|
|
900b975c6a | ||
|
|
2ddb03a6c7 | ||
|
|
4145a31e5b | ||
|
|
96717f0c33 | ||
|
|
09348211b6 | ||
|
|
179f9d63ab | ||
|
|
7692446fd8 | ||
|
|
0bebee1537 | ||
|
|
61569c3a92 | ||
|
|
0d6e10ad33 | ||
|
|
77a6300dae | ||
|
|
8f268b8b56 | ||
|
|
efb5710727 | ||
|
|
7fc0b21764 | ||
|
|
2f524010a1 | ||
|
|
c537240d3d | ||
|
|
d3640f7519 | ||
|
|
575326bed1 |
13
AUTHORIZATION.md
Normal file
13
AUTHORIZATION.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# GoProxy特殊授权
|
||||||
|
|
||||||
|
1.goproxy采用GPLv3源代码开放协议,未经许可,基于本项目开发的软件,衍生软件,相关软件,必须严格遵守GPLv3,否则一经发现,
|
||||||
|
将严厉追责.
|
||||||
|
|
||||||
|
2.如果公司或个人使用本项目代码开发相关软件,衍生软件,又不想遵守GPLv3协议,需要取得作者的"GoProxy特殊授权"书面授权.
|
||||||
|
|
||||||
|
3.如果本页面查询不到"GoProxy特殊授权"书面授权信息,则"GoProxy特殊授权"书面授权无效.
|
||||||
|
|
||||||
|
4.下面列出了有效的授权编号和有效期.
|
||||||
|
|
||||||
|
授权编号 | 授权有效期
|
||||||
|
:--- | :---
|
||||||
16
CHANGELOG
16
CHANGELOG
@ -1,5 +1,21 @@
|
|||||||
proxy更新日志
|
proxy更新日志
|
||||||
|
|
||||||
|
v6.2
|
||||||
|
1.修复encrypt.Conn释放内存,导致的潜在panic问题.
|
||||||
|
2.修复了basic认证,处理认证文件没有正确处理注释的bug.
|
||||||
|
3.修正了ssh中转手册参数-A调整为-D.
|
||||||
|
|
||||||
|
v6.1
|
||||||
|
1.黑白名单支持设置顶级域了,比如:com,匹配所有的.com域名
|
||||||
|
2.优化TCPS内存释放.
|
||||||
|
3.优化了域名检查.
|
||||||
|
4.内网穿透增加了TCPS和TOU协议,
|
||||||
|
TCPS提供了多种自定义加密TCP方式传输.
|
||||||
|
TOU提供了TCP over UDP,多种自定义加密UDP方式传输TCP数据.
|
||||||
|
5.优化了DST,防止意外crash.
|
||||||
|
6.修复了mapx的Keys()方法的bug导致内网穿透bridge不稳定的问题.
|
||||||
|
7.修复了部分服务不能绑定IPv6地址的bug.
|
||||||
|
|
||||||
v6.0 企业版开源啦
|
v6.0 企业版开源啦
|
||||||
本次更新主要是把企业版开源,把企业版代码合并到现在的开源goproxy当中,继续遵循GPLv3,免费开源,
|
本次更新主要是把企业版开源,把企业版代码合并到现在的开源goproxy当中,继续遵循GPLv3,免费开源,
|
||||||
之所以直接跳过5.x,用6.0版本号是为了与现有开源版本做一个明显的区分,下面功能主要来自企业版.
|
之所以直接跳过5.x,用6.0版本号是为了与现有开源版本做一个明显的区分,下面功能主要来自企业版.
|
||||||
|
|||||||
203
README.md
203
README.md
@ -1,5 +1,5 @@
|
|||||||
<img src="https://github.com/snail007/goproxy/blob/master/docs/images/logo.jpg?raw=true" width="200"/>
|
<img src="https://github.com/snail007/goproxy/blob/master/docs/images/logo.jpg?raw=true" width="200"/>
|
||||||
Proxy is a high performance HTTP, HTTPS, HTTPS, websocket, TCP, UDP, Socks5 proxy server implemented by golang. It supports parent proxy,nat forward,TCP/UDP port forwarding, SSH transfer, TLS encrypted transmission, protocol conversion. you can expose a local server behind a NAT or firewall to the internet, secure DNS proxy.
|
Proxy is a high performance HTTP, HTTPS, HTTPS, websocket, TCP, UDP, Socks5, ss proxy server implemented by golang. It supports parent proxy,nat forward,TCP/UDP port forwarding, SSH transfer, TLS encrypted transmission, protocol conversion. you can expose a local server behind a NAT or firewall to the internet, secure DNS proxy.
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -10,7 +10,9 @@ Proxy is a high performance HTTP, HTTPS, HTTPS, websocket, TCP, UDP, Socks5 prox
|
|||||||
|
|
||||||
**[全平台图形界面版本](/gui/README.md)**
|
**[全平台图形界面版本](/gui/README.md)**
|
||||||
|
|
||||||
**[全平台SDK](/sdk/README.md)**
|
**[全平台SDK](/sdk/README.md)**
|
||||||
|
|
||||||
|
**[GoProxy特殊授权](/AUTHORIZATION.md)**
|
||||||
|
|
||||||
### How to contribute to the code (Pull Request)?
|
### How to contribute to the code (Pull Request)?
|
||||||
|
|
||||||
@ -33,10 +35,15 @@ PR needs to explain what changes have been made and why you change them.
|
|||||||
- The integrated external API, HTTP (S): SOCKS5 proxy authentication can be integrated with the external HTTP API, which can easily control the user's access through the external system.
|
- The integrated external API, HTTP (S): SOCKS5 proxy authentication can be integrated with the external HTTP API, which can easily control the user's access through the external system.
|
||||||
- Reverse proxy: goproxy supports directly parsing the domain to proxy monitor IP, and then proxy will help you to access the HTTP (S) site that you need to access.
|
- Reverse proxy: goproxy supports directly parsing the domain to proxy monitor IP, and then proxy will help you to access the HTTP (S) site that you need to access.
|
||||||
- Transparent proxy: with the iptables, goproxy can directly forward the 80 and 443 port's traffic to proxy in the gateway, and can realize the unaware intelligent router proxy.
|
- Transparent proxy: with the iptables, goproxy can directly forward the 80 and 443 port's traffic to proxy in the gateway, and can realize the unaware intelligent router proxy.
|
||||||
- Protocol conversion: The existing HTTP (S) or SOCKS5 proxy can be converted to a proxy which support both HTTP (S) and SOCKS5 by one port, but the converted SOCKS5 proxy does not support the UDP function.Also support powerful cascading authentication.
|
- Protocol conversion: The existing HTTP (S) or SOCKS5 or ss proxy can be converted to a proxy which support HTTP (S), SOCKS5 and ss by one port, if the converted SOCKS5 and ss proxy's parent proxy is SOCKS5, which can support the UDP function.Also support powerful cascading authentication.
|
||||||
- Custom underlying encrypted transmission, HTTP(s)\sps\socks proxy can encrypt TCP data through TLS standard encryption and KCP protocol encryption. In addition, it also supports custom encryption after TLS and KCP. That is to say, custom encryption and tls|kcp can be used together. The internal uses AES256 encryption, and it only needs to define one password by yourself when is used.
|
- Custom underlying encrypted transmission, HTTP(s)\sps\socks proxy can encrypt TCP data through TLS standard encryption and KCP protocol encryption. In addition, it also supports custom encryption after TLS and KCP. That is to say, custom encryption and tls|kcp can be used together. The internal uses AES256 encryption, and it only needs to define one password by yourself when is used.
|
||||||
- Low level compression and efficient transmission,The HTTP(s)\sps\socks proxy can encrypt TCP data through a custom encryption and TLS standard encryption and KCP protocol encryption, and can also compress the data after encryption. That is to say, the compression and custom encryption and tls|kcp can be used together.
|
- Low level compression and efficient transmission,The HTTP(s)\sps\socks proxy can encrypt TCP data through a custom encryption and TLS standard encryption and KCP protocol encryption, and can also compress the data after encryption. That is to say, the compression and custom encryption and tls|kcp can be used together.
|
||||||
- The secure DNS proxy, Through the DNS proxy provided by the local proxy, you can encrypted communicate with the father proxy to realize the DNS query of security and pollution prevention.
|
- The secure DNS proxy, Through the DNS proxy provided by the local proxy, you can encrypted communicate with the father proxy to realize the DNS query of security and pollution prevention.
|
||||||
|
- Load balance,High availability,HTTP(S)\SOCKS5\SPS proxy support Superior load balance and high availability. Multiple superiors repeat -P parameters.
|
||||||
|
- Designated exporting IP,HTTP(S)\SOCKS5\SPS proxy supports the client to connect with the entry IP,Using the entry IP as the exporting IP to visit the target website。If the entry IP is the intranet IP,Exporting IP will not use entry IP
|
||||||
|
- Support speed limit. HTTP (S) \SOCKS5\SPS proxy supports speed limit.
|
||||||
|
- SOCKS5 proxy supports cascade authentication.
|
||||||
|
- Certificate parameters use base64 data. By default, the - C, - K parameters are the path of the CRT certificate and key file. If “base64://” begins, the subsequent data is thought to be Base64 encoded which will be decoded and used.
|
||||||
|
|
||||||
### Why need these?
|
### Why need these?
|
||||||
- Because for some reason, we cannot access our services elsewhere. We can build a secure tunnel to access our services through multiple connected proxy nodes.
|
- Because for some reason, we cannot access our services elsewhere. We can build a secure tunnel to access our services through multiple connected proxy nodes.
|
||||||
@ -48,7 +55,7 @@ PR needs to explain what changes have been made and why you change them.
|
|||||||
- ...
|
- ...
|
||||||
|
|
||||||
|
|
||||||
This page is the v5.4 manual, and the other version of the manual can be checked by the following [link](docs/old-release.md).
|
This page is the v6.0 manual, and the other version of the manual can be checked by the following [link](docs/old-release.md).
|
||||||
|
|
||||||
|
|
||||||
### How to find the organization?
|
### How to find the organization?
|
||||||
@ -72,6 +79,7 @@ This page is the v5.4 manual, and the other version of the manual can be checked
|
|||||||
- [Safety advice](#safety-advice)
|
- [Safety advice](#safety-advice)
|
||||||
|
|
||||||
### Manual catalogues
|
### Manual catalogues
|
||||||
|
- [Load balance and high available](#load-balance-and-high-available)
|
||||||
- [1.HTTP proxy](#1http-proxy)
|
- [1.HTTP proxy](#1http-proxy)
|
||||||
- [1.1 Common HTTP proxy](#11common-http-proxy)
|
- [1.1 Common HTTP proxy](#11common-http-proxy)
|
||||||
- [1.2 Common HTTP second level proxy](#12common-http-second-level-proxy)
|
- [1.2 Common HTTP second level proxy](#12common-http-second-level-proxy)
|
||||||
@ -88,7 +96,11 @@ This page is the v5.4 manual, and the other version of the manual can be checked
|
|||||||
- [1.11 Custom DNS](#111custom-dns)
|
- [1.11 Custom DNS](#111custom-dns)
|
||||||
- [1.12 Custom encryption](#112-custom-encryption)
|
- [1.12 Custom encryption](#112-custom-encryption)
|
||||||
- [1.13 Compressed transmission](#113-compressed-transmission)
|
- [1.13 Compressed transmission](#113-compressed-transmission)
|
||||||
- [1.14 View help](#114view-help)
|
- [1.14 load balance](#114-load-balance)
|
||||||
|
- [1.15 speed limit](#115-speed-limit)
|
||||||
|
- [1.16 Designated exporting IP](#116-designated-export-ip)
|
||||||
|
- [1.17 Certificate parameters using Base64 data](#117-certificate-parameters-using-Base64-data)
|
||||||
|
- [1.18 View help](#118view-help)
|
||||||
- [2.TCP proxy](#2tcp-proxy)
|
- [2.TCP proxy](#2tcp-proxy)
|
||||||
- [2.1 Common TCP first level proxy](#21common-tcp-first-level-proxy)
|
- [2.1 Common TCP first level proxy](#21common-tcp-first-level-proxy)
|
||||||
- [2.2 Common TCP second level proxy](#22common-tcp-second-level-proxy)
|
- [2.2 Common TCP second level proxy](#22common-tcp-second-level-proxy)
|
||||||
@ -128,17 +140,27 @@ This page is the v5.4 manual, and the other version of the manual can be checked
|
|||||||
- [5.9 Custom DNS](#59custom-dns)
|
- [5.9 Custom DNS](#59custom-dns)
|
||||||
- [5.10 Custom encryption](#510custom-encryption)
|
- [5.10 Custom encryption](#510custom-encryption)
|
||||||
- [5.11 Compressed transmission](#511compressed-transmission)
|
- [5.11 Compressed transmission](#511compressed-transmission)
|
||||||
- [5.12 View help](#512view-help)
|
- [5.12 load balance](#512-load-balance)
|
||||||
|
- [5.13 speed limit](#513-speed-limit)
|
||||||
|
- [5.14 Designated exporting IP](#514-designated-exporting-ip)
|
||||||
|
- [5.15 Cascade authentication](#515-cascade-authentication)
|
||||||
|
- [5.16 Certificate parameters using Base64 data](#516-certificate-parameters-using-base64-data)
|
||||||
|
- [5.17 View help](#517view-help)
|
||||||
- [6.Proxy protocol conversion](#6proxy-protocol-conversion)
|
- [6.Proxy protocol conversion](#6proxy-protocol-conversion)
|
||||||
- [6.1 Functional introduction](#61functional-introduction)
|
- [6.1 Functional introduction](#61functional-introduction)
|
||||||
- [6.2 HTTP(S) to HTTP(S) + SOCKS5](#62http-to-http-socks5)
|
- [6.2 HTTP(S) to HTTP(S) + SOCKS5](#62http-to-http-socks5)
|
||||||
- [6.3 SOCKS5 to HTTP(S) + SOCKS5](#63socks5-to-http-socks5)
|
- [6.3 SOCKS5 to HTTP(S) + SOCKS5](#63socks5-to-http-socks5)
|
||||||
- [6.4 Chain style connection](#64chain-style-connection)
|
- [6.4 SS to HTTP(S)+SOCKS5+SS](#64-ss-to-httpssocks5ss)
|
||||||
- [6.5 Listening on multiple ports](#65listening-on-multiple-ports)
|
- [6.5 Chain style connection](#65chain-style-connection)
|
||||||
- [6.6 Authentication](#66authentication)
|
- [6.6 Listening on multiple ports](#66listening-on-multiple-ports)
|
||||||
- [6.7 Custom encryption](#67-custom-encryption)
|
- [6.7 Authentication](#67authentication)
|
||||||
- [6.8 Compressed transmission](#68-compressed-transmission)
|
- [6.8 Custom encryption](#68-custom-encryption)
|
||||||
- [6.9 View Help](#69view-help)
|
- [6.9 Compressed transmission](#69-compressed-transmission)
|
||||||
|
- [6.10 Disable-protocol](#610-disable-protocol)
|
||||||
|
- [6.11 speed limit](#611-speed-limit)
|
||||||
|
- [6.12 Designated exporting IP](#612-designated-exporting-ip)
|
||||||
|
- [6.13 Certificate parameters using Base64 data](#613-certificate-parameters-using-base64-data)
|
||||||
|
- [6.14 View Help](#614view-help)
|
||||||
- [7.KCP Configuration](#7kcp-configuration)
|
- [7.KCP Configuration](#7kcp-configuration)
|
||||||
- [7.1 Configuration introduction](#71configuration-introduction)
|
- [7.1 Configuration introduction](#71configuration-introduction)
|
||||||
- [7.2 Configuration details](#72configuration-details)
|
- [7.2 Configuration details](#72configuration-details)
|
||||||
@ -155,7 +177,7 @@ tips:all operations require root permissions.
|
|||||||
```shell
|
```shell
|
||||||
curl -L https://raw.githubusercontent.com/snail007/goproxy/master/install_auto.sh | bash
|
curl -L https://raw.githubusercontent.com/snail007/goproxy/master/install_auto.sh | bash
|
||||||
```
|
```
|
||||||
The installation is completed, the configuration directory is /etc/proxy, more detailed use of the method referred to the following manual for further understanding.
|
The installation is completed, the configuration directory is /etc/proxy, For more detailed usage, please refer to the manual above to further understand the functions you want to use.
|
||||||
If the installation fails or your VPS is not a linux64 system, please follow the semi-automatic step below:
|
If the installation fails or your VPS is not a linux64 system, please follow the semi-automatic step below:
|
||||||
|
|
||||||
#### Manual installation
|
#### Manual installation
|
||||||
@ -164,7 +186,7 @@ If the installation fails or your VPS is not a linux64 system, please follow the
|
|||||||
Download address: https://github.com/snail007/goproxy/releases
|
Download address: https://github.com/snail007/goproxy/releases
|
||||||
```shell
|
```shell
|
||||||
cd /root/proxy/
|
cd /root/proxy/
|
||||||
wget https://github.com/snail007/goproxy/releases/download/v5.4/proxy-linux-amd64.tar.gz
|
wget https://github.com/snail007/goproxy/releases/download/v6.0/proxy-linux-amd64.tar.gz
|
||||||
|
|
||||||
```
|
```
|
||||||
#### **2.Download the automatic installation script**
|
#### **2.Download the automatic installation script**
|
||||||
@ -179,10 +201,10 @@ chmod +x install.sh
|
|||||||
|
|
||||||
Dockerfile root of project uses multistage build and alpine project to comply with best practices. Uses golang 1.10.3 for building as noted in the project README.md and will be pretty small image. total extracted size will be 17.3MB for goproxy latest version.
|
Dockerfile root of project uses multistage build and alpine project to comply with best practices. Uses golang 1.10.3 for building as noted in the project README.md and will be pretty small image. total extracted size will be 17.3MB for goproxy latest version.
|
||||||
|
|
||||||
The default build process builds the master branch (latest commits/ cutting edge), and it can be configured to build specific version, just edit Dockerfile before build, following builds release version 5.4:
|
The default build process builds the master branch (latest commits/ cutting edge), and it can be configured to build specific version, just edit Dockerfile before build, following builds release version 6.0:
|
||||||
|
|
||||||
```
|
```
|
||||||
ARG GOPROXY_VERSION=v5.4
|
ARG GOPROXY_VERSION=v6.0
|
||||||
```
|
```
|
||||||
|
|
||||||
To Run:
|
To Run:
|
||||||
@ -261,6 +283,20 @@ When vps is behind the NAT, the network card IP on VPS is an internal network IP
|
|||||||
Assuming that your VPS outer external network IP is 23.23.23.23, the following command sets the 23.23.23.23 through the -g parameter.
|
Assuming that your VPS outer external network IP is 23.23.23.23, the following command sets the 23.23.23.23 through the -g parameter.
|
||||||
`./proxy http -g "23.23.23.23"`
|
`./proxy http -g "23.23.23.23"`
|
||||||
|
|
||||||
|
### **Load balance and high available**
|
||||||
|
HTTP(S)\SOCKS5\SPS proxy support Superior load balance and high availability. Multiple superiors repeat -P parameters.
|
||||||
|
Load balancing have 5 kinds of policy, It can be specified by the `--lb-method` parameter.:
|
||||||
|
roundrobin take turns
|
||||||
|
leastconn Using minimum connection number
|
||||||
|
leasttime Use minimum connection time
|
||||||
|
hash Use the client address to calculate a fixed superior
|
||||||
|
weight According to the weight and connection number of each superior, choose a superior
|
||||||
|
Tips:
|
||||||
|
The load balance check interval can be set by `--lb-retrytime`, unit milliseconds.
|
||||||
|
Load balancing connection timeout can be set by `--lb-timeout`, unit milliseconds.
|
||||||
|
If the load balance policy is weighted (weight), the -P format is: 2.2.2.2:3880@1,1 is the weight which is greater than 0.
|
||||||
|
If the load balance strategy is hash, the default is to select the parent based on the client address, and the parent can be selected by switching `- lb-hashtarget', using the access destination address.
|
||||||
|
|
||||||
### **1.HTTP proxy**
|
### **1.HTTP proxy**
|
||||||
#### **1.1.common HTTP proxy**
|
#### **1.1.common HTTP proxy**
|
||||||

|

|
||||||
@ -457,9 +493,34 @@ Second level VPS (ip:3.3.3.3) execution:
|
|||||||
`proxy http -T tcp -P 2.2.2.2:7777 -M -t tcp -m -p :8888`
|
`proxy http -T tcp -P 2.2.2.2:7777 -M -t tcp -m -p :8888`
|
||||||
Local third level execution:
|
Local third level execution:
|
||||||
`proxy http -T tcp -P 3.3.3.3:8888 -M -t tcp -p :8080`
|
`proxy http -T tcp -P 3.3.3.3:8888 -M -t tcp -p :8080`
|
||||||
through this way, When you visits the website by local proxy 8080, it visits the target website by compressed transmission with the parents proxy.
|
through this way, When you visits the website by local proxy 8080, it visits the target website by compressed transmission with the parents proxy.
|
||||||
|
|
||||||
#### **1.14.view help**
|
### **1.14 Load balance**
|
||||||
|
HTTP (S) proxy supports superior load balance, and multiple -P parameters can be repeated by multiple superiors.
|
||||||
|
`proxy http --lb-method=hash -T tcp -P 1.1.1.1:33080 -P 2.1.1.1:33080 -P 3.1.1.1:33080`
|
||||||
|
|
||||||
|
#### **1.14.1 Set retry interval and timeout time**
|
||||||
|
`proxy http --lb-method=leastconn --lb-retrytime 300 --lb-timeout 300 -T tcp -P 1.1.1.1:33080 -P 2.1.1.1:33080 -P 3.1.1.1:33080 -t tcp -p :33080`
|
||||||
|
|
||||||
|
#### **1.14.2 Set weight**
|
||||||
|
`proxy http --lb-method=weight -T tcp -P 1.1.1.1:33080@1 -P 2.1.1.1:33080@2 -P 3.1.1.1:33080@1 -t tcp -p :33080`
|
||||||
|
|
||||||
|
#### **1.14.3 Use target address to select superior**
|
||||||
|
`proxy http --lb-hashtarget --lb-method=leasttime -T tcp -P 1.1.1.1:33080 -P 2.1.1.1:33080 -P 3.1.1.1:33080 -t tcp -p :33080`
|
||||||
|
|
||||||
|
### **1.15 Speed limit**
|
||||||
|
The speed limit is 100K, which can be specified through the `-l` parameter, for example: 100K 1.5M. 0 means unlimited.
|
||||||
|
`proxy http -t tcp -p 2.2.2.2:33080 -l 100K`
|
||||||
|
|
||||||
|
### **1.16 Designated exporting IP**
|
||||||
|
The `- bind-listen` parameter opens the client's ability to access the target site with an entry IP connection, using the entry IP as the exporting IP. If the entry IP is the intranet IP, the exporting IP will not use the entry IP..
|
||||||
|
`proxy http -t tcp -p 2.2.2.2:33080 --bind-listen`
|
||||||
|
|
||||||
|
### **1.17 Certificate parameters using Base64 data**
|
||||||
|
By default, the -C and -K parameters are the paths of CRT certificates and key files,
|
||||||
|
If it is the beginning of base64://, then it is considered that the data behind is Base64 encoded and will be used after decoding.
|
||||||
|
|
||||||
|
#### **1.18.view help**
|
||||||
`./proxy help http`
|
`./proxy help http`
|
||||||
|
|
||||||
### **2.TCP proxy**
|
### **2.TCP proxy**
|
||||||
@ -866,43 +927,82 @@ Second level VPS (ip:3.3.3.3) execution:
|
|||||||
`proxy socks -T tcp -P 2.2.2.2:7777 -M -t tcp -m -p :8888`
|
`proxy socks -T tcp -P 2.2.2.2:7777 -M -t tcp -m -p :8888`
|
||||||
Local third level execution:
|
Local third level execution:
|
||||||
`proxy socks -T tcp -P 3.3.3.3:8888 -M -t tcp -p :8080`
|
`proxy socks -T tcp -P 3.3.3.3:8888 -M -t tcp -p :8080`
|
||||||
through this way, When you visits the website by local proxy 8080, it visits the target website by compressed transmission with the parents proxy.
|
through this way, When you visits the website by local proxy 8080, it visits the target website by compressed transmission with the parents proxy.
|
||||||
|
|
||||||
#### **5.12.view help**
|
#### **5.12 Load balance**
|
||||||
|
SOCKS proxy supports the load balancing of superior authorities, and the -P parameters can be repeated by multiple superiors.
|
||||||
|
`proxy socks --lb-method=hash -T tcp -P 1.1.1.1:33080 -P 2.1.1.1:33080 -P 3.1.1.1:33080 -p :33080 -t tcp`
|
||||||
|
|
||||||
|
#### **5.12.1 Set retry interval and timeout time**
|
||||||
|
`proxy socks --lb-method=leastconn --lb-retrytime 300 --lb-timeout 300 -T tcp -P 1.1.1.1:33080 -P 2.1.1.1:33080 -P 3.1.1.1:33080 -p :33080 -t tcp`
|
||||||
|
|
||||||
|
#### **5.12.2 Set weight**
|
||||||
|
`proxy socks --lb-method=weight -T tcp -P 1.1.1.1:33080@1 -P 2.1.1.1:33080@2 -P 3.1.1.1:33080@1 -p :33080 -t tcp`
|
||||||
|
|
||||||
|
#### **5.12.3 Use target address to select parent proxy**
|
||||||
|
`proxy socks --lb-hashtarget --lb-method=leasttime -T tcp -P 1.1.1.1:33080 -P 2.1.1.1:33080 -P 3.1.1.1:33080 -p :33080 -t tcp`
|
||||||
|
|
||||||
|
#### **5.13 Speed limit**
|
||||||
|
The speed limit is 100K, which can be specified through the -l parameter, for example: 100K 1.5M. 0 means unlimited.
|
||||||
|
`proxy socks -t tcp -p 2.2.2.2:33080 -l 100K`
|
||||||
|
|
||||||
|
#### **5.14 Designated exporting IP**
|
||||||
|
The `- bind-listen` parameter opens the client's ability to access the target site with an entry IP connection, using the entry IP as the exporting IP. If the entry IP is the intranet IP, the exporting IP will not use the entry IP..
|
||||||
|
`proxy socks -t tcp -p 2.2.2.2:33080 --bind-listen`
|
||||||
|
|
||||||
|
#### **5.15 Cascade authentication**
|
||||||
|
SOCKS5 supports cascading authentication, and -A can set up parents proxy's authentication information..
|
||||||
|
parents proxy:
|
||||||
|
`proxy socks -t tcp -p 2.2.2.2:33080 -a user:pass`
|
||||||
|
localhost:
|
||||||
|
`proxy socks -T tcp -P 2.2.2.2:33080 -A user:pass -t tcp -p :33080`
|
||||||
|
|
||||||
|
#### **5.16 Certificate parameters using Base64 data**
|
||||||
|
By default, the -C and -K parameters are the paths of CRT certificates and key files,
|
||||||
|
If it is the beginning of base64://, then it is considered that the data behind is Base64 encoded and will be used after decoding..
|
||||||
|
|
||||||
|
#### **5.17.view help**
|
||||||
`./proxy help socks`
|
`./proxy help socks`
|
||||||
|
|
||||||
### **6.Proxy protocol conversion**
|
### **6.Proxy protocol conversion**
|
||||||
|
|
||||||
#### **6.1.Functional introduction**
|
#### **6.1.Functional introduction**
|
||||||
The proxy protocol conversion use the SPS subcommand (abbreviation of socks+https), SPS itself does not provide the proxy function, just accept the proxy request and then converse protocol and forwarded to the existing HTTP (s) or Socks5 proxy. SPS can use existing HTTP (s) or Socks5 proxy converse to support HTTP (s) and Socks5 HTTP (s) proxy at the same time by one port, and proxy supports forward and reverse proxy (SNI), SOCKS5 proxy which is also does support UDP when parent is Socks5. in addition to the existing HTTP or Socks5 proxy, which supports TLS, TCP, KCP three modes and chain-style connection. That is more than one SPS node connection can build encryption channel.
|
The proxy protocol conversion use the SPS subcommand, SPS itself does not provide the proxy function, just accept the proxy request and then converse protocol and forwarded to the existing HTTP (s) or Socks5 proxy. SPS can use existing HTTP (s) or Socks5 proxy converse to support HTTP (s) and Socks5 HTTP (s) proxy at the same time by one port, and proxy supports forward and reverse proxy (SNI), SOCKS5 proxy which is also does support UDP when parent is Socks5. in addition to the existing HTTP or Socks5 proxy, which supports TLS, TCP, KCP three modes and chain-style connection. That is more than one SPS node connection can build encryption channel.
|
||||||
|
|
||||||
#### **6.2.HTTP(S) to HTTP(S) + SOCKS5**
|
#### **6.2.HTTP(S) to HTTP(S) + SOCKS5**
|
||||||
Suppose there is a common HTTP (s) proxy: 127.0.0.1:8080. Now we turn it into a common proxy that supports HTTP (s) and Socks5 at the same time. The local port after transformation is 18080.
|
Suppose there is a common HTTP (s) proxy: 127.0.0.1:8080. Now we turn it into a common proxy that supports HTTP (s), Socks5 and ss at the same time. The local port after transformation is 18080. ss's Encryption method is aes-192-cfb and its password is pass.
|
||||||
command:
|
command:
|
||||||
`./proxy sps -S http -T tcp -P 127.0.0.1:8080 -t tcp -p :18080`
|
`./proxy sps -S http -T tcp -P 127.0.0.1:8080 -t tcp -p :18080 -h aes-192-cfb -j pass`
|
||||||
|
|
||||||
Suppose that there is a TLS HTTP (s) proxy: 127.0.0.1:8080. Now we turn it into a common proxy that supports HTTP (s) and Socks5 at the same time. The local port after transformation is 18080, TLS needs certificate file.
|
Suppose that there is a TLS HTTP (s) proxy: 127.0.0.1:8080. Now we turn it into a common proxy that supports HTTP (s), Socks5 and ss at the same time. The local port after transformation is 18080, TLS needs certificate file,ss's Encryption method is aes-192-cfb and its password is pass.
|
||||||
command:
|
command:
|
||||||
`./proxy sps -S http -T tls -P 127.0.0.1:8080 -t tcp -p :18080 -C proxy.crt -K proxy.key`
|
`./proxy sps -S http -T tls -P 127.0.0.1:8080 -t tcp -p :18080 -C proxy.crt -K proxy.key -h aes-192-cfb -j pass`
|
||||||
|
|
||||||
Suppose there is a KCP HTTP (s) proxy (password: demo123): 127.0.0.1:8080. Now we turn it into a common proxy that supports HTTP (s) and Socks5 at the same time. The local port after transformation is 18080.
|
Suppose there is a KCP HTTP (s) proxy (password: demo123): 127.0.0.1:8080. Now we turn it into a common proxy that supports HTTP (s), Socks5 and ss at the same time. The local port after transformation is 18080. ss's Encryption method is aes-192-cfb and its password is pass.
|
||||||
command:
|
command:
|
||||||
`./proxy sps -S http -T kcp -P 127.0.0.1:8080 -t tcp -p :18080 --kcp-key demo123`
|
`./proxy sps -S http -T kcp -P 127.0.0.1:8080 -t tcp -p :18080 --kcp-key demo123 -h aes-192-cfb -j pass`
|
||||||
|
|
||||||
#### **6.3.SOCKS5 to HTTP(S) + SOCKS5**
|
#### **6.3.SOCKS5 to HTTP(S) + SOCKS5**
|
||||||
Suppose there is a common Socks5 proxy: 127.0.0.1:8080, now we turn it into a common proxy that supports HTTP (s) and Socks5 at the same time, and the local port after transformation is 18080.
|
Suppose there is a common Socks5 proxy: 127.0.0.1:8080, now we turn it into a common proxy that supports HTTP (s), Socks5 and ss at the same time, and the local port after transformation is 18080. ss's Encryption method is aes-192-cfb and its password is pass.
|
||||||
command:
|
command:
|
||||||
`./proxy sps -S socks -T tcp -P 127.0.0.1:8080 -t tcp -p :18080`
|
`./proxy sps -S socks -T tcp -P 127.0.0.1:8080 -t tcp -p :18080 -h aes-192-cfb -j pass`
|
||||||
|
|
||||||
Suppose there is a TLS Socks5 proxy: 127.0.0.1:8080. Now we turn it into a common proxy that support HTTP (s) and Socks5 at the same time. The local port after transformation is 18080, TLS needs certificate file.
|
Suppose there is a TLS Socks5 proxy: 127.0.0.1:8080. Now we turn it into a common proxy that supports HTTP (s), Socks5 and ss at the same time. The local port after transformation is 18080, TLS needs certificate file. ss's Encryption method is aes-192-cfb and its password is pass.
|
||||||
command:
|
command:
|
||||||
`./proxy sps -S socks -T tls -P 127.0.0.1:8080 -t tcp -p :18080 -C proxy.crt -K proxy.key`
|
`./proxy sps -S socks -T tls -P 127.0.0.1:8080 -t tcp -p :18080 -C proxy.crt -K proxy.key -h aes-192-cfb -j pass`
|
||||||
|
|
||||||
Suppose there is a KCP Socks5 proxy (password: demo123): 127.0.0.1:8080, now we turn it into a common proxy that support HTTP (s) and Socks5 at the same time, and the local port after transformation is 18080.
|
Suppose there is a KCP Socks5 proxy (password: demo123): 127.0.0.1:8080, now we turn it into a common proxy that supports HTTP (s), Socks5 and ss at the same time, and the local port after transformation is 18080. ss's Encryption method is aes-192-cfb and its password is pass.
|
||||||
command:
|
command:
|
||||||
`./proxy sps -S socks -T kcp -P 127.0.0.1:8080 -t tcp -p :18080 --kcp-key demo123`
|
`./proxy sps -S socks -T kcp -P 127.0.0.1:8080 -t tcp -p :18080 --kcp-key demo123 -h aes-192-cfb -j pass`
|
||||||
|
|
||||||
#### **6.4.Chain style connection**
|
#### **6.4 SS to HTTP(S)+SOCKS5+SS**
|
||||||
|
SPS support the SS protocol with the local authorities. The parent proxy can be SPS or standard SS services.
|
||||||
|
By default, SPS provides three proxies, HTTP (S), SOCKS5 and SPS. the converted SOCKS5 and SS support UDP when the parent proxy is SOCKS5.
|
||||||
|
Suppose there is an ordinary SS or SPS proxy (open SS, encryption: aes-256-cfb, password: Demo):127.0.0.1:8080,Now we turn it into a common proxy that supports both http (s) and Socks5 and ss. The converted local port is 18080, and the converted ss encryption mode is aes-192-cfb, ss password:pass.
|
||||||
|
command:
|
||||||
|
`./proxy sps -S socks -T kcp -P 127.0.0.1:8080 -t tcp -p :18080 --kcp-key demo123` `./proxy sps -S ss -H aes-256-cfb -J pass -T tcp -P 127.0.0.1:8080 -t tcp -p :18080 -h aes-192-cfb -j pass`.
|
||||||
|
|
||||||
|
#### **6.5.Chain style connection**
|
||||||

|

|
||||||
It is mentioned above that multiple SPS nodes can be connected to build encrypted channels, assuming you have the following VPS and a PC.
|
It is mentioned above that multiple SPS nodes can be connected to build encrypted channels, assuming you have the following VPS and a PC.
|
||||||
vps01:2.2.2.2
|
vps01:2.2.2.2
|
||||||
@ -922,11 +1022,11 @@ Then run a SPS node on the PC,excute:
|
|||||||
|
|
||||||
finish。
|
finish。
|
||||||
|
|
||||||
#### **6.5.Listening on multiple ports**
|
#### **6.6.Listening on multiple ports**
|
||||||
In general, listening one port is enough, but if you need to monitor 80 and 443 ports at the same time as a reverse proxy, the -p parameter can support it.
|
In general, listening one port is enough, but if you need to monitor 80 and 443 ports at the same time as a reverse proxy, the -p parameter can support it.
|
||||||
The format is:`-p 0.0.0.0:80,0.0.0.0:443`, Multiple bindings are separated by a comma.
|
The format is:`-p 0.0.0.0:80,0.0.0.0:443`, Multiple bindings are separated by a comma.
|
||||||
|
|
||||||
#### **6.6.Authentication**
|
#### **6.7.Authentication**
|
||||||
SPS supports HTTP(s)\socks5 proxy authentication, which can concatenate authentication, there are four important information:
|
SPS supports HTTP(s)\socks5 proxy authentication, which can concatenate authentication, there are four important information:
|
||||||
1:Users send authentication information`user-auth`。
|
1:Users send authentication information`user-auth`。
|
||||||
2:Local authentication information set up`local-auth`。
|
2:Local authentication information set up`local-auth`。
|
||||||
@ -968,7 +1068,7 @@ target: if the client is the HTTP (s) proxy request, this represents the complet
|
|||||||
If there is no -a or -F or --auth-url parameters, local authentication is closed.
|
If there is no -a or -F or --auth-url parameters, local authentication is closed.
|
||||||
If there is no -A parameter, the connection to the father proxy does not use authentication.
|
If there is no -A parameter, the connection to the father proxy does not use authentication.
|
||||||
|
|
||||||
#### **6.7 Custom encryption**
|
#### **6.8 Custom encryption**
|
||||||
HTTP(s) proxy can encrypt TCP data by TLS standard encryption and KCP protocol encryption, in addition to supporting custom encryption after TLS and KCP, That is to say, custom encryption and tls|kcp can be combined to use. The internal AES256 encryption is used, and it only needs to define one password by yourself. Encryption is divided into two parts, the one is whether the local (-z) is encrypted and decrypted, the other is whether the parents (-Z) is encrypted and decrypted.
|
HTTP(s) proxy can encrypt TCP data by TLS standard encryption and KCP protocol encryption, in addition to supporting custom encryption after TLS and KCP, That is to say, custom encryption and tls|kcp can be combined to use. The internal AES256 encryption is used, and it only needs to define one password by yourself. Encryption is divided into two parts, the one is whether the local (-z) is encrypted and decrypted, the other is whether the parents (-Z) is encrypted and decrypted.
|
||||||
Custom encryption requires both ends are proxy. Next, we use two level example and three level example as examples:
|
Custom encryption requires both ends are proxy. Next, we use two level example and three level example as examples:
|
||||||
Suppose there is already a HTTP (s) proxy:`6.6.6.6:6666`
|
Suppose there is already a HTTP (s) proxy:`6.6.6.6:6666`
|
||||||
@ -989,7 +1089,7 @@ Local third level execution:
|
|||||||
`proxy sps -T tcp -P 3.3.3.3:8888 -Z other_password -t tcp -p :8080`
|
`proxy sps -T tcp -P 3.3.3.3:8888 -Z other_password -t tcp -p :8080`
|
||||||
through this way, When you visits the website by local proxy 8080, it visits the target website by encryption transmission with the parents proxy.
|
through this way, When you visits the website by local proxy 8080, it visits the target website by encryption transmission with the parents proxy.
|
||||||
|
|
||||||
#### **6.8 Compressed transmission**
|
#### **6.9 Compressed transmission**
|
||||||
HTTP(s) proxy can encrypt TCP data through TCP standard encryption and KCP protocol encryption, and can also compress data before custom encryption.
|
HTTP(s) proxy can encrypt TCP data through TCP standard encryption and KCP protocol encryption, and can also compress data before custom encryption.
|
||||||
That is to say, compression and custom encryption and tls|kcp can be used together, compression is divided into two parts, the one is whether the local (-z) is compressed transmission, the other is whether the parents (-Z) is compressed transmission.
|
That is to say, compression and custom encryption and tls|kcp can be used together, compression is divided into two parts, the one is whether the local (-z) is compressed transmission, the other is whether the parents (-Z) is compressed transmission.
|
||||||
The compression requires both ends are proxy. Compression also protects the (encryption) data in certain extent. we use two level example and three level example as examples:
|
The compression requires both ends are proxy. Compression also protects the (encryption) data in certain extent. we use two level example and three level example as examples:
|
||||||
@ -1008,9 +1108,32 @@ Second level VPS (ip:3.3.3.3) execution::
|
|||||||
`proxy sps -T tcp -P 2.2.2.2:7777 -M -t tcp -m -p :8888`
|
`proxy sps -T tcp -P 2.2.2.2:7777 -M -t tcp -m -p :8888`
|
||||||
Local third level execution:
|
Local third level execution:
|
||||||
`proxy sps -T tcp -P 3.3.3.3:8888 -M -t tcp -p :8080`
|
`proxy sps -T tcp -P 3.3.3.3:8888 -M -t tcp -p :8080`
|
||||||
through this way, When you visits the website by local proxy 8080, it visits the target website by compressed transmission with the parents proxy.
|
through this way, When you visits the website by local proxy 8080, it visits the target website by compressed transmission with the parents proxy.
|
||||||
|
|
||||||
#### **6.9.view help**
|
#### **6.10 Disable protocol**
|
||||||
|
By default, SPS's port supports two proxy protocols, http (s) and socks5, and we can disable a protocol with parameters.
|
||||||
|
for example:
|
||||||
|
1.Disable the HTTP (S) proxy, retaining only the SOCKS5 proxy,parameter:`--disable-http`.
|
||||||
|
`proxy sps -T tcp -P 3.3.3.3:8888 -M -t tcp -p :8080 --disable-http`
|
||||||
|
1.Disable the SOCKS5 proxy, retaining only the HTTP (S) proxy,parameter:`--disable-socks`.
|
||||||
|
`proxy sps -T tcp -P 3.3.3.3:8888 -M -t tcp -p :8080 --disable-http`
|
||||||
|
|
||||||
|
#### **6.11 Speed limit**
|
||||||
|
Suppose there has a SOCKS5 parent proxy:
|
||||||
|
`proxy socks -p 2.2.2.2:33080 -z password -t tcp`
|
||||||
|
SPS lower speed limit 100K
|
||||||
|
`proxy sps -S socks -P 2.2.2.2:33080 -T tcp -Z password -l 100K -t tcp -p :33080`
|
||||||
|
It can be specified through the `-l` parameter, for example: 100K 1.5M. 0 means unlimited..
|
||||||
|
|
||||||
|
#### **6.12 Designated exporting IP**
|
||||||
|
The `- bind-listen` parameter opens the client's ability to access the target site with an entry IP connection, using the entry IP as the exporting IP. If the entry IP is the intranet IP, the exporting IP will not use the entry IP.
|
||||||
|
`proxy sps -S socks -P 2.2.2.2:33080 -T tcp -Z password -l 100K -t tcp --bind-listen -p :33080`
|
||||||
|
|
||||||
|
#### **6.13 Certificate parameters using Base64 data**
|
||||||
|
By default, the -C and -K parameters are the paths of CRT certificates and key files,
|
||||||
|
If it is the beginning of base64://, then it is considered that the data behind is Base64 encoded and will be used after decoding.
|
||||||
|
|
||||||
|
#### **6.14.view help**
|
||||||
`./proxy help sps`
|
`./proxy help sps`
|
||||||
|
|
||||||
### **7.KCP Configuration**
|
### **7.KCP Configuration**
|
||||||
|
|||||||
12
README_ZH.md
12
README_ZH.md
@ -13,6 +13,8 @@ Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5,ss代理服
|
|||||||
|
|
||||||
**[全平台SDK](/sdk/README.md)**
|
**[全平台SDK](/sdk/README.md)**
|
||||||
|
|
||||||
|
**[GoProxy特殊授权](/AUTHORIZATION.md)**
|
||||||
|
|
||||||
### 如何贡献代码(Pull Request)?
|
### 如何贡献代码(Pull Request)?
|
||||||
|
|
||||||
欢迎加入一起发展壮大proxy.首先需要clone本项目到自己的帐号下面,
|
欢迎加入一起发展壮大proxy.首先需要clone本项目到自己的帐号下面,
|
||||||
@ -181,7 +183,7 @@ curl -L https://raw.githubusercontent.com/snail007/goproxy/master/install_auto.s
|
|||||||
下载地址:https://github.com/snail007/goproxy/releases
|
下载地址:https://github.com/snail007/goproxy/releases
|
||||||
```shell
|
```shell
|
||||||
cd /root/proxy/
|
cd /root/proxy/
|
||||||
wget https://github.com/snail007/goproxy/releases/download/v6.0/proxy-linux-amd64.tar.gz
|
wget https://github.com/snail007/goproxy/releases/download/v6.2/proxy-linux-amd64.tar.gz
|
||||||
```
|
```
|
||||||
#### **2.下载自动安装脚本**
|
#### **2.下载自动安装脚本**
|
||||||
```shell
|
```shell
|
||||||
@ -378,7 +380,7 @@ target:用户访问的URL,比如:http://demo.com:80/1.html或https://www.baidu.c
|
|||||||
|
|
||||||
##### ***1.7.1 ssh用户名和密码的方式***
|
##### ***1.7.1 ssh用户名和密码的方式***
|
||||||
本地HTTP(S)代理28080端口,执行:
|
本地HTTP(S)代理28080端口,执行:
|
||||||
`./proxy http -T ssh -P "2.2.2.2:22" -u user -A demo -t tcp -p ":28080"`
|
`./proxy http -T ssh -P "2.2.2.2:22" -u user -D demo -t tcp -p ":28080"`
|
||||||
##### ***1.7.2 ssh用户名和密钥的方式***
|
##### ***1.7.2 ssh用户名和密钥的方式***
|
||||||
本地HTTP(S)代理28080端口,执行:
|
本地HTTP(S)代理28080端口,执行:
|
||||||
`./proxy http -T ssh -P "2.2.2.2:22" -u user -S user.key -t tcp -p ":28080"`
|
`./proxy http -T ssh -P "2.2.2.2:22" -u user -S user.key -t tcp -p ":28080"`
|
||||||
@ -523,7 +525,7 @@ HTTP(S)代理支持上级负载均衡,多个上级重复-P参数即可.
|
|||||||
|
|
||||||
#### **1.14.3 使用目标地址选择上级**
|
#### **1.14.3 使用目标地址选择上级**
|
||||||
|
|
||||||
`proxy http --lb-hashtarget --lb-method=leasttime -T tcp -P 1.1.1.1:33080 -P 2.1.1.1:33080 -P 3.1.1.1:33080 -t tcp -p :33080`
|
`proxy http --lb-hashtarget --lb-method=hash -T tcp -P 1.1.1.1:33080 -P 2.1.1.1:33080 -P 3.1.1.1:33080 -t tcp -p :33080`
|
||||||
|
|
||||||
### **1.15 限速**
|
### **1.15 限速**
|
||||||
|
|
||||||
@ -877,7 +879,7 @@ SOCKS5代理,支持CONNECT,UDP协议,不支持BIND,支持用户名密码认证.
|
|||||||
|
|
||||||
##### ***5.6.1 ssh用户名和密码的方式***
|
##### ***5.6.1 ssh用户名和密码的方式***
|
||||||
本地SOCKS5代理28080端口,执行:
|
本地SOCKS5代理28080端口,执行:
|
||||||
`./proxy socks -T ssh -P "2.2.2.2:22" -u user -A demo -t tcp -p ":28080"`
|
`./proxy socks -T ssh -P "2.2.2.2:22" -u user -D demo -t tcp -p ":28080"`
|
||||||
##### ***5.6.2 ssh用户名和密钥的方式***
|
##### ***5.6.2 ssh用户名和密钥的方式***
|
||||||
本地SOCKS5代理28080端口,执行:
|
本地SOCKS5代理28080端口,执行:
|
||||||
`./proxy socks -T ssh -P "2.2.2.2:22" -u user -S user.key -t tcp -p ":28080"`
|
`./proxy socks -T ssh -P "2.2.2.2:22" -u user -S user.key -t tcp -p ":28080"`
|
||||||
@ -989,7 +991,7 @@ SOCKS代理支持上级负载均衡,多个上级重复-P参数即可.
|
|||||||
|
|
||||||
#### **5.12.3 使用目标地址选择上级**
|
#### **5.12.3 使用目标地址选择上级**
|
||||||
|
|
||||||
`proxy socks --lb-hashtarget --lb-method=leasttime -T tcp -P 1.1.1.1:33080 -P 2.1.1.1:33080 -P 3.1.1.1:33080 -p :33080 -t tcp`
|
`proxy socks --lb-hashtarget --lb-method=hash -T tcp -P 1.1.1.1:33080 -P 2.1.1.1:33080 -P 3.1.1.1:33080 -p :33080 -t tcp`
|
||||||
|
|
||||||
#### **5.13 限速**
|
#### **5.13 限速**
|
||||||
|
|
||||||
|
|||||||
28
config.go
28
config.go
@ -12,12 +12,14 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"runtime/pprof"
|
"runtime/pprof"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
||||||
|
encryptconn "github.com/snail007/goproxy/core/lib/transport/encrypt"
|
||||||
sdk "github.com/snail007/goproxy/sdk/android-ios"
|
sdk "github.com/snail007/goproxy/sdk/android-ios"
|
||||||
services "github.com/snail007/goproxy/services"
|
services "github.com/snail007/goproxy/services"
|
||||||
httpx "github.com/snail007/goproxy/services/http"
|
httpx "github.com/snail007/goproxy/services/http"
|
||||||
"github.com/snail007/goproxy/services/kcpcfg"
|
|
||||||
keygenx "github.com/snail007/goproxy/services/keygen"
|
keygenx "github.com/snail007/goproxy/services/keygen"
|
||||||
mux "github.com/snail007/goproxy/services/mux"
|
mux "github.com/snail007/goproxy/services/mux"
|
||||||
socksx "github.com/snail007/goproxy/services/socks"
|
socksx "github.com/snail007/goproxy/services/socks"
|
||||||
@ -147,7 +149,7 @@ func initConfig() (err error) {
|
|||||||
//########mux-server#########
|
//########mux-server#########
|
||||||
muxServer := app.Command("server", "proxy on mux server mode")
|
muxServer := app.Command("server", "proxy on mux server mode")
|
||||||
muxServerArgs.Parent = muxServer.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
muxServerArgs.Parent = muxServer.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
||||||
muxServerArgs.ParentType = muxServer.Flag("parent-type", "parent protocol type <tls|tcp|kcp>").Default("tls").Short('T').Enum("tls", "tcp", "kcp")
|
muxServerArgs.ParentType = muxServer.Flag("parent-type", "parent protocol type <tls|tcp|tcps|kcp|tou>").Default("tls").Short('T').Enum("tls", "tcp", "tcps", "kcp", "tou")
|
||||||
muxServerArgs.CertFile = muxServer.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
muxServerArgs.CertFile = muxServer.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
||||||
muxServerArgs.KeyFile = muxServer.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
muxServerArgs.KeyFile = muxServer.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||||
muxServerArgs.Timeout = muxServer.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int()
|
muxServerArgs.Timeout = muxServer.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int()
|
||||||
@ -157,11 +159,15 @@ func initConfig() (err error) {
|
|||||||
muxServerArgs.IsCompress = muxServer.Flag("c", "compress data when tcp|tls mode").Default("false").Bool()
|
muxServerArgs.IsCompress = muxServer.Flag("c", "compress data when tcp|tls mode").Default("false").Bool()
|
||||||
muxServerArgs.SessionCount = muxServer.Flag("session-count", "session count which connect to bridge").Short('n').Default("10").Int()
|
muxServerArgs.SessionCount = muxServer.Flag("session-count", "session count which connect to bridge").Short('n').Default("10").Int()
|
||||||
muxServerArgs.Jumper = muxServer.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String()
|
muxServerArgs.Jumper = muxServer.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String()
|
||||||
|
muxServerArgs.TCPSMethod = muxServer.Flag("tcps-method", "method of parent tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
|
||||||
|
muxServerArgs.TCPSPassword = muxServer.Flag("tcps-password", "password of parent tcps's encrpyt/decrypt").Default("snail007's_goproxy").String()
|
||||||
|
muxServerArgs.TOUMethod = muxServer.Flag("tou-method", "method of parent tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
|
||||||
|
muxServerArgs.TOUPassword = muxServer.Flag("tou-password", "password of parent tou's encrpyt/decrypt").Default("snail007's_goproxy").String()
|
||||||
|
|
||||||
//########mux-client#########
|
//########mux-client#########
|
||||||
muxClient := app.Command("client", "proxy on mux client mode")
|
muxClient := app.Command("client", "proxy on mux client mode")
|
||||||
muxClientArgs.Parent = muxClient.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
muxClientArgs.Parent = muxClient.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
||||||
muxClientArgs.ParentType = muxClient.Flag("parent-type", "parent protocol type <tls|tcp|kcp>").Default("tls").Short('T').Enum("tls", "tcp", "kcp")
|
muxClientArgs.ParentType = muxClient.Flag("parent-type", "parent protocol type <tls|tcp|tcps|kcp|tou>").Default("tls").Short('T').Enum("tls", "tcp", "tcps", "kcp", "tou")
|
||||||
muxClientArgs.CertFile = muxClient.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
muxClientArgs.CertFile = muxClient.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
||||||
muxClientArgs.KeyFile = muxClient.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
muxClientArgs.KeyFile = muxClient.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||||
muxClientArgs.Timeout = muxClient.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int()
|
muxClientArgs.Timeout = muxClient.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int()
|
||||||
@ -169,6 +175,10 @@ func initConfig() (err error) {
|
|||||||
muxClientArgs.IsCompress = muxClient.Flag("c", "compress data when tcp|tls mode").Default("false").Bool()
|
muxClientArgs.IsCompress = muxClient.Flag("c", "compress data when tcp|tls mode").Default("false").Bool()
|
||||||
muxClientArgs.SessionCount = muxClient.Flag("session-count", "session count which connect to bridge").Short('n').Default("10").Int()
|
muxClientArgs.SessionCount = muxClient.Flag("session-count", "session count which connect to bridge").Short('n').Default("10").Int()
|
||||||
muxClientArgs.Jumper = muxClient.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String()
|
muxClientArgs.Jumper = muxClient.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String()
|
||||||
|
muxClientArgs.TCPSMethod = muxClient.Flag("tcps-method", "method of parent tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
|
||||||
|
muxClientArgs.TCPSPassword = muxClient.Flag("tcps-password", "password of parent tcps's encrpyt/decrypt").Default("snail007's_goproxy").String()
|
||||||
|
muxClientArgs.TOUMethod = muxClient.Flag("tou-method", "method of parent tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
|
||||||
|
muxClientArgs.TOUPassword = muxClient.Flag("tou-password", "password of parent tou's encrpyt/decrypt").Default("snail007's_goproxy").String()
|
||||||
|
|
||||||
//########mux-bridge#########
|
//########mux-bridge#########
|
||||||
muxBridge := app.Command("bridge", "proxy on mux bridge mode")
|
muxBridge := app.Command("bridge", "proxy on mux bridge mode")
|
||||||
@ -176,7 +186,11 @@ func initConfig() (err error) {
|
|||||||
muxBridgeArgs.KeyFile = muxBridge.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
muxBridgeArgs.KeyFile = muxBridge.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||||
muxBridgeArgs.Timeout = muxBridge.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int()
|
muxBridgeArgs.Timeout = muxBridge.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int()
|
||||||
muxBridgeArgs.Local = muxBridge.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
|
muxBridgeArgs.Local = muxBridge.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
|
||||||
muxBridgeArgs.LocalType = muxBridge.Flag("local-type", "local protocol type <tls|tcp|kcp>").Default("tls").Short('t').Enum("tls", "tcp", "kcp")
|
muxBridgeArgs.LocalType = muxBridge.Flag("local-type", "local protocol type <tls|tcp|tcps|kcp|tou>").Default("tls").Short('t').Enum("tls", "tcp", "tcps", "kcp", "tou")
|
||||||
|
muxBridgeArgs.TCPSMethod = muxBridge.Flag("tcps-method", "method of local tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
|
||||||
|
muxBridgeArgs.TCPSPassword = muxBridge.Flag("tcps-password", "password of local tcps's encrpyt/decrypt").Default("snail007's_goproxy").String()
|
||||||
|
muxBridgeArgs.TOUMethod = muxBridge.Flag("tou-method", "method of local tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
|
||||||
|
muxBridgeArgs.TOUPassword = muxBridge.Flag("tou-password", "password of local tou's encrpyt/decrypt").Default("snail007's_goproxy").String()
|
||||||
|
|
||||||
//########tunnel-server#########
|
//########tunnel-server#########
|
||||||
tunnelServer := app.Command("tserver", "proxy on tunnel server mode")
|
tunnelServer := app.Command("tserver", "proxy on tunnel server mode")
|
||||||
@ -418,7 +432,7 @@ func initConfig() (err error) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for {
|
for {
|
||||||
@ -442,7 +456,7 @@ func initConfig() (err error) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
@ -452,7 +466,7 @@ func initConfig() (err error) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for scannerStdErr.Scan() {
|
for scannerStdErr.Scan() {
|
||||||
|
|||||||
@ -11,10 +11,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/snail007/goproxy/core/dst"
|
||||||
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
||||||
compressconn "github.com/snail007/goproxy/core/lib/transport"
|
compressconn "github.com/snail007/goproxy/core/lib/transport"
|
||||||
encryptconn "github.com/snail007/goproxy/core/lib/transport/encrypt"
|
encryptconn "github.com/snail007/goproxy/core/lib/transport/encrypt"
|
||||||
"github.com/snail007/goproxy/core/dst"
|
|
||||||
kcp "github.com/xtaci/kcp-go"
|
kcp "github.com/xtaci/kcp-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -35,6 +35,9 @@ func TlsConnect(host string, port, timeout int, certBytes, keyBytes, caCertBytes
|
|||||||
}
|
}
|
||||||
return *tls.Client(_conn, conf), err
|
return *tls.Client(_conn, conf), err
|
||||||
}
|
}
|
||||||
|
func TlsConfig(certBytes, keyBytes, caCertBytes []byte) (conf *tls.Config, err error) {
|
||||||
|
return getRequestTlsConfig(certBytes, keyBytes, caCertBytes)
|
||||||
|
}
|
||||||
func getRequestTlsConfig(certBytes, keyBytes, caCertBytes []byte) (conf *tls.Config, err error) {
|
func getRequestTlsConfig(certBytes, keyBytes, caCertBytes []byte) (conf *tls.Config, err error) {
|
||||||
|
|
||||||
var cert tls.Certificate
|
var cert tls.Certificate
|
||||||
|
|||||||
@ -11,10 +11,10 @@ import (
|
|||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
tou "github.com/snail007/goproxy/core/dst"
|
||||||
compressconn "github.com/snail007/goproxy/core/lib/transport"
|
compressconn "github.com/snail007/goproxy/core/lib/transport"
|
||||||
transportc "github.com/snail007/goproxy/core/lib/transport"
|
transportc "github.com/snail007/goproxy/core/lib/transport"
|
||||||
encryptconn "github.com/snail007/goproxy/core/lib/transport/encrypt"
|
encryptconn "github.com/snail007/goproxy/core/lib/transport/encrypt"
|
||||||
tou "github.com/snail007/goproxy/core/dst"
|
|
||||||
|
|
||||||
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ func (s *ServerChannel) listenTLS(ip string, port int, certBytes, keyBytes, caCe
|
|||||||
config.ClientCAs = clientCertPool
|
config.ClientCAs = clientCertPool
|
||||||
config.ClientAuth = tls.RequireAndVerifyClientCert
|
config.ClientAuth = tls.RequireAndVerifyClientCert
|
||||||
}
|
}
|
||||||
_ln, err := tls.Listen("tcp", fmt.Sprintf("%s:%d", ip, port), config)
|
_ln, err := tls.Listen("tcp", net.JoinHostPort(ip, fmt.Sprintf("%d", port)), config)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ln = &_ln
|
ln = &_ln
|
||||||
}
|
}
|
||||||
@ -141,7 +141,7 @@ func (s *ServerChannel) ListenTCPS(method, password string, compress bool, fn fu
|
|||||||
}
|
}
|
||||||
func (s *ServerChannel) ListenTCP(fn func(conn net.Conn)) (err error) {
|
func (s *ServerChannel) ListenTCP(fn func(conn net.Conn)) (err error) {
|
||||||
var l net.Listener
|
var l net.Listener
|
||||||
l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", s.ip, s.port))
|
l, err = net.Listen("tcp", net.JoinHostPort(s.ip, fmt.Sprintf("%d", s.port)))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
s.Listener = &l
|
s.Listener = &l
|
||||||
go func() {
|
go func() {
|
||||||
@ -172,7 +172,7 @@ func (s *ServerChannel) ListenTCP(fn func(conn net.Conn)) (err error) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (s *ServerChannel) ListenUDP(fn func(packet []byte, localAddr, srcAddr *net.UDPAddr)) (err error) {
|
func (s *ServerChannel) ListenUDP(fn func(listener *net.UDPConn, packet []byte, localAddr, srcAddr *net.UDPAddr)) (err error) {
|
||||||
addr := &net.UDPAddr{IP: net.ParseIP(s.ip), Port: s.port}
|
addr := &net.UDPAddr{IP: net.ParseIP(s.ip), Port: s.port}
|
||||||
l, err := net.ListenUDP("udp", addr)
|
l, err := net.ListenUDP("udp", addr)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -194,7 +194,7 @@ func (s *ServerChannel) ListenUDP(fn func(packet []byte, localAddr, srcAddr *net
|
|||||||
s.log.Printf("udp data handler crashed , err : %s , \ntrace:%s", e, string(debug.Stack()))
|
s.log.Printf("udp data handler crashed , err : %s , \ntrace:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
fn(packet, addr, srcAddr)
|
fn(s.UDPListener, packet, addr, srcAddr)
|
||||||
}()
|
}()
|
||||||
} else {
|
} else {
|
||||||
s.errAcceptHandler(err)
|
s.errAcceptHandler(err)
|
||||||
@ -207,7 +207,7 @@ func (s *ServerChannel) ListenUDP(fn func(packet []byte, localAddr, srcAddr *net
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (s *ServerChannel) ListenKCP(config kcpcfg.KCPConfigArgs, fn func(conn net.Conn), log *logger.Logger) (err error) {
|
func (s *ServerChannel) ListenKCP(config kcpcfg.KCPConfigArgs, fn func(conn net.Conn), log *logger.Logger) (err error) {
|
||||||
lis, err := kcp.ListenWithOptions(fmt.Sprintf("%s:%d", s.ip, s.port), config.Block, *config.DataShard, *config.ParityShard)
|
lis, err := kcp.ListenWithOptions(net.JoinHostPort(s.ip, fmt.Sprintf("%d", s.port)), config.Block, *config.DataShard, *config.ParityShard)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if err = lis.SetDSCP(*config.DSCP); err != nil {
|
if err = lis.SetDSCP(*config.DSCP); err != nil {
|
||||||
log.Println("SetDSCP:", err)
|
log.Println("SetDSCP:", err)
|
||||||
@ -230,7 +230,6 @@ func (s *ServerChannel) ListenKCP(config kcpcfg.KCPConfigArgs, fn func(conn net.
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for {
|
for {
|
||||||
//var conn net.Conn
|
|
||||||
conn, err := lis.AcceptKCP()
|
conn, err := lis.AcceptKCP()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
go func() {
|
go func() {
|
||||||
|
|||||||
@ -137,7 +137,7 @@ func (c *Conn) start() {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
c.reader()
|
c.reader()
|
||||||
@ -433,6 +433,12 @@ func (c *Conn) String() string {
|
|||||||
// Read can be made to time out and return a Error with Timeout() == true
|
// Read can be made to time out and return a Error with Timeout() == true
|
||||||
// after a fixed time limit; see SetDeadline and SetReadDeadline.
|
// after a fixed time limit; see SetDeadline and SetReadDeadline.
|
||||||
func (c *Conn) Read(b []byte) (n int, err error) {
|
func (c *Conn) Read(b []byte) (n int, err error) {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
n = 0
|
||||||
|
err = io.EOF
|
||||||
|
}
|
||||||
|
}()
|
||||||
c.inbufMut.Lock()
|
c.inbufMut.Lock()
|
||||||
defer c.inbufMut.Unlock()
|
defer c.inbufMut.Unlock()
|
||||||
for c.inbuf.Len() == 0 {
|
for c.inbuf.Len() == 0 {
|
||||||
@ -497,6 +503,9 @@ func (c *Conn) Write(b []byte) (n int, err error) {
|
|||||||
// Close closes the connection.
|
// Close closes the connection.
|
||||||
// Any blocked Read or Write operations will be unblocked and return errors.
|
// Any blocked Read or Write operations will be unblocked and return errors.
|
||||||
func (c *Conn) Close() error {
|
func (c *Conn) Close() error {
|
||||||
|
defer func() {
|
||||||
|
_ = recover()
|
||||||
|
}()
|
||||||
c.closeOnce.Do(func() {
|
c.closeOnce.Do(func() {
|
||||||
if debugConnection {
|
if debugConnection {
|
||||||
log.Println(c, "explicit close start")
|
log.Println(c, "explicit close start")
|
||||||
|
|||||||
@ -82,7 +82,7 @@ func NewMux(conn net.PacketConn, packetSize int) *Mux {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
m.readerLoop()
|
m.readerLoop()
|
||||||
|
|||||||
@ -56,7 +56,7 @@ func newSendBuffer(m *Mux) *sendBuffer {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
b.writerLoop()
|
b.writerLoop()
|
||||||
|
|||||||
@ -155,7 +155,7 @@ func (m ConcurrentMap) Iter() <-chan Tuple {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
fanIn(chans, ch)
|
fanIn(chans, ch)
|
||||||
@ -174,7 +174,7 @@ func (m ConcurrentMap) IterBuffered() <-chan Tuple {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
fanIn(chans, ch)
|
fanIn(chans, ch)
|
||||||
@ -195,7 +195,7 @@ func snapshot(m ConcurrentMap) (chans []chan Tuple) {
|
|||||||
go func(index int, shard *ConcurrentMapShared) {
|
go func(index int, shard *ConcurrentMapShared) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
// Foreach key, value pair.
|
// Foreach key, value pair.
|
||||||
@ -221,7 +221,7 @@ func fanIn(chans []chan Tuple, out chan Tuple) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
func(ch chan Tuple) {
|
func(ch chan Tuple) {
|
||||||
@ -274,7 +274,7 @@ func (m ConcurrentMap) Keys() []string {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
// Foreach shard.
|
// Foreach shard.
|
||||||
@ -284,7 +284,7 @@ func (m ConcurrentMap) Keys() []string {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
func(shard *ConcurrentMapShared) {
|
func(shard *ConcurrentMapShared) {
|
||||||
|
|||||||
@ -39,8 +39,11 @@ func (c *CompStream) Write(p []byte) (n int, err error) {
|
|||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CompStream) Close() error {
|
func (c *CompStream) Close() (err error) {
|
||||||
return c.conn.Close()
|
err = c.conn.Close()
|
||||||
|
c.r = nil
|
||||||
|
c.w = nil
|
||||||
|
return
|
||||||
}
|
}
|
||||||
func (c *CompStream) LocalAddr() net.Addr {
|
func (c *CompStream) LocalAddr() net.Addr {
|
||||||
return c.conn.LocalAddr()
|
return c.conn.LocalAddr()
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package encrypt
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
@ -33,8 +34,23 @@ func NewConn(c net.Conn, method, password string) (conn net.Conn, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (s *Conn) Read(b []byte) (n int, err error) {
|
func (s *Conn) Read(b []byte) (n int, err error) {
|
||||||
|
if s.r == nil {
|
||||||
|
return 0, fmt.Errorf("use of closed network connection")
|
||||||
|
}
|
||||||
return s.r.Read(b)
|
return s.r.Read(b)
|
||||||
}
|
}
|
||||||
func (s *Conn) Write(b []byte) (n int, err error) {
|
func (s *Conn) Write(b []byte) (n int, err error) {
|
||||||
|
if s.w == nil {
|
||||||
|
return 0, fmt.Errorf("use of closed network connection")
|
||||||
|
}
|
||||||
return s.w.Write(b)
|
return s.w.Write(b)
|
||||||
}
|
}
|
||||||
|
func (s *Conn) Close() (err error) {
|
||||||
|
if s.Cipher != nil {
|
||||||
|
err = s.Conn.Close()
|
||||||
|
s.Cipher = nil
|
||||||
|
s.r = nil
|
||||||
|
s.w = nil
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@ -62,7 +62,7 @@ func (s *IOBinder) AliveWithServeConn(srcAddr string, inTCPConn *net.Conn) *IOBi
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
buf := make([]byte, 1)
|
buf := make([]byte, 1)
|
||||||
@ -75,7 +75,7 @@ func (s *IOBinder) AliveWithServeConn(srcAddr string, inTCPConn *net.Conn) *IOBi
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for {
|
for {
|
||||||
@ -96,7 +96,7 @@ func (s *IOBinder) AliveWithClientConn(srcAddr string, outTCPConn *net.Conn) *IO
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
buf := make([]byte, 1)
|
buf := make([]byte, 1)
|
||||||
@ -156,7 +156,7 @@ func (s *IOBinder) Run() (err error) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
defer func() {
|
defer func() {
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
socks5c "github.com/snail007/goproxy/core/proxy/common/socks5"
|
socks5c "github.com/snail007/goproxy/core/lib/socks5"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BasicAuther interface {
|
type BasicAuther interface {
|
||||||
|
|||||||
@ -81,7 +81,7 @@ func dtoi(s string, i0 int) (n int, i int, ok bool) {
|
|||||||
return n, i, true
|
return n, i, true
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPTcpAddrToUnixSocksAddr ---
|
// IPTcpAddrToUnixSocksAddr returns Sockaddr for specified TCP addr.
|
||||||
func IPTcpAddrToUnixSocksAddr(addr string) (sa unix.Sockaddr, err error) {
|
func IPTcpAddrToUnixSocksAddr(addr string) (sa unix.Sockaddr, err error) {
|
||||||
if Debug {
|
if Debug {
|
||||||
fmt.Println("DEBUG: IPTcpAddrToUnixSocksAddr recieved address:", addr)
|
fmt.Println("DEBUG: IPTcpAddrToUnixSocksAddr recieved address:", addr)
|
||||||
@ -97,7 +97,7 @@ func IPTcpAddrToUnixSocksAddr(addr string) (sa unix.Sockaddr, err error) {
|
|||||||
return ipToSocksAddr(ipType(addr), tcpAddr.IP, tcpAddr.Port, tcpAddr.Zone)
|
return ipToSocksAddr(ipType(addr), tcpAddr.IP, tcpAddr.Port, tcpAddr.Zone)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPv6UdpAddrToUnixSocksAddr ---
|
// IPv6UdpAddrToUnixSocksAddr returns Sockaddr for specified IPv6 addr.
|
||||||
func IPv6UdpAddrToUnixSocksAddr(addr string) (sa unix.Sockaddr, err error) {
|
func IPv6UdpAddrToUnixSocksAddr(addr string) (sa unix.Sockaddr, err error) {
|
||||||
tcpAddr, err := net.ResolveTCPAddr("udp6", addr)
|
tcpAddr, err := net.ResolveTCPAddr("udp6", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -5,7 +5,7 @@ if [ -e /tmp/proxy ]; then
|
|||||||
fi
|
fi
|
||||||
mkdir /tmp/proxy
|
mkdir /tmp/proxy
|
||||||
cd /tmp/proxy
|
cd /tmp/proxy
|
||||||
wget https://github.com/snail007/goproxy/releases/download/v6.0/proxy-linux-amd64.tar.gz
|
wget https://github.com/snail007/goproxy/releases/download/v6.2/proxy-linux-amd64.tar.gz
|
||||||
|
|
||||||
# #install proxy
|
# #install proxy
|
||||||
tar zxvf proxy-linux-amd64.tar.gz
|
tar zxvf proxy-linux-amd64.tar.gz
|
||||||
|
|||||||
2
main.go
2
main.go
@ -36,7 +36,7 @@ func Clean(s *services.Service) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for _ = range signalChan {
|
for _ = range signalChan {
|
||||||
|
|||||||
@ -13,8 +13,8 @@ import (
|
|||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
gocache "github.com/pmylund/go-cache"
|
gocache "github.com/pmylund/go-cache"
|
||||||
|
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
||||||
services "github.com/snail007/goproxy/services"
|
services "github.com/snail007/goproxy/services"
|
||||||
"github.com/snail007/goproxy/services/kcpcfg"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type DNSArgs struct {
|
type DNSArgs struct {
|
||||||
@ -60,7 +60,7 @@ func (s *DNS) InitService() (err error) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for {
|
for {
|
||||||
@ -142,7 +142,7 @@ func (s *DNS) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
log.Printf("dns server on udp %s", *s.cfg.Local)
|
log.Printf("dns server on udp %s", *s.cfg.Local)
|
||||||
|
|||||||
@ -10,9 +10,10 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
||||||
|
encryptconn "github.com/snail007/goproxy/core/lib/transport/encrypt"
|
||||||
"github.com/snail007/goproxy/services"
|
"github.com/snail007/goproxy/services"
|
||||||
httpx "github.com/snail007/goproxy/services/http"
|
httpx "github.com/snail007/goproxy/services/http"
|
||||||
"github.com/snail007/goproxy/services/kcpcfg"
|
|
||||||
keygenx "github.com/snail007/goproxy/services/keygen"
|
keygenx "github.com/snail007/goproxy/services/keygen"
|
||||||
mux "github.com/snail007/goproxy/services/mux"
|
mux "github.com/snail007/goproxy/services/mux"
|
||||||
socksx "github.com/snail007/goproxy/services/socks"
|
socksx "github.com/snail007/goproxy/services/socks"
|
||||||
@ -166,7 +167,7 @@ func StartWithLog(serviceID, serviceArgsStr string, loggerCallback LogCallback)
|
|||||||
//########mux-server#########
|
//########mux-server#########
|
||||||
muxServer := app.Command("server", "proxy on mux server mode")
|
muxServer := app.Command("server", "proxy on mux server mode")
|
||||||
muxServerArgs.Parent = muxServer.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
muxServerArgs.Parent = muxServer.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
||||||
muxServerArgs.ParentType = muxServer.Flag("parent-type", "parent protocol type <tls|tcp|kcp>").Default("tls").Short('T').Enum("tls", "tcp", "kcp")
|
muxServerArgs.ParentType = muxServer.Flag("parent-type", "parent protocol type <tls|tcp|tcps|kcp|tou>").Default("tls").Short('T').Enum("tls", "tcp", "tcps", "kcp", "tou")
|
||||||
muxServerArgs.CertFile = muxServer.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
muxServerArgs.CertFile = muxServer.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
||||||
muxServerArgs.KeyFile = muxServer.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
muxServerArgs.KeyFile = muxServer.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||||
muxServerArgs.Timeout = muxServer.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int()
|
muxServerArgs.Timeout = muxServer.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int()
|
||||||
@ -176,11 +177,15 @@ func StartWithLog(serviceID, serviceArgsStr string, loggerCallback LogCallback)
|
|||||||
muxServerArgs.IsCompress = muxServer.Flag("c", "compress data when tcp|tls mode").Default("false").Bool()
|
muxServerArgs.IsCompress = muxServer.Flag("c", "compress data when tcp|tls mode").Default("false").Bool()
|
||||||
muxServerArgs.SessionCount = muxServer.Flag("session-count", "session count which connect to bridge").Short('n').Default("10").Int()
|
muxServerArgs.SessionCount = muxServer.Flag("session-count", "session count which connect to bridge").Short('n').Default("10").Int()
|
||||||
muxServerArgs.Jumper = muxServer.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String()
|
muxServerArgs.Jumper = muxServer.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String()
|
||||||
|
muxServerArgs.TCPSMethod = muxServer.Flag("tcps-method", "method of parent tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
|
||||||
|
muxServerArgs.TCPSPassword = muxServer.Flag("tcps-password", "password of parent tcps's encrpyt/decrypt").Default("snail007's_goproxy").String()
|
||||||
|
muxServerArgs.TOUMethod = muxServer.Flag("tou-method", "method of parent tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
|
||||||
|
muxServerArgs.TOUPassword = muxServer.Flag("tou-password", "password of parent tou's encrpyt/decrypt").Default("snail007's_goproxy").String()
|
||||||
|
|
||||||
//########mux-client#########
|
//########mux-client#########
|
||||||
muxClient := app.Command("client", "proxy on mux client mode")
|
muxClient := app.Command("client", "proxy on mux client mode")
|
||||||
muxClientArgs.Parent = muxClient.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
muxClientArgs.Parent = muxClient.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
||||||
muxClientArgs.ParentType = muxClient.Flag("parent-type", "parent protocol type <tls|tcp|kcp>").Default("tls").Short('T').Enum("tls", "tcp", "kcp")
|
muxClientArgs.ParentType = muxClient.Flag("parent-type", "parent protocol type <tls|tcp|tcps|kcp|tou>").Default("tls").Short('T').Enum("tls", "tcp", "tcps", "kcp", "tou")
|
||||||
muxClientArgs.CertFile = muxClient.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
muxClientArgs.CertFile = muxClient.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
||||||
muxClientArgs.KeyFile = muxClient.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
muxClientArgs.KeyFile = muxClient.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||||
muxClientArgs.Timeout = muxClient.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int()
|
muxClientArgs.Timeout = muxClient.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int()
|
||||||
@ -188,6 +193,10 @@ func StartWithLog(serviceID, serviceArgsStr string, loggerCallback LogCallback)
|
|||||||
muxClientArgs.IsCompress = muxClient.Flag("c", "compress data when tcp|tls mode").Default("false").Bool()
|
muxClientArgs.IsCompress = muxClient.Flag("c", "compress data when tcp|tls mode").Default("false").Bool()
|
||||||
muxClientArgs.SessionCount = muxClient.Flag("session-count", "session count which connect to bridge").Short('n').Default("10").Int()
|
muxClientArgs.SessionCount = muxClient.Flag("session-count", "session count which connect to bridge").Short('n').Default("10").Int()
|
||||||
muxClientArgs.Jumper = muxClient.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String()
|
muxClientArgs.Jumper = muxClient.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String()
|
||||||
|
muxClientArgs.TCPSMethod = muxClient.Flag("tcps-method", "method of parent tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
|
||||||
|
muxClientArgs.TCPSPassword = muxClient.Flag("tcps-password", "password of parent tcps's encrpyt/decrypt").Default("snail007's_goproxy").String()
|
||||||
|
muxClientArgs.TOUMethod = muxClient.Flag("tou-method", "method of parent tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
|
||||||
|
muxClientArgs.TOUPassword = muxClient.Flag("tou-password", "password of parent tou's encrpyt/decrypt").Default("snail007's_goproxy").String()
|
||||||
|
|
||||||
//########mux-bridge#########
|
//########mux-bridge#########
|
||||||
muxBridge := app.Command("bridge", "proxy on mux bridge mode")
|
muxBridge := app.Command("bridge", "proxy on mux bridge mode")
|
||||||
@ -195,7 +204,11 @@ func StartWithLog(serviceID, serviceArgsStr string, loggerCallback LogCallback)
|
|||||||
muxBridgeArgs.KeyFile = muxBridge.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
muxBridgeArgs.KeyFile = muxBridge.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||||
muxBridgeArgs.Timeout = muxBridge.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int()
|
muxBridgeArgs.Timeout = muxBridge.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int()
|
||||||
muxBridgeArgs.Local = muxBridge.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
|
muxBridgeArgs.Local = muxBridge.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
|
||||||
muxBridgeArgs.LocalType = muxBridge.Flag("local-type", "local protocol type <tls|tcp|kcp>").Default("tls").Short('t').Enum("tls", "tcp", "kcp")
|
muxBridgeArgs.LocalType = muxBridge.Flag("local-type", "local protocol type <tls|tcp|tcps|kcp|tou>").Default("tls").Short('t').Enum("tls", "tcp", "tcps", "kcp", "tou")
|
||||||
|
muxBridgeArgs.TCPSMethod = muxBridge.Flag("tcps-method", "method of local tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
|
||||||
|
muxBridgeArgs.TCPSPassword = muxBridge.Flag("tcps-password", "password of local tcps's encrpyt/decrypt").Default("snail007's_goproxy").String()
|
||||||
|
muxBridgeArgs.TOUMethod = muxBridge.Flag("tou-method", "method of local tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
|
||||||
|
muxBridgeArgs.TOUPassword = muxBridge.Flag("tou-password", "password of local tou's encrpyt/decrypt").Default("snail007's_goproxy").String()
|
||||||
|
|
||||||
//########tunnel-server#########
|
//########tunnel-server#########
|
||||||
tunnelServer := app.Command("tserver", "proxy on tunnel server mode")
|
tunnelServer := app.Command("tserver", "proxy on tunnel server mode")
|
||||||
|
|||||||
@ -12,8 +12,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
server "github.com/snail007/goproxy/core/cs/server"
|
||||||
|
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
||||||
"github.com/snail007/goproxy/services"
|
"github.com/snail007/goproxy/services"
|
||||||
"github.com/snail007/goproxy/services/kcpcfg"
|
|
||||||
"github.com/snail007/goproxy/utils/datasize"
|
"github.com/snail007/goproxy/utils/datasize"
|
||||||
"github.com/snail007/goproxy/utils/dnsx"
|
"github.com/snail007/goproxy/utils/dnsx"
|
||||||
"github.com/snail007/goproxy/utils/iolimiter"
|
"github.com/snail007/goproxy/utils/iolimiter"
|
||||||
@ -83,7 +84,7 @@ type HTTP struct {
|
|||||||
lockChn chan bool
|
lockChn chan bool
|
||||||
domainResolver dnsx.DomainResolver
|
domainResolver dnsx.DomainResolver
|
||||||
isStop bool
|
isStop bool
|
||||||
serverChannels []*utils.ServerChannel
|
serverChannels []*server.ServerChannel
|
||||||
userConns mapx.ConcurrentMap
|
userConns mapx.ConcurrentMap
|
||||||
log *logger.Logger
|
log *logger.Logger
|
||||||
lb *lb.Group
|
lb *lb.Group
|
||||||
@ -96,7 +97,7 @@ func NewHTTP() services.Service {
|
|||||||
basicAuth: utils.BasicAuth{},
|
basicAuth: utils.BasicAuth{},
|
||||||
lockChn: make(chan bool, 1),
|
lockChn: make(chan bool, 1),
|
||||||
isStop: false,
|
isStop: false,
|
||||||
serverChannels: []*utils.ServerChannel{},
|
serverChannels: []*server.ServerChannel{},
|
||||||
userConns: mapx.NewConcurrentMap(),
|
userConns: mapx.NewConcurrentMap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,7 +173,7 @@ func (s *HTTP) InitService() (err error) {
|
|||||||
s.InitLB()
|
s.InitLB()
|
||||||
}
|
}
|
||||||
if *s.cfg.DNSAddress != "" {
|
if *s.cfg.DNSAddress != "" {
|
||||||
(*s).domainResolver = dnsx.NewDomainResolver(*s.cfg.DNSAddress, *s.cfg.DNSTTL, s.log)
|
s.domainResolver = dnsx.NewDomainResolver(*s.cfg.DNSAddress, *s.cfg.DNSTTL, s.log)
|
||||||
}
|
}
|
||||||
if *s.cfg.ParentType == "ssh" {
|
if *s.cfg.ParentType == "ssh" {
|
||||||
err = s.ConnectSSH()
|
err = s.ConnectSSH()
|
||||||
@ -183,7 +184,7 @@ func (s *HTTP) InitService() (err error) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
//循环检查ssh网络连通性
|
//循环检查ssh网络连通性
|
||||||
@ -273,11 +274,11 @@ func (s *HTTP) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
if addr != "" {
|
if addr != "" {
|
||||||
host, port, _ := net.SplitHostPort(addr)
|
host, port, _ := net.SplitHostPort(addr)
|
||||||
p, _ := strconv.Atoi(port)
|
p, _ := strconv.Atoi(port)
|
||||||
sc := utils.NewServerChannel(host, p, s.log)
|
sc := server.NewServerChannel(host, p, s.log)
|
||||||
if *s.cfg.LocalType == "tcp" {
|
if *s.cfg.LocalType == "tcp" {
|
||||||
err = sc.ListenTCP(s.callback)
|
err = sc.ListenTCP(s.callback)
|
||||||
} else if *s.cfg.LocalType == "tls" {
|
} else if *s.cfg.LocalType == "tls" {
|
||||||
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes, s.callback)
|
err = sc.ListenTLS(s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes, s.callback)
|
||||||
} else if *s.cfg.LocalType == "kcp" {
|
} else if *s.cfg.LocalType == "kcp" {
|
||||||
err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log)
|
err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,30 +8,33 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
srvtransport "github.com/snail007/goproxy/core/cs/server"
|
||||||
|
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
||||||
"github.com/snail007/goproxy/services"
|
"github.com/snail007/goproxy/services"
|
||||||
"github.com/snail007/goproxy/services/kcpcfg"
|
|
||||||
"github.com/snail007/goproxy/utils"
|
"github.com/snail007/goproxy/utils"
|
||||||
"github.com/snail007/goproxy/utils/mapx"
|
"github.com/snail007/goproxy/utils/mapx"
|
||||||
|
|
||||||
//"github.com/xtaci/smux"
|
//"github.com/xtaci/smux"
|
||||||
smux "github.com/hashicorp/yamux"
|
smux "github.com/hashicorp/yamux"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MuxBridgeArgs struct {
|
type MuxBridgeArgs struct {
|
||||||
CertFile *string
|
CertFile *string
|
||||||
KeyFile *string
|
KeyFile *string
|
||||||
CertBytes []byte
|
CertBytes []byte
|
||||||
KeyBytes []byte
|
KeyBytes []byte
|
||||||
Local *string
|
Local *string
|
||||||
LocalType *string
|
LocalType *string
|
||||||
Timeout *int
|
Timeout *int
|
||||||
IsCompress *bool
|
IsCompress *bool
|
||||||
KCP kcpcfg.KCPConfigArgs
|
KCP kcpcfg.KCPConfigArgs
|
||||||
|
TCPSMethod *string
|
||||||
|
TCPSPassword *string
|
||||||
|
TOUMethod *string
|
||||||
|
TOUPassword *string
|
||||||
}
|
}
|
||||||
type MuxBridge struct {
|
type MuxBridge struct {
|
||||||
cfg MuxBridgeArgs
|
cfg MuxBridgeArgs
|
||||||
@ -40,7 +43,7 @@ type MuxBridge struct {
|
|||||||
router utils.ClientKeyRouter
|
router utils.ClientKeyRouter
|
||||||
l *sync.Mutex
|
l *sync.Mutex
|
||||||
isStop bool
|
isStop bool
|
||||||
sc *utils.ServerChannel
|
sc *srvtransport.ServerChannel
|
||||||
log *logger.Logger
|
log *logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,21 +115,27 @@ func (s *MuxBridge) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
host, port, _ := net.SplitHostPort(*s.cfg.Local)
|
sc := srvtransport.NewServerChannelHost(*s.cfg.Local, s.log)
|
||||||
p, _ := strconv.Atoi(port)
|
|
||||||
sc := utils.NewServerChannel(host, p, s.log)
|
|
||||||
if *s.cfg.LocalType == "tcp" {
|
if *s.cfg.LocalType == "tcp" {
|
||||||
err = sc.ListenTCP(s.handler)
|
err = sc.ListenTCP(s.handler)
|
||||||
} else if *s.cfg.LocalType == "tls" {
|
} else if *s.cfg.LocalType == "tls" {
|
||||||
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, nil, s.handler)
|
err = sc.ListenTLS(s.cfg.CertBytes, s.cfg.KeyBytes, nil, s.handler)
|
||||||
} else if *s.cfg.LocalType == "kcp" {
|
} else if *s.cfg.LocalType == "kcp" {
|
||||||
err = sc.ListenKCP(s.cfg.KCP, s.handler, s.log)
|
err = sc.ListenKCP(s.cfg.KCP, s.handler, s.log)
|
||||||
|
} else if *s.cfg.LocalType == "tcps" {
|
||||||
|
err = sc.ListenTCPS(*s.cfg.TCPSMethod, *s.cfg.TCPSPassword, false, s.handler)
|
||||||
|
} else if *s.cfg.LocalType == "tou" {
|
||||||
|
err = sc.ListenTOU(*s.cfg.TOUMethod, *s.cfg.TOUPassword, false, s.handler)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.sc = &sc
|
s.sc = &sc
|
||||||
s.log.Printf("%s bridge on %s", *s.cfg.LocalType, (*sc.Listener).Addr())
|
if *s.cfg.LocalType == "tou" {
|
||||||
|
s.log.Printf("%s bridge on %s", *s.cfg.LocalType, sc.UDPListener.LocalAddr())
|
||||||
|
} else {
|
||||||
|
s.log.Printf("%s bridge on %s", *s.cfg.LocalType, (*sc.Listener).Addr())
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (s *MuxBridge) Clean() {
|
func (s *MuxBridge) Clean() {
|
||||||
@ -206,21 +215,25 @@ func (s *MuxBridge) handler(inConn net.Conn) {
|
|||||||
index := keyInfo[1]
|
index := keyInfo[1]
|
||||||
s.l.Lock()
|
s.l.Lock()
|
||||||
defer s.l.Unlock()
|
defer s.l.Unlock()
|
||||||
|
var group *mapx.ConcurrentMap
|
||||||
if !s.clientControlConns.Has(groupKey) {
|
if !s.clientControlConns.Has(groupKey) {
|
||||||
item := mapx.NewConcurrentMap()
|
_g := mapx.NewConcurrentMap()
|
||||||
s.clientControlConns.Set(groupKey, &item)
|
group = &_g
|
||||||
|
s.clientControlConns.Set(groupKey, group)
|
||||||
|
//s.log.Printf("init client session group %s", groupKey)
|
||||||
|
} else {
|
||||||
|
_group, _ := s.clientControlConns.Get(groupKey)
|
||||||
|
group = _group.(*mapx.ConcurrentMap)
|
||||||
}
|
}
|
||||||
_group, _ := s.clientControlConns.Get(groupKey)
|
|
||||||
group := _group.(*mapx.ConcurrentMap)
|
|
||||||
if v, ok := group.Get(index); ok {
|
if v, ok := group.Get(index); ok {
|
||||||
v.(*smux.Session).Close()
|
v.(*smux.Session).Close()
|
||||||
}
|
}
|
||||||
group.Set(index, session)
|
group.Set(index, session)
|
||||||
// s.clientControlConns.Set(key, session)
|
//s.log.Printf("set client session %s to group %s,grouplen:%d", index, groupKey, group.Count())
|
||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for {
|
for {
|
||||||
@ -232,10 +245,12 @@ func (s *MuxBridge) handler(inConn net.Conn) {
|
|||||||
defer s.l.Unlock()
|
defer s.l.Unlock()
|
||||||
if sess, ok := group.Get(index); ok && sess.(*smux.Session).IsClosed() {
|
if sess, ok := group.Get(index); ok && sess.(*smux.Session).IsClosed() {
|
||||||
group.Remove(index)
|
group.Remove(index)
|
||||||
|
//s.log.Printf("client session %s removed from group %s, grouplen:%d", key, groupKey, group.Count())
|
||||||
s.log.Printf("client connection %s released", key)
|
s.log.Printf("client connection %s released", key)
|
||||||
}
|
}
|
||||||
if group.IsEmpty() {
|
if group.IsEmpty() {
|
||||||
s.clientControlConns.Remove(groupKey)
|
s.clientControlConns.Remove(groupKey)
|
||||||
|
//s.log.Printf("client session group %s removed", groupKey)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -259,6 +274,7 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) {
|
|||||||
if key == "*" {
|
if key == "*" {
|
||||||
key = s.router.GetKey()
|
key = s.router.GetKey()
|
||||||
}
|
}
|
||||||
|
//s.log.Printf("server get client session %s", key)
|
||||||
_group, ok := s.clientControlConns.Get(key)
|
_group, ok := s.clientControlConns.Get(key)
|
||||||
if !ok {
|
if !ok {
|
||||||
s.log.Printf("client %s session not exists for server stream %s, retrying...", key, serverID)
|
s.log.Printf("client %s session not exists for server stream %s, retrying...", key, serverID)
|
||||||
@ -266,8 +282,12 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
group := _group.(*mapx.ConcurrentMap)
|
group := _group.(*mapx.ConcurrentMap)
|
||||||
keys := group.Keys()
|
keys := []string{}
|
||||||
|
group.IterCb(func(key string, v interface{}) {
|
||||||
|
keys = append(keys, key)
|
||||||
|
})
|
||||||
keysLen := len(keys)
|
keysLen := len(keys)
|
||||||
|
//s.log.Printf("client session %s , len:%d , keysLen: %d", key, group.Count(), keysLen)
|
||||||
i := 0
|
i := 0
|
||||||
if keysLen > 0 {
|
if keysLen > 0 {
|
||||||
i = rand.Intn(keysLen)
|
i = rand.Intn(keysLen)
|
||||||
@ -293,7 +313,7 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
io.Copy(stream, inConn)
|
io.Copy(stream, inConn)
|
||||||
@ -302,7 +322,7 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
io.Copy(inConn, stream)
|
io.Copy(inConn, stream)
|
||||||
|
|||||||
@ -8,15 +8,17 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/snappy"
|
||||||
|
clienttransport "github.com/snail007/goproxy/core/cs/client"
|
||||||
|
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
||||||
|
encryptconn "github.com/snail007/goproxy/core/lib/transport/encrypt"
|
||||||
"github.com/snail007/goproxy/services"
|
"github.com/snail007/goproxy/services"
|
||||||
"github.com/snail007/goproxy/services/kcpcfg"
|
|
||||||
"github.com/snail007/goproxy/utils"
|
"github.com/snail007/goproxy/utils"
|
||||||
"github.com/snail007/goproxy/utils/jumper"
|
"github.com/snail007/goproxy/utils/jumper"
|
||||||
"github.com/snail007/goproxy/utils/mapx"
|
"github.com/snail007/goproxy/utils/mapx"
|
||||||
|
|
||||||
"github.com/golang/snappy"
|
|
||||||
//"github.com/xtaci/smux"
|
//"github.com/xtaci/smux"
|
||||||
smux "github.com/hashicorp/yamux"
|
smux "github.com/hashicorp/yamux"
|
||||||
)
|
)
|
||||||
@ -34,6 +36,10 @@ type MuxClientArgs struct {
|
|||||||
SessionCount *int
|
SessionCount *int
|
||||||
KCP kcpcfg.KCPConfigArgs
|
KCP kcpcfg.KCPConfigArgs
|
||||||
Jumper *string
|
Jumper *string
|
||||||
|
TCPSMethod *string
|
||||||
|
TCPSPassword *string
|
||||||
|
TOUMethod *string
|
||||||
|
TOUPassword *string
|
||||||
}
|
}
|
||||||
type ClientUDPConnItem struct {
|
type ClientUDPConnItem struct {
|
||||||
conn *smux.Stream
|
conn *smux.Stream
|
||||||
@ -140,7 +146,7 @@ func (s *MuxClient) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
defer func() {
|
defer func() {
|
||||||
e := recover()
|
e := recover()
|
||||||
if e != nil {
|
if e != nil {
|
||||||
s.log.Printf("session worker crashed: %s", e)
|
s.log.Printf("session worker crashed: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for {
|
for {
|
||||||
@ -154,7 +160,16 @@ func (s *MuxClient) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
|
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
|
||||||
_, err = conn.Write(utils.BuildPacket(CONN_CLIENT, fmt.Sprintf("%s-%d", *s.cfg.Key, i)))
|
g := sync.WaitGroup{}
|
||||||
|
g.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
_ = recover()
|
||||||
|
g.Done()
|
||||||
|
}()
|
||||||
|
_, err = conn.Write(utils.BuildPacket(CONN_CLIENT, fmt.Sprintf("%s-%d", *s.cfg.Key, i)))
|
||||||
|
}()
|
||||||
|
g.Wait()
|
||||||
conn.SetDeadline(time.Time{})
|
conn.SetDeadline(time.Time{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
@ -222,7 +237,7 @@ func (s *MuxClient) getParentConn() (conn net.Conn, err error) {
|
|||||||
if *s.cfg.ParentType == "tls" {
|
if *s.cfg.ParentType == "tls" {
|
||||||
if s.jumper == nil {
|
if s.jumper == nil {
|
||||||
var _conn tls.Conn
|
var _conn tls.Conn
|
||||||
_conn, err = utils.TlsConnectHost(*s.cfg.Parent, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes, nil)
|
_conn, err = clienttransport.TlsConnectHost(*s.cfg.Parent, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes, nil)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
conn = net.Conn(&_conn)
|
conn = net.Conn(&_conn)
|
||||||
}
|
}
|
||||||
@ -239,10 +254,22 @@ func (s *MuxClient) getParentConn() (conn net.Conn, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if *s.cfg.ParentType == "kcp" {
|
} else if *s.cfg.ParentType == "kcp" {
|
||||||
conn, err = utils.ConnectKCPHost(*s.cfg.Parent, s.cfg.KCP)
|
conn, err = clienttransport.KCPConnectHost(*s.cfg.Parent, s.cfg.KCP)
|
||||||
|
} else if *s.cfg.ParentType == "tcps" {
|
||||||
|
if s.jumper == nil {
|
||||||
|
conn, err = clienttransport.TCPSConnectHost(*s.cfg.Parent, *s.cfg.TCPSMethod, *s.cfg.TCPSPassword, false, *s.cfg.Timeout)
|
||||||
|
} else {
|
||||||
|
conn, err = s.jumper.Dial(*s.cfg.Parent, time.Millisecond*time.Duration(*s.cfg.Timeout))
|
||||||
|
if err == nil {
|
||||||
|
conn, err = encryptconn.NewConn(conn, *s.cfg.TCPSMethod, *s.cfg.TCPSPassword)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if *s.cfg.ParentType == "tou" {
|
||||||
|
conn, err = clienttransport.TOUConnectHost(*s.cfg.Parent, *s.cfg.TCPSMethod, *s.cfg.TCPSPassword, false, *s.cfg.Timeout)
|
||||||
} else {
|
} else {
|
||||||
if s.jumper == nil {
|
if s.jumper == nil {
|
||||||
conn, err = utils.ConnectHost(*s.cfg.Parent, *s.cfg.Timeout)
|
conn, err = clienttransport.TCPConnectHost(*s.cfg.Parent, *s.cfg.Timeout)
|
||||||
} else {
|
} else {
|
||||||
conn, err = s.jumper.Dial(*s.cfg.Parent, time.Millisecond*time.Duration(*s.cfg.Timeout))
|
conn, err = s.jumper.Dial(*s.cfg.Parent, time.Millisecond*time.Duration(*s.cfg.Timeout))
|
||||||
}
|
}
|
||||||
@ -299,14 +326,17 @@ func (s *MuxClient) ServeUDP(inConn *smux.Stream, localAddr, ID string) {
|
|||||||
item = v.(*ClientUDPConnItem)
|
item = v.(*ClientUDPConnItem)
|
||||||
}
|
}
|
||||||
(*item).touchtime = time.Now().Unix()
|
(*item).touchtime = time.Now().Unix()
|
||||||
go (*item).udpConn.Write(body)
|
go func() {
|
||||||
|
defer func() { _ = recover() }()
|
||||||
|
(*item).udpConn.Write(body)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (s *MuxClient) UDPRevecive(key, ID string) {
|
func (s *MuxClient) UDPRevecive(key, ID string) {
|
||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
s.log.Printf("udp conn %s connected", ID)
|
s.log.Printf("udp conn %s connected", ID)
|
||||||
@ -336,7 +366,7 @@ func (s *MuxClient) UDPRevecive(key, ID string) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
cui.conn.SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
|
cui.conn.SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
|
||||||
@ -355,7 +385,7 @@ func (s *MuxClient) UDPGCDeamon() {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if s.isStop {
|
if s.isStop {
|
||||||
@ -414,7 +444,7 @@ func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
io.Copy(outConn, snappy.NewReader(inConn))
|
io.Copy(outConn, snappy.NewReader(inConn))
|
||||||
@ -423,7 +453,7 @@ func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
io.Copy(snappy.NewWriter(inConn), outConn)
|
io.Copy(snappy.NewWriter(inConn), outConn)
|
||||||
|
|||||||
@ -12,8 +12,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
clienttransport "github.com/snail007/goproxy/core/cs/client"
|
||||||
|
server "github.com/snail007/goproxy/core/cs/server"
|
||||||
|
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
||||||
|
encryptconn "github.com/snail007/goproxy/core/lib/transport/encrypt"
|
||||||
"github.com/snail007/goproxy/services"
|
"github.com/snail007/goproxy/services"
|
||||||
"github.com/snail007/goproxy/services/kcpcfg"
|
|
||||||
"github.com/snail007/goproxy/utils"
|
"github.com/snail007/goproxy/utils"
|
||||||
"github.com/snail007/goproxy/utils/jumper"
|
"github.com/snail007/goproxy/utils/jumper"
|
||||||
"github.com/snail007/goproxy/utils/mapx"
|
"github.com/snail007/goproxy/utils/mapx"
|
||||||
@ -47,10 +50,14 @@ type MuxServerArgs struct {
|
|||||||
SessionCount *int
|
SessionCount *int
|
||||||
KCP kcpcfg.KCPConfigArgs
|
KCP kcpcfg.KCPConfigArgs
|
||||||
Jumper *string
|
Jumper *string
|
||||||
|
TCPSMethod *string
|
||||||
|
TCPSPassword *string
|
||||||
|
TOUMethod *string
|
||||||
|
TOUPassword *string
|
||||||
}
|
}
|
||||||
type MuxServer struct {
|
type MuxServer struct {
|
||||||
cfg MuxServerArgs
|
cfg MuxServerArgs
|
||||||
sc utils.ServerChannel
|
sc server.ServerChannel
|
||||||
sessions mapx.ConcurrentMap
|
sessions mapx.ConcurrentMap
|
||||||
lockChn chan bool
|
lockChn chan bool
|
||||||
isStop bool
|
isStop bool
|
||||||
@ -133,6 +140,10 @@ func (s *MuxServerManager) Start(args interface{}, log *logger.Logger) (err erro
|
|||||||
KCP: s.cfg.KCP,
|
KCP: s.cfg.KCP,
|
||||||
ParentType: s.cfg.ParentType,
|
ParentType: s.cfg.ParentType,
|
||||||
Jumper: s.cfg.Jumper,
|
Jumper: s.cfg.Jumper,
|
||||||
|
TCPSMethod: s.cfg.TCPSMethod,
|
||||||
|
TCPSPassword: s.cfg.TCPSPassword,
|
||||||
|
TOUMethod: s.cfg.TOUMethod,
|
||||||
|
TOUPassword: s.cfg.TOUPassword,
|
||||||
}, log)
|
}, log)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -202,7 +213,7 @@ func (s *MuxServer) StopService() {
|
|||||||
s.jumper = nil
|
s.jumper = nil
|
||||||
s.lockChn = nil
|
s.lockChn = nil
|
||||||
s.log = nil
|
s.log = nil
|
||||||
s.sc = utils.ServerChannel{}
|
s.sc = server.ServerChannel{}
|
||||||
s.sessions = nil
|
s.sessions = nil
|
||||||
s.udpConns = nil
|
s.udpConns = nil
|
||||||
s = nil
|
s = nil
|
||||||
@ -254,7 +265,7 @@ func (s *MuxServer) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
}
|
}
|
||||||
host, port, _ := net.SplitHostPort(*s.cfg.Local)
|
host, port, _ := net.SplitHostPort(*s.cfg.Local)
|
||||||
p, _ := strconv.Atoi(port)
|
p, _ := strconv.Atoi(port)
|
||||||
s.sc = utils.NewServerChannel(host, p, s.log)
|
s.sc = server.NewServerChannel(host, p, s.log)
|
||||||
if *s.cfg.IsUDP {
|
if *s.cfg.IsUDP {
|
||||||
err = s.sc.ListenUDP(func(listener *net.UDPConn, packet []byte, localAddr, srcAddr *net.UDPAddr) {
|
err = s.sc.ListenUDP(func(listener *net.UDPConn, packet []byte, localAddr, srcAddr *net.UDPAddr) {
|
||||||
s.UDPSend(packet, localAddr, srcAddr)
|
s.UDPSend(packet, localAddr, srcAddr)
|
||||||
@ -293,7 +304,7 @@ func (s *MuxServer) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
io.Copy(inConn, snappy.NewReader(outConn))
|
io.Copy(inConn, snappy.NewReader(outConn))
|
||||||
@ -302,7 +313,7 @@ func (s *MuxServer) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
io.Copy(snappy.NewWriter(outConn), inConn)
|
io.Copy(snappy.NewWriter(outConn), inConn)
|
||||||
@ -397,7 +408,7 @@ func (s *MuxServer) GetConn(index string) (conn net.Conn, err error) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for {
|
for {
|
||||||
@ -443,6 +454,18 @@ func (s *MuxServer) getParentConn() (conn net.Conn, err error) {
|
|||||||
|
|
||||||
} else if *s.cfg.ParentType == "kcp" {
|
} else if *s.cfg.ParentType == "kcp" {
|
||||||
conn, err = utils.ConnectKCPHost(*s.cfg.Parent, s.cfg.KCP)
|
conn, err = utils.ConnectKCPHost(*s.cfg.Parent, s.cfg.KCP)
|
||||||
|
} else if *s.cfg.ParentType == "tcps" {
|
||||||
|
if s.jumper == nil {
|
||||||
|
conn, err = clienttransport.TCPSConnectHost(*s.cfg.Parent, *s.cfg.TCPSMethod, *s.cfg.TCPSPassword, false, *s.cfg.Timeout)
|
||||||
|
} else {
|
||||||
|
conn, err = s.jumper.Dial(*s.cfg.Parent, time.Millisecond*time.Duration(*s.cfg.Timeout))
|
||||||
|
if err == nil {
|
||||||
|
conn, err = encryptconn.NewConn(conn, *s.cfg.TCPSMethod, *s.cfg.TCPSPassword)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if *s.cfg.ParentType == "tou" {
|
||||||
|
conn, err = clienttransport.TOUConnectHost(*s.cfg.Parent, *s.cfg.TCPSMethod, *s.cfg.TCPSPassword, false, *s.cfg.Timeout)
|
||||||
} else {
|
} else {
|
||||||
if s.jumper == nil {
|
if s.jumper == nil {
|
||||||
conn, err = utils.ConnectHost(*s.cfg.Parent, *s.cfg.Timeout)
|
conn, err = utils.ConnectHost(*s.cfg.Parent, *s.cfg.Timeout)
|
||||||
@ -457,7 +480,7 @@ func (s *MuxServer) UDPGCDeamon() {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if s.isStop {
|
if s.isStop {
|
||||||
@ -536,7 +559,7 @@ func (s *MuxServer) UDPRevecive(key, ID string) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
s.log.Printf("udp conn %s connected", ID)
|
s.log.Printf("udp conn %s connected", ID)
|
||||||
@ -569,7 +592,7 @@ func (s *MuxServer) UDPRevecive(key, ID string) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
s.sc.UDPListener.WriteToUDP(body, uc.srcAddr)
|
s.sc.UDPListener.WriteToUDP(body, uc.srcAddr)
|
||||||
|
|||||||
@ -12,8 +12,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
server "github.com/snail007/goproxy/core/cs/server"
|
||||||
|
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
||||||
"github.com/snail007/goproxy/services"
|
"github.com/snail007/goproxy/services"
|
||||||
"github.com/snail007/goproxy/services/kcpcfg"
|
|
||||||
"github.com/snail007/goproxy/utils"
|
"github.com/snail007/goproxy/utils"
|
||||||
"github.com/snail007/goproxy/utils/conncrypt"
|
"github.com/snail007/goproxy/utils/conncrypt"
|
||||||
"github.com/snail007/goproxy/utils/datasize"
|
"github.com/snail007/goproxy/utils/datasize"
|
||||||
@ -80,8 +81,8 @@ type Socks struct {
|
|||||||
basicAuth utils.BasicAuth
|
basicAuth utils.BasicAuth
|
||||||
sshClient *ssh.Client
|
sshClient *ssh.Client
|
||||||
lockChn chan bool
|
lockChn chan bool
|
||||||
udpSC utils.ServerChannel
|
udpSC server.ServerChannel
|
||||||
sc *utils.ServerChannel
|
sc *server.ServerChannel
|
||||||
domainResolver dnsx.DomainResolver
|
domainResolver dnsx.DomainResolver
|
||||||
isStop bool
|
isStop bool
|
||||||
userConns mapx.ConcurrentMap
|
userConns mapx.ConcurrentMap
|
||||||
@ -191,7 +192,7 @@ func (s *Socks) InitService() (err error) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
//循环检查ssh网络连通性
|
//循环检查ssh网络连通性
|
||||||
@ -243,7 +244,7 @@ func (s *Socks) StopService() {
|
|||||||
s.udpLocalKey = nil
|
s.udpLocalKey = nil
|
||||||
s.udpParentKey = nil
|
s.udpParentKey = nil
|
||||||
s.udpRelatedPacketConns = nil
|
s.udpRelatedPacketConns = nil
|
||||||
s.udpSC = utils.ServerChannel{}
|
s.udpSC = server.ServerChannel{}
|
||||||
s.userConns = nil
|
s.userConns = nil
|
||||||
s = nil
|
s = nil
|
||||||
}()
|
}()
|
||||||
@ -283,11 +284,11 @@ func (s *Socks) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
if len(*s.cfg.Parent) > 0 {
|
if len(*s.cfg.Parent) > 0 {
|
||||||
s.log.Printf("use %s parent %v [ %s ]", *s.cfg.ParentType, *s.cfg.Parent, strings.ToUpper(*s.cfg.LoadBalanceMethod))
|
s.log.Printf("use %s parent %v [ %s ]", *s.cfg.ParentType, *s.cfg.Parent, strings.ToUpper(*s.cfg.LoadBalanceMethod))
|
||||||
}
|
}
|
||||||
sc := utils.NewServerChannelHost(*s.cfg.Local, s.log)
|
sc := server.NewServerChannelHost(*s.cfg.Local, s.log)
|
||||||
if *s.cfg.LocalType == "tcp" {
|
if *s.cfg.LocalType == "tcp" {
|
||||||
err = sc.ListenTCP(s.socksConnCallback)
|
err = sc.ListenTCP(s.socksConnCallback)
|
||||||
} else if *s.cfg.LocalType == "tls" {
|
} else if *s.cfg.LocalType == "tls" {
|
||||||
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes, s.socksConnCallback)
|
err = sc.ListenTLS(s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes, s.socksConnCallback)
|
||||||
} else if *s.cfg.LocalType == "kcp" {
|
} else if *s.cfg.LocalType == "kcp" {
|
||||||
err = sc.ListenKCP(s.cfg.KCP, s.socksConnCallback, s.log)
|
err = sc.ListenKCP(s.cfg.KCP, s.socksConnCallback, s.log)
|
||||||
}
|
}
|
||||||
@ -462,11 +463,7 @@ func (s *Socks) proxyTCP(inConn *net.Conn, serverConn *socks.ServerConn) {
|
|||||||
}
|
}
|
||||||
func (s *Socks) GetParentConn(parentAddress string, serverConn *socks.ServerConn) (outConn net.Conn, err interface{}) {
|
func (s *Socks) GetParentConn(parentAddress string, serverConn *socks.ServerConn) (outConn net.Conn, err interface{}) {
|
||||||
switch *s.cfg.ParentType {
|
switch *s.cfg.ParentType {
|
||||||
case "kcp":
|
case "kcp", "tls", "tcp":
|
||||||
fallthrough
|
|
||||||
case "tls":
|
|
||||||
fallthrough
|
|
||||||
case "tcp":
|
|
||||||
if *s.cfg.ParentType == "tls" {
|
if *s.cfg.ParentType == "tls" {
|
||||||
var _conn tls.Conn
|
var _conn tls.Conn
|
||||||
_conn, err = utils.TlsConnectHost(parentAddress, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes)
|
_conn, err = utils.TlsConnectHost(parentAddress, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes)
|
||||||
|
|||||||
@ -15,8 +15,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/snail007/goproxy/core/cs/server"
|
||||||
|
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
||||||
"github.com/snail007/goproxy/services"
|
"github.com/snail007/goproxy/services"
|
||||||
"github.com/snail007/goproxy/services/kcpcfg"
|
|
||||||
"github.com/snail007/goproxy/utils"
|
"github.com/snail007/goproxy/utils"
|
||||||
"github.com/snail007/goproxy/utils/conncrypt"
|
"github.com/snail007/goproxy/utils/conncrypt"
|
||||||
"github.com/snail007/goproxy/utils/datasize"
|
"github.com/snail007/goproxy/utils/datasize"
|
||||||
@ -78,7 +79,7 @@ type SPS struct {
|
|||||||
cfg SPSArgs
|
cfg SPSArgs
|
||||||
domainResolver dnsx.DomainResolver
|
domainResolver dnsx.DomainResolver
|
||||||
basicAuth utils.BasicAuth
|
basicAuth utils.BasicAuth
|
||||||
serverChannels []*utils.ServerChannel
|
serverChannels []*server.ServerChannel
|
||||||
userConns mapx.ConcurrentMap
|
userConns mapx.ConcurrentMap
|
||||||
log *logger.Logger
|
log *logger.Logger
|
||||||
localCipher *ss.Cipher
|
localCipher *ss.Cipher
|
||||||
@ -93,7 +94,7 @@ func NewSPS() services.Service {
|
|||||||
return &SPS{
|
return &SPS{
|
||||||
cfg: SPSArgs{},
|
cfg: SPSArgs{},
|
||||||
basicAuth: utils.BasicAuth{},
|
basicAuth: utils.BasicAuth{},
|
||||||
serverChannels: []*utils.ServerChannel{},
|
serverChannels: []*server.ServerChannel{},
|
||||||
userConns: mapx.NewConcurrentMap(),
|
userConns: mapx.NewConcurrentMap(),
|
||||||
udpRelatedPacketConns: mapx.NewConcurrentMap(),
|
udpRelatedPacketConns: mapx.NewConcurrentMap(),
|
||||||
}
|
}
|
||||||
@ -145,7 +146,7 @@ func (s *SPS) CheckArgs() (err error) {
|
|||||||
func (s *SPS) InitService() (err error) {
|
func (s *SPS) InitService() (err error) {
|
||||||
|
|
||||||
if *s.cfg.DNSAddress != "" {
|
if *s.cfg.DNSAddress != "" {
|
||||||
(*s).domainResolver = dnsx.NewDomainResolver(*s.cfg.DNSAddress, *s.cfg.DNSTTL, s.log)
|
s.domainResolver = dnsx.NewDomainResolver(*s.cfg.DNSAddress, *s.cfg.DNSTTL, s.log)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(*s.cfg.Parent) > 0 {
|
if len(*s.cfg.Parent) > 0 {
|
||||||
@ -230,12 +231,12 @@ func (s *SPS) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
if addr != "" {
|
if addr != "" {
|
||||||
host, port, _ := net.SplitHostPort(addr)
|
host, port, _ := net.SplitHostPort(addr)
|
||||||
p, _ := strconv.Atoi(port)
|
p, _ := strconv.Atoi(port)
|
||||||
sc := utils.NewServerChannel(host, p, s.log)
|
sc := server.NewServerChannel(host, p, s.log)
|
||||||
s.serverChannels = append(s.serverChannels, &sc)
|
s.serverChannels = append(s.serverChannels, &sc)
|
||||||
if *s.cfg.LocalType == "tcp" {
|
if *s.cfg.LocalType == "tcp" {
|
||||||
err = sc.ListenTCP(s.callback)
|
err = sc.ListenTCP(s.callback)
|
||||||
} else if *s.cfg.LocalType == "tls" {
|
} else if *s.cfg.LocalType == "tls" {
|
||||||
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes, s.callback)
|
err = sc.ListenTLS(s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes, s.callback)
|
||||||
} else if *s.cfg.LocalType == "tcp" {
|
} else if *s.cfg.LocalType == "tcp" {
|
||||||
err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log)
|
err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log)
|
||||||
}
|
}
|
||||||
@ -273,11 +274,7 @@ func (s *SPS) callback(inConn net.Conn) {
|
|||||||
var err error
|
var err error
|
||||||
lbAddr := ""
|
lbAddr := ""
|
||||||
switch *s.cfg.ParentType {
|
switch *s.cfg.ParentType {
|
||||||
case "kcp":
|
case "kcp", "tcp", "tls":
|
||||||
fallthrough
|
|
||||||
case "tcp":
|
|
||||||
fallthrough
|
|
||||||
case "tls":
|
|
||||||
lbAddr, err = s.OutToTCP(&inConn)
|
lbAddr, err = s.OutToTCP(&inConn)
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType)
|
err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType)
|
||||||
@ -363,7 +360,6 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (lbAddr string, err error) {
|
|||||||
request.HTTPSReply()
|
request.HTTPSReply()
|
||||||
//s.log.Printf("https reply: %s", request.Host)
|
//s.log.Printf("https reply: %s", request.Host)
|
||||||
} else {
|
} else {
|
||||||
//forwardBytes = bytes.TrimRight(request.HeadBuf,"\r\n")
|
|
||||||
forwardBytes = request.HeadBuf
|
forwardBytes = request.HeadBuf
|
||||||
}
|
}
|
||||||
address = request.Host
|
address = request.Host
|
||||||
@ -412,7 +408,6 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (lbAddr string, err error) {
|
|||||||
selectAddr = address
|
selectAddr = address
|
||||||
}
|
}
|
||||||
lbAddr = s.lb.Select(selectAddr, *s.cfg.LoadBalanceOnlyHA)
|
lbAddr = s.lb.Select(selectAddr, *s.cfg.LoadBalanceOnlyHA)
|
||||||
//lbAddr = s.lb.Select((*inConn).RemoteAddr().String())
|
|
||||||
outConn, err = s.GetParentConn(lbAddr)
|
outConn, err = s.GetParentConn(lbAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Printf("connect to %s , err:%s", lbAddr, err)
|
s.log.Printf("connect to %s , err:%s", lbAddr, err)
|
||||||
|
|||||||
@ -9,8 +9,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/snail007/goproxy/core/cs/server"
|
||||||
|
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
||||||
"github.com/snail007/goproxy/services"
|
"github.com/snail007/goproxy/services"
|
||||||
"github.com/snail007/goproxy/services/kcpcfg"
|
|
||||||
"github.com/snail007/goproxy/utils"
|
"github.com/snail007/goproxy/utils"
|
||||||
"github.com/snail007/goproxy/utils/jumper"
|
"github.com/snail007/goproxy/utils/jumper"
|
||||||
"github.com/snail007/goproxy/utils/mapx"
|
"github.com/snail007/goproxy/utils/mapx"
|
||||||
@ -43,7 +44,7 @@ type UDPConnItem struct {
|
|||||||
}
|
}
|
||||||
type TCP struct {
|
type TCP struct {
|
||||||
cfg TCPArgs
|
cfg TCPArgs
|
||||||
sc *utils.ServerChannel
|
sc *server.ServerChannel
|
||||||
isStop bool
|
isStop bool
|
||||||
userConns mapx.ConcurrentMap
|
userConns mapx.ConcurrentMap
|
||||||
log *logger.Logger
|
log *logger.Logger
|
||||||
@ -131,12 +132,12 @@ func (s *TCP) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
s.log.Printf("use %s parent %v", *s.cfg.ParentType, *s.cfg.Parent)
|
s.log.Printf("use %s parent %v", *s.cfg.ParentType, *s.cfg.Parent)
|
||||||
host, port, _ := net.SplitHostPort(*s.cfg.Local)
|
host, port, _ := net.SplitHostPort(*s.cfg.Local)
|
||||||
p, _ := strconv.Atoi(port)
|
p, _ := strconv.Atoi(port)
|
||||||
sc := utils.NewServerChannel(host, p, s.log)
|
sc := server.NewServerChannel(host, p, s.log)
|
||||||
|
|
||||||
if *s.cfg.LocalType == "tcp" {
|
if *s.cfg.LocalType == "tcp" {
|
||||||
err = sc.ListenTCP(s.callback)
|
err = sc.ListenTCP(s.callback)
|
||||||
} else if *s.cfg.LocalType == "tls" {
|
} else if *s.cfg.LocalType == "tls" {
|
||||||
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, nil, s.callback)
|
err = sc.ListenTLS(s.cfg.CertBytes, s.cfg.KeyBytes, nil, s.callback)
|
||||||
} else if *s.cfg.LocalType == "kcp" {
|
} else if *s.cfg.LocalType == "kcp" {
|
||||||
err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log)
|
err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log)
|
||||||
}
|
}
|
||||||
@ -160,11 +161,7 @@ func (s *TCP) callback(inConn net.Conn) {
|
|||||||
var err error
|
var err error
|
||||||
lbAddr := ""
|
lbAddr := ""
|
||||||
switch *s.cfg.ParentType {
|
switch *s.cfg.ParentType {
|
||||||
case "kcp":
|
case "kcp", "tcp", "tls":
|
||||||
fallthrough
|
|
||||||
case "tcp":
|
|
||||||
fallthrough
|
|
||||||
case "tls":
|
|
||||||
err = s.OutToTCP(&inConn)
|
err = s.OutToTCP(&inConn)
|
||||||
case "udp":
|
case "udp":
|
||||||
s.OutToUDP(&inConn)
|
s.OutToUDP(&inConn)
|
||||||
@ -208,8 +205,8 @@ func (s *TCP) OutToUDP(inConn *net.Conn) (err error) {
|
|||||||
srcAddr := ""
|
srcAddr := ""
|
||||||
defer func() {
|
defer func() {
|
||||||
if item != nil {
|
if item != nil {
|
||||||
(*(*item).conn).Close()
|
(*item.conn).Close()
|
||||||
(*item).udpConn.Close()
|
item.udpConn.Close()
|
||||||
s.udpConns.Remove(srcAddr)
|
s.udpConns.Remove(srcAddr)
|
||||||
(*inConn).Close()
|
(*inConn).Close()
|
||||||
}
|
}
|
||||||
@ -252,15 +249,15 @@ func (s *TCP) OutToUDP(inConn *net.Conn) (err error) {
|
|||||||
} else {
|
} else {
|
||||||
item = v.(*UDPConnItem)
|
item = v.(*UDPConnItem)
|
||||||
}
|
}
|
||||||
(*item).touchtime = time.Now().Unix()
|
item.touchtime = time.Now().Unix()
|
||||||
go (*item).udpConn.Write(body)
|
go item.udpConn.Write(body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (s *TCP) UDPRevecive(key string) {
|
func (s *TCP) UDPRevecive(key string) {
|
||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
s.log.Printf("udp conn %s connected", key)
|
s.log.Printf("udp conn %s connected", key)
|
||||||
@ -290,7 +287,7 @@ func (s *TCP) UDPRevecive(key string) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
(*cui.conn).SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
|
(*cui.conn).SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
|
||||||
@ -309,7 +306,7 @@ func (s *TCP) UDPGCDeamon() {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if s.isStop {
|
if s.isStop {
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/snail007/goproxy/core/cs/server"
|
||||||
"github.com/snail007/goproxy/services"
|
"github.com/snail007/goproxy/services"
|
||||||
"github.com/snail007/goproxy/utils"
|
"github.com/snail007/goproxy/utils"
|
||||||
"github.com/snail007/goproxy/utils/mapx"
|
"github.com/snail007/goproxy/utils/mapx"
|
||||||
@ -98,9 +99,9 @@ func (s *TunnelBridge) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
}
|
}
|
||||||
host, port, _ := net.SplitHostPort(*s.cfg.Local)
|
host, port, _ := net.SplitHostPort(*s.cfg.Local)
|
||||||
p, _ := strconv.Atoi(port)
|
p, _ := strconv.Atoi(port)
|
||||||
sc := utils.NewServerChannel(host, p, s.log)
|
sc := server.NewServerChannel(host, p, s.log)
|
||||||
|
|
||||||
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, nil, s.callback)
|
err = sc.ListenTLS(s.cfg.CertBytes, s.cfg.KeyBytes, nil, s.callback)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -159,7 +159,7 @@ func (s *TunnelClient) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
s.ServeUDP(localAddr, ID, serverID)
|
s.ServeUDP(localAddr, ID, serverID)
|
||||||
@ -168,7 +168,7 @@ func (s *TunnelClient) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
s.ServeConn(localAddr, ID, serverID)
|
s.ServeConn(localAddr, ID, serverID)
|
||||||
@ -324,7 +324,7 @@ func (s *TunnelClient) ServeUDP(localAddr, ID, serverID string) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
(*item).udpConn.Write(body)
|
(*item).udpConn.Write(body)
|
||||||
@ -335,7 +335,7 @@ func (s *TunnelClient) UDPRevecive(key, ID string) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
s.log.Printf("udp conn %s connected", ID)
|
s.log.Printf("udp conn %s connected", ID)
|
||||||
@ -365,7 +365,7 @@ func (s *TunnelClient) UDPRevecive(key, ID string) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
(*cui.conn).SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
|
(*cui.conn).SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
|
||||||
@ -384,7 +384,7 @@ func (s *TunnelClient) UDPGCDeamon() {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if s.isStop {
|
if s.isStop {
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/snail007/goproxy/core/cs/server"
|
||||||
"github.com/snail007/goproxy/services"
|
"github.com/snail007/goproxy/services"
|
||||||
"github.com/snail007/goproxy/utils"
|
"github.com/snail007/goproxy/utils"
|
||||||
"github.com/snail007/goproxy/utils/jumper"
|
"github.com/snail007/goproxy/utils/jumper"
|
||||||
@ -38,7 +39,7 @@ type TunnelServerArgs struct {
|
|||||||
}
|
}
|
||||||
type TunnelServer struct {
|
type TunnelServer struct {
|
||||||
cfg TunnelServerArgs
|
cfg TunnelServerArgs
|
||||||
sc utils.ServerChannel
|
sc server.ServerChannel
|
||||||
isStop bool
|
isStop bool
|
||||||
udpConn *net.Conn
|
udpConn *net.Conn
|
||||||
userConns mapx.ConcurrentMap
|
userConns mapx.ConcurrentMap
|
||||||
@ -180,7 +181,7 @@ func (s *TunnelServer) StopService() {
|
|||||||
s.cfg = TunnelServerArgs{}
|
s.cfg = TunnelServerArgs{}
|
||||||
s.jumper = nil
|
s.jumper = nil
|
||||||
s.log = nil
|
s.log = nil
|
||||||
s.sc = utils.ServerChannel{}
|
s.sc = server.ServerChannel{}
|
||||||
s.udpConn = nil
|
s.udpConn = nil
|
||||||
s.udpConns = nil
|
s.udpConns = nil
|
||||||
s.userConns = nil
|
s.userConns = nil
|
||||||
@ -233,7 +234,7 @@ func (s *TunnelServer) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
}
|
}
|
||||||
host, port, _ := net.SplitHostPort(*s.cfg.Local)
|
host, port, _ := net.SplitHostPort(*s.cfg.Local)
|
||||||
p, _ := strconv.Atoi(port)
|
p, _ := strconv.Atoi(port)
|
||||||
s.sc = utils.NewServerChannel(host, p, s.log)
|
s.sc = server.NewServerChannel(host, p, s.log)
|
||||||
if *s.cfg.IsUDP {
|
if *s.cfg.IsUDP {
|
||||||
err = s.sc.ListenUDP(func(listener *net.UDPConn, packet []byte, localAddr, srcAddr *net.UDPAddr) {
|
err = s.sc.ListenUDP(func(listener *net.UDPConn, packet []byte, localAddr, srcAddr *net.UDPAddr) {
|
||||||
s.UDPSend(packet, localAddr, srcAddr)
|
s.UDPSend(packet, localAddr, srcAddr)
|
||||||
@ -368,7 +369,7 @@ func (s *TunnelServer) UDPGCDeamon() {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if s.isStop {
|
if s.isStop {
|
||||||
@ -439,7 +440,7 @@ func (s *TunnelServer) UDPRevecive(key, ID string) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
s.log.Printf("udp conn %s connected", ID)
|
s.log.Printf("udp conn %s connected", ID)
|
||||||
@ -472,7 +473,7 @@ func (s *TunnelServer) UDPRevecive(key, ID string) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
s.sc.UDPListener.WriteToUDP(body, uc.srcAddr)
|
s.sc.UDPListener.WriteToUDP(body, uc.srcAddr)
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/snail007/goproxy/core/cs/server"
|
||||||
"github.com/snail007/goproxy/services"
|
"github.com/snail007/goproxy/services"
|
||||||
"github.com/snail007/goproxy/utils"
|
"github.com/snail007/goproxy/utils"
|
||||||
"github.com/snail007/goproxy/utils/mapx"
|
"github.com/snail007/goproxy/utils/mapx"
|
||||||
@ -30,7 +31,7 @@ type UDPArgs struct {
|
|||||||
type UDP struct {
|
type UDP struct {
|
||||||
p mapx.ConcurrentMap
|
p mapx.ConcurrentMap
|
||||||
cfg UDPArgs
|
cfg UDPArgs
|
||||||
sc *utils.ServerChannel
|
sc *server.ServerChannel
|
||||||
isStop bool
|
isStop bool
|
||||||
log *logger.Logger
|
log *logger.Logger
|
||||||
outUDPConnCtxMap mapx.ConcurrentMap
|
outUDPConnCtxMap mapx.ConcurrentMap
|
||||||
@ -121,7 +122,7 @@ func (s *UDP) Start(args interface{}, log *logger.Logger) (err error) {
|
|||||||
}
|
}
|
||||||
host, port, _ := net.SplitHostPort(*s.cfg.Local)
|
host, port, _ := net.SplitHostPort(*s.cfg.Local)
|
||||||
p, _ := strconv.Atoi(port)
|
p, _ := strconv.Atoi(port)
|
||||||
sc := utils.NewServerChannel(host, p, s.log)
|
sc := server.NewServerChannel(host, p, s.log)
|
||||||
s.sc = &sc
|
s.sc = &sc
|
||||||
err = sc.ListenUDP(s.callback)
|
err = sc.ListenUDP(s.callback)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -141,9 +142,7 @@ func (s *UDP) callback(listener *net.UDPConn, packet []byte, localAddr, srcAddr
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
switch *s.cfg.ParentType {
|
switch *s.cfg.ParentType {
|
||||||
case "tcp":
|
case "tcp", "tls":
|
||||||
fallthrough
|
|
||||||
case "tls":
|
|
||||||
s.OutToTCP(packet, localAddr, srcAddr)
|
s.OutToTCP(packet, localAddr, srcAddr)
|
||||||
case "udp":
|
case "udp":
|
||||||
s.OutToUDP(packet, localAddr, srcAddr)
|
s.OutToUDP(packet, localAddr, srcAddr)
|
||||||
@ -175,7 +174,7 @@ func (s *UDP) OutToUDPGCDeamon() {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if s.isStop {
|
if s.isStop {
|
||||||
@ -217,7 +216,7 @@ func (s *UDP) OutToUDP(packet []byte, localAddr, srcAddr *net.UDPAddr) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
s.log.Printf("udp conn %s <--> %s connected", srcAddr.String(), localAddr.String())
|
s.log.Printf("udp conn %s <--> %s connected", srcAddr.String(), localAddr.String())
|
||||||
@ -239,7 +238,7 @@ func (s *UDP) OutToUDP(packet []byte, localAddr, srcAddr *net.UDPAddr) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
(*(s.sc).UDPListener).SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
|
(*(s.sc).UDPListener).SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
|
||||||
@ -276,7 +275,7 @@ func (s *UDP) UDPGCDeamon() {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if s.isStop {
|
if s.isStop {
|
||||||
@ -353,7 +352,7 @@ func (s *UDP) UDPRevecive(key string) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
s.log.Printf("udp conn %s connected", key)
|
s.log.Printf("udp conn %s connected", key)
|
||||||
@ -386,7 +385,7 @@ func (s *UDP) UDPRevecive(key string) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
s.sc.UDPListener.WriteToUDP(body, uc.srcAddr)
|
s.sc.UDPListener.WriteToUDP(body, uc.srcAddr)
|
||||||
|
|||||||
@ -20,10 +20,9 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/snail007/goproxy/services/kcpcfg"
|
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
||||||
"github.com/snail007/goproxy/utils/lb"
|
"github.com/snail007/goproxy/utils/lb"
|
||||||
|
|
||||||
"golang.org/x/crypto/pbkdf2"
|
"golang.org/x/crypto/pbkdf2"
|
||||||
@ -245,98 +244,6 @@ func CloseConn(conn *net.Conn) {
|
|||||||
(*conn).Close()
|
(*conn).Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func Keygen() (err error) {
|
|
||||||
CList := []string{"AD", "AE", "AF", "AG", "AI", "AL", "AM", "AO", "AR", "AT", "AU", "AZ", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BR", "BS", "BW", "BY", "BZ", "CA", "CF", "CG", "CH", "CK", "CL", "CM", "CN", "CO", "CR", "CS", "CU", "CY", "CZ", "DE", "DJ", "DK", "DO", "DZ", "EC", "EE", "EG", "ES", "ET", "FI", "FJ", "FR", "GA", "GB", "GD", "GE", "GF", "GH", "GI", "GM", "GN", "GR", "GT", "GU", "GY", "HK", "HN", "HT", "HU", "ID", "IE", "IL", "IN", "IQ", "IR", "IS", "IT", "JM", "JO", "JP", "KE", "KG", "KH", "KP", "KR", "KT", "KW", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "MG", "ML", "MM", "MN", "MO", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NE", "NG", "NI", "NL", "NO", "NP", "NR", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PR", "PT", "PY", "QA", "RO", "RU", "SA", "SB", "SC", "SD", "SE", "SG", "SI", "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", "SY", "SZ", "TD", "TG", "TH", "TJ", "TM", "TN", "TO", "TR", "TT", "TW", "TZ", "UA", "UG", "US", "UY", "UZ", "VC", "VE", "VN", "YE", "YU", "ZA", "ZM", "ZR", "ZW"}
|
|
||||||
domainSubfixList := []string{".com", ".edu", ".gov", ".int", ".mil", ".net", ".org", ".biz", ".info", ".pro", ".name", ".museum", ".coop", ".aero", ".xxx", ".idv", ".ac", ".ad", ".ae", ".af", ".ag", ".ai", ".al", ".am", ".an", ".ao", ".aq", ".ar", ".as", ".at", ".au", ".aw", ".az", ".ba", ".bb", ".bd", ".be", ".bf", ".bg", ".bh", ".bi", ".bj", ".bm", ".bn", ".bo", ".br", ".bs", ".bt", ".bv", ".bw", ".by", ".bz", ".ca", ".cc", ".cd", ".cf", ".cg", ".ch", ".ci", ".ck", ".cl", ".cm", ".cn", ".co", ".cr", ".cu", ".cv", ".cx", ".cy", ".cz", ".de", ".dj", ".dk", ".dm", ".do", ".dz", ".ec", ".ee", ".eg", ".eh", ".er", ".es", ".et", ".eu", ".fi", ".fj", ".fk", ".fm", ".fo", ".fr", ".ga", ".gd", ".ge", ".gf", ".gg", ".gh", ".gi", ".gl", ".gm", ".gn", ".gp", ".gq", ".gr", ".gs", ".gt", ".gu", ".gw", ".gy", ".hk", ".hm", ".hn", ".hr", ".ht", ".hu", ".id", ".ie", ".il", ".im", ".in", ".io", ".iq", ".ir", ".is", ".it", ".je", ".jm", ".jo", ".jp", ".ke", ".kg", ".kh", ".ki", ".km", ".kn", ".kp", ".kr", ".kw", ".ky", ".kz", ".la", ".lb", ".lc", ".li", ".lk", ".lr", ".ls", ".lt", ".lu", ".lv", ".ly", ".ma", ".mc", ".md", ".mg", ".mh", ".mk", ".ml", ".mm", ".mn", ".mo", ".mp", ".mq", ".mr", ".ms", ".mt", ".mu", ".mv", ".mw", ".mx", ".my", ".mz", ".na", ".nc", ".ne", ".nf", ".ng", ".ni", ".nl", ".no", ".np", ".nr", ".nu", ".nz", ".om", ".pa", ".pe", ".pf", ".pg", ".ph", ".pk", ".pl", ".pm", ".pn", ".pr", ".ps", ".pt", ".pw", ".py", ".qa", ".re", ".ro", ".ru", ".rw", ".sa", ".sb", ".sc", ".sd", ".se", ".sg", ".sh", ".si", ".sj", ".sk", ".sl", ".sm", ".sn", ".so", ".sr", ".st", ".sv", ".sy", ".sz", ".tc", ".td", ".tf", ".tg", ".th", ".tj", ".tk", ".tl", ".tm", ".tn", ".to", ".tp", ".tr", ".tt", ".tv", ".tw", ".tz", ".ua", ".ug", ".uk", ".um", ".us", ".uy", ".uz", ".va", ".vc", ".ve", ".vg", ".vi", ".vn", ".vu", ".wf", ".ws", ".ye", ".yt", ".yu", ".yr", ".za", ".zm", ".zw"}
|
|
||||||
C := CList[int(RandInt(4))%len(CList)]
|
|
||||||
ST := RandString(int(RandInt(4) % 10))
|
|
||||||
O := RandString(int(RandInt(4) % 10))
|
|
||||||
CN := strings.ToLower(RandString(int(RandInt(4)%10)) + domainSubfixList[int(RandInt(4))%len(domainSubfixList)])
|
|
||||||
//log.Printf("C: %s, ST: %s, O: %s, CN: %s", C, ST, O, CN)
|
|
||||||
var out []byte
|
|
||||||
if len(os.Args) == 3 && os.Args[2] == "ca" {
|
|
||||||
cmd := exec.Command("sh", "-c", "openssl genrsa -out ca.key 2048")
|
|
||||||
out, err = cmd.CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
logger.Printf("err:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fmt.Println(string(out))
|
|
||||||
|
|
||||||
cmdStr := fmt.Sprintf("openssl req -new -key ca.key -x509 -days 36500 -out ca.crt -subj /C=%s/ST=%s/O=%s/CN=%s", C, ST, O, "*."+CN)
|
|
||||||
cmd = exec.Command("sh", "-c", cmdStr)
|
|
||||||
out, err = cmd.CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
logger.Printf("err:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fmt.Println(string(out))
|
|
||||||
} else if len(os.Args) == 5 && os.Args[2] == "ca" && os.Args[3] != "" && os.Args[4] != "" {
|
|
||||||
certBytes, _ := ioutil.ReadFile("ca.crt")
|
|
||||||
block, _ := pem.Decode(certBytes)
|
|
||||||
if block == nil || certBytes == nil {
|
|
||||||
panic("failed to parse ca certificate PEM")
|
|
||||||
}
|
|
||||||
x509Cert, _ := x509.ParseCertificate(block.Bytes)
|
|
||||||
if x509Cert == nil {
|
|
||||||
panic("failed to parse block")
|
|
||||||
}
|
|
||||||
name := os.Args[3]
|
|
||||||
days := os.Args[4]
|
|
||||||
cmd := exec.Command("sh", "-c", "openssl genrsa -out "+name+".key 2048")
|
|
||||||
out, err = cmd.CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
logger.Printf("err:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fmt.Println(string(out))
|
|
||||||
|
|
||||||
cmdStr := fmt.Sprintf("openssl req -new -key %s.key -out %s.csr -subj /C=%s/ST=%s/O=%s/CN=%s", name, name, C, ST, O, CN)
|
|
||||||
fmt.Printf("%s", cmdStr)
|
|
||||||
cmd = exec.Command("sh", "-c", cmdStr)
|
|
||||||
out, err = cmd.CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
logger.Printf("err:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fmt.Println(string(out))
|
|
||||||
|
|
||||||
cmdStr = fmt.Sprintf("openssl x509 -req -days %s -in %s.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out %s.crt", days, name, name)
|
|
||||||
fmt.Printf("%s", cmdStr)
|
|
||||||
cmd = exec.Command("sh", "-c", cmdStr)
|
|
||||||
out, err = cmd.CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
logger.Printf("err:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(string(out))
|
|
||||||
} else if len(os.Args) == 3 && os.Args[2] == "usage" {
|
|
||||||
fmt.Println(`proxy keygen //generate proxy.crt and proxy.key
|
|
||||||
proxy keygen ca //generate ca.crt and ca.key
|
|
||||||
proxy keygen ca client0 30 //generate client0.crt client0.key and use ca.crt sign it with 30 days
|
|
||||||
`)
|
|
||||||
} else if len(os.Args) == 2 {
|
|
||||||
cmd := exec.Command("sh", "-c", "openssl genrsa -out proxy.key 2048")
|
|
||||||
out, err = cmd.CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
logger.Printf("err:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fmt.Println(string(out))
|
|
||||||
|
|
||||||
cmdStr := fmt.Sprintf("openssl req -new -key proxy.key -x509 -days 36500 -out proxy.crt -subj /C=%s/ST=%s/O=%s/CN=%s", C, ST, O, CN)
|
|
||||||
cmd = exec.Command("sh", "-c", cmdStr)
|
|
||||||
out, err = cmd.CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
logger.Printf("err:%s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fmt.Println(string(out))
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var allInterfaceAddrCache []net.IP
|
var allInterfaceAddrCache []net.IP
|
||||||
|
|
||||||
@ -464,11 +371,20 @@ func RandInt(strLen int) int64 {
|
|||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
func ReadBytes(r io.Reader) (data []byte, err error) {
|
func ReadBytes(r io.Reader) (data []byte, err error) {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
err = fmt.Errorf("read bytes fail ,err : %s", e)
|
||||||
|
}
|
||||||
|
}()
|
||||||
var len uint64
|
var len uint64
|
||||||
err = binary.Read(r, binary.LittleEndian, &len)
|
err = binary.Read(r, binary.LittleEndian, &len)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if len == 0 || len > ^uint64(0) {
|
||||||
|
err = fmt.Errorf("data len out of range, %d", len)
|
||||||
|
return
|
||||||
|
}
|
||||||
var n int
|
var n int
|
||||||
data = make([]byte, len)
|
data = make([]byte, len)
|
||||||
n, err = r.Read(data)
|
n, err = r.Read(data)
|
||||||
|
|||||||
@ -116,7 +116,7 @@ func (b *Backend) startMuxHeartCheck() {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for {
|
for {
|
||||||
@ -151,7 +151,7 @@ func (b *Backend) startTCPHeartCheck() {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for {
|
for {
|
||||||
|
|||||||
@ -36,6 +36,7 @@ type Group struct {
|
|||||||
lock *sync.Mutex
|
lock *sync.Mutex
|
||||||
last *Backend
|
last *Backend
|
||||||
debug bool
|
debug bool
|
||||||
|
bks []*Backend
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGroup(selectType int, configs BackendsConfig, dr *dnsx.DomainResolver, log *log.Logger, debug bool) Group {
|
func NewGroup(selectType int, configs BackendsConfig, dr *dnsx.DomainResolver, log *log.Logger, debug bool) Group {
|
||||||
@ -68,9 +69,13 @@ func NewGroup(selectType int, configs BackendsConfig, dr *dnsx.DomainResolver, l
|
|||||||
dr: dr,
|
dr: dr,
|
||||||
lock: &sync.Mutex{},
|
lock: &sync.Mutex{},
|
||||||
debug: debug,
|
debug: debug,
|
||||||
|
bks: bks,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (g *Group) Select(srcAddr string, onlyHa bool) (addr string) {
|
func (g *Group) Select(srcAddr string, onlyHa bool) (addr string) {
|
||||||
|
if len(g.bks) == 1 {
|
||||||
|
return g.bks[0].Address
|
||||||
|
}
|
||||||
if onlyHa {
|
if onlyHa {
|
||||||
g.lock.Lock()
|
g.lock.Lock()
|
||||||
defer g.lock.Unlock()
|
defer g.lock.Unlock()
|
||||||
@ -121,6 +126,7 @@ func (g *Group) Reset(addrs []string) {
|
|||||||
configs = append(configs, &c)
|
configs = append(configs, &c)
|
||||||
}
|
}
|
||||||
(*g.selector).Reset(configs, g.dr, g.log)
|
(*g.selector).Reset(configs, g.dr, g.log)
|
||||||
|
g.bks = (*g.selector).Backends()
|
||||||
}
|
}
|
||||||
func (g *Group) Backends() []*Backend {
|
func (g *Group) Backends() []*Backend {
|
||||||
return (*g.selector).Backends()
|
return (*g.selector).Backends()
|
||||||
|
|||||||
@ -152,14 +152,7 @@ type Tuple struct {
|
|||||||
func (m ConcurrentMap) Iter() <-chan Tuple {
|
func (m ConcurrentMap) Iter() <-chan Tuple {
|
||||||
chans := snapshot(m)
|
chans := snapshot(m)
|
||||||
ch := make(chan Tuple)
|
ch := make(chan Tuple)
|
||||||
go func() {
|
go fanIn(chans, ch)
|
||||||
defer func() {
|
|
||||||
if e := recover(); e != nil {
|
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
fanIn(chans, ch)
|
|
||||||
}()
|
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,14 +164,7 @@ func (m ConcurrentMap) IterBuffered() <-chan Tuple {
|
|||||||
total += cap(c)
|
total += cap(c)
|
||||||
}
|
}
|
||||||
ch := make(chan Tuple, total)
|
ch := make(chan Tuple, total)
|
||||||
go func() {
|
go fanIn(chans, ch)
|
||||||
defer func() {
|
|
||||||
if e := recover(); e != nil {
|
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
fanIn(chans, ch)
|
|
||||||
}()
|
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,11 +179,6 @@ func snapshot(m ConcurrentMap) (chans []chan Tuple) {
|
|||||||
// Foreach shard.
|
// Foreach shard.
|
||||||
for index, shard := range m {
|
for index, shard := range m {
|
||||||
go func(index int, shard *ConcurrentMapShared) {
|
go func(index int, shard *ConcurrentMapShared) {
|
||||||
defer func() {
|
|
||||||
if e := recover(); e != nil {
|
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
// Foreach key, value pair.
|
// Foreach key, value pair.
|
||||||
shard.RLock()
|
shard.RLock()
|
||||||
chans[index] = make(chan Tuple, len(shard.items))
|
chans[index] = make(chan Tuple, len(shard.items))
|
||||||
@ -215,22 +196,25 @@ func snapshot(m ConcurrentMap) (chans []chan Tuple) {
|
|||||||
|
|
||||||
// fanIn reads elements from channels `chans` into channel `out`
|
// fanIn reads elements from channels `chans` into channel `out`
|
||||||
func fanIn(chans []chan Tuple, out chan Tuple) {
|
func fanIn(chans []chan Tuple, out chan Tuple) {
|
||||||
|
defer func() {
|
||||||
|
if e := recover(); e != nil {
|
||||||
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
wg.Add(len(chans))
|
wg.Add(len(chans))
|
||||||
for _, ch := range chans {
|
for _, ch := range chans {
|
||||||
go func() {
|
go func(ch chan Tuple) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
func(ch chan Tuple) {
|
for t := range ch {
|
||||||
for t := range ch {
|
out <- t
|
||||||
out <- t
|
}
|
||||||
}
|
wg.Done()
|
||||||
wg.Done()
|
}(ch)
|
||||||
}(ch)
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
close(out)
|
close(out)
|
||||||
@ -274,29 +258,27 @@ func (m ConcurrentMap) Keys() []string {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
// Foreach shard.
|
// Foreach shard.
|
||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
wg.Add(SHARD_COUNT)
|
wg.Add(SHARD_COUNT)
|
||||||
for _, shard := range m {
|
for _, shard := range m {
|
||||||
go func() {
|
go func(shard *ConcurrentMapShared) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
func(shard *ConcurrentMapShared) {
|
// Foreach key, value pair.
|
||||||
// Foreach key, value pair.
|
shard.RLock()
|
||||||
shard.RLock()
|
for key := range shard.items {
|
||||||
for key := range shard.items {
|
ch <- key
|
||||||
ch <- key
|
}
|
||||||
}
|
shard.RUnlock()
|
||||||
shard.RUnlock()
|
wg.Done()
|
||||||
wg.Done()
|
}(shard)
|
||||||
}(shard)
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
close(ch)
|
close(ch)
|
||||||
|
|||||||
@ -1,230 +0,0 @@
|
|||||||
package utils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/tls"
|
|
||||||
"crypto/x509"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
logger "log"
|
|
||||||
"net"
|
|
||||||
"runtime/debug"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/snail007/goproxy/services/kcpcfg"
|
|
||||||
|
|
||||||
kcp "github.com/xtaci/kcp-go"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ServerChannel struct {
|
|
||||||
ip string
|
|
||||||
port int
|
|
||||||
Listener *net.Listener
|
|
||||||
UDPListener *net.UDPConn
|
|
||||||
errAcceptHandler func(err error)
|
|
||||||
log *logger.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewServerChannel(ip string, port int, log *logger.Logger) ServerChannel {
|
|
||||||
return ServerChannel{
|
|
||||||
ip: ip,
|
|
||||||
port: port,
|
|
||||||
log: log,
|
|
||||||
errAcceptHandler: func(err error) {
|
|
||||||
log.Printf("accept error , ERR:%s", err)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func NewServerChannelHost(host string, log *logger.Logger) ServerChannel {
|
|
||||||
h, port, _ := net.SplitHostPort(host)
|
|
||||||
p, _ := strconv.Atoi(port)
|
|
||||||
return ServerChannel{
|
|
||||||
ip: h,
|
|
||||||
port: p,
|
|
||||||
log: log,
|
|
||||||
errAcceptHandler: func(err error) {
|
|
||||||
log.Printf("accept error , ERR:%s", err)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func (sc *ServerChannel) SetErrAcceptHandler(fn func(err error)) {
|
|
||||||
sc.errAcceptHandler = fn
|
|
||||||
}
|
|
||||||
func (sc *ServerChannel) ListenTls(certBytes, keyBytes, caCertBytes []byte, fn func(conn net.Conn)) (err error) {
|
|
||||||
sc.Listener, err = sc.listenTls(sc.ip, sc.port, certBytes, keyBytes, caCertBytes)
|
|
||||||
if err == nil {
|
|
||||||
go func() {
|
|
||||||
defer func() {
|
|
||||||
if e := recover(); e != nil {
|
|
||||||
sc.log.Printf("ListenTls crashed , err : %s , \ntrace:%s", e, string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
for {
|
|
||||||
var conn net.Conn
|
|
||||||
conn, err = (*sc.Listener).Accept()
|
|
||||||
if err == nil {
|
|
||||||
go func() {
|
|
||||||
defer func() {
|
|
||||||
if e := recover(); e != nil {
|
|
||||||
sc.log.Printf("tls connection handler crashed , err : %s , \ntrace:%s", e, string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
fn(conn)
|
|
||||||
}()
|
|
||||||
} else {
|
|
||||||
sc.errAcceptHandler(err)
|
|
||||||
(*sc.Listener).Close()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
func (sc *ServerChannel) listenTls(ip string, port int, certBytes, keyBytes, caCertBytes []byte) (ln *net.Listener, err error) {
|
|
||||||
|
|
||||||
var cert tls.Certificate
|
|
||||||
cert, err = tls.X509KeyPair(certBytes, keyBytes)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
clientCertPool := x509.NewCertPool()
|
|
||||||
caBytes := certBytes
|
|
||||||
if caCertBytes != nil {
|
|
||||||
caBytes = caCertBytes
|
|
||||||
}
|
|
||||||
ok := clientCertPool.AppendCertsFromPEM(caBytes)
|
|
||||||
if !ok {
|
|
||||||
err = errors.New("failed to parse root certificate")
|
|
||||||
}
|
|
||||||
config := &tls.Config{
|
|
||||||
ClientCAs: clientCertPool,
|
|
||||||
Certificates: []tls.Certificate{cert},
|
|
||||||
ClientAuth: tls.RequireAndVerifyClientCert,
|
|
||||||
}
|
|
||||||
_ln, err := tls.Listen("tcp", fmt.Sprintf("%s:%d", ip, port), config)
|
|
||||||
if err == nil {
|
|
||||||
ln = &_ln
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
func (sc *ServerChannel) ListenTCP(fn func(conn net.Conn)) (err error) {
|
|
||||||
var l net.Listener
|
|
||||||
l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", sc.ip, sc.port))
|
|
||||||
if err == nil {
|
|
||||||
sc.Listener = &l
|
|
||||||
go func() {
|
|
||||||
defer func() {
|
|
||||||
if e := recover(); e != nil {
|
|
||||||
sc.log.Printf("ListenTCP crashed , err : %s , \ntrace:%s", e, string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
for {
|
|
||||||
var conn net.Conn
|
|
||||||
conn, err = (*sc.Listener).Accept()
|
|
||||||
if err == nil {
|
|
||||||
go func() {
|
|
||||||
defer func() {
|
|
||||||
if e := recover(); e != nil {
|
|
||||||
sc.log.Printf("tcp connection handler crashed , err : %s , \ntrace:%s", e, string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
fn(conn)
|
|
||||||
}()
|
|
||||||
} else {
|
|
||||||
sc.errAcceptHandler(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
func (sc *ServerChannel) ListenUDP(fn func(listener *net.UDPConn, packet []byte, localAddr, srcAddr *net.UDPAddr)) (err error) {
|
|
||||||
addr := &net.UDPAddr{IP: net.ParseIP(sc.ip), Port: sc.port}
|
|
||||||
l, err := net.ListenUDP("udp", addr)
|
|
||||||
if err == nil {
|
|
||||||
sc.UDPListener = l
|
|
||||||
go func() {
|
|
||||||
defer func() {
|
|
||||||
if e := recover(); e != nil {
|
|
||||||
sc.log.Printf("ListenUDP crashed , err : %s , \ntrace:%s", e, string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
for {
|
|
||||||
var buf = make([]byte, 2048)
|
|
||||||
n, srcAddr, err := (*sc.UDPListener).ReadFromUDP(buf)
|
|
||||||
if err == nil {
|
|
||||||
packet := buf[0:n]
|
|
||||||
go func() {
|
|
||||||
defer func() {
|
|
||||||
if e := recover(); e != nil {
|
|
||||||
sc.log.Printf("udp data handler crashed , err : %s , \ntrace:%s", e, string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
fn(l, packet, addr, srcAddr)
|
|
||||||
}()
|
|
||||||
} else {
|
|
||||||
sc.errAcceptHandler(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sc *ServerChannel) ListenKCP(config kcpcfg.KCPConfigArgs, fn func(conn net.Conn), log *logger.Logger) (err error) {
|
|
||||||
lis, err := kcp.ListenWithOptions(fmt.Sprintf("%s:%d", sc.ip, sc.port), config.Block, *config.DataShard, *config.ParityShard)
|
|
||||||
if err == nil {
|
|
||||||
if err = lis.SetDSCP(*config.DSCP); err != nil {
|
|
||||||
log.Println("SetDSCP:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = lis.SetReadBuffer(*config.SockBuf); err != nil {
|
|
||||||
log.Println("SetReadBuffer:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = lis.SetWriteBuffer(*config.SockBuf); err != nil {
|
|
||||||
log.Println("SetWriteBuffer:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sc.Listener = new(net.Listener)
|
|
||||||
*sc.Listener = lis
|
|
||||||
go func() {
|
|
||||||
defer func() {
|
|
||||||
if e := recover(); e != nil {
|
|
||||||
sc.log.Printf("ListenKCP crashed , err : %s , \ntrace:%s", e, string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
for {
|
|
||||||
//var conn net.Conn
|
|
||||||
conn, err := lis.AcceptKCP()
|
|
||||||
if err == nil {
|
|
||||||
go func() {
|
|
||||||
defer func() {
|
|
||||||
if e := recover(); e != nil {
|
|
||||||
sc.log.Printf("kcp connection handler crashed , err : %s , \ntrace:%s", e, string(debug.Stack()))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
conn.SetStreamMode(true)
|
|
||||||
conn.SetWriteDelay(true)
|
|
||||||
conn.SetNoDelay(*config.NoDelay, *config.Interval, *config.Resend, *config.NoCongestion)
|
|
||||||
conn.SetMtu(*config.MTU)
|
|
||||||
conn.SetWindowSize(*config.SndWnd, *config.RcvWnd)
|
|
||||||
conn.SetACKNoDelay(*config.AckNodelay)
|
|
||||||
if *config.NoComp {
|
|
||||||
fn(conn)
|
|
||||||
} else {
|
|
||||||
cconn := NewCompStream(conn)
|
|
||||||
fn(cconn)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
} else {
|
|
||||||
sc.errAcceptHandler(err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@ -90,7 +90,7 @@ func (c *Checker) start() {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
//log.Printf("checker started")
|
//log.Printf("checker started")
|
||||||
@ -100,7 +100,7 @@ func (c *Checker) start() {
|
|||||||
go func(item CheckerItem) {
|
go func(item CheckerItem) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if c.isNeedCheck(item) {
|
if c.isNeedCheck(item) {
|
||||||
@ -176,11 +176,9 @@ func (c *Checker) domainIsInMap(address string, blockedMap bool) bool {
|
|||||||
}
|
}
|
||||||
domainSlice := strings.Split(u.Hostname(), ".")
|
domainSlice := strings.Split(u.Hostname(), ".")
|
||||||
if len(domainSlice) > 1 {
|
if len(domainSlice) > 1 {
|
||||||
subSlice := domainSlice[:len(domainSlice)-1]
|
checkDomain := ""
|
||||||
topDomain := strings.Join(domainSlice[len(domainSlice)-1:], ".")
|
for i := len(domainSlice) - 1; i >= 0; i-- {
|
||||||
checkDomain := topDomain
|
checkDomain = strings.Join(domainSlice[i:], ".")
|
||||||
for i := len(subSlice) - 1; i >= 0; i-- {
|
|
||||||
checkDomain = subSlice[i] + "." + checkDomain
|
|
||||||
if !blockedMap && c.directMap.Has(checkDomain) {
|
if !blockedMap && c.directMap.Has(checkDomain) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -237,7 +235,7 @@ func (ba *BasicAuth) AddFromFile(file string) (n int, err error) {
|
|||||||
}
|
}
|
||||||
userpassArr := strings.Split(strings.Replace(string(_content), "\r", "", -1), "\n")
|
userpassArr := strings.Split(strings.Replace(string(_content), "\r", "", -1), "\n")
|
||||||
for _, userpass := range userpassArr {
|
for _, userpass := range userpassArr {
|
||||||
if strings.HasPrefix("#", userpass) {
|
if strings.HasPrefix(userpass, "#") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
u := strings.Split(strings.Trim(userpass, " "), ":")
|
u := strings.Split(strings.Trim(userpass, " "), ":")
|
||||||
|
|||||||
Reference in New Issue
Block a user