Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e95a1f8ad5 | ||
|
|
9e496f246c | ||
|
|
f0389cdd5b | ||
|
|
bcca92affc | ||
|
|
421e72188b | ||
|
|
cc8416e6bf | ||
|
|
fb09a100e1 | ||
|
|
1b1091d75f | ||
|
|
ea30beb79b | ||
|
|
99881e2c70 | ||
|
|
325acb2942 | ||
|
|
6babe1ea10 | ||
|
|
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.下面列出了有效的授权编号和有效期.
|
||||
|
||||
授权编号 | 授权有效期
|
||||
:--- | :---
|
||||
27
CHANGELOG
27
CHANGELOG
@ -1,4 +1,31 @@
|
||||
proxy更新日志
|
||||
v6.4
|
||||
1.http(s)代理增加了--jumper参数,可以穿透外部代理连接上级.
|
||||
2.优化了socks5代理UDP功能可能存在的内存占用过多问题.
|
||||
3.优化了jumper,避免某些情况下不能正确返回错误的问题.
|
||||
4.sps代理增加了--jumper参数,可以穿透外部代理连接上级.
|
||||
5.修复了--debug不能正常工作的问题.
|
||||
|
||||
v6.3
|
||||
1.fixed #156
|
||||
2.修复DNS代理,没有定时保存缓存结果到文件.重启会降低查询速度.
|
||||
|
||||
|
||||
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 企业版开源啦
|
||||
本次更新主要是把企业版开源,把企业版代码合并到现在的开源goproxy当中,继续遵循GPLv3,免费开源,
|
||||
|
||||
20
Gopkg.lock
generated
20
Gopkg.lock
generated
@ -1,6 +1,12 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/Yawning/chacha20"
|
||||
packages = ["."]
|
||||
revision = "e3b1f968fc6397b51d963fee8ec8711a47bc0ce8"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/alecthomas/template"
|
||||
@ -28,6 +34,12 @@
|
||||
packages = ["."]
|
||||
revision = "3520598351bb3500a49ae9563f5539666ae0a27c"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/juju/ratelimit"
|
||||
packages = ["."]
|
||||
revision = "59fac5042749a5afb9af70e813da1dd5474f0167"
|
||||
version = "1.0.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/klauspost/cpuid"
|
||||
packages = ["."]
|
||||
@ -119,6 +131,12 @@
|
||||
]
|
||||
revision = "db08ff08e8622530d9ed3a0e8ac279f6d4c02196"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix"]
|
||||
revision = "dad3d9fb7b6e83d0f9ac8f54670f6334c3a287b4"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/time"
|
||||
@ -134,6 +152,6 @@
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "eab0ef29432489696d8bfd524757dcb03a83f91c329f2d05c36da70df850360d"
|
||||
inputs-digest = "15e4e23c0695db1458b3dc5514c8765be091a420c923b24bb9e186f43400995f"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
||||
195
README.md
195
README.md
@ -1,5 +1,5 @@
|
||||
<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.
|
||||
|
||||
|
||||
---
|
||||
@ -12,6 +12,8 @@ Proxy is a high performance HTTP, HTTPS, HTTPS, websocket, TCP, UDP, Socks5 prox
|
||||
|
||||
**[全平台SDK](/sdk/README.md)**
|
||||
|
||||
**[GoProxy特殊授权](/AUTHORIZATION.md)**
|
||||
|
||||
### How to contribute to the code (Pull Request)?
|
||||
|
||||
Pull Request is welcomed.
|
||||
@ -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.
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
- 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?
|
||||
- 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?
|
||||
@ -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)
|
||||
|
||||
### Manual catalogues
|
||||
- [Load balance and high available](#load-balance-and-high-available)
|
||||
- [1.HTTP proxy](#1http-proxy)
|
||||
- [1.1 Common HTTP proxy](#11common-http-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.12 Custom encryption](#112-custom-encryption)
|
||||
- [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.1 Common TCP first level proxy](#21common-tcp-first-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.10 Custom encryption](#510custom-encryption)
|
||||
- [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.1 Functional introduction](#61functional-introduction)
|
||||
- [6.2 HTTP(S) to HTTP(S) + SOCKS5](#62http-to-http-socks5)
|
||||
- [6.3 SOCKS5 to HTTP(S) + SOCKS5](#63socks5-to-http-socks5)
|
||||
- [6.4 Chain style connection](#64chain-style-connection)
|
||||
- [6.5 Listening on multiple ports](#65listening-on-multiple-ports)
|
||||
- [6.6 Authentication](#66authentication)
|
||||
- [6.7 Custom encryption](#67-custom-encryption)
|
||||
- [6.8 Compressed transmission](#68-compressed-transmission)
|
||||
- [6.9 View Help](#69view-help)
|
||||
- [6.4 SS to HTTP(S)+SOCKS5+SS](#64-ss-to-httpssocks5ss)
|
||||
- [6.5 Chain style connection](#65chain-style-connection)
|
||||
- [6.6 Listening on multiple ports](#66listening-on-multiple-ports)
|
||||
- [6.7 Authentication](#67authentication)
|
||||
- [6.8 Custom encryption](#68-custom-encryption)
|
||||
- [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.1 Configuration introduction](#71configuration-introduction)
|
||||
- [7.2 Configuration details](#72configuration-details)
|
||||
@ -155,7 +177,7 @@ tips:all operations require root permissions.
|
||||
```shell
|
||||
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:
|
||||
|
||||
#### 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
|
||||
```shell
|
||||
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**
|
||||
@ -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.
|
||||
|
||||
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:
|
||||
@ -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.
|
||||
`./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.1.common HTTP proxy**
|
||||

|
||||
@ -459,7 +495,32 @@ Local third level execution:
|
||||
`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.
|
||||
|
||||
#### **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`
|
||||
|
||||
### **2.TCP proxy**
|
||||
@ -868,41 +929,80 @@ Local third level execution:
|
||||
`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.
|
||||
|
||||
#### **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`
|
||||
|
||||
### **6.Proxy protocol conversion**
|
||||
|
||||
#### **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**
|
||||
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:
|
||||
`./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:
|
||||
`./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:
|
||||
`./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**
|
||||
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:
|
||||
`./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:
|
||||
`./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:
|
||||
`./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.
|
||||
vps01:2.2.2.2
|
||||
@ -922,11 +1022,11 @@ Then run a SPS node on the PC,excute:
|
||||
|
||||
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.
|
||||
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:
|
||||
1:Users send authentication information`user-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 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.
|
||||
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`
|
||||
@ -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`
|
||||
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.
|
||||
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:
|
||||
@ -1010,7 +1110,30 @@ Local third level execution:
|
||||
`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.
|
||||
|
||||
#### **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`
|
||||
|
||||
### **7.KCP Configuration**
|
||||
|
||||
20
README_ZH.md
20
README_ZH.md
@ -13,6 +13,8 @@ Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5,ss代理服
|
||||
|
||||
**[全平台SDK](/sdk/README.md)**
|
||||
|
||||
**[GoProxy特殊授权](/AUTHORIZATION.md)**
|
||||
|
||||
### 如何贡献代码(Pull Request)?
|
||||
|
||||
欢迎加入一起发展壮大proxy.首先需要clone本项目到自己的帐号下面,
|
||||
@ -169,21 +171,27 @@ Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5,ss代理服
|
||||
提示:所有操作需要root权限.
|
||||
#### 自动安装
|
||||
#### **0.如果你的VPS是linux64位的系统,那么只需要执行下面一句,就可以完成自动安装和配置.**
|
||||
|
||||
```shell
|
||||
curl -L https://raw.githubusercontent.com/snail007/goproxy/master/install_auto.sh | bash
|
||||
```
|
||||
|
||||
安装完成,配置目录是/etc/proxy,更详细的使用方法请参考上面的手册目录,进一步了解你想要使用的功能.
|
||||
如果安装失败或者你的vps不是linux64位系统,请按照下面的半自动步骤安装:
|
||||
|
||||
#### 手动安装
|
||||
|
||||
#### **1.下载proxy**
|
||||
下载地址:https://github.com/snail007/goproxy/releases
|
||||
下载地址:https://github.com/snail007/goproxy/releases/latest
|
||||
下面以v6.2为例,如果有最新版,请使用最新版链接.
|
||||
|
||||
```shell
|
||||
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.下载自动安装脚本**
|
||||
|
||||
```shell
|
||||
cd /root/proxy/
|
||||
wget https://raw.githubusercontent.com/snail007/goproxy/master/install.sh
|
||||
@ -378,7 +386,7 @@ target:用户访问的URL,比如:http://demo.com:80/1.html或https://www.baidu.c
|
||||
|
||||
##### ***1.7.1 ssh用户名和密码的方式***
|
||||
本地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用户名和密钥的方式***
|
||||
本地HTTP(S)代理28080端口,执行:
|
||||
`./proxy http -T ssh -P "2.2.2.2:22" -u user -S user.key -t tcp -p ":28080"`
|
||||
@ -523,7 +531,7 @@ HTTP(S)代理支持上级负载均衡,多个上级重复-P参数即可.
|
||||
|
||||
#### **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 限速**
|
||||
|
||||
@ -877,7 +885,7 @@ SOCKS5代理,支持CONNECT,UDP协议,不支持BIND,支持用户名密码认证.
|
||||
|
||||
##### ***5.6.1 ssh用户名和密码的方式***
|
||||
本地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用户名和密钥的方式***
|
||||
本地SOCKS5代理28080端口,执行:
|
||||
`./proxy socks -T ssh -P "2.2.2.2:22" -u user -S user.key -t tcp -p ":28080"`
|
||||
@ -989,7 +997,7 @@ SOCKS代理支持上级负载均衡,多个上级重复-P参数即可.
|
||||
|
||||
#### **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 限速**
|
||||
|
||||
|
||||
49
config.go
49
config.go
@ -12,12 +12,14 @@ import (
|
||||
"path/filepath"
|
||||
"runtime/debug"
|
||||
"runtime/pprof"
|
||||
"strings"
|
||||
"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"
|
||||
services "github.com/snail007/goproxy/services"
|
||||
httpx "github.com/snail007/goproxy/services/http"
|
||||
"github.com/snail007/goproxy/services/kcpcfg"
|
||||
keygenx "github.com/snail007/goproxy/services/keygen"
|
||||
mux "github.com/snail007/goproxy/services/mux"
|
||||
socksx "github.com/snail007/goproxy/services/socks"
|
||||
@ -32,11 +34,12 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
app *kingpin.Application
|
||||
service *services.ServiceItem
|
||||
cmd *exec.Cmd
|
||||
cpuProfilingFile, memProfilingFile, blockProfilingFile, goroutineProfilingFile, threadcreateProfilingFile *os.File
|
||||
isDebug bool
|
||||
app *kingpin.Application
|
||||
service *services.ServiceItem
|
||||
cmd *exec.Cmd
|
||||
cpuProfilingFile, memProfilingFile, blockProfilingFile,
|
||||
goroutineProfilingFile, threadcreateProfilingFile *os.File
|
||||
isDebug *bool
|
||||
)
|
||||
|
||||
func initConfig() (err error) {
|
||||
@ -58,7 +61,7 @@ func initConfig() (err error) {
|
||||
//build srvice args
|
||||
app = kingpin.New("proxy", "happy with proxy")
|
||||
app.Author("snail").Version(APP_VERSION)
|
||||
isDebug := app.Flag("debug", "debug log output").Default("false").Bool()
|
||||
isDebug = app.Flag("debug", "debug log output").Default("false").Bool()
|
||||
daemon := app.Flag("daemon", "run proxy in background").Default("false").Bool()
|
||||
forever := app.Flag("forever", "run proxy in forever,fail and retry").Default("false").Bool()
|
||||
logfile := app.Flag("log", "log file path").Default("").String()
|
||||
@ -114,13 +117,14 @@ func initConfig() (err error) {
|
||||
httpArgs.ParentKey = http.Flag("parent-key", "the password for auto encrypt/decrypt parent connection data").Short('Z').Default("").String()
|
||||
httpArgs.LocalCompress = http.Flag("local-compress", "auto compress/decompress data on local connection").Short('m').Default("false").Bool()
|
||||
httpArgs.ParentCompress = http.Flag("parent-compress", "auto compress/decompress data on parent connection").Short('M').Default("false").Bool()
|
||||
httpArgs.LoadBalanceMethod = http.Flag("lb-method", "load balance method when use multiple parent,can be <roundrobin|leastconn|leasttime|hash|weight>").Default("hash").Enum("roundrobin", "weight", "leastconn", "leasttime", "hash")
|
||||
httpArgs.LoadBalanceMethod = http.Flag("lb-method", "load balance method when use multiple parent,can be <roundrobin|leastconn|leasttime|hash|weight>").Default("roundrobin").Enum("roundrobin", "weight", "leastconn", "leasttime", "hash")
|
||||
httpArgs.LoadBalanceTimeout = http.Flag("lb-timeout", "tcp milliseconds timeout of connecting to parent").Default("500").Int()
|
||||
httpArgs.LoadBalanceRetryTime = http.Flag("lb-retrytime", "sleep time milliseconds after checking").Default("1000").Int()
|
||||
httpArgs.LoadBalanceHashTarget = http.Flag("lb-hashtarget", "use target address to choose parent for LB").Default("false").Bool()
|
||||
httpArgs.LoadBalanceOnlyHA = http.Flag("lb-onlyha", "use only `high availability mode` to choose parent for LB").Default("false").Bool()
|
||||
httpArgs.RateLimit = http.Flag("rate-limit", "rate limit (bytes/second) of each connection, such as: 100K 1.5M . 0 means no limitation").Short('l').Default("0").String()
|
||||
httpArgs.BindListen = http.Flag("bind-listen", "using listener binding IP when connect to target").Short('B').Default("false").Bool()
|
||||
httpArgs.Jumper = http.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()
|
||||
httpArgs.Debug = isDebug
|
||||
//########tcp#########
|
||||
tcp := app.Command("tcp", "proxy on tcp mode")
|
||||
@ -147,7 +151,7 @@ func initConfig() (err error) {
|
||||
//########mux-server#########
|
||||
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.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.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()
|
||||
@ -157,11 +161,15 @@ func initConfig() (err error) {
|
||||
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.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#########
|
||||
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.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.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()
|
||||
@ -169,6 +177,10 @@ func initConfig() (err error) {
|
||||
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.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#########
|
||||
muxBridge := app.Command("bridge", "proxy on mux bridge mode")
|
||||
@ -176,7 +188,11 @@ func initConfig() (err error) {
|
||||
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.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#########
|
||||
tunnelServer := app.Command("tserver", "proxy on tunnel server mode")
|
||||
@ -237,7 +253,7 @@ func initConfig() (err error) {
|
||||
socksArgs.ParentKey = socks.Flag("parent-key", "the password for auto encrypt/decrypt parent connection data").Short('Z').Default("").String()
|
||||
socksArgs.LocalCompress = socks.Flag("local-compress", "auto compress/decompress data on local connection").Short('m').Default("false").Bool()
|
||||
socksArgs.ParentCompress = socks.Flag("parent-compress", "auto compress/decompress data on parent connection").Short('M').Default("false").Bool()
|
||||
socksArgs.LoadBalanceMethod = socks.Flag("lb-method", "load balance method when use multiple parent,can be <roundrobin|leastconn|leasttime|hash|weight>").Default("hash").Enum("roundrobin", "weight", "leastconn", "leasttime", "hash")
|
||||
socksArgs.LoadBalanceMethod = socks.Flag("lb-method", "load balance method when use multiple parent,can be <roundrobin|leastconn|leasttime|hash|weight>").Default("roundrobin").Enum("roundrobin", "weight", "leastconn", "leasttime", "hash")
|
||||
socksArgs.LoadBalanceTimeout = socks.Flag("lb-timeout", "tcp milliseconds timeout of connecting to parent").Default("500").Int()
|
||||
socksArgs.LoadBalanceRetryTime = socks.Flag("lb-retrytime", "sleep time milliseconds after checking").Default("1000").Int()
|
||||
socksArgs.LoadBalanceHashTarget = socks.Flag("lb-hashtarget", "use target address to choose parent for LB").Default("false").Bool()
|
||||
@ -278,12 +294,13 @@ func initConfig() (err error) {
|
||||
spsArgs.DisableHTTP = sps.Flag("disable-http", "disable http(s) proxy").Default("false").Bool()
|
||||
spsArgs.DisableSocks5 = sps.Flag("disable-socks", "disable socks proxy").Default("false").Bool()
|
||||
spsArgs.DisableSS = sps.Flag("disable-ss", "disable ss proxy").Default("false").Bool()
|
||||
spsArgs.LoadBalanceMethod = sps.Flag("lb-method", "load balance method when use multiple parent,can be <roundrobin|leastconn|leasttime|hash|weight>").Default("hash").Enum("roundrobin", "weight", "leastconn", "leasttime", "hash")
|
||||
spsArgs.LoadBalanceMethod = sps.Flag("lb-method", "load balance method when use multiple parent,can be <roundrobin|leastconn|leasttime|hash|weight>").Default("roundrobin").Enum("roundrobin", "weight", "leastconn", "leasttime", "hash")
|
||||
spsArgs.LoadBalanceTimeout = sps.Flag("lb-timeout", "tcp milliseconds timeout of connecting to parent").Default("500").Int()
|
||||
spsArgs.LoadBalanceRetryTime = sps.Flag("lb-retrytime", "sleep time milliseconds after checking").Default("1000").Int()
|
||||
spsArgs.LoadBalanceHashTarget = sps.Flag("lb-hashtarget", "use target address to choose parent for LB").Default("false").Bool()
|
||||
spsArgs.LoadBalanceOnlyHA = sps.Flag("lb-onlyha", "use only `high availability mode` to choose parent for LB").Default("false").Bool()
|
||||
spsArgs.RateLimit = sps.Flag("rate-limit", "rate limit (bytes/second) of each connection, such as: 100K 1.5M . 0 means no limitation").Short('l').Default("0").String()
|
||||
spsArgs.Jumper = sps.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").Default("").String()
|
||||
spsArgs.Debug = isDebug
|
||||
|
||||
//########dns#########
|
||||
@ -418,7 +435,7 @@ func initConfig() (err error) {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
for {
|
||||
@ -442,7 +459,7 @@ func initConfig() (err error) {
|
||||
go func() {
|
||||
defer func() {
|
||||
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() {
|
||||
@ -452,7 +469,7 @@ func initConfig() (err error) {
|
||||
go func() {
|
||||
defer func() {
|
||||
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() {
|
||||
|
||||
@ -11,10 +11,10 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/snail007/goproxy/core/dst"
|
||||
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
||||
compressconn "github.com/snail007/goproxy/core/lib/transport"
|
||||
encryptconn "github.com/snail007/goproxy/core/lib/transport/encrypt"
|
||||
"github.com/snail007/goproxy/core/dst"
|
||||
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
|
||||
}
|
||||
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) {
|
||||
|
||||
var cert tls.Certificate
|
||||
|
||||
@ -11,10 +11,10 @@ import (
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
|
||||
tou "github.com/snail007/goproxy/core/dst"
|
||||
compressconn "github.com/snail007/goproxy/core/lib/transport"
|
||||
transportc "github.com/snail007/goproxy/core/lib/transport"
|
||||
encryptconn "github.com/snail007/goproxy/core/lib/transport/encrypt"
|
||||
tou "github.com/snail007/goproxy/core/dst"
|
||||
|
||||
"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.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 {
|
||||
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) {
|
||||
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 {
|
||||
s.Listener = &l
|
||||
go func() {
|
||||
@ -172,7 +172,7 @@ func (s *ServerChannel) ListenTCP(fn func(conn net.Conn)) (err error) {
|
||||
}
|
||||
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}
|
||||
l, err := net.ListenUDP("udp", addr)
|
||||
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()))
|
||||
}
|
||||
}()
|
||||
fn(packet, addr, srcAddr)
|
||||
fn(s.UDPListener, packet, addr, srcAddr)
|
||||
}()
|
||||
} else {
|
||||
s.errAcceptHandler(err)
|
||||
@ -207,7 +207,7 @@ func (s *ServerChannel) ListenUDP(fn func(packet []byte, localAddr, srcAddr *net
|
||||
return
|
||||
}
|
||||
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 = lis.SetDSCP(*config.DSCP); err != nil {
|
||||
log.Println("SetDSCP:", err)
|
||||
@ -230,7 +230,6 @@ func (s *ServerChannel) ListenKCP(config kcpcfg.KCPConfigArgs, fn func(conn net.
|
||||
}
|
||||
}()
|
||||
for {
|
||||
//var conn net.Conn
|
||||
conn, err := lis.AcceptKCP()
|
||||
if err == nil {
|
||||
go func() {
|
||||
|
||||
@ -137,7 +137,7 @@ func (c *Conn) start() {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
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
|
||||
// after a fixed time limit; see SetDeadline and SetReadDeadline.
|
||||
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()
|
||||
defer c.inbufMut.Unlock()
|
||||
for c.inbuf.Len() == 0 {
|
||||
@ -497,6 +503,9 @@ func (c *Conn) Write(b []byte) (n int, err error) {
|
||||
// Close closes the connection.
|
||||
// Any blocked Read or Write operations will be unblocked and return errors.
|
||||
func (c *Conn) Close() error {
|
||||
defer func() {
|
||||
_ = recover()
|
||||
}()
|
||||
c.closeOnce.Do(func() {
|
||||
if debugConnection {
|
||||
log.Println(c, "explicit close start")
|
||||
|
||||
@ -82,7 +82,7 @@ func NewMux(conn net.PacketConn, packetSize int) *Mux {
|
||||
go func() {
|
||||
defer func() {
|
||||
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()
|
||||
|
||||
@ -56,7 +56,7 @@ func newSendBuffer(m *Mux) *sendBuffer {
|
||||
go func() {
|
||||
defer func() {
|
||||
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()
|
||||
|
||||
@ -155,7 +155,7 @@ func (m ConcurrentMap) Iter() <-chan Tuple {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
fanIn(chans, ch)
|
||||
@ -174,7 +174,7 @@ func (m ConcurrentMap) IterBuffered() <-chan Tuple {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
fanIn(chans, ch)
|
||||
@ -195,7 +195,7 @@ func snapshot(m ConcurrentMap) (chans []chan Tuple) {
|
||||
go func(index int, shard *ConcurrentMapShared) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
// Foreach key, value pair.
|
||||
@ -221,7 +221,7 @@ func fanIn(chans []chan Tuple, out chan Tuple) {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
func(ch chan Tuple) {
|
||||
@ -274,7 +274,7 @@ func (m ConcurrentMap) Keys() []string {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
// Foreach shard.
|
||||
@ -284,7 +284,7 @@ func (m ConcurrentMap) Keys() []string {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
func(shard *ConcurrentMapShared) {
|
||||
|
||||
@ -39,8 +39,11 @@ func (c *CompStream) Write(p []byte) (n int, err error) {
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (c *CompStream) Close() error {
|
||||
return c.conn.Close()
|
||||
func (c *CompStream) Close() (err error) {
|
||||
err = c.conn.Close()
|
||||
c.r = nil
|
||||
c.w = nil
|
||||
return
|
||||
}
|
||||
func (c *CompStream) LocalAddr() net.Addr {
|
||||
return c.conn.LocalAddr()
|
||||
|
||||
@ -2,6 +2,7 @@ package encrypt
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
|
||||
@ -33,8 +34,23 @@ func NewConn(c net.Conn, method, password string) (conn net.Conn, err error) {
|
||||
return
|
||||
}
|
||||
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)
|
||||
}
|
||||
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)
|
||||
}
|
||||
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() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
buf := make([]byte, 1)
|
||||
@ -75,7 +75,7 @@ func (s *IOBinder) AliveWithServeConn(srcAddr string, inTCPConn *net.Conn) *IOBi
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
for {
|
||||
@ -96,7 +96,7 @@ func (s *IOBinder) AliveWithClientConn(srcAddr string, outTCPConn *net.Conn) *IO
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
buf := make([]byte, 1)
|
||||
@ -156,7 +156,7 @@ func (s *IOBinder) Run() (err error) {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
defer func() {
|
||||
|
||||
@ -10,7 +10,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
socks5c "github.com/snail007/goproxy/core/proxy/common/socks5"
|
||||
socks5c "github.com/snail007/goproxy/core/lib/socks5"
|
||||
)
|
||||
|
||||
type BasicAuther interface {
|
||||
|
||||
@ -81,7 +81,7 @@ func dtoi(s string, i0 int) (n int, i int, ok bool) {
|
||||
return n, i, true
|
||||
}
|
||||
|
||||
// IPTcpAddrToUnixSocksAddr ---
|
||||
// IPTcpAddrToUnixSocksAddr returns Sockaddr for specified TCP addr.
|
||||
func IPTcpAddrToUnixSocksAddr(addr string) (sa unix.Sockaddr, err error) {
|
||||
if Debug {
|
||||
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)
|
||||
}
|
||||
|
||||
// IPv6UdpAddrToUnixSocksAddr ---
|
||||
// IPv6UdpAddrToUnixSocksAddr returns Sockaddr for specified IPv6 addr.
|
||||
func IPv6UdpAddrToUnixSocksAddr(addr string) (sa unix.Sockaddr, err error) {
|
||||
tcpAddr, err := net.ResolveTCPAddr("udp6", addr)
|
||||
if err != nil {
|
||||
|
||||
@ -5,7 +5,10 @@ if [ -e /tmp/proxy ]; then
|
||||
fi
|
||||
mkdir /tmp/proxy
|
||||
cd /tmp/proxy
|
||||
wget https://github.com/snail007/goproxy/releases/download/v6.0/proxy-linux-amd64.tar.gz
|
||||
|
||||
LAST_VERSION=$(curl --silent "https://api.github.com/repos/snail007/goproxy/releases/latest" | grep -Po '"tag_name": "\K.*?(?=")')
|
||||
|
||||
wget "https://github.com/snail007/goproxy/releases/download/${LAST_VERSION}/proxy-linux-amd64.tar.gz"
|
||||
|
||||
# #install proxy
|
||||
tar zxvf proxy-linux-amd64.tar.gz
|
||||
|
||||
4
main.go
4
main.go
@ -36,7 +36,7 @@ func Clean(s *services.Service) {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
for _ = range signalChan {
|
||||
@ -48,7 +48,7 @@ func Clean(s *services.Service) {
|
||||
log.Printf("clean process %d", cmd.Process.Pid)
|
||||
cmd.Process.Kill()
|
||||
}
|
||||
if isDebug {
|
||||
if *isDebug {
|
||||
saveProfiling()
|
||||
}
|
||||
cleanupDone <- true
|
||||
|
||||
@ -82,6 +82,3 @@ CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build $OPTS -ldflags "$X" -o proxy.e
|
||||
|
||||
rm -rf proxy proxy.exe proxy-noconsole.exe .cert
|
||||
|
||||
#todo
|
||||
#1.install_auto.sh goproxy/releases/download/vxxx
|
||||
#2.README goproxy/releases/download/vxxx
|
||||
|
||||
@ -13,8 +13,8 @@ import (
|
||||
|
||||
"github.com/miekg/dns"
|
||||
gocache "github.com/pmylund/go-cache"
|
||||
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
||||
services "github.com/snail007/goproxy/services"
|
||||
"github.com/snail007/goproxy/services/kcpcfg"
|
||||
)
|
||||
|
||||
type DNSArgs struct {
|
||||
@ -57,10 +57,21 @@ func (s *DNS) CheckArgs() (err error) {
|
||||
func (s *DNS) InitService() (err error) {
|
||||
s.cache = gocache.New(time.Second*time.Duration(*s.cfg.DNSTTL), time.Second*60)
|
||||
s.cache.LoadFile(*s.cfg.CacheFile)
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-s.exitSig:
|
||||
return
|
||||
case <-time.After(time.Second * 300):
|
||||
s.cache.DeleteExpired()
|
||||
s.cache.SaveFile(*s.cfg.CacheFile)
|
||||
}
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
for {
|
||||
@ -142,7 +153,7 @@ func (s *DNS) Start(args interface{}, log *logger.Logger) (err error) {
|
||||
go func() {
|
||||
defer func() {
|
||||
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)
|
||||
|
||||
@ -10,9 +10,10 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
||||
encryptconn "github.com/snail007/goproxy/core/lib/transport/encrypt"
|
||||
"github.com/snail007/goproxy/services"
|
||||
httpx "github.com/snail007/goproxy/services/http"
|
||||
"github.com/snail007/goproxy/services/kcpcfg"
|
||||
keygenx "github.com/snail007/goproxy/services/keygen"
|
||||
mux "github.com/snail007/goproxy/services/mux"
|
||||
socksx "github.com/snail007/goproxy/services/socks"
|
||||
@ -133,13 +134,14 @@ func StartWithLog(serviceID, serviceArgsStr string, loggerCallback LogCallback)
|
||||
httpArgs.ParentKey = http.Flag("parent-key", "the password for auto encrypt/decrypt parent connection data").Short('Z').Default("").String()
|
||||
httpArgs.LocalCompress = http.Flag("local-compress", "auto compress/decompress data on local connection").Short('m').Default("false").Bool()
|
||||
httpArgs.ParentCompress = http.Flag("parent-compress", "auto compress/decompress data on parent connection").Short('M').Default("false").Bool()
|
||||
httpArgs.LoadBalanceMethod = http.Flag("lb-method", "load balance method when use multiple parent,can be <roundrobin|leastconn|leasttime|hash|weight>").Default("hash").Enum("roundrobin", "weight", "leastconn", "leasttime", "hash")
|
||||
httpArgs.LoadBalanceMethod = http.Flag("lb-method", "load balance method when use multiple parent,can be <roundrobin|leastconn|leasttime|hash|weight>").Default("roundrobin").Enum("roundrobin", "weight", "leastconn", "leasttime", "hash")
|
||||
httpArgs.LoadBalanceTimeout = http.Flag("lb-timeout", "tcp milliseconds timeout of connecting to parent").Default("500").Int()
|
||||
httpArgs.LoadBalanceRetryTime = http.Flag("lb-retrytime", "sleep time milliseconds after checking").Default("1000").Int()
|
||||
httpArgs.LoadBalanceHashTarget = http.Flag("lb-hashtarget", "use target address to choose parent for LB").Default("false").Bool()
|
||||
httpArgs.LoadBalanceOnlyHA = http.Flag("lb-onlyha", "use only `high availability mode` to choose parent for LB").Default("false").Bool()
|
||||
httpArgs.RateLimit = http.Flag("rate-limit", "rate limit (bytes/second) of each connection, such as: 100K 1.5M . 0 means no limitation").Short('l').Default("0").String()
|
||||
httpArgs.BindListen = http.Flag("bind-listen", "using listener binding IP when connect to target").Short('B').Default("false").Bool()
|
||||
httpArgs.Jumper = http.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()
|
||||
httpArgs.Debug = debug
|
||||
//########tcp#########
|
||||
tcp := app.Command("tcp", "proxy on tcp mode")
|
||||
@ -166,7 +168,7 @@ func StartWithLog(serviceID, serviceArgsStr string, loggerCallback LogCallback)
|
||||
//########mux-server#########
|
||||
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.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.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()
|
||||
@ -176,11 +178,15 @@ func StartWithLog(serviceID, serviceArgsStr string, loggerCallback LogCallback)
|
||||
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.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#########
|
||||
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.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.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()
|
||||
@ -188,6 +194,10 @@ func StartWithLog(serviceID, serviceArgsStr string, loggerCallback LogCallback)
|
||||
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.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#########
|
||||
muxBridge := app.Command("bridge", "proxy on mux bridge mode")
|
||||
@ -195,7 +205,11 @@ func StartWithLog(serviceID, serviceArgsStr string, loggerCallback LogCallback)
|
||||
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.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#########
|
||||
tunnelServer := app.Command("tserver", "proxy on tunnel server mode")
|
||||
@ -256,7 +270,7 @@ func StartWithLog(serviceID, serviceArgsStr string, loggerCallback LogCallback)
|
||||
socksArgs.ParentKey = socks.Flag("parent-key", "the password for auto encrypt/decrypt parent connection data").Short('Z').Default("").String()
|
||||
socksArgs.LocalCompress = socks.Flag("local-compress", "auto compress/decompress data on local connection").Short('m').Default("false").Bool()
|
||||
socksArgs.ParentCompress = socks.Flag("parent-compress", "auto compress/decompress data on parent connection").Short('M').Default("false").Bool()
|
||||
socksArgs.LoadBalanceMethod = socks.Flag("lb-method", "load balance method when use multiple parent,can be <roundrobin|leastconn|leasttime|hash|weight>").Default("hash").Enum("roundrobin", "weight", "leastconn", "leasttime", "hash")
|
||||
socksArgs.LoadBalanceMethod = socks.Flag("lb-method", "load balance method when use multiple parent,can be <roundrobin|leastconn|leasttime|hash|weight>").Default("roundrobin").Enum("roundrobin", "weight", "leastconn", "leasttime", "hash")
|
||||
socksArgs.LoadBalanceTimeout = socks.Flag("lb-timeout", "tcp milliseconds timeout of connecting to parent").Default("500").Int()
|
||||
socksArgs.LoadBalanceRetryTime = socks.Flag("lb-retrytime", "sleep time milliseconds after checking").Default("1000").Int()
|
||||
socksArgs.LoadBalanceHashTarget = socks.Flag("lb-hashtarget", "use target address to choose parent for LB").Default("false").Bool()
|
||||
@ -303,6 +317,7 @@ func StartWithLog(serviceID, serviceArgsStr string, loggerCallback LogCallback)
|
||||
spsArgs.LoadBalanceHashTarget = sps.Flag("lb-hashtarget", "use target address to choose parent for LB").Default("false").Bool()
|
||||
spsArgs.LoadBalanceOnlyHA = sps.Flag("lb-onlyha", "use only `high availability mode` to choose parent for LB").Default("false").Bool()
|
||||
spsArgs.RateLimit = sps.Flag("rate-limit", "rate limit (bytes/second) of each connection, such as: 100K 1.5M . 0 means no limitation").Short('l').Default("0").String()
|
||||
spsArgs.Jumper = sps.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").Default("").String()
|
||||
spsArgs.Debug = debug
|
||||
|
||||
//########dns#########
|
||||
|
||||
@ -12,11 +12,13 @@ import (
|
||||
"strings"
|
||||
"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/kcpcfg"
|
||||
"github.com/snail007/goproxy/utils/datasize"
|
||||
"github.com/snail007/goproxy/utils/dnsx"
|
||||
"github.com/snail007/goproxy/utils/iolimiter"
|
||||
"github.com/snail007/goproxy/utils/jumper"
|
||||
"github.com/snail007/goproxy/utils/lb"
|
||||
"github.com/snail007/goproxy/utils/mapx"
|
||||
|
||||
@ -74,6 +76,7 @@ type HTTPArgs struct {
|
||||
RateLimitBytes float64
|
||||
BindListen *bool
|
||||
Debug *bool
|
||||
Jumper *string
|
||||
}
|
||||
type HTTP struct {
|
||||
cfg HTTPArgs
|
||||
@ -83,10 +86,11 @@ type HTTP struct {
|
||||
lockChn chan bool
|
||||
domainResolver dnsx.DomainResolver
|
||||
isStop bool
|
||||
serverChannels []*utils.ServerChannel
|
||||
serverChannels []*server.ServerChannel
|
||||
userConns mapx.ConcurrentMap
|
||||
log *logger.Logger
|
||||
lb *lb.Group
|
||||
jumper *jumper.Jumper
|
||||
}
|
||||
|
||||
func NewHTTP() services.Service {
|
||||
@ -96,7 +100,7 @@ func NewHTTP() services.Service {
|
||||
basicAuth: utils.BasicAuth{},
|
||||
lockChn: make(chan bool, 1),
|
||||
isStop: false,
|
||||
serverChannels: []*utils.ServerChannel{},
|
||||
serverChannels: []*server.ServerChannel{},
|
||||
userConns: mapx.NewConcurrentMap(),
|
||||
}
|
||||
}
|
||||
@ -162,6 +166,19 @@ func (s *HTTP) CheckArgs() (err error) {
|
||||
}
|
||||
s.cfg.RateLimitBytes = float64(size)
|
||||
}
|
||||
if *s.cfg.Jumper != "" {
|
||||
if *s.cfg.ParentType != "tls" && *s.cfg.ParentType != "tcp" {
|
||||
err = fmt.Errorf("jumper only worked of -T is tls or tcp")
|
||||
return
|
||||
}
|
||||
var j jumper.Jumper
|
||||
j, err = jumper.New(*s.cfg.Jumper, time.Millisecond*time.Duration(*s.cfg.Timeout))
|
||||
if err != nil {
|
||||
err = fmt.Errorf("parse jumper fail, err %s", err)
|
||||
return
|
||||
}
|
||||
s.jumper = &j
|
||||
}
|
||||
return
|
||||
}
|
||||
func (s *HTTP) InitService() (err error) {
|
||||
@ -172,7 +189,7 @@ func (s *HTTP) InitService() (err error) {
|
||||
s.InitLB()
|
||||
}
|
||||
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" {
|
||||
err = s.ConnectSSH()
|
||||
@ -183,7 +200,7 @@ func (s *HTTP) InitService() (err error) {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
//循环检查ssh网络连通性
|
||||
@ -230,6 +247,7 @@ func (s *HTTP) StopService() {
|
||||
s.lb = nil
|
||||
s.lockChn = nil
|
||||
s.log = nil
|
||||
s.jumper = nil
|
||||
s.serverChannels = nil
|
||||
s.sshClient = nil
|
||||
s.userConns = nil
|
||||
@ -273,11 +291,11 @@ func (s *HTTP) Start(args interface{}, log *logger.Logger) (err error) {
|
||||
if addr != "" {
|
||||
host, port, _ := net.SplitHostPort(addr)
|
||||
p, _ := strconv.Atoi(port)
|
||||
sc := utils.NewServerChannel(host, p, s.log)
|
||||
sc := server.NewServerChannel(host, p, s.log)
|
||||
if *s.cfg.LocalType == "tcp" {
|
||||
err = sc.ListenTCP(s.callback)
|
||||
} 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" {
|
||||
err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log)
|
||||
}
|
||||
@ -601,11 +619,24 @@ func (s *HTTP) Resolve(address string) string {
|
||||
}
|
||||
func (s *HTTP) GetParentConn(address string) (conn net.Conn, err error) {
|
||||
if *s.cfg.ParentType == "tls" {
|
||||
var _conn tls.Conn
|
||||
_conn, err = utils.TlsConnectHost(address, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes)
|
||||
if err == nil {
|
||||
conn = net.Conn(&_conn)
|
||||
if s.jumper == nil {
|
||||
var _conn tls.Conn
|
||||
_conn, err = utils.TlsConnectHost(address, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes)
|
||||
if err == nil {
|
||||
conn = net.Conn(&_conn)
|
||||
}
|
||||
} else {
|
||||
conf, err := utils.TlsConfig(s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var _c net.Conn
|
||||
_c, err = s.jumper.Dial(address, time.Millisecond*time.Duration(*s.cfg.Timeout))
|
||||
if err == nil {
|
||||
conn = net.Conn(tls.Client(_c, conf))
|
||||
}
|
||||
}
|
||||
|
||||
} else if *s.cfg.ParentType == "kcp" {
|
||||
conn, err = utils.ConnectKCPHost(address, s.cfg.KCP)
|
||||
} else if *s.cfg.ParentType == "ssh" {
|
||||
@ -615,7 +646,11 @@ func (s *HTTP) GetParentConn(address string) (conn net.Conn, err error) {
|
||||
err = fmt.Errorf("%s", e)
|
||||
}
|
||||
} else {
|
||||
conn, err = utils.ConnectHost(address, *s.cfg.Timeout)
|
||||
if s.jumper == nil {
|
||||
conn, err = utils.ConnectHost(address, *s.cfg.Timeout)
|
||||
} else {
|
||||
conn, err = s.jumper.Dial(address, time.Millisecond*time.Duration(*s.cfg.Timeout))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -8,30 +8,33 @@ import (
|
||||
"math/rand"
|
||||
"net"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"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/kcpcfg"
|
||||
"github.com/snail007/goproxy/utils"
|
||||
"github.com/snail007/goproxy/utils/mapx"
|
||||
|
||||
//"github.com/xtaci/smux"
|
||||
smux "github.com/hashicorp/yamux"
|
||||
)
|
||||
|
||||
type MuxBridgeArgs struct {
|
||||
CertFile *string
|
||||
KeyFile *string
|
||||
CertBytes []byte
|
||||
KeyBytes []byte
|
||||
Local *string
|
||||
LocalType *string
|
||||
Timeout *int
|
||||
IsCompress *bool
|
||||
KCP kcpcfg.KCPConfigArgs
|
||||
CertFile *string
|
||||
KeyFile *string
|
||||
CertBytes []byte
|
||||
KeyBytes []byte
|
||||
Local *string
|
||||
LocalType *string
|
||||
Timeout *int
|
||||
IsCompress *bool
|
||||
KCP kcpcfg.KCPConfigArgs
|
||||
TCPSMethod *string
|
||||
TCPSPassword *string
|
||||
TOUMethod *string
|
||||
TOUPassword *string
|
||||
}
|
||||
type MuxBridge struct {
|
||||
cfg MuxBridgeArgs
|
||||
@ -40,7 +43,7 @@ type MuxBridge struct {
|
||||
router utils.ClientKeyRouter
|
||||
l *sync.Mutex
|
||||
isStop bool
|
||||
sc *utils.ServerChannel
|
||||
sc *srvtransport.ServerChannel
|
||||
log *logger.Logger
|
||||
}
|
||||
|
||||
@ -112,21 +115,27 @@ func (s *MuxBridge) Start(args interface{}, log *logger.Logger) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
host, port, _ := net.SplitHostPort(*s.cfg.Local)
|
||||
p, _ := strconv.Atoi(port)
|
||||
sc := utils.NewServerChannel(host, p, s.log)
|
||||
sc := srvtransport.NewServerChannelHost(*s.cfg.Local, s.log)
|
||||
if *s.cfg.LocalType == "tcp" {
|
||||
err = sc.ListenTCP(s.handler)
|
||||
} 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" {
|
||||
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 {
|
||||
return
|
||||
}
|
||||
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
|
||||
}
|
||||
func (s *MuxBridge) Clean() {
|
||||
@ -206,21 +215,25 @@ func (s *MuxBridge) handler(inConn net.Conn) {
|
||||
index := keyInfo[1]
|
||||
s.l.Lock()
|
||||
defer s.l.Unlock()
|
||||
var group *mapx.ConcurrentMap
|
||||
if !s.clientControlConns.Has(groupKey) {
|
||||
item := mapx.NewConcurrentMap()
|
||||
s.clientControlConns.Set(groupKey, &item)
|
||||
_g := mapx.NewConcurrentMap()
|
||||
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 {
|
||||
v.(*smux.Session).Close()
|
||||
}
|
||||
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() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
for {
|
||||
@ -232,10 +245,12 @@ func (s *MuxBridge) handler(inConn net.Conn) {
|
||||
defer s.l.Unlock()
|
||||
if sess, ok := group.Get(index); ok && sess.(*smux.Session).IsClosed() {
|
||||
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)
|
||||
}
|
||||
if group.IsEmpty() {
|
||||
s.clientControlConns.Remove(groupKey)
|
||||
//s.log.Printf("client session group %s removed", groupKey)
|
||||
}
|
||||
break
|
||||
}
|
||||
@ -259,6 +274,7 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) {
|
||||
if key == "*" {
|
||||
key = s.router.GetKey()
|
||||
}
|
||||
//s.log.Printf("server get client session %s", key)
|
||||
_group, ok := s.clientControlConns.Get(key)
|
||||
if !ok {
|
||||
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
|
||||
}
|
||||
group := _group.(*mapx.ConcurrentMap)
|
||||
keys := group.Keys()
|
||||
keys := []string{}
|
||||
group.IterCb(func(key string, v interface{}) {
|
||||
keys = append(keys, key)
|
||||
})
|
||||
keysLen := len(keys)
|
||||
//s.log.Printf("client session %s , len:%d , keysLen: %d", key, group.Count(), keysLen)
|
||||
i := 0
|
||||
if keysLen > 0 {
|
||||
i = rand.Intn(keysLen)
|
||||
@ -293,7 +313,7 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) {
|
||||
go func() {
|
||||
defer func() {
|
||||
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)
|
||||
@ -302,7 +322,7 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) {
|
||||
go func() {
|
||||
defer func() {
|
||||
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)
|
||||
|
||||
@ -8,15 +8,17 @@ import (
|
||||
"net"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"sync"
|
||||
"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/kcpcfg"
|
||||
"github.com/snail007/goproxy/utils"
|
||||
"github.com/snail007/goproxy/utils/jumper"
|
||||
"github.com/snail007/goproxy/utils/mapx"
|
||||
|
||||
"github.com/golang/snappy"
|
||||
//"github.com/xtaci/smux"
|
||||
smux "github.com/hashicorp/yamux"
|
||||
)
|
||||
@ -34,6 +36,10 @@ type MuxClientArgs struct {
|
||||
SessionCount *int
|
||||
KCP kcpcfg.KCPConfigArgs
|
||||
Jumper *string
|
||||
TCPSMethod *string
|
||||
TCPSPassword *string
|
||||
TOUMethod *string
|
||||
TOUPassword *string
|
||||
}
|
||||
type ClientUDPConnItem struct {
|
||||
conn *smux.Stream
|
||||
@ -140,7 +146,7 @@ func (s *MuxClient) Start(args interface{}, log *logger.Logger) (err error) {
|
||||
defer func() {
|
||||
e := recover()
|
||||
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 {
|
||||
@ -154,7 +160,16 @@ func (s *MuxClient) Start(args interface{}, log *logger.Logger) (err error) {
|
||||
continue
|
||||
}
|
||||
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{})
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
@ -222,14 +237,14 @@ func (s *MuxClient) getParentConn() (conn net.Conn, err error) {
|
||||
if *s.cfg.ParentType == "tls" {
|
||||
if s.jumper == nil {
|
||||
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 {
|
||||
conn = net.Conn(&_conn)
|
||||
}
|
||||
} else {
|
||||
conf, err := utils.TlsConfig(s.cfg.CertBytes, s.cfg.KeyBytes, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
conf, e := utils.TlsConfig(s.cfg.CertBytes, s.cfg.KeyBytes, nil)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
var _c net.Conn
|
||||
_c, err = s.jumper.Dial(*s.cfg.Parent, time.Millisecond*time.Duration(*s.cfg.Timeout))
|
||||
@ -239,10 +254,22 @@ func (s *MuxClient) getParentConn() (conn net.Conn, err error) {
|
||||
}
|
||||
|
||||
} 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 {
|
||||
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 {
|
||||
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).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) {
|
||||
go func() {
|
||||
defer func() {
|
||||
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)
|
||||
@ -336,7 +366,7 @@ func (s *MuxClient) UDPRevecive(key, ID string) {
|
||||
go func() {
|
||||
defer func() {
|
||||
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)))
|
||||
@ -355,7 +385,7 @@ func (s *MuxClient) UDPGCDeamon() {
|
||||
go func() {
|
||||
defer func() {
|
||||
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 {
|
||||
@ -414,7 +444,7 @@ func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) {
|
||||
go func() {
|
||||
defer func() {
|
||||
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))
|
||||
@ -423,7 +453,7 @@ func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) {
|
||||
go func() {
|
||||
defer func() {
|
||||
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)
|
||||
|
||||
@ -12,8 +12,11 @@ import (
|
||||
"strings"
|
||||
"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/kcpcfg"
|
||||
"github.com/snail007/goproxy/utils"
|
||||
"github.com/snail007/goproxy/utils/jumper"
|
||||
"github.com/snail007/goproxy/utils/mapx"
|
||||
@ -47,10 +50,14 @@ type MuxServerArgs struct {
|
||||
SessionCount *int
|
||||
KCP kcpcfg.KCPConfigArgs
|
||||
Jumper *string
|
||||
TCPSMethod *string
|
||||
TCPSPassword *string
|
||||
TOUMethod *string
|
||||
TOUPassword *string
|
||||
}
|
||||
type MuxServer struct {
|
||||
cfg MuxServerArgs
|
||||
sc utils.ServerChannel
|
||||
sc server.ServerChannel
|
||||
sessions mapx.ConcurrentMap
|
||||
lockChn chan bool
|
||||
isStop bool
|
||||
@ -133,6 +140,10 @@ func (s *MuxServerManager) Start(args interface{}, log *logger.Logger) (err erro
|
||||
KCP: s.cfg.KCP,
|
||||
ParentType: s.cfg.ParentType,
|
||||
Jumper: s.cfg.Jumper,
|
||||
TCPSMethod: s.cfg.TCPSMethod,
|
||||
TCPSPassword: s.cfg.TCPSPassword,
|
||||
TOUMethod: s.cfg.TOUMethod,
|
||||
TOUPassword: s.cfg.TOUPassword,
|
||||
}, log)
|
||||
|
||||
if err != nil {
|
||||
@ -202,7 +213,7 @@ func (s *MuxServer) StopService() {
|
||||
s.jumper = nil
|
||||
s.lockChn = nil
|
||||
s.log = nil
|
||||
s.sc = utils.ServerChannel{}
|
||||
s.sc = server.ServerChannel{}
|
||||
s.sessions = nil
|
||||
s.udpConns = 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)
|
||||
p, _ := strconv.Atoi(port)
|
||||
s.sc = utils.NewServerChannel(host, p, s.log)
|
||||
s.sc = server.NewServerChannel(host, p, s.log)
|
||||
if *s.cfg.IsUDP {
|
||||
err = s.sc.ListenUDP(func(listener *net.UDPConn, packet []byte, localAddr, srcAddr *net.UDPAddr) {
|
||||
s.UDPSend(packet, localAddr, srcAddr)
|
||||
@ -293,7 +304,7 @@ func (s *MuxServer) Start(args interface{}, log *logger.Logger) (err error) {
|
||||
go func() {
|
||||
defer func() {
|
||||
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))
|
||||
@ -302,7 +313,7 @@ func (s *MuxServer) Start(args interface{}, log *logger.Logger) (err error) {
|
||||
go func() {
|
||||
defer func() {
|
||||
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)
|
||||
@ -397,7 +408,7 @@ func (s *MuxServer) GetConn(index string) (conn net.Conn, err error) {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
for {
|
||||
@ -443,6 +454,18 @@ func (s *MuxServer) getParentConn() (conn net.Conn, err error) {
|
||||
|
||||
} else if *s.cfg.ParentType == "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 {
|
||||
if s.jumper == nil {
|
||||
conn, err = utils.ConnectHost(*s.cfg.Parent, *s.cfg.Timeout)
|
||||
@ -457,7 +480,7 @@ func (s *MuxServer) UDPGCDeamon() {
|
||||
go func() {
|
||||
defer func() {
|
||||
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 {
|
||||
@ -536,7 +559,7 @@ func (s *MuxServer) UDPRevecive(key, ID string) {
|
||||
go func() {
|
||||
defer func() {
|
||||
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)
|
||||
@ -569,7 +592,7 @@ func (s *MuxServer) UDPRevecive(key, ID string) {
|
||||
go func() {
|
||||
defer func() {
|
||||
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)
|
||||
|
||||
@ -12,8 +12,9 @@ import (
|
||||
"strings"
|
||||
"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/kcpcfg"
|
||||
"github.com/snail007/goproxy/utils"
|
||||
"github.com/snail007/goproxy/utils/conncrypt"
|
||||
"github.com/snail007/goproxy/utils/datasize"
|
||||
@ -80,8 +81,8 @@ type Socks struct {
|
||||
basicAuth utils.BasicAuth
|
||||
sshClient *ssh.Client
|
||||
lockChn chan bool
|
||||
udpSC utils.ServerChannel
|
||||
sc *utils.ServerChannel
|
||||
udpSC server.ServerChannel
|
||||
sc *server.ServerChannel
|
||||
domainResolver dnsx.DomainResolver
|
||||
isStop bool
|
||||
userConns mapx.ConcurrentMap
|
||||
@ -191,7 +192,7 @@ func (s *Socks) InitService() (err error) {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
//循环检查ssh网络连通性
|
||||
@ -243,7 +244,7 @@ func (s *Socks) StopService() {
|
||||
s.udpLocalKey = nil
|
||||
s.udpParentKey = nil
|
||||
s.udpRelatedPacketConns = nil
|
||||
s.udpSC = utils.ServerChannel{}
|
||||
s.udpSC = server.ServerChannel{}
|
||||
s.userConns = nil
|
||||
s = nil
|
||||
}()
|
||||
@ -283,11 +284,11 @@ func (s *Socks) Start(args interface{}, log *logger.Logger) (err error) {
|
||||
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))
|
||||
}
|
||||
sc := utils.NewServerChannelHost(*s.cfg.Local, s.log)
|
||||
sc := server.NewServerChannelHost(*s.cfg.Local, s.log)
|
||||
if *s.cfg.LocalType == "tcp" {
|
||||
err = sc.ListenTCP(s.socksConnCallback)
|
||||
} 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" {
|
||||
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{}) {
|
||||
switch *s.cfg.ParentType {
|
||||
case "kcp":
|
||||
fallthrough
|
||||
case "tls":
|
||||
fallthrough
|
||||
case "tcp":
|
||||
case "kcp", "tls", "tcp":
|
||||
if *s.cfg.ParentType == "tls" {
|
||||
var _conn tls.Conn
|
||||
_conn, err = utils.TlsConnectHost(parentAddress, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes)
|
||||
|
||||
@ -174,9 +174,9 @@ func (s *Socks) proxyUDP(inConn *net.Conn, serverConn *socks.ServerConn) {
|
||||
}
|
||||
s.log.Printf("use proxy %v : udp %s", useProxy, serverConn.Target())
|
||||
//relay
|
||||
buf := utils.LeakyBuffer.Get()
|
||||
defer utils.LeakyBuffer.Put(buf)
|
||||
for {
|
||||
buf := utils.LeakyBuffer.Get()
|
||||
defer utils.LeakyBuffer.Put(buf)
|
||||
n, srcAddr, err := udpListener.ReadFromUDP(buf)
|
||||
if err != nil {
|
||||
s.log.Printf("udp listener read fail, %s", err.Error())
|
||||
|
||||
@ -126,9 +126,9 @@ func (s *SPS) proxyUDP(inConn *net.Conn, serverConn *socks.ServerConn) {
|
||||
//s.log.Printf("parent udp address %s", client.UDPAddr)
|
||||
destAddr, _ = net.ResolveUDPAddr("udp", client.UDPAddr)
|
||||
//relay
|
||||
buf := utils.LeakyBuffer.Get()
|
||||
defer utils.LeakyBuffer.Put(buf)
|
||||
for {
|
||||
buf := utils.LeakyBuffer.Get()
|
||||
defer utils.LeakyBuffer.Put(buf)
|
||||
n, srcAddr, err := udpListener.ReadFromUDP(buf)
|
||||
if err != nil {
|
||||
s.log.Printf("udp listener read fail, %s", err.Error())
|
||||
|
||||
@ -15,13 +15,15 @@ import (
|
||||
"strings"
|
||||
"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/kcpcfg"
|
||||
"github.com/snail007/goproxy/utils"
|
||||
"github.com/snail007/goproxy/utils/conncrypt"
|
||||
"github.com/snail007/goproxy/utils/datasize"
|
||||
"github.com/snail007/goproxy/utils/dnsx"
|
||||
"github.com/snail007/goproxy/utils/iolimiter"
|
||||
"github.com/snail007/goproxy/utils/jumper"
|
||||
"github.com/snail007/goproxy/utils/lb"
|
||||
"github.com/snail007/goproxy/utils/mapx"
|
||||
"github.com/snail007/goproxy/utils/sni"
|
||||
@ -73,12 +75,13 @@ type SPSArgs struct {
|
||||
RateLimit *string
|
||||
RateLimitBytes float64
|
||||
Debug *bool
|
||||
Jumper *string
|
||||
}
|
||||
type SPS struct {
|
||||
cfg SPSArgs
|
||||
domainResolver dnsx.DomainResolver
|
||||
basicAuth utils.BasicAuth
|
||||
serverChannels []*utils.ServerChannel
|
||||
serverChannels []*server.ServerChannel
|
||||
userConns mapx.ConcurrentMap
|
||||
log *logger.Logger
|
||||
localCipher *ss.Cipher
|
||||
@ -87,13 +90,14 @@ type SPS struct {
|
||||
lb *lb.Group
|
||||
udpLocalKey []byte
|
||||
udpParentKey []byte
|
||||
jumper *jumper.Jumper
|
||||
}
|
||||
|
||||
func NewSPS() services.Service {
|
||||
return &SPS{
|
||||
cfg: SPSArgs{},
|
||||
basicAuth: utils.BasicAuth{},
|
||||
serverChannels: []*utils.ServerChannel{},
|
||||
serverChannels: []*server.ServerChannel{},
|
||||
userConns: mapx.NewConcurrentMap(),
|
||||
udpRelatedPacketConns: mapx.NewConcurrentMap(),
|
||||
}
|
||||
@ -140,12 +144,25 @@ func (s *SPS) CheckArgs() (err error) {
|
||||
}
|
||||
s.udpLocalKey = s.LocalUDPKey()
|
||||
s.udpParentKey = s.ParentUDPKey()
|
||||
if *s.cfg.Jumper != "" {
|
||||
if *s.cfg.ParentType != "tls" && *s.cfg.ParentType != "tcp" {
|
||||
err = fmt.Errorf("jumper only worked of -T is tls or tcp")
|
||||
return
|
||||
}
|
||||
var j jumper.Jumper
|
||||
j, err = jumper.New(*s.cfg.Jumper, time.Millisecond*time.Duration(*s.cfg.Timeout))
|
||||
if err != nil {
|
||||
err = fmt.Errorf("parse jumper fail, err %s", err)
|
||||
return
|
||||
}
|
||||
s.jumper = &j
|
||||
}
|
||||
return
|
||||
}
|
||||
func (s *SPS) InitService() (err error) {
|
||||
|
||||
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 {
|
||||
@ -183,6 +200,7 @@ func (s *SPS) StopService() {
|
||||
s.domainResolver = dnsx.DomainResolver{}
|
||||
s.lb = nil
|
||||
s.localCipher = nil
|
||||
s.jumper = nil
|
||||
s.log = nil
|
||||
s.parentCipher = nil
|
||||
s.serverChannels = nil
|
||||
@ -230,12 +248,12 @@ func (s *SPS) Start(args interface{}, log *logger.Logger) (err error) {
|
||||
if addr != "" {
|
||||
host, port, _ := net.SplitHostPort(addr)
|
||||
p, _ := strconv.Atoi(port)
|
||||
sc := utils.NewServerChannel(host, p, s.log)
|
||||
sc := server.NewServerChannel(host, p, s.log)
|
||||
s.serverChannels = append(s.serverChannels, &sc)
|
||||
if *s.cfg.LocalType == "tcp" {
|
||||
err = sc.ListenTCP(s.callback)
|
||||
} 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" {
|
||||
err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log)
|
||||
}
|
||||
@ -273,11 +291,7 @@ func (s *SPS) callback(inConn net.Conn) {
|
||||
var err error
|
||||
lbAddr := ""
|
||||
switch *s.cfg.ParentType {
|
||||
case "kcp":
|
||||
fallthrough
|
||||
case "tcp":
|
||||
fallthrough
|
||||
case "tls":
|
||||
case "kcp", "tcp", "tls":
|
||||
lbAddr, err = s.OutToTCP(&inConn)
|
||||
default:
|
||||
err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType)
|
||||
@ -363,7 +377,6 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (lbAddr string, err error) {
|
||||
request.HTTPSReply()
|
||||
//s.log.Printf("https reply: %s", request.Host)
|
||||
} else {
|
||||
//forwardBytes = bytes.TrimRight(request.HeadBuf,"\r\n")
|
||||
forwardBytes = request.HeadBuf
|
||||
}
|
||||
address = request.Host
|
||||
@ -412,7 +425,6 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (lbAddr string, err error) {
|
||||
selectAddr = address
|
||||
}
|
||||
lbAddr = s.lb.Select(selectAddr, *s.cfg.LoadBalanceOnlyHA)
|
||||
//lbAddr = s.lb.Select((*inConn).RemoteAddr().String())
|
||||
outConn, err = s.GetParentConn(lbAddr)
|
||||
if err != nil {
|
||||
s.log.Printf("connect to %s , err:%s", lbAddr, err)
|
||||
@ -640,15 +652,32 @@ func (s *SPS) Resolve(address string) string {
|
||||
}
|
||||
func (s *SPS) GetParentConn(address string) (conn net.Conn, err error) {
|
||||
if *s.cfg.ParentType == "tls" {
|
||||
var _conn tls.Conn
|
||||
_conn, err = utils.TlsConnectHost(address, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes)
|
||||
if err == nil {
|
||||
conn = net.Conn(&_conn)
|
||||
if s.jumper == nil {
|
||||
var _conn tls.Conn
|
||||
_conn, err = utils.TlsConnectHost(address, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes)
|
||||
if err == nil {
|
||||
conn = net.Conn(&_conn)
|
||||
}
|
||||
} else {
|
||||
conf, err := utils.TlsConfig(s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var _c net.Conn
|
||||
_c, err = s.jumper.Dial(address, time.Millisecond*time.Duration(*s.cfg.Timeout))
|
||||
if err == nil {
|
||||
conn = net.Conn(tls.Client(_c, conf))
|
||||
}
|
||||
}
|
||||
|
||||
} else if *s.cfg.ParentType == "kcp" {
|
||||
conn, err = utils.ConnectKCPHost(address, s.cfg.KCP)
|
||||
} else {
|
||||
conn, err = utils.ConnectHost(address, *s.cfg.Timeout)
|
||||
if s.jumper == nil {
|
||||
conn, err = utils.ConnectHost(address, *s.cfg.Timeout)
|
||||
} else {
|
||||
conn, err = s.jumper.Dial(address, time.Millisecond*time.Duration(*s.cfg.Timeout))
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
if *s.cfg.ParentCompress {
|
||||
|
||||
@ -27,9 +27,9 @@ func (s *SPS) RunSSUDP(addr string) (err error) {
|
||||
s.log.Printf("udp local->out io copy crashed:\n%s\n%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
buf := utils.LeakyBuffer.Get()
|
||||
defer utils.LeakyBuffer.Put(buf)
|
||||
for {
|
||||
buf := utils.LeakyBuffer.Get()
|
||||
defer utils.LeakyBuffer.Put(buf)
|
||||
n, srcAddr, err := listener.ReadFrom(buf)
|
||||
if err != nil {
|
||||
s.log.Printf("read from client error %s", err)
|
||||
|
||||
@ -9,8 +9,9 @@ import (
|
||||
"strings"
|
||||
"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/kcpcfg"
|
||||
"github.com/snail007/goproxy/utils"
|
||||
"github.com/snail007/goproxy/utils/jumper"
|
||||
"github.com/snail007/goproxy/utils/mapx"
|
||||
@ -43,7 +44,7 @@ type UDPConnItem struct {
|
||||
}
|
||||
type TCP struct {
|
||||
cfg TCPArgs
|
||||
sc *utils.ServerChannel
|
||||
sc *server.ServerChannel
|
||||
isStop bool
|
||||
userConns mapx.ConcurrentMap
|
||||
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)
|
||||
host, port, _ := net.SplitHostPort(*s.cfg.Local)
|
||||
p, _ := strconv.Atoi(port)
|
||||
sc := utils.NewServerChannel(host, p, s.log)
|
||||
sc := server.NewServerChannel(host, p, s.log)
|
||||
|
||||
if *s.cfg.LocalType == "tcp" {
|
||||
err = sc.ListenTCP(s.callback)
|
||||
} 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" {
|
||||
err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log)
|
||||
}
|
||||
@ -160,11 +161,7 @@ func (s *TCP) callback(inConn net.Conn) {
|
||||
var err error
|
||||
lbAddr := ""
|
||||
switch *s.cfg.ParentType {
|
||||
case "kcp":
|
||||
fallthrough
|
||||
case "tcp":
|
||||
fallthrough
|
||||
case "tls":
|
||||
case "kcp", "tcp", "tls":
|
||||
err = s.OutToTCP(&inConn)
|
||||
case "udp":
|
||||
s.OutToUDP(&inConn)
|
||||
@ -208,8 +205,8 @@ func (s *TCP) OutToUDP(inConn *net.Conn) (err error) {
|
||||
srcAddr := ""
|
||||
defer func() {
|
||||
if item != nil {
|
||||
(*(*item).conn).Close()
|
||||
(*item).udpConn.Close()
|
||||
(*item.conn).Close()
|
||||
item.udpConn.Close()
|
||||
s.udpConns.Remove(srcAddr)
|
||||
(*inConn).Close()
|
||||
}
|
||||
@ -252,15 +249,15 @@ func (s *TCP) OutToUDP(inConn *net.Conn) (err error) {
|
||||
} else {
|
||||
item = v.(*UDPConnItem)
|
||||
}
|
||||
(*item).touchtime = time.Now().Unix()
|
||||
go (*item).udpConn.Write(body)
|
||||
item.touchtime = time.Now().Unix()
|
||||
go item.udpConn.Write(body)
|
||||
}
|
||||
}
|
||||
func (s *TCP) UDPRevecive(key string) {
|
||||
go func() {
|
||||
defer func() {
|
||||
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)
|
||||
@ -290,7 +287,7 @@ func (s *TCP) UDPRevecive(key string) {
|
||||
go func() {
|
||||
defer func() {
|
||||
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)))
|
||||
@ -309,7 +306,7 @@ func (s *TCP) UDPGCDeamon() {
|
||||
go func() {
|
||||
defer func() {
|
||||
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 {
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/snail007/goproxy/core/cs/server"
|
||||
"github.com/snail007/goproxy/services"
|
||||
"github.com/snail007/goproxy/utils"
|
||||
"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)
|
||||
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 {
|
||||
return
|
||||
}
|
||||
|
||||
@ -159,7 +159,7 @@ func (s *TunnelClient) Start(args interface{}, log *logger.Logger) (err error) {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
s.ServeUDP(localAddr, ID, serverID)
|
||||
@ -168,7 +168,7 @@ func (s *TunnelClient) Start(args interface{}, log *logger.Logger) (err error) {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
s.ServeConn(localAddr, ID, serverID)
|
||||
@ -324,7 +324,7 @@ func (s *TunnelClient) ServeUDP(localAddr, ID, serverID string) {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
(*item).udpConn.Write(body)
|
||||
@ -335,7 +335,7 @@ func (s *TunnelClient) UDPRevecive(key, ID string) {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
s.log.Printf("udp conn %s connected", ID)
|
||||
@ -365,7 +365,7 @@ func (s *TunnelClient) UDPRevecive(key, ID string) {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
(*cui.conn).SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
|
||||
@ -384,7 +384,7 @@ func (s *TunnelClient) UDPGCDeamon() {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
if s.isStop {
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/snail007/goproxy/core/cs/server"
|
||||
"github.com/snail007/goproxy/services"
|
||||
"github.com/snail007/goproxy/utils"
|
||||
"github.com/snail007/goproxy/utils/jumper"
|
||||
@ -38,7 +39,7 @@ type TunnelServerArgs struct {
|
||||
}
|
||||
type TunnelServer struct {
|
||||
cfg TunnelServerArgs
|
||||
sc utils.ServerChannel
|
||||
sc server.ServerChannel
|
||||
isStop bool
|
||||
udpConn *net.Conn
|
||||
userConns mapx.ConcurrentMap
|
||||
@ -180,7 +181,7 @@ func (s *TunnelServer) StopService() {
|
||||
s.cfg = TunnelServerArgs{}
|
||||
s.jumper = nil
|
||||
s.log = nil
|
||||
s.sc = utils.ServerChannel{}
|
||||
s.sc = server.ServerChannel{}
|
||||
s.udpConn = nil
|
||||
s.udpConns = 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)
|
||||
p, _ := strconv.Atoi(port)
|
||||
s.sc = utils.NewServerChannel(host, p, s.log)
|
||||
s.sc = server.NewServerChannel(host, p, s.log)
|
||||
if *s.cfg.IsUDP {
|
||||
err = s.sc.ListenUDP(func(listener *net.UDPConn, packet []byte, localAddr, srcAddr *net.UDPAddr) {
|
||||
s.UDPSend(packet, localAddr, srcAddr)
|
||||
@ -368,7 +369,7 @@ func (s *TunnelServer) UDPGCDeamon() {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
if s.isStop {
|
||||
@ -439,7 +440,7 @@ func (s *TunnelServer) UDPRevecive(key, ID string) {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
s.log.Printf("udp conn %s connected", ID)
|
||||
@ -472,7 +473,7 @@ func (s *TunnelServer) UDPRevecive(key, ID string) {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
s.sc.UDPListener.WriteToUDP(body, uc.srcAddr)
|
||||
|
||||
@ -11,6 +11,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/snail007/goproxy/core/cs/server"
|
||||
"github.com/snail007/goproxy/services"
|
||||
"github.com/snail007/goproxy/utils"
|
||||
"github.com/snail007/goproxy/utils/mapx"
|
||||
@ -30,7 +31,7 @@ type UDPArgs struct {
|
||||
type UDP struct {
|
||||
p mapx.ConcurrentMap
|
||||
cfg UDPArgs
|
||||
sc *utils.ServerChannel
|
||||
sc *server.ServerChannel
|
||||
isStop bool
|
||||
log *logger.Logger
|
||||
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)
|
||||
p, _ := strconv.Atoi(port)
|
||||
sc := utils.NewServerChannel(host, p, s.log)
|
||||
sc := server.NewServerChannel(host, p, s.log)
|
||||
s.sc = &sc
|
||||
err = sc.ListenUDP(s.callback)
|
||||
if err != nil {
|
||||
@ -141,9 +142,7 @@ func (s *UDP) callback(listener *net.UDPConn, packet []byte, localAddr, srcAddr
|
||||
}
|
||||
}()
|
||||
switch *s.cfg.ParentType {
|
||||
case "tcp":
|
||||
fallthrough
|
||||
case "tls":
|
||||
case "tcp", "tls":
|
||||
s.OutToTCP(packet, localAddr, srcAddr)
|
||||
case "udp":
|
||||
s.OutToUDP(packet, localAddr, srcAddr)
|
||||
@ -175,7 +174,7 @@ func (s *UDP) OutToUDPGCDeamon() {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
if s.isStop {
|
||||
@ -217,7 +216,7 @@ func (s *UDP) OutToUDP(packet []byte, localAddr, srcAddr *net.UDPAddr) {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
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() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
(*(s.sc).UDPListener).SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
|
||||
@ -276,7 +275,7 @@ func (s *UDP) UDPGCDeamon() {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
if s.isStop {
|
||||
@ -353,7 +352,7 @@ func (s *UDP) UDPRevecive(key string) {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
s.log.Printf("udp conn %s connected", key)
|
||||
@ -367,7 +366,7 @@ func (s *UDP) UDPRevecive(key string) {
|
||||
}()
|
||||
v, ok := s.udpConns.Get(key)
|
||||
if !ok {
|
||||
s.log.Printf("[warn] udp conn not exists for %s, connid : %s", key)
|
||||
s.log.Printf("[warn] udp conn not exists for %s", key)
|
||||
return
|
||||
}
|
||||
uc = v.(*UDPConnItem)
|
||||
@ -386,7 +385,7 @@ func (s *UDP) UDPRevecive(key string) {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s", e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
s.sc.UDPListener.WriteToUDP(body, uc.srcAddr)
|
||||
|
||||
@ -20,10 +20,9 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/snail007/goproxy/services/kcpcfg"
|
||||
"github.com/snail007/goproxy/core/lib/kcpcfg"
|
||||
"github.com/snail007/goproxy/utils/lb"
|
||||
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
@ -245,98 +244,6 @@ func CloseConn(conn *net.Conn) {
|
||||
(*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
|
||||
|
||||
@ -464,11 +371,20 @@ func RandInt(strLen int) int64 {
|
||||
return i
|
||||
}
|
||||
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
|
||||
err = binary.Read(r, binary.LittleEndian, &len)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len == 0 || len > ^uint64(0) {
|
||||
err = fmt.Errorf("data len out of range, %d", len)
|
||||
return
|
||||
}
|
||||
var n int
|
||||
data = make([]byte, len)
|
||||
n, err = r.Read(data)
|
||||
|
||||
@ -24,8 +24,9 @@ func (s socks5Dialer) Dial(network, addr string) (net.Conn, error) {
|
||||
}
|
||||
|
||||
func New(proxyURL string, timeout time.Duration) (j Jumper, err error) {
|
||||
u, err := url.Parse(proxyURL)
|
||||
if err != nil {
|
||||
u, e := url.Parse(proxyURL)
|
||||
if e != nil {
|
||||
err = e
|
||||
return
|
||||
}
|
||||
j = Jumper{
|
||||
@ -34,7 +35,7 @@ func New(proxyURL string, timeout time.Duration) (j Jumper, err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
func (j *Jumper) Dial(address string, timeout time.Duration) (conn net.Conn, err error) {
|
||||
func (j *Jumper) Dial(address string, timeout time.Duration) (net.Conn, error) {
|
||||
switch j.proxyURL.Scheme {
|
||||
case "https":
|
||||
return j.dialHTTPS(address, timeout)
|
||||
@ -70,10 +71,10 @@ func (j *Jumper) dialHTTPS(address string, timeout time.Duration) (conn net.Conn
|
||||
}
|
||||
reply := make([]byte, 1024)
|
||||
conn.SetDeadline(time.Now().Add(timeout))
|
||||
n, err := conn.Read(reply)
|
||||
n, e := conn.Read(reply)
|
||||
conn.SetDeadline(time.Time{})
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error read reply from proxy: %s", err)
|
||||
if e != nil {
|
||||
err = fmt.Errorf("error read reply from proxy: %s", e)
|
||||
conn.Close()
|
||||
conn = nil
|
||||
return
|
||||
@ -94,9 +95,9 @@ func (j *Jumper) dialSOCKS5(address string, timeout time.Duration) (conn net.Con
|
||||
} else {
|
||||
auth = nil
|
||||
}
|
||||
dialSocksProxy, err := proxy.SOCKS5("tcp", j.proxyURL.Host, auth, socks5Dialer{timeout: timeout})
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error connecting to proxy: %s", err)
|
||||
dialSocksProxy, e := proxy.SOCKS5("tcp", j.proxyURL.Host, auth, socks5Dialer{timeout: timeout})
|
||||
if e != nil {
|
||||
err = fmt.Errorf("error connecting to proxy: %s", e)
|
||||
return
|
||||
}
|
||||
return dialSocksProxy.Dial("tcp", address)
|
||||
|
||||
@ -116,7 +116,7 @@ func (b *Backend) startMuxHeartCheck() {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
for {
|
||||
@ -151,7 +151,7 @@ func (b *Backend) startTCPHeartCheck() {
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
fmt.Printf("crashed, err: %s\nstack:\n%s",e, string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
for {
|
||||
|
||||
@ -36,6 +36,7 @@ type Group struct {
|
||||
lock *sync.Mutex
|
||||
last *Backend
|
||||
debug bool
|
||||
bks []*Backend
|
||||
}
|
||||
|
||||
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,
|
||||
lock: &sync.Mutex{},
|
||||
debug: debug,
|
||||
bks: bks,
|
||||
}
|
||||
}
|
||||
func (g *Group) Select(srcAddr string, onlyHa bool) (addr string) {
|
||||
if len(g.bks) == 1 {
|
||||
return g.bks[0].Address
|
||||
}
|
||||
if onlyHa {
|
||||
g.lock.Lock()
|
||||
defer g.lock.Unlock()
|
||||
@ -121,6 +126,7 @@ func (g *Group) Reset(addrs []string) {
|
||||
configs = append(configs, &c)
|
||||
}
|
||||
(*g.selector).Reset(configs, g.dr, g.log)
|
||||
g.bks = (*g.selector).Backends()
|
||||
}
|
||||
func (g *Group) Backends() []*Backend {
|
||||
return (*g.selector).Backends()
|
||||
|
||||
@ -152,14 +152,7 @@ type Tuple struct {
|
||||
func (m ConcurrentMap) Iter() <-chan Tuple {
|
||||
chans := snapshot(m)
|
||||
ch := make(chan Tuple)
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
fanIn(chans, ch)
|
||||
}()
|
||||
go fanIn(chans, ch)
|
||||
return ch
|
||||
}
|
||||
|
||||
@ -171,14 +164,7 @@ func (m ConcurrentMap) IterBuffered() <-chan Tuple {
|
||||
total += cap(c)
|
||||
}
|
||||
ch := make(chan Tuple, total)
|
||||
go func() {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
fanIn(chans, ch)
|
||||
}()
|
||||
go fanIn(chans, ch)
|
||||
return ch
|
||||
}
|
||||
|
||||
@ -193,11 +179,6 @@ func snapshot(m ConcurrentMap) (chans []chan Tuple) {
|
||||
// Foreach shard.
|
||||
for index, shard := range m {
|
||||
go func(index int, shard *ConcurrentMapShared) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
fmt.Printf("crashed:%s", string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
// Foreach key, value pair.
|
||||
shard.RLock()
|
||||
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`
|
||||
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.Add(len(chans))
|
||||
for _, ch := range chans {
|
||||
go func() {
|
||||
go func(ch chan Tuple) {
|
||||
defer func() {
|
||||
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 {
|
||||
out <- t
|
||||
}
|
||||
wg.Done()
|
||||
}(ch)
|
||||
}()
|
||||
for t := range ch {
|
||||
out <- t
|
||||
}
|
||||
wg.Done()
|
||||
}(ch)
|
||||
}
|
||||
wg.Wait()
|
||||
close(out)
|
||||
@ -274,29 +258,27 @@ func (m ConcurrentMap) Keys() []string {
|
||||
go func() {
|
||||
defer func() {
|
||||
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.
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(SHARD_COUNT)
|
||||
for _, shard := range m {
|
||||
go func() {
|
||||
go func(shard *ConcurrentMapShared) {
|
||||
defer func() {
|
||||
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.
|
||||
shard.RLock()
|
||||
for key := range shard.items {
|
||||
ch <- key
|
||||
}
|
||||
shard.RUnlock()
|
||||
wg.Done()
|
||||
}(shard)
|
||||
}()
|
||||
// Foreach key, value pair.
|
||||
shard.RLock()
|
||||
for key := range shard.items {
|
||||
ch <- key
|
||||
}
|
||||
shard.RUnlock()
|
||||
wg.Done()
|
||||
}(shard)
|
||||
}
|
||||
wg.Wait()
|
||||
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() {
|
||||
defer func() {
|
||||
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")
|
||||
@ -100,7 +100,7 @@ func (c *Checker) start() {
|
||||
go func(item CheckerItem) {
|
||||
defer func() {
|
||||
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) {
|
||||
@ -176,11 +176,9 @@ func (c *Checker) domainIsInMap(address string, blockedMap bool) bool {
|
||||
}
|
||||
domainSlice := strings.Split(u.Hostname(), ".")
|
||||
if len(domainSlice) > 1 {
|
||||
subSlice := domainSlice[:len(domainSlice)-1]
|
||||
topDomain := strings.Join(domainSlice[len(domainSlice)-1:], ".")
|
||||
checkDomain := topDomain
|
||||
for i := len(subSlice) - 1; i >= 0; i-- {
|
||||
checkDomain = subSlice[i] + "." + checkDomain
|
||||
checkDomain := ""
|
||||
for i := len(domainSlice) - 1; i >= 0; i-- {
|
||||
checkDomain = strings.Join(domainSlice[i:], ".")
|
||||
if !blockedMap && c.directMap.Has(checkDomain) {
|
||||
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")
|
||||
for _, userpass := range userpassArr {
|
||||
if strings.HasPrefix("#", userpass) {
|
||||
if strings.HasPrefix(userpass, "#") {
|
||||
continue
|
||||
}
|
||||
u := strings.Split(strings.Trim(userpass, " "), ":")
|
||||
|
||||
122
vendor/github.com/Yawning/chacha20/LICENSE
generated
vendored
Normal file
122
vendor/github.com/Yawning/chacha20/LICENSE
generated
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
||||
|
||||
14
vendor/github.com/Yawning/chacha20/README.md
generated
vendored
Normal file
14
vendor/github.com/Yawning/chacha20/README.md
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
### chacha20 - ChaCha20
|
||||
#### Yawning Angel (yawning at schwanenlied dot me)
|
||||
|
||||
Yet another Go ChaCha20 implementation. Everything else I found was slow,
|
||||
didn't support all the variants I need to use, or relied on cgo to go fast.
|
||||
|
||||
Features:
|
||||
|
||||
* 20 round, 256 bit key only. Everything else is pointless and stupid.
|
||||
* IETF 96 bit nonce variant.
|
||||
* XChaCha 24 byte nonce variant.
|
||||
* SSE2 and AVX2 support on amd64 targets.
|
||||
* Incremental encrypt/decrypt support, unlike golang.org/x/crypto/salsa20.
|
||||
|
||||
273
vendor/github.com/Yawning/chacha20/chacha20.go
generated
vendored
Normal file
273
vendor/github.com/Yawning/chacha20/chacha20.go
generated
vendored
Normal file
@ -0,0 +1,273 @@
|
||||
// chacha20.go - A ChaCha stream cipher implementation.
|
||||
//
|
||||
// To the extent possible under law, Yawning Angel has waived all copyright
|
||||
// and related or neighboring rights to chacha20, using the Creative
|
||||
// Commons "CC0" public domain dedication. See LICENSE or
|
||||
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
|
||||
|
||||
package chacha20
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"math"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
const (
|
||||
// KeySize is the ChaCha20 key size in bytes.
|
||||
KeySize = 32
|
||||
|
||||
// NonceSize is the ChaCha20 nonce size in bytes.
|
||||
NonceSize = 8
|
||||
|
||||
// INonceSize is the IETF ChaCha20 nonce size in bytes.
|
||||
INonceSize = 12
|
||||
|
||||
// XNonceSize is the XChaCha20 nonce size in bytes.
|
||||
XNonceSize = 24
|
||||
|
||||
// HNonceSize is the HChaCha20 nonce size in bytes.
|
||||
HNonceSize = 16
|
||||
|
||||
// BlockSize is the ChaCha20 block size in bytes.
|
||||
BlockSize = 64
|
||||
|
||||
stateSize = 16
|
||||
chachaRounds = 20
|
||||
|
||||
// The constant "expand 32-byte k" as little endian uint32s.
|
||||
sigma0 = uint32(0x61707865)
|
||||
sigma1 = uint32(0x3320646e)
|
||||
sigma2 = uint32(0x79622d32)
|
||||
sigma3 = uint32(0x6b206574)
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrInvalidKey is the error returned when the key is invalid.
|
||||
ErrInvalidKey = errors.New("key length must be KeySize bytes")
|
||||
|
||||
// ErrInvalidNonce is the error returned when the nonce is invalid.
|
||||
ErrInvalidNonce = errors.New("nonce length must be NonceSize/INonceSize/XNonceSize bytes")
|
||||
|
||||
// ErrInvalidCounter is the error returned when the counter is invalid.
|
||||
ErrInvalidCounter = errors.New("block counter is invalid (out of range)")
|
||||
|
||||
useUnsafe = false
|
||||
usingVectors = false
|
||||
blocksFn = blocksRef
|
||||
)
|
||||
|
||||
// A Cipher is an instance of ChaCha20/XChaCha20 using a particular key and
|
||||
// nonce.
|
||||
type Cipher struct {
|
||||
state [stateSize]uint32
|
||||
|
||||
buf [BlockSize]byte
|
||||
off int
|
||||
ietf bool
|
||||
}
|
||||
|
||||
// Reset zeros the key data so that it will no longer appear in the process's
|
||||
// memory.
|
||||
func (c *Cipher) Reset() {
|
||||
for i := range c.state {
|
||||
c.state[i] = 0
|
||||
}
|
||||
for i := range c.buf {
|
||||
c.buf[i] = 0
|
||||
}
|
||||
}
|
||||
|
||||
// XORKeyStream sets dst to the result of XORing src with the key stream. Dst
|
||||
// and src may be the same slice but otherwise should not overlap.
|
||||
func (c *Cipher) XORKeyStream(dst, src []byte) {
|
||||
if len(dst) < len(src) {
|
||||
src = src[:len(dst)]
|
||||
}
|
||||
|
||||
for remaining := len(src); remaining > 0; {
|
||||
// Process multiple blocks at once.
|
||||
if c.off == BlockSize {
|
||||
nrBlocks := remaining / BlockSize
|
||||
directBytes := nrBlocks * BlockSize
|
||||
if nrBlocks > 0 {
|
||||
blocksFn(&c.state, src, dst, nrBlocks, c.ietf)
|
||||
remaining -= directBytes
|
||||
if remaining == 0 {
|
||||
return
|
||||
}
|
||||
dst = dst[directBytes:]
|
||||
src = src[directBytes:]
|
||||
}
|
||||
|
||||
// If there's a partial block, generate 1 block of keystream into
|
||||
// the internal buffer.
|
||||
blocksFn(&c.state, nil, c.buf[:], 1, c.ietf)
|
||||
c.off = 0
|
||||
}
|
||||
|
||||
// Process partial blocks from the buffered keystream.
|
||||
toXor := BlockSize - c.off
|
||||
if remaining < toXor {
|
||||
toXor = remaining
|
||||
}
|
||||
if toXor > 0 {
|
||||
for i, v := range src[:toXor] {
|
||||
dst[i] = v ^ c.buf[c.off+i]
|
||||
}
|
||||
dst = dst[toXor:]
|
||||
src = src[toXor:]
|
||||
|
||||
remaining -= toXor
|
||||
c.off += toXor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// KeyStream sets dst to the raw keystream.
|
||||
func (c *Cipher) KeyStream(dst []byte) {
|
||||
for remaining := len(dst); remaining > 0; {
|
||||
// Process multiple blocks at once.
|
||||
if c.off == BlockSize {
|
||||
nrBlocks := remaining / BlockSize
|
||||
directBytes := nrBlocks * BlockSize
|
||||
if nrBlocks > 0 {
|
||||
blocksFn(&c.state, nil, dst, nrBlocks, c.ietf)
|
||||
remaining -= directBytes
|
||||
if remaining == 0 {
|
||||
return
|
||||
}
|
||||
dst = dst[directBytes:]
|
||||
}
|
||||
|
||||
// If there's a partial block, generate 1 block of keystream into
|
||||
// the internal buffer.
|
||||
blocksFn(&c.state, nil, c.buf[:], 1, c.ietf)
|
||||
c.off = 0
|
||||
}
|
||||
|
||||
// Process partial blocks from the buffered keystream.
|
||||
toCopy := BlockSize - c.off
|
||||
if remaining < toCopy {
|
||||
toCopy = remaining
|
||||
}
|
||||
if toCopy > 0 {
|
||||
copy(dst[:toCopy], c.buf[c.off:c.off+toCopy])
|
||||
dst = dst[toCopy:]
|
||||
remaining -= toCopy
|
||||
c.off += toCopy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ReKey reinitializes the ChaCha20/XChaCha20 instance with the provided key
|
||||
// and nonce.
|
||||
func (c *Cipher) ReKey(key, nonce []byte) error {
|
||||
if len(key) != KeySize {
|
||||
return ErrInvalidKey
|
||||
}
|
||||
|
||||
switch len(nonce) {
|
||||
case NonceSize:
|
||||
case INonceSize:
|
||||
case XNonceSize:
|
||||
var subkey [KeySize]byte
|
||||
var subnonce [HNonceSize]byte
|
||||
copy(subnonce[:], nonce[0:16])
|
||||
HChaCha(key, &subnonce, &subkey)
|
||||
key = subkey[:]
|
||||
nonce = nonce[16:24]
|
||||
defer func() {
|
||||
for i := range subkey {
|
||||
subkey[i] = 0
|
||||
}
|
||||
}()
|
||||
default:
|
||||
return ErrInvalidNonce
|
||||
}
|
||||
|
||||
c.Reset()
|
||||
c.state[0] = sigma0
|
||||
c.state[1] = sigma1
|
||||
c.state[2] = sigma2
|
||||
c.state[3] = sigma3
|
||||
c.state[4] = binary.LittleEndian.Uint32(key[0:4])
|
||||
c.state[5] = binary.LittleEndian.Uint32(key[4:8])
|
||||
c.state[6] = binary.LittleEndian.Uint32(key[8:12])
|
||||
c.state[7] = binary.LittleEndian.Uint32(key[12:16])
|
||||
c.state[8] = binary.LittleEndian.Uint32(key[16:20])
|
||||
c.state[9] = binary.LittleEndian.Uint32(key[20:24])
|
||||
c.state[10] = binary.LittleEndian.Uint32(key[24:28])
|
||||
c.state[11] = binary.LittleEndian.Uint32(key[28:32])
|
||||
c.state[12] = 0
|
||||
if len(nonce) == INonceSize {
|
||||
c.state[13] = binary.LittleEndian.Uint32(nonce[0:4])
|
||||
c.state[14] = binary.LittleEndian.Uint32(nonce[4:8])
|
||||
c.state[15] = binary.LittleEndian.Uint32(nonce[8:12])
|
||||
c.ietf = true
|
||||
} else {
|
||||
c.state[13] = 0
|
||||
c.state[14] = binary.LittleEndian.Uint32(nonce[0:4])
|
||||
c.state[15] = binary.LittleEndian.Uint32(nonce[4:8])
|
||||
c.ietf = false
|
||||
}
|
||||
c.off = BlockSize
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// Seek sets the block counter to a given offset.
|
||||
func (c *Cipher) Seek(blockCounter uint64) error {
|
||||
if c.ietf {
|
||||
if blockCounter > math.MaxUint32 {
|
||||
return ErrInvalidCounter
|
||||
}
|
||||
c.state[12] = uint32(blockCounter)
|
||||
} else {
|
||||
c.state[12] = uint32(blockCounter)
|
||||
c.state[13] = uint32(blockCounter >> 32)
|
||||
}
|
||||
c.off = BlockSize
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewCipher returns a new ChaCha20/XChaCha20 instance.
|
||||
func NewCipher(key, nonce []byte) (*Cipher, error) {
|
||||
c := new(Cipher)
|
||||
if err := c.ReKey(key, nonce); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// HChaCha is the HChaCha20 hash function used to make XChaCha.
|
||||
func HChaCha(key []byte, nonce *[HNonceSize]byte, out *[32]byte) {
|
||||
var x [stateSize]uint32 // Last 4 slots unused, sigma hardcoded.
|
||||
x[0] = binary.LittleEndian.Uint32(key[0:4])
|
||||
x[1] = binary.LittleEndian.Uint32(key[4:8])
|
||||
x[2] = binary.LittleEndian.Uint32(key[8:12])
|
||||
x[3] = binary.LittleEndian.Uint32(key[12:16])
|
||||
x[4] = binary.LittleEndian.Uint32(key[16:20])
|
||||
x[5] = binary.LittleEndian.Uint32(key[20:24])
|
||||
x[6] = binary.LittleEndian.Uint32(key[24:28])
|
||||
x[7] = binary.LittleEndian.Uint32(key[28:32])
|
||||
x[8] = binary.LittleEndian.Uint32(nonce[0:4])
|
||||
x[9] = binary.LittleEndian.Uint32(nonce[4:8])
|
||||
x[10] = binary.LittleEndian.Uint32(nonce[8:12])
|
||||
x[11] = binary.LittleEndian.Uint32(nonce[12:16])
|
||||
hChaChaRef(&x, out)
|
||||
}
|
||||
|
||||
func init() {
|
||||
switch runtime.GOARCH {
|
||||
case "386", "amd64":
|
||||
// Abuse unsafe to skip calling binary.LittleEndian.PutUint32
|
||||
// in the critical path. This is a big boost on systems that are
|
||||
// little endian and not overly picky about alignment.
|
||||
useUnsafe = true
|
||||
}
|
||||
}
|
||||
|
||||
var _ cipher.Stream = (*Cipher)(nil)
|
||||
95
vendor/github.com/Yawning/chacha20/chacha20_amd64.go
generated
vendored
Normal file
95
vendor/github.com/Yawning/chacha20/chacha20_amd64.go
generated
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
// chacha20_amd64.go - AMD64 optimized chacha20.
|
||||
//
|
||||
// To the extent possible under law, Yawning Angel has waived all copyright
|
||||
// and related or neighboring rights to chacha20, using the Creative
|
||||
// Commons "CC0" public domain dedication. See LICENSE or
|
||||
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
|
||||
|
||||
// +build amd64,!gccgo,!appengine
|
||||
|
||||
package chacha20
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
var usingAVX2 = false
|
||||
|
||||
func blocksAmd64SSE2(x *uint32, inp, outp *byte, nrBlocks uint)
|
||||
|
||||
func blocksAmd64AVX2(x *uint32, inp, outp *byte, nrBlocks uint)
|
||||
|
||||
func cpuidAmd64(cpuidParams *uint32)
|
||||
|
||||
func xgetbv0Amd64(xcrVec *uint32)
|
||||
|
||||
func blocksAmd64(x *[stateSize]uint32, in []byte, out []byte, nrBlocks int, isIetf bool) {
|
||||
// Probably unneeded, but stating this explicitly simplifies the assembly.
|
||||
if nrBlocks == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if isIetf {
|
||||
var totalBlocks uint64
|
||||
totalBlocks = uint64(x[12]) + uint64(nrBlocks)
|
||||
if totalBlocks > math.MaxUint32 {
|
||||
panic("chacha20: Exceeded keystream per nonce limit")
|
||||
}
|
||||
}
|
||||
|
||||
if in == nil {
|
||||
for i := range out {
|
||||
out[i] = 0
|
||||
}
|
||||
in = out
|
||||
}
|
||||
|
||||
// Pointless to call the AVX2 code for just a single block, since half of
|
||||
// the output gets discarded...
|
||||
if usingAVX2 && nrBlocks > 1 {
|
||||
blocksAmd64AVX2(&x[0], &in[0], &out[0], uint(nrBlocks))
|
||||
} else {
|
||||
blocksAmd64SSE2(&x[0], &in[0], &out[0], uint(nrBlocks))
|
||||
}
|
||||
}
|
||||
|
||||
func supportsAVX2() bool {
|
||||
// https://software.intel.com/en-us/articles/how-to-detect-new-instruction-support-in-the-4th-generation-intel-core-processor-family
|
||||
const (
|
||||
osXsaveBit = 1 << 27
|
||||
avx2Bit = 1 << 5
|
||||
)
|
||||
|
||||
// Check to see if CPUID actually supports the leaf that indicates AVX2.
|
||||
// CPUID.(EAX=0H, ECX=0H) >= 7
|
||||
regs := [4]uint32{0x00}
|
||||
cpuidAmd64(®s[0])
|
||||
if regs[0] < 7 {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check to see if the OS knows how to save/restore XMM/YMM state.
|
||||
// CPUID.(EAX=01H, ECX=0H):ECX.OSXSAVE[bit 27]==1
|
||||
regs = [4]uint32{0x01}
|
||||
cpuidAmd64(®s[0])
|
||||
if regs[2]&osXsaveBit == 0 {
|
||||
return false
|
||||
}
|
||||
xcrRegs := [2]uint32{}
|
||||
xgetbv0Amd64(&xcrRegs[0])
|
||||
if xcrRegs[0]&6 != 6 {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check for AVX2 support.
|
||||
// CPUID.(EAX=07H, ECX=0H):EBX.AVX2[bit 5]==1
|
||||
regs = [4]uint32{0x07}
|
||||
cpuidAmd64(®s[0])
|
||||
return regs[1]&avx2Bit != 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
blocksFn = blocksAmd64
|
||||
usingVectors = true
|
||||
usingAVX2 = supportsAVX2()
|
||||
}
|
||||
1295
vendor/github.com/Yawning/chacha20/chacha20_amd64.py
generated
vendored
Normal file
1295
vendor/github.com/Yawning/chacha20/chacha20_amd64.py
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1180
vendor/github.com/Yawning/chacha20/chacha20_amd64.s
generated
vendored
Normal file
1180
vendor/github.com/Yawning/chacha20/chacha20_amd64.s
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
394
vendor/github.com/Yawning/chacha20/chacha20_ref.go
generated
vendored
Normal file
394
vendor/github.com/Yawning/chacha20/chacha20_ref.go
generated
vendored
Normal file
@ -0,0 +1,394 @@
|
||||
// chacha20_ref.go - Reference ChaCha20.
|
||||
//
|
||||
// To the extent possible under law, Yawning Angel has waived all copyright
|
||||
// and related or neighboring rights to chacha20, using the Creative
|
||||
// Commons "CC0" public domain dedication. See LICENSE or
|
||||
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
|
||||
|
||||
// +build !go1.9
|
||||
|
||||
package chacha20
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"math"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func blocksRef(x *[stateSize]uint32, in []byte, out []byte, nrBlocks int, isIetf bool) {
|
||||
if isIetf {
|
||||
var totalBlocks uint64
|
||||
totalBlocks = uint64(x[12]) + uint64(nrBlocks)
|
||||
if totalBlocks > math.MaxUint32 {
|
||||
panic("chacha20: Exceeded keystream per nonce limit")
|
||||
}
|
||||
}
|
||||
|
||||
// This routine ignores x[0]...x[4] in favor the const values since it's
|
||||
// ever so slightly faster.
|
||||
|
||||
for n := 0; n < nrBlocks; n++ {
|
||||
x0, x1, x2, x3 := sigma0, sigma1, sigma2, sigma3
|
||||
x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 := x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15]
|
||||
|
||||
for i := chachaRounds; i > 0; i -= 2 {
|
||||
// quarterround(x, 0, 4, 8, 12)
|
||||
x0 += x4
|
||||
x12 ^= x0
|
||||
x12 = (x12 << 16) | (x12 >> 16)
|
||||
x8 += x12
|
||||
x4 ^= x8
|
||||
x4 = (x4 << 12) | (x4 >> 20)
|
||||
x0 += x4
|
||||
x12 ^= x0
|
||||
x12 = (x12 << 8) | (x12 >> 24)
|
||||
x8 += x12
|
||||
x4 ^= x8
|
||||
x4 = (x4 << 7) | (x4 >> 25)
|
||||
|
||||
// quarterround(x, 1, 5, 9, 13)
|
||||
x1 += x5
|
||||
x13 ^= x1
|
||||
x13 = (x13 << 16) | (x13 >> 16)
|
||||
x9 += x13
|
||||
x5 ^= x9
|
||||
x5 = (x5 << 12) | (x5 >> 20)
|
||||
x1 += x5
|
||||
x13 ^= x1
|
||||
x13 = (x13 << 8) | (x13 >> 24)
|
||||
x9 += x13
|
||||
x5 ^= x9
|
||||
x5 = (x5 << 7) | (x5 >> 25)
|
||||
|
||||
// quarterround(x, 2, 6, 10, 14)
|
||||
x2 += x6
|
||||
x14 ^= x2
|
||||
x14 = (x14 << 16) | (x14 >> 16)
|
||||
x10 += x14
|
||||
x6 ^= x10
|
||||
x6 = (x6 << 12) | (x6 >> 20)
|
||||
x2 += x6
|
||||
x14 ^= x2
|
||||
x14 = (x14 << 8) | (x14 >> 24)
|
||||
x10 += x14
|
||||
x6 ^= x10
|
||||
x6 = (x6 << 7) | (x6 >> 25)
|
||||
|
||||
// quarterround(x, 3, 7, 11, 15)
|
||||
x3 += x7
|
||||
x15 ^= x3
|
||||
x15 = (x15 << 16) | (x15 >> 16)
|
||||
x11 += x15
|
||||
x7 ^= x11
|
||||
x7 = (x7 << 12) | (x7 >> 20)
|
||||
x3 += x7
|
||||
x15 ^= x3
|
||||
x15 = (x15 << 8) | (x15 >> 24)
|
||||
x11 += x15
|
||||
x7 ^= x11
|
||||
x7 = (x7 << 7) | (x7 >> 25)
|
||||
|
||||
// quarterround(x, 0, 5, 10, 15)
|
||||
x0 += x5
|
||||
x15 ^= x0
|
||||
x15 = (x15 << 16) | (x15 >> 16)
|
||||
x10 += x15
|
||||
x5 ^= x10
|
||||
x5 = (x5 << 12) | (x5 >> 20)
|
||||
x0 += x5
|
||||
x15 ^= x0
|
||||
x15 = (x15 << 8) | (x15 >> 24)
|
||||
x10 += x15
|
||||
x5 ^= x10
|
||||
x5 = (x5 << 7) | (x5 >> 25)
|
||||
|
||||
// quarterround(x, 1, 6, 11, 12)
|
||||
x1 += x6
|
||||
x12 ^= x1
|
||||
x12 = (x12 << 16) | (x12 >> 16)
|
||||
x11 += x12
|
||||
x6 ^= x11
|
||||
x6 = (x6 << 12) | (x6 >> 20)
|
||||
x1 += x6
|
||||
x12 ^= x1
|
||||
x12 = (x12 << 8) | (x12 >> 24)
|
||||
x11 += x12
|
||||
x6 ^= x11
|
||||
x6 = (x6 << 7) | (x6 >> 25)
|
||||
|
||||
// quarterround(x, 2, 7, 8, 13)
|
||||
x2 += x7
|
||||
x13 ^= x2
|
||||
x13 = (x13 << 16) | (x13 >> 16)
|
||||
x8 += x13
|
||||
x7 ^= x8
|
||||
x7 = (x7 << 12) | (x7 >> 20)
|
||||
x2 += x7
|
||||
x13 ^= x2
|
||||
x13 = (x13 << 8) | (x13 >> 24)
|
||||
x8 += x13
|
||||
x7 ^= x8
|
||||
x7 = (x7 << 7) | (x7 >> 25)
|
||||
|
||||
// quarterround(x, 3, 4, 9, 14)
|
||||
x3 += x4
|
||||
x14 ^= x3
|
||||
x14 = (x14 << 16) | (x14 >> 16)
|
||||
x9 += x14
|
||||
x4 ^= x9
|
||||
x4 = (x4 << 12) | (x4 >> 20)
|
||||
x3 += x4
|
||||
x14 ^= x3
|
||||
x14 = (x14 << 8) | (x14 >> 24)
|
||||
x9 += x14
|
||||
x4 ^= x9
|
||||
x4 = (x4 << 7) | (x4 >> 25)
|
||||
}
|
||||
|
||||
// On amd64 at least, this is a rather big boost.
|
||||
if useUnsafe {
|
||||
if in != nil {
|
||||
inArr := (*[16]uint32)(unsafe.Pointer(&in[n*BlockSize]))
|
||||
outArr := (*[16]uint32)(unsafe.Pointer(&out[n*BlockSize]))
|
||||
outArr[0] = inArr[0] ^ (x0 + sigma0)
|
||||
outArr[1] = inArr[1] ^ (x1 + sigma1)
|
||||
outArr[2] = inArr[2] ^ (x2 + sigma2)
|
||||
outArr[3] = inArr[3] ^ (x3 + sigma3)
|
||||
outArr[4] = inArr[4] ^ (x4 + x[4])
|
||||
outArr[5] = inArr[5] ^ (x5 + x[5])
|
||||
outArr[6] = inArr[6] ^ (x6 + x[6])
|
||||
outArr[7] = inArr[7] ^ (x7 + x[7])
|
||||
outArr[8] = inArr[8] ^ (x8 + x[8])
|
||||
outArr[9] = inArr[9] ^ (x9 + x[9])
|
||||
outArr[10] = inArr[10] ^ (x10 + x[10])
|
||||
outArr[11] = inArr[11] ^ (x11 + x[11])
|
||||
outArr[12] = inArr[12] ^ (x12 + x[12])
|
||||
outArr[13] = inArr[13] ^ (x13 + x[13])
|
||||
outArr[14] = inArr[14] ^ (x14 + x[14])
|
||||
outArr[15] = inArr[15] ^ (x15 + x[15])
|
||||
} else {
|
||||
outArr := (*[16]uint32)(unsafe.Pointer(&out[n*BlockSize]))
|
||||
outArr[0] = x0 + sigma0
|
||||
outArr[1] = x1 + sigma1
|
||||
outArr[2] = x2 + sigma2
|
||||
outArr[3] = x3 + sigma3
|
||||
outArr[4] = x4 + x[4]
|
||||
outArr[5] = x5 + x[5]
|
||||
outArr[6] = x6 + x[6]
|
||||
outArr[7] = x7 + x[7]
|
||||
outArr[8] = x8 + x[8]
|
||||
outArr[9] = x9 + x[9]
|
||||
outArr[10] = x10 + x[10]
|
||||
outArr[11] = x11 + x[11]
|
||||
outArr[12] = x12 + x[12]
|
||||
outArr[13] = x13 + x[13]
|
||||
outArr[14] = x14 + x[14]
|
||||
outArr[15] = x15 + x[15]
|
||||
}
|
||||
} else {
|
||||
// Slow path, either the architecture cares about alignment, or is not little endian.
|
||||
x0 += sigma0
|
||||
x1 += sigma1
|
||||
x2 += sigma2
|
||||
x3 += sigma3
|
||||
x4 += x[4]
|
||||
x5 += x[5]
|
||||
x6 += x[6]
|
||||
x7 += x[7]
|
||||
x8 += x[8]
|
||||
x9 += x[9]
|
||||
x10 += x[10]
|
||||
x11 += x[11]
|
||||
x12 += x[12]
|
||||
x13 += x[13]
|
||||
x14 += x[14]
|
||||
x15 += x[15]
|
||||
if in != nil {
|
||||
binary.LittleEndian.PutUint32(out[0:4], binary.LittleEndian.Uint32(in[0:4])^x0)
|
||||
binary.LittleEndian.PutUint32(out[4:8], binary.LittleEndian.Uint32(in[4:8])^x1)
|
||||
binary.LittleEndian.PutUint32(out[8:12], binary.LittleEndian.Uint32(in[8:12])^x2)
|
||||
binary.LittleEndian.PutUint32(out[12:16], binary.LittleEndian.Uint32(in[12:16])^x3)
|
||||
binary.LittleEndian.PutUint32(out[16:20], binary.LittleEndian.Uint32(in[16:20])^x4)
|
||||
binary.LittleEndian.PutUint32(out[20:24], binary.LittleEndian.Uint32(in[20:24])^x5)
|
||||
binary.LittleEndian.PutUint32(out[24:28], binary.LittleEndian.Uint32(in[24:28])^x6)
|
||||
binary.LittleEndian.PutUint32(out[28:32], binary.LittleEndian.Uint32(in[28:32])^x7)
|
||||
binary.LittleEndian.PutUint32(out[32:36], binary.LittleEndian.Uint32(in[32:36])^x8)
|
||||
binary.LittleEndian.PutUint32(out[36:40], binary.LittleEndian.Uint32(in[36:40])^x9)
|
||||
binary.LittleEndian.PutUint32(out[40:44], binary.LittleEndian.Uint32(in[40:44])^x10)
|
||||
binary.LittleEndian.PutUint32(out[44:48], binary.LittleEndian.Uint32(in[44:48])^x11)
|
||||
binary.LittleEndian.PutUint32(out[48:52], binary.LittleEndian.Uint32(in[48:52])^x12)
|
||||
binary.LittleEndian.PutUint32(out[52:56], binary.LittleEndian.Uint32(in[52:56])^x13)
|
||||
binary.LittleEndian.PutUint32(out[56:60], binary.LittleEndian.Uint32(in[56:60])^x14)
|
||||
binary.LittleEndian.PutUint32(out[60:64], binary.LittleEndian.Uint32(in[60:64])^x15)
|
||||
in = in[BlockSize:]
|
||||
} else {
|
||||
binary.LittleEndian.PutUint32(out[0:4], x0)
|
||||
binary.LittleEndian.PutUint32(out[4:8], x1)
|
||||
binary.LittleEndian.PutUint32(out[8:12], x2)
|
||||
binary.LittleEndian.PutUint32(out[12:16], x3)
|
||||
binary.LittleEndian.PutUint32(out[16:20], x4)
|
||||
binary.LittleEndian.PutUint32(out[20:24], x5)
|
||||
binary.LittleEndian.PutUint32(out[24:28], x6)
|
||||
binary.LittleEndian.PutUint32(out[28:32], x7)
|
||||
binary.LittleEndian.PutUint32(out[32:36], x8)
|
||||
binary.LittleEndian.PutUint32(out[36:40], x9)
|
||||
binary.LittleEndian.PutUint32(out[40:44], x10)
|
||||
binary.LittleEndian.PutUint32(out[44:48], x11)
|
||||
binary.LittleEndian.PutUint32(out[48:52], x12)
|
||||
binary.LittleEndian.PutUint32(out[52:56], x13)
|
||||
binary.LittleEndian.PutUint32(out[56:60], x14)
|
||||
binary.LittleEndian.PutUint32(out[60:64], x15)
|
||||
}
|
||||
out = out[BlockSize:]
|
||||
}
|
||||
|
||||
// Stoping at 2^70 bytes per nonce is the user's responsibility.
|
||||
ctr := uint64(x[13])<<32 | uint64(x[12])
|
||||
ctr++
|
||||
x[12] = uint32(ctr)
|
||||
x[13] = uint32(ctr >> 32)
|
||||
}
|
||||
}
|
||||
|
||||
func hChaChaRef(x *[stateSize]uint32, out *[32]byte) {
|
||||
x0, x1, x2, x3 := sigma0, sigma1, sigma2, sigma3
|
||||
x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 := x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11]
|
||||
|
||||
for i := chachaRounds; i > 0; i -= 2 {
|
||||
// quarterround(x, 0, 4, 8, 12)
|
||||
x0 += x4
|
||||
x12 ^= x0
|
||||
x12 = (x12 << 16) | (x12 >> 16)
|
||||
x8 += x12
|
||||
x4 ^= x8
|
||||
x4 = (x4 << 12) | (x4 >> 20)
|
||||
x0 += x4
|
||||
x12 ^= x0
|
||||
x12 = (x12 << 8) | (x12 >> 24)
|
||||
x8 += x12
|
||||
x4 ^= x8
|
||||
x4 = (x4 << 7) | (x4 >> 25)
|
||||
|
||||
// quarterround(x, 1, 5, 9, 13)
|
||||
x1 += x5
|
||||
x13 ^= x1
|
||||
x13 = (x13 << 16) | (x13 >> 16)
|
||||
x9 += x13
|
||||
x5 ^= x9
|
||||
x5 = (x5 << 12) | (x5 >> 20)
|
||||
x1 += x5
|
||||
x13 ^= x1
|
||||
x13 = (x13 << 8) | (x13 >> 24)
|
||||
x9 += x13
|
||||
x5 ^= x9
|
||||
x5 = (x5 << 7) | (x5 >> 25)
|
||||
|
||||
// quarterround(x, 2, 6, 10, 14)
|
||||
x2 += x6
|
||||
x14 ^= x2
|
||||
x14 = (x14 << 16) | (x14 >> 16)
|
||||
x10 += x14
|
||||
x6 ^= x10
|
||||
x6 = (x6 << 12) | (x6 >> 20)
|
||||
x2 += x6
|
||||
x14 ^= x2
|
||||
x14 = (x14 << 8) | (x14 >> 24)
|
||||
x10 += x14
|
||||
x6 ^= x10
|
||||
x6 = (x6 << 7) | (x6 >> 25)
|
||||
|
||||
// quarterround(x, 3, 7, 11, 15)
|
||||
x3 += x7
|
||||
x15 ^= x3
|
||||
x15 = (x15 << 16) | (x15 >> 16)
|
||||
x11 += x15
|
||||
x7 ^= x11
|
||||
x7 = (x7 << 12) | (x7 >> 20)
|
||||
x3 += x7
|
||||
x15 ^= x3
|
||||
x15 = (x15 << 8) | (x15 >> 24)
|
||||
x11 += x15
|
||||
x7 ^= x11
|
||||
x7 = (x7 << 7) | (x7 >> 25)
|
||||
|
||||
// quarterround(x, 0, 5, 10, 15)
|
||||
x0 += x5
|
||||
x15 ^= x0
|
||||
x15 = (x15 << 16) | (x15 >> 16)
|
||||
x10 += x15
|
||||
x5 ^= x10
|
||||
x5 = (x5 << 12) | (x5 >> 20)
|
||||
x0 += x5
|
||||
x15 ^= x0
|
||||
x15 = (x15 << 8) | (x15 >> 24)
|
||||
x10 += x15
|
||||
x5 ^= x10
|
||||
x5 = (x5 << 7) | (x5 >> 25)
|
||||
|
||||
// quarterround(x, 1, 6, 11, 12)
|
||||
x1 += x6
|
||||
x12 ^= x1
|
||||
x12 = (x12 << 16) | (x12 >> 16)
|
||||
x11 += x12
|
||||
x6 ^= x11
|
||||
x6 = (x6 << 12) | (x6 >> 20)
|
||||
x1 += x6
|
||||
x12 ^= x1
|
||||
x12 = (x12 << 8) | (x12 >> 24)
|
||||
x11 += x12
|
||||
x6 ^= x11
|
||||
x6 = (x6 << 7) | (x6 >> 25)
|
||||
|
||||
// quarterround(x, 2, 7, 8, 13)
|
||||
x2 += x7
|
||||
x13 ^= x2
|
||||
x13 = (x13 << 16) | (x13 >> 16)
|
||||
x8 += x13
|
||||
x7 ^= x8
|
||||
x7 = (x7 << 12) | (x7 >> 20)
|
||||
x2 += x7
|
||||
x13 ^= x2
|
||||
x13 = (x13 << 8) | (x13 >> 24)
|
||||
x8 += x13
|
||||
x7 ^= x8
|
||||
x7 = (x7 << 7) | (x7 >> 25)
|
||||
|
||||
// quarterround(x, 3, 4, 9, 14)
|
||||
x3 += x4
|
||||
x14 ^= x3
|
||||
x14 = (x14 << 16) | (x14 >> 16)
|
||||
x9 += x14
|
||||
x4 ^= x9
|
||||
x4 = (x4 << 12) | (x4 >> 20)
|
||||
x3 += x4
|
||||
x14 ^= x3
|
||||
x14 = (x14 << 8) | (x14 >> 24)
|
||||
x9 += x14
|
||||
x4 ^= x9
|
||||
x4 = (x4 << 7) | (x4 >> 25)
|
||||
}
|
||||
|
||||
// HChaCha returns x0...x3 | x12...x15, which corresponds to the
|
||||
// indexes of the ChaCha constant and the indexes of the IV.
|
||||
if useUnsafe {
|
||||
outArr := (*[16]uint32)(unsafe.Pointer(&out[0]))
|
||||
outArr[0] = x0
|
||||
outArr[1] = x1
|
||||
outArr[2] = x2
|
||||
outArr[3] = x3
|
||||
outArr[4] = x12
|
||||
outArr[5] = x13
|
||||
outArr[6] = x14
|
||||
outArr[7] = x15
|
||||
} else {
|
||||
binary.LittleEndian.PutUint32(out[0:4], x0)
|
||||
binary.LittleEndian.PutUint32(out[4:8], x1)
|
||||
binary.LittleEndian.PutUint32(out[8:12], x2)
|
||||
binary.LittleEndian.PutUint32(out[12:16], x3)
|
||||
binary.LittleEndian.PutUint32(out[16:20], x12)
|
||||
binary.LittleEndian.PutUint32(out[20:24], x13)
|
||||
binary.LittleEndian.PutUint32(out[24:28], x14)
|
||||
binary.LittleEndian.PutUint32(out[28:32], x15)
|
||||
}
|
||||
return
|
||||
}
|
||||
395
vendor/github.com/Yawning/chacha20/chacha20_ref_go19.go
generated
vendored
Normal file
395
vendor/github.com/Yawning/chacha20/chacha20_ref_go19.go
generated
vendored
Normal file
@ -0,0 +1,395 @@
|
||||
// chacha20_ref.go - Reference ChaCha20.
|
||||
//
|
||||
// To the extent possible under law, Yawning Angel has waived all copyright
|
||||
// and related or neighboring rights to chacha20, using the Creative
|
||||
// Commons "CC0" public domain dedication. See LICENSE or
|
||||
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
|
||||
|
||||
// +build go1.9
|
||||
|
||||
package chacha20
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"math"
|
||||
"math/bits"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func blocksRef(x *[stateSize]uint32, in []byte, out []byte, nrBlocks int, isIetf bool) {
|
||||
if isIetf {
|
||||
var totalBlocks uint64
|
||||
totalBlocks = uint64(x[12]) + uint64(nrBlocks)
|
||||
if totalBlocks > math.MaxUint32 {
|
||||
panic("chacha20: Exceeded keystream per nonce limit")
|
||||
}
|
||||
}
|
||||
|
||||
// This routine ignores x[0]...x[4] in favor the const values since it's
|
||||
// ever so slightly faster.
|
||||
|
||||
for n := 0; n < nrBlocks; n++ {
|
||||
x0, x1, x2, x3 := sigma0, sigma1, sigma2, sigma3
|
||||
x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 := x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15]
|
||||
|
||||
for i := chachaRounds; i > 0; i -= 2 {
|
||||
// quarterround(x, 0, 4, 8, 12)
|
||||
x0 += x4
|
||||
x12 ^= x0
|
||||
x12 = bits.RotateLeft32(x12, 16)
|
||||
x8 += x12
|
||||
x4 ^= x8
|
||||
x4 = bits.RotateLeft32(x4, 12)
|
||||
x0 += x4
|
||||
x12 ^= x0
|
||||
x12 = bits.RotateLeft32(x12, 8)
|
||||
x8 += x12
|
||||
x4 ^= x8
|
||||
x4 = bits.RotateLeft32(x4, 7)
|
||||
|
||||
// quarterround(x, 1, 5, 9, 13)
|
||||
x1 += x5
|
||||
x13 ^= x1
|
||||
x13 = bits.RotateLeft32(x13, 16)
|
||||
x9 += x13
|
||||
x5 ^= x9
|
||||
x5 = bits.RotateLeft32(x5, 12)
|
||||
x1 += x5
|
||||
x13 ^= x1
|
||||
x13 = bits.RotateLeft32(x13, 8)
|
||||
x9 += x13
|
||||
x5 ^= x9
|
||||
x5 = bits.RotateLeft32(x5, 7)
|
||||
|
||||
// quarterround(x, 2, 6, 10, 14)
|
||||
x2 += x6
|
||||
x14 ^= x2
|
||||
x14 = bits.RotateLeft32(x14, 16)
|
||||
x10 += x14
|
||||
x6 ^= x10
|
||||
x6 = bits.RotateLeft32(x6, 12)
|
||||
x2 += x6
|
||||
x14 ^= x2
|
||||
x14 = bits.RotateLeft32(x14, 8)
|
||||
x10 += x14
|
||||
x6 ^= x10
|
||||
x6 = bits.RotateLeft32(x6, 7)
|
||||
|
||||
// quarterround(x, 3, 7, 11, 15)
|
||||
x3 += x7
|
||||
x15 ^= x3
|
||||
x15 = bits.RotateLeft32(x15, 16)
|
||||
x11 += x15
|
||||
x7 ^= x11
|
||||
x7 = bits.RotateLeft32(x7, 12)
|
||||
x3 += x7
|
||||
x15 ^= x3
|
||||
x15 = bits.RotateLeft32(x15, 8)
|
||||
x11 += x15
|
||||
x7 ^= x11
|
||||
x7 = bits.RotateLeft32(x7, 7)
|
||||
|
||||
// quarterround(x, 0, 5, 10, 15)
|
||||
x0 += x5
|
||||
x15 ^= x0
|
||||
x15 = bits.RotateLeft32(x15, 16)
|
||||
x10 += x15
|
||||
x5 ^= x10
|
||||
x5 = bits.RotateLeft32(x5, 12)
|
||||
x0 += x5
|
||||
x15 ^= x0
|
||||
x15 = bits.RotateLeft32(x15, 8)
|
||||
x10 += x15
|
||||
x5 ^= x10
|
||||
x5 = bits.RotateLeft32(x5, 7)
|
||||
|
||||
// quarterround(x, 1, 6, 11, 12)
|
||||
x1 += x6
|
||||
x12 ^= x1
|
||||
x12 = bits.RotateLeft32(x12, 16)
|
||||
x11 += x12
|
||||
x6 ^= x11
|
||||
x6 = bits.RotateLeft32(x6, 12)
|
||||
x1 += x6
|
||||
x12 ^= x1
|
||||
x12 = bits.RotateLeft32(x12, 8)
|
||||
x11 += x12
|
||||
x6 ^= x11
|
||||
x6 = bits.RotateLeft32(x6, 7)
|
||||
|
||||
// quarterround(x, 2, 7, 8, 13)
|
||||
x2 += x7
|
||||
x13 ^= x2
|
||||
x13 = bits.RotateLeft32(x13, 16)
|
||||
x8 += x13
|
||||
x7 ^= x8
|
||||
x7 = bits.RotateLeft32(x7, 12)
|
||||
x2 += x7
|
||||
x13 ^= x2
|
||||
x13 = bits.RotateLeft32(x13, 8)
|
||||
x8 += x13
|
||||
x7 ^= x8
|
||||
x7 = bits.RotateLeft32(x7, 7)
|
||||
|
||||
// quarterround(x, 3, 4, 9, 14)
|
||||
x3 += x4
|
||||
x14 ^= x3
|
||||
x14 = bits.RotateLeft32(x14, 16)
|
||||
x9 += x14
|
||||
x4 ^= x9
|
||||
x4 = bits.RotateLeft32(x4, 12)
|
||||
x3 += x4
|
||||
x14 ^= x3
|
||||
x14 = bits.RotateLeft32(x14, 8)
|
||||
x9 += x14
|
||||
x4 ^= x9
|
||||
x4 = bits.RotateLeft32(x4, 7)
|
||||
}
|
||||
|
||||
// On amd64 at least, this is a rather big boost.
|
||||
if useUnsafe {
|
||||
if in != nil {
|
||||
inArr := (*[16]uint32)(unsafe.Pointer(&in[n*BlockSize]))
|
||||
outArr := (*[16]uint32)(unsafe.Pointer(&out[n*BlockSize]))
|
||||
outArr[0] = inArr[0] ^ (x0 + sigma0)
|
||||
outArr[1] = inArr[1] ^ (x1 + sigma1)
|
||||
outArr[2] = inArr[2] ^ (x2 + sigma2)
|
||||
outArr[3] = inArr[3] ^ (x3 + sigma3)
|
||||
outArr[4] = inArr[4] ^ (x4 + x[4])
|
||||
outArr[5] = inArr[5] ^ (x5 + x[5])
|
||||
outArr[6] = inArr[6] ^ (x6 + x[6])
|
||||
outArr[7] = inArr[7] ^ (x7 + x[7])
|
||||
outArr[8] = inArr[8] ^ (x8 + x[8])
|
||||
outArr[9] = inArr[9] ^ (x9 + x[9])
|
||||
outArr[10] = inArr[10] ^ (x10 + x[10])
|
||||
outArr[11] = inArr[11] ^ (x11 + x[11])
|
||||
outArr[12] = inArr[12] ^ (x12 + x[12])
|
||||
outArr[13] = inArr[13] ^ (x13 + x[13])
|
||||
outArr[14] = inArr[14] ^ (x14 + x[14])
|
||||
outArr[15] = inArr[15] ^ (x15 + x[15])
|
||||
} else {
|
||||
outArr := (*[16]uint32)(unsafe.Pointer(&out[n*BlockSize]))
|
||||
outArr[0] = x0 + sigma0
|
||||
outArr[1] = x1 + sigma1
|
||||
outArr[2] = x2 + sigma2
|
||||
outArr[3] = x3 + sigma3
|
||||
outArr[4] = x4 + x[4]
|
||||
outArr[5] = x5 + x[5]
|
||||
outArr[6] = x6 + x[6]
|
||||
outArr[7] = x7 + x[7]
|
||||
outArr[8] = x8 + x[8]
|
||||
outArr[9] = x9 + x[9]
|
||||
outArr[10] = x10 + x[10]
|
||||
outArr[11] = x11 + x[11]
|
||||
outArr[12] = x12 + x[12]
|
||||
outArr[13] = x13 + x[13]
|
||||
outArr[14] = x14 + x[14]
|
||||
outArr[15] = x15 + x[15]
|
||||
}
|
||||
} else {
|
||||
// Slow path, either the architecture cares about alignment, or is not little endian.
|
||||
x0 += sigma0
|
||||
x1 += sigma1
|
||||
x2 += sigma2
|
||||
x3 += sigma3
|
||||
x4 += x[4]
|
||||
x5 += x[5]
|
||||
x6 += x[6]
|
||||
x7 += x[7]
|
||||
x8 += x[8]
|
||||
x9 += x[9]
|
||||
x10 += x[10]
|
||||
x11 += x[11]
|
||||
x12 += x[12]
|
||||
x13 += x[13]
|
||||
x14 += x[14]
|
||||
x15 += x[15]
|
||||
if in != nil {
|
||||
binary.LittleEndian.PutUint32(out[0:4], binary.LittleEndian.Uint32(in[0:4])^x0)
|
||||
binary.LittleEndian.PutUint32(out[4:8], binary.LittleEndian.Uint32(in[4:8])^x1)
|
||||
binary.LittleEndian.PutUint32(out[8:12], binary.LittleEndian.Uint32(in[8:12])^x2)
|
||||
binary.LittleEndian.PutUint32(out[12:16], binary.LittleEndian.Uint32(in[12:16])^x3)
|
||||
binary.LittleEndian.PutUint32(out[16:20], binary.LittleEndian.Uint32(in[16:20])^x4)
|
||||
binary.LittleEndian.PutUint32(out[20:24], binary.LittleEndian.Uint32(in[20:24])^x5)
|
||||
binary.LittleEndian.PutUint32(out[24:28], binary.LittleEndian.Uint32(in[24:28])^x6)
|
||||
binary.LittleEndian.PutUint32(out[28:32], binary.LittleEndian.Uint32(in[28:32])^x7)
|
||||
binary.LittleEndian.PutUint32(out[32:36], binary.LittleEndian.Uint32(in[32:36])^x8)
|
||||
binary.LittleEndian.PutUint32(out[36:40], binary.LittleEndian.Uint32(in[36:40])^x9)
|
||||
binary.LittleEndian.PutUint32(out[40:44], binary.LittleEndian.Uint32(in[40:44])^x10)
|
||||
binary.LittleEndian.PutUint32(out[44:48], binary.LittleEndian.Uint32(in[44:48])^x11)
|
||||
binary.LittleEndian.PutUint32(out[48:52], binary.LittleEndian.Uint32(in[48:52])^x12)
|
||||
binary.LittleEndian.PutUint32(out[52:56], binary.LittleEndian.Uint32(in[52:56])^x13)
|
||||
binary.LittleEndian.PutUint32(out[56:60], binary.LittleEndian.Uint32(in[56:60])^x14)
|
||||
binary.LittleEndian.PutUint32(out[60:64], binary.LittleEndian.Uint32(in[60:64])^x15)
|
||||
in = in[BlockSize:]
|
||||
} else {
|
||||
binary.LittleEndian.PutUint32(out[0:4], x0)
|
||||
binary.LittleEndian.PutUint32(out[4:8], x1)
|
||||
binary.LittleEndian.PutUint32(out[8:12], x2)
|
||||
binary.LittleEndian.PutUint32(out[12:16], x3)
|
||||
binary.LittleEndian.PutUint32(out[16:20], x4)
|
||||
binary.LittleEndian.PutUint32(out[20:24], x5)
|
||||
binary.LittleEndian.PutUint32(out[24:28], x6)
|
||||
binary.LittleEndian.PutUint32(out[28:32], x7)
|
||||
binary.LittleEndian.PutUint32(out[32:36], x8)
|
||||
binary.LittleEndian.PutUint32(out[36:40], x9)
|
||||
binary.LittleEndian.PutUint32(out[40:44], x10)
|
||||
binary.LittleEndian.PutUint32(out[44:48], x11)
|
||||
binary.LittleEndian.PutUint32(out[48:52], x12)
|
||||
binary.LittleEndian.PutUint32(out[52:56], x13)
|
||||
binary.LittleEndian.PutUint32(out[56:60], x14)
|
||||
binary.LittleEndian.PutUint32(out[60:64], x15)
|
||||
}
|
||||
out = out[BlockSize:]
|
||||
}
|
||||
|
||||
// Stoping at 2^70 bytes per nonce is the user's responsibility.
|
||||
ctr := uint64(x[13])<<32 | uint64(x[12])
|
||||
ctr++
|
||||
x[12] = uint32(ctr)
|
||||
x[13] = uint32(ctr >> 32)
|
||||
}
|
||||
}
|
||||
|
||||
func hChaChaRef(x *[stateSize]uint32, out *[32]byte) {
|
||||
x0, x1, x2, x3 := sigma0, sigma1, sigma2, sigma3
|
||||
x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 := x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11]
|
||||
|
||||
for i := chachaRounds; i > 0; i -= 2 {
|
||||
// quarterround(x, 0, 4, 8, 12)
|
||||
x0 += x4
|
||||
x12 ^= x0
|
||||
x12 = bits.RotateLeft32(x12, 16)
|
||||
x8 += x12
|
||||
x4 ^= x8
|
||||
x4 = bits.RotateLeft32(x4, 12)
|
||||
x0 += x4
|
||||
x12 ^= x0
|
||||
x12 = bits.RotateLeft32(x12, 8)
|
||||
x8 += x12
|
||||
x4 ^= x8
|
||||
x4 = bits.RotateLeft32(x4, 7)
|
||||
|
||||
// quarterround(x, 1, 5, 9, 13)
|
||||
x1 += x5
|
||||
x13 ^= x1
|
||||
x13 = bits.RotateLeft32(x13, 16)
|
||||
x9 += x13
|
||||
x5 ^= x9
|
||||
x5 = bits.RotateLeft32(x5, 12)
|
||||
x1 += x5
|
||||
x13 ^= x1
|
||||
x13 = bits.RotateLeft32(x13, 8)
|
||||
x9 += x13
|
||||
x5 ^= x9
|
||||
x5 = bits.RotateLeft32(x5, 7)
|
||||
|
||||
// quarterround(x, 2, 6, 10, 14)
|
||||
x2 += x6
|
||||
x14 ^= x2
|
||||
x14 = bits.RotateLeft32(x14, 16)
|
||||
x10 += x14
|
||||
x6 ^= x10
|
||||
x6 = bits.RotateLeft32(x6, 12)
|
||||
x2 += x6
|
||||
x14 ^= x2
|
||||
x14 = bits.RotateLeft32(x14, 8)
|
||||
x10 += x14
|
||||
x6 ^= x10
|
||||
x6 = bits.RotateLeft32(x6, 7)
|
||||
|
||||
// quarterround(x, 3, 7, 11, 15)
|
||||
x3 += x7
|
||||
x15 ^= x3
|
||||
x15 = bits.RotateLeft32(x15, 16)
|
||||
x11 += x15
|
||||
x7 ^= x11
|
||||
x7 = bits.RotateLeft32(x7, 12)
|
||||
x3 += x7
|
||||
x15 ^= x3
|
||||
x15 = bits.RotateLeft32(x15, 8)
|
||||
x11 += x15
|
||||
x7 ^= x11
|
||||
x7 = bits.RotateLeft32(x7, 7)
|
||||
|
||||
// quarterround(x, 0, 5, 10, 15)
|
||||
x0 += x5
|
||||
x15 ^= x0
|
||||
x15 = bits.RotateLeft32(x15, 16)
|
||||
x10 += x15
|
||||
x5 ^= x10
|
||||
x5 = bits.RotateLeft32(x5, 12)
|
||||
x0 += x5
|
||||
x15 ^= x0
|
||||
x15 = bits.RotateLeft32(x15, 8)
|
||||
x10 += x15
|
||||
x5 ^= x10
|
||||
x5 = bits.RotateLeft32(x5, 7)
|
||||
|
||||
// quarterround(x, 1, 6, 11, 12)
|
||||
x1 += x6
|
||||
x12 ^= x1
|
||||
x12 = bits.RotateLeft32(x12, 16)
|
||||
x11 += x12
|
||||
x6 ^= x11
|
||||
x6 = bits.RotateLeft32(x6, 12)
|
||||
x1 += x6
|
||||
x12 ^= x1
|
||||
x12 = bits.RotateLeft32(x12, 8)
|
||||
x11 += x12
|
||||
x6 ^= x11
|
||||
x6 = bits.RotateLeft32(x6, 7)
|
||||
|
||||
// quarterround(x, 2, 7, 8, 13)
|
||||
x2 += x7
|
||||
x13 ^= x2
|
||||
x13 = bits.RotateLeft32(x13, 16)
|
||||
x8 += x13
|
||||
x7 ^= x8
|
||||
x7 = bits.RotateLeft32(x7, 12)
|
||||
x2 += x7
|
||||
x13 ^= x2
|
||||
x13 = bits.RotateLeft32(x13, 8)
|
||||
x8 += x13
|
||||
x7 ^= x8
|
||||
x7 = bits.RotateLeft32(x7, 7)
|
||||
|
||||
// quarterround(x, 3, 4, 9, 14)
|
||||
x3 += x4
|
||||
x14 ^= x3
|
||||
x14 = bits.RotateLeft32(x14, 16)
|
||||
x9 += x14
|
||||
x4 ^= x9
|
||||
x4 = bits.RotateLeft32(x4, 12)
|
||||
x3 += x4
|
||||
x14 ^= x3
|
||||
x14 = bits.RotateLeft32(x14, 8)
|
||||
x9 += x14
|
||||
x4 ^= x9
|
||||
x4 = bits.RotateLeft32(x4, 7)
|
||||
}
|
||||
|
||||
// HChaCha returns x0...x3 | x12...x15, which corresponds to the
|
||||
// indexes of the ChaCha constant and the indexes of the IV.
|
||||
if useUnsafe {
|
||||
outArr := (*[16]uint32)(unsafe.Pointer(&out[0]))
|
||||
outArr[0] = x0
|
||||
outArr[1] = x1
|
||||
outArr[2] = x2
|
||||
outArr[3] = x3
|
||||
outArr[4] = x12
|
||||
outArr[5] = x13
|
||||
outArr[6] = x14
|
||||
outArr[7] = x15
|
||||
} else {
|
||||
binary.LittleEndian.PutUint32(out[0:4], x0)
|
||||
binary.LittleEndian.PutUint32(out[4:8], x1)
|
||||
binary.LittleEndian.PutUint32(out[8:12], x2)
|
||||
binary.LittleEndian.PutUint32(out[12:16], x3)
|
||||
binary.LittleEndian.PutUint32(out[16:20], x12)
|
||||
binary.LittleEndian.PutUint32(out[20:24], x13)
|
||||
binary.LittleEndian.PutUint32(out[24:28], x14)
|
||||
binary.LittleEndian.PutUint32(out[28:32], x15)
|
||||
}
|
||||
return
|
||||
}
|
||||
191
vendor/github.com/juju/ratelimit/LICENSE
generated
vendored
Normal file
191
vendor/github.com/juju/ratelimit/LICENSE
generated
vendored
Normal file
@ -0,0 +1,191 @@
|
||||
All files in this repository are licensed as follows. If you contribute
|
||||
to this repository, it is assumed that you license your contribution
|
||||
under the same license unless you state otherwise.
|
||||
|
||||
All files Copyright (C) 2015 Canonical Ltd. unless otherwise specified in the file.
|
||||
|
||||
This software is licensed under the LGPLv3, included below.
|
||||
|
||||
As a special exception to the GNU Lesser General Public License version 3
|
||||
("LGPL3"), the copyright holders of this Library give you permission to
|
||||
convey to a third party a Combined Work that links statically or dynamically
|
||||
to this Library without providing any Minimal Corresponding Source or
|
||||
Minimal Application Code as set out in 4d or providing the installation
|
||||
information set out in section 4e, provided that you comply with the other
|
||||
provisions of LGPL3 and provided that you meet, for the Application the
|
||||
terms and conditions of the license(s) which apply to the Application.
|
||||
|
||||
Except as stated in this special exception, the provisions of LGPL3 will
|
||||
continue to comply in full to this Library. If you modify this Library, you
|
||||
may apply this exception to your version of this Library, but you are not
|
||||
obliged to do so. If you do not wish to do so, delete this exception
|
||||
statement from your version. This exception does not (and cannot) modify any
|
||||
license terms which apply to the Application, with which you must still
|
||||
comply.
|
||||
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
117
vendor/github.com/juju/ratelimit/README.md
generated
vendored
Normal file
117
vendor/github.com/juju/ratelimit/README.md
generated
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
# ratelimit
|
||||
--
|
||||
import "github.com/juju/ratelimit"
|
||||
|
||||
The ratelimit package provides an efficient token bucket implementation. See
|
||||
http://en.wikipedia.org/wiki/Token_bucket.
|
||||
|
||||
## Usage
|
||||
|
||||
#### func Reader
|
||||
|
||||
```go
|
||||
func Reader(r io.Reader, bucket *Bucket) io.Reader
|
||||
```
|
||||
Reader returns a reader that is rate limited by the given token bucket. Each
|
||||
token in the bucket represents one byte.
|
||||
|
||||
#### func Writer
|
||||
|
||||
```go
|
||||
func Writer(w io.Writer, bucket *Bucket) io.Writer
|
||||
```
|
||||
Writer returns a writer that is rate limited by the given token bucket. Each
|
||||
token in the bucket represents one byte.
|
||||
|
||||
#### type Bucket
|
||||
|
||||
```go
|
||||
type Bucket struct {
|
||||
}
|
||||
```
|
||||
|
||||
Bucket represents a token bucket that fills at a predetermined rate. Methods on
|
||||
Bucket may be called concurrently.
|
||||
|
||||
#### func NewBucket
|
||||
|
||||
```go
|
||||
func NewBucket(fillInterval time.Duration, capacity int64) *Bucket
|
||||
```
|
||||
NewBucket returns a new token bucket that fills at the rate of one token every
|
||||
fillInterval, up to the given maximum capacity. Both arguments must be positive.
|
||||
The bucket is initially full.
|
||||
|
||||
#### func NewBucketWithQuantum
|
||||
|
||||
```go
|
||||
func NewBucketWithQuantum(fillInterval time.Duration, capacity, quantum int64) *Bucket
|
||||
```
|
||||
NewBucketWithQuantum is similar to NewBucket, but allows the specification of
|
||||
the quantum size - quantum tokens are added every fillInterval.
|
||||
|
||||
#### func NewBucketWithRate
|
||||
|
||||
```go
|
||||
func NewBucketWithRate(rate float64, capacity int64) *Bucket
|
||||
```
|
||||
NewBucketWithRate returns a token bucket that fills the bucket at the rate of
|
||||
rate tokens per second up to the given maximum capacity. Because of limited
|
||||
clock resolution, at high rates, the actual rate may be up to 1% different from
|
||||
the specified rate.
|
||||
|
||||
#### func (*Bucket) Rate
|
||||
|
||||
```go
|
||||
func (tb *Bucket) Rate() float64
|
||||
```
|
||||
Rate returns the fill rate of the bucket, in tokens per second.
|
||||
|
||||
#### func (*Bucket) Take
|
||||
|
||||
```go
|
||||
func (tb *Bucket) Take(count int64) time.Duration
|
||||
```
|
||||
Take takes count tokens from the bucket without blocking. It returns the time
|
||||
that the caller should wait until the tokens are actually available.
|
||||
|
||||
Note that if the request is irrevocable - there is no way to return tokens to
|
||||
the bucket once this method commits us to taking them.
|
||||
|
||||
#### func (*Bucket) TakeAvailable
|
||||
|
||||
```go
|
||||
func (tb *Bucket) TakeAvailable(count int64) int64
|
||||
```
|
||||
TakeAvailable takes up to count immediately available tokens from the bucket. It
|
||||
returns the number of tokens removed, or zero if there are no available tokens.
|
||||
It does not block.
|
||||
|
||||
#### func (*Bucket) TakeMaxDuration
|
||||
|
||||
```go
|
||||
func (tb *Bucket) TakeMaxDuration(count int64, maxWait time.Duration) (time.Duration, bool)
|
||||
```
|
||||
TakeMaxDuration is like Take, except that it will only take tokens from the
|
||||
bucket if the wait time for the tokens is no greater than maxWait.
|
||||
|
||||
If it would take longer than maxWait for the tokens to become available, it does
|
||||
nothing and reports false, otherwise it returns the time that the caller should
|
||||
wait until the tokens are actually available, and reports true.
|
||||
|
||||
#### func (*Bucket) Wait
|
||||
|
||||
```go
|
||||
func (tb *Bucket) Wait(count int64)
|
||||
```
|
||||
Wait takes count tokens from the bucket, waiting until they are available.
|
||||
|
||||
#### func (*Bucket) WaitMaxDuration
|
||||
|
||||
```go
|
||||
func (tb *Bucket) WaitMaxDuration(count int64, maxWait time.Duration) bool
|
||||
```
|
||||
WaitMaxDuration is like Wait except that it will only take tokens from the
|
||||
bucket if it needs to wait for no greater than maxWait. It reports whether any
|
||||
tokens have been removed from the bucket If no tokens have been removed, it
|
||||
returns immediately.
|
||||
344
vendor/github.com/juju/ratelimit/ratelimit.go
generated
vendored
Normal file
344
vendor/github.com/juju/ratelimit/ratelimit.go
generated
vendored
Normal file
@ -0,0 +1,344 @@
|
||||
// Copyright 2014 Canonical Ltd.
|
||||
// Licensed under the LGPLv3 with static-linking exception.
|
||||
// See LICENCE file for details.
|
||||
|
||||
// Package ratelimit provides an efficient token bucket implementation
|
||||
// that can be used to limit the rate of arbitrary things.
|
||||
// See http://en.wikipedia.org/wiki/Token_bucket.
|
||||
package ratelimit
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// The algorithm that this implementation uses does computational work
|
||||
// only when tokens are removed from the bucket, and that work completes
|
||||
// in short, bounded-constant time (Bucket.Wait benchmarks at 175ns on
|
||||
// my laptop).
|
||||
//
|
||||
// Time is measured in equal measured ticks, a given interval
|
||||
// (fillInterval) apart. On each tick a number of tokens (quantum) are
|
||||
// added to the bucket.
|
||||
//
|
||||
// When any of the methods are called the bucket updates the number of
|
||||
// tokens that are in the bucket, and it records the current tick
|
||||
// number too. Note that it doesn't record the current time - by
|
||||
// keeping things in units of whole ticks, it's easy to dish out tokens
|
||||
// at exactly the right intervals as measured from the start time.
|
||||
//
|
||||
// This allows us to calculate the number of tokens that will be
|
||||
// available at some time in the future with a few simple arithmetic
|
||||
// operations.
|
||||
//
|
||||
// The main reason for being able to transfer multiple tokens on each tick
|
||||
// is so that we can represent rates greater than 1e9 (the resolution of the Go
|
||||
// time package) tokens per second, but it's also useful because
|
||||
// it means we can easily represent situations like "a person gets
|
||||
// five tokens an hour, replenished on the hour".
|
||||
|
||||
// Bucket represents a token bucket that fills at a predetermined rate.
|
||||
// Methods on Bucket may be called concurrently.
|
||||
type Bucket struct {
|
||||
clock Clock
|
||||
|
||||
// startTime holds the moment when the bucket was
|
||||
// first created and ticks began.
|
||||
startTime time.Time
|
||||
|
||||
// capacity holds the overall capacity of the bucket.
|
||||
capacity int64
|
||||
|
||||
// quantum holds how many tokens are added on
|
||||
// each tick.
|
||||
quantum int64
|
||||
|
||||
// fillInterval holds the interval between each tick.
|
||||
fillInterval time.Duration
|
||||
|
||||
// mu guards the fields below it.
|
||||
mu sync.Mutex
|
||||
|
||||
// availableTokens holds the number of available
|
||||
// tokens as of the associated latestTick.
|
||||
// It will be negative when there are consumers
|
||||
// waiting for tokens.
|
||||
availableTokens int64
|
||||
|
||||
// latestTick holds the latest tick for which
|
||||
// we know the number of tokens in the bucket.
|
||||
latestTick int64
|
||||
}
|
||||
|
||||
// NewBucket returns a new token bucket that fills at the
|
||||
// rate of one token every fillInterval, up to the given
|
||||
// maximum capacity. Both arguments must be
|
||||
// positive. The bucket is initially full.
|
||||
func NewBucket(fillInterval time.Duration, capacity int64) *Bucket {
|
||||
return NewBucketWithClock(fillInterval, capacity, nil)
|
||||
}
|
||||
|
||||
// NewBucketWithClock is identical to NewBucket but injects a testable clock
|
||||
// interface.
|
||||
func NewBucketWithClock(fillInterval time.Duration, capacity int64, clock Clock) *Bucket {
|
||||
return NewBucketWithQuantumAndClock(fillInterval, capacity, 1, clock)
|
||||
}
|
||||
|
||||
// rateMargin specifes the allowed variance of actual
|
||||
// rate from specified rate. 1% seems reasonable.
|
||||
const rateMargin = 0.01
|
||||
|
||||
// NewBucketWithRate returns a token bucket that fills the bucket
|
||||
// at the rate of rate tokens per second up to the given
|
||||
// maximum capacity. Because of limited clock resolution,
|
||||
// at high rates, the actual rate may be up to 1% different from the
|
||||
// specified rate.
|
||||
func NewBucketWithRate(rate float64, capacity int64) *Bucket {
|
||||
return NewBucketWithRateAndClock(rate, capacity, nil)
|
||||
}
|
||||
|
||||
// NewBucketWithRateAndClock is identical to NewBucketWithRate but injects a
|
||||
// testable clock interface.
|
||||
func NewBucketWithRateAndClock(rate float64, capacity int64, clock Clock) *Bucket {
|
||||
// Use the same bucket each time through the loop
|
||||
// to save allocations.
|
||||
tb := NewBucketWithQuantumAndClock(1, capacity, 1, clock)
|
||||
for quantum := int64(1); quantum < 1<<50; quantum = nextQuantum(quantum) {
|
||||
fillInterval := time.Duration(1e9 * float64(quantum) / rate)
|
||||
if fillInterval <= 0 {
|
||||
continue
|
||||
}
|
||||
tb.fillInterval = fillInterval
|
||||
tb.quantum = quantum
|
||||
if diff := math.Abs(tb.Rate() - rate); diff/rate <= rateMargin {
|
||||
return tb
|
||||
}
|
||||
}
|
||||
panic("cannot find suitable quantum for " + strconv.FormatFloat(rate, 'g', -1, 64))
|
||||
}
|
||||
|
||||
// nextQuantum returns the next quantum to try after q.
|
||||
// We grow the quantum exponentially, but slowly, so we
|
||||
// get a good fit in the lower numbers.
|
||||
func nextQuantum(q int64) int64 {
|
||||
q1 := q * 11 / 10
|
||||
if q1 == q {
|
||||
q1++
|
||||
}
|
||||
return q1
|
||||
}
|
||||
|
||||
// NewBucketWithQuantum is similar to NewBucket, but allows
|
||||
// the specification of the quantum size - quantum tokens
|
||||
// are added every fillInterval.
|
||||
func NewBucketWithQuantum(fillInterval time.Duration, capacity, quantum int64) *Bucket {
|
||||
return NewBucketWithQuantumAndClock(fillInterval, capacity, quantum, nil)
|
||||
}
|
||||
|
||||
// NewBucketWithQuantumAndClock is like NewBucketWithQuantum, but
|
||||
// also has a clock argument that allows clients to fake the passing
|
||||
// of time. If clock is nil, the system clock will be used.
|
||||
func NewBucketWithQuantumAndClock(fillInterval time.Duration, capacity, quantum int64, clock Clock) *Bucket {
|
||||
if clock == nil {
|
||||
clock = realClock{}
|
||||
}
|
||||
if fillInterval <= 0 {
|
||||
panic("token bucket fill interval is not > 0")
|
||||
}
|
||||
if capacity <= 0 {
|
||||
panic("token bucket capacity is not > 0")
|
||||
}
|
||||
if quantum <= 0 {
|
||||
panic("token bucket quantum is not > 0")
|
||||
}
|
||||
return &Bucket{
|
||||
clock: clock,
|
||||
startTime: clock.Now(),
|
||||
latestTick: 0,
|
||||
fillInterval: fillInterval,
|
||||
capacity: capacity,
|
||||
quantum: quantum,
|
||||
availableTokens: capacity,
|
||||
}
|
||||
}
|
||||
|
||||
// Wait takes count tokens from the bucket, waiting until they are
|
||||
// available.
|
||||
func (tb *Bucket) Wait(count int64) {
|
||||
if d := tb.Take(count); d > 0 {
|
||||
tb.clock.Sleep(d)
|
||||
}
|
||||
}
|
||||
|
||||
// WaitMaxDuration is like Wait except that it will
|
||||
// only take tokens from the bucket if it needs to wait
|
||||
// for no greater than maxWait. It reports whether
|
||||
// any tokens have been removed from the bucket
|
||||
// If no tokens have been removed, it returns immediately.
|
||||
func (tb *Bucket) WaitMaxDuration(count int64, maxWait time.Duration) bool {
|
||||
d, ok := tb.TakeMaxDuration(count, maxWait)
|
||||
if d > 0 {
|
||||
tb.clock.Sleep(d)
|
||||
}
|
||||
return ok
|
||||
}
|
||||
|
||||
const infinityDuration time.Duration = 0x7fffffffffffffff
|
||||
|
||||
// Take takes count tokens from the bucket without blocking. It returns
|
||||
// the time that the caller should wait until the tokens are actually
|
||||
// available.
|
||||
//
|
||||
// Note that if the request is irrevocable - there is no way to return
|
||||
// tokens to the bucket once this method commits us to taking them.
|
||||
func (tb *Bucket) Take(count int64) time.Duration {
|
||||
tb.mu.Lock()
|
||||
defer tb.mu.Unlock()
|
||||
d, _ := tb.take(tb.clock.Now(), count, infinityDuration)
|
||||
return d
|
||||
}
|
||||
|
||||
// TakeMaxDuration is like Take, except that
|
||||
// it will only take tokens from the bucket if the wait
|
||||
// time for the tokens is no greater than maxWait.
|
||||
//
|
||||
// If it would take longer than maxWait for the tokens
|
||||
// to become available, it does nothing and reports false,
|
||||
// otherwise it returns the time that the caller should
|
||||
// wait until the tokens are actually available, and reports
|
||||
// true.
|
||||
func (tb *Bucket) TakeMaxDuration(count int64, maxWait time.Duration) (time.Duration, bool) {
|
||||
tb.mu.Lock()
|
||||
defer tb.mu.Unlock()
|
||||
return tb.take(tb.clock.Now(), count, maxWait)
|
||||
}
|
||||
|
||||
// TakeAvailable takes up to count immediately available tokens from the
|
||||
// bucket. It returns the number of tokens removed, or zero if there are
|
||||
// no available tokens. It does not block.
|
||||
func (tb *Bucket) TakeAvailable(count int64) int64 {
|
||||
tb.mu.Lock()
|
||||
defer tb.mu.Unlock()
|
||||
return tb.takeAvailable(tb.clock.Now(), count)
|
||||
}
|
||||
|
||||
// takeAvailable is the internal version of TakeAvailable - it takes the
|
||||
// current time as an argument to enable easy testing.
|
||||
func (tb *Bucket) takeAvailable(now time.Time, count int64) int64 {
|
||||
if count <= 0 {
|
||||
return 0
|
||||
}
|
||||
tb.adjustavailableTokens(tb.currentTick(now))
|
||||
if tb.availableTokens <= 0 {
|
||||
return 0
|
||||
}
|
||||
if count > tb.availableTokens {
|
||||
count = tb.availableTokens
|
||||
}
|
||||
tb.availableTokens -= count
|
||||
return count
|
||||
}
|
||||
|
||||
// Available returns the number of available tokens. It will be negative
|
||||
// when there are consumers waiting for tokens. Note that if this
|
||||
// returns greater than zero, it does not guarantee that calls that take
|
||||
// tokens from the buffer will succeed, as the number of available
|
||||
// tokens could have changed in the meantime. This method is intended
|
||||
// primarily for metrics reporting and debugging.
|
||||
func (tb *Bucket) Available() int64 {
|
||||
return tb.available(tb.clock.Now())
|
||||
}
|
||||
|
||||
// available is the internal version of available - it takes the current time as
|
||||
// an argument to enable easy testing.
|
||||
func (tb *Bucket) available(now time.Time) int64 {
|
||||
tb.mu.Lock()
|
||||
defer tb.mu.Unlock()
|
||||
tb.adjustavailableTokens(tb.currentTick(now))
|
||||
return tb.availableTokens
|
||||
}
|
||||
|
||||
// Capacity returns the capacity that the bucket was created with.
|
||||
func (tb *Bucket) Capacity() int64 {
|
||||
return tb.capacity
|
||||
}
|
||||
|
||||
// Rate returns the fill rate of the bucket, in tokens per second.
|
||||
func (tb *Bucket) Rate() float64 {
|
||||
return 1e9 * float64(tb.quantum) / float64(tb.fillInterval)
|
||||
}
|
||||
|
||||
// take is the internal version of Take - it takes the current time as
|
||||
// an argument to enable easy testing.
|
||||
func (tb *Bucket) take(now time.Time, count int64, maxWait time.Duration) (time.Duration, bool) {
|
||||
if count <= 0 {
|
||||
return 0, true
|
||||
}
|
||||
|
||||
tick := tb.currentTick(now)
|
||||
tb.adjustavailableTokens(tick)
|
||||
avail := tb.availableTokens - count
|
||||
if avail >= 0 {
|
||||
tb.availableTokens = avail
|
||||
return 0, true
|
||||
}
|
||||
// Round up the missing tokens to the nearest multiple
|
||||
// of quantum - the tokens won't be available until
|
||||
// that tick.
|
||||
|
||||
// endTick holds the tick when all the requested tokens will
|
||||
// become available.
|
||||
endTick := tick + (-avail+tb.quantum-1)/tb.quantum
|
||||
endTime := tb.startTime.Add(time.Duration(endTick) * tb.fillInterval)
|
||||
waitTime := endTime.Sub(now)
|
||||
if waitTime > maxWait {
|
||||
return 0, false
|
||||
}
|
||||
tb.availableTokens = avail
|
||||
return waitTime, true
|
||||
}
|
||||
|
||||
// currentTick returns the current time tick, measured
|
||||
// from tb.startTime.
|
||||
func (tb *Bucket) currentTick(now time.Time) int64 {
|
||||
return int64(now.Sub(tb.startTime) / tb.fillInterval)
|
||||
}
|
||||
|
||||
// adjustavailableTokens adjusts the current number of tokens
|
||||
// available in the bucket at the given time, which must
|
||||
// be in the future (positive) with respect to tb.latestTick.
|
||||
func (tb *Bucket) adjustavailableTokens(tick int64) {
|
||||
if tb.availableTokens >= tb.capacity {
|
||||
return
|
||||
}
|
||||
tb.availableTokens += (tick - tb.latestTick) * tb.quantum
|
||||
if tb.availableTokens > tb.capacity {
|
||||
tb.availableTokens = tb.capacity
|
||||
}
|
||||
tb.latestTick = tick
|
||||
return
|
||||
}
|
||||
|
||||
// Clock represents the passage of time in a way that
|
||||
// can be faked out for tests.
|
||||
type Clock interface {
|
||||
// Now returns the current time.
|
||||
Now() time.Time
|
||||
// Sleep sleeps for at least the given duration.
|
||||
Sleep(d time.Duration)
|
||||
}
|
||||
|
||||
// realClock implements Clock in terms of standard time functions.
|
||||
type realClock struct{}
|
||||
|
||||
// Now implements Clock.Now by calling time.Now.
|
||||
func (realClock) Now() time.Time {
|
||||
return time.Now()
|
||||
}
|
||||
|
||||
// Now implements Clock.Sleep by calling time.Sleep.
|
||||
func (realClock) Sleep(d time.Duration) {
|
||||
time.Sleep(d)
|
||||
}
|
||||
51
vendor/github.com/juju/ratelimit/reader.go
generated
vendored
Normal file
51
vendor/github.com/juju/ratelimit/reader.go
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright 2014 Canonical Ltd.
|
||||
// Licensed under the LGPLv3 with static-linking exception.
|
||||
// See LICENCE file for details.
|
||||
|
||||
package ratelimit
|
||||
|
||||
import "io"
|
||||
|
||||
type reader struct {
|
||||
r io.Reader
|
||||
bucket *Bucket
|
||||
}
|
||||
|
||||
// Reader returns a reader that is rate limited by
|
||||
// the given token bucket. Each token in the bucket
|
||||
// represents one byte.
|
||||
func Reader(r io.Reader, bucket *Bucket) io.Reader {
|
||||
return &reader{
|
||||
r: r,
|
||||
bucket: bucket,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *reader) Read(buf []byte) (int, error) {
|
||||
n, err := r.r.Read(buf)
|
||||
if n <= 0 {
|
||||
return n, err
|
||||
}
|
||||
r.bucket.Wait(int64(n))
|
||||
return n, err
|
||||
}
|
||||
|
||||
type writer struct {
|
||||
w io.Writer
|
||||
bucket *Bucket
|
||||
}
|
||||
|
||||
// Writer returns a reader that is rate limited by
|
||||
// the given token bucket. Each token in the bucket
|
||||
// represents one byte.
|
||||
func Writer(w io.Writer, bucket *Bucket) io.Writer {
|
||||
return &writer{
|
||||
w: w,
|
||||
bucket: bucket,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *writer) Write(buf []byte) (int, error) {
|
||||
w.bucket.Wait(int64(len(buf)))
|
||||
return w.w.Write(buf)
|
||||
}
|
||||
3
vendor/golang.org/x/sys/AUTHORS
generated
vendored
Normal file
3
vendor/golang.org/x/sys/AUTHORS
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# This source code refers to The Go Authors for copyright purposes.
|
||||
# The master list of authors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/AUTHORS.
|
||||
3
vendor/golang.org/x/sys/CONTRIBUTORS
generated
vendored
Normal file
3
vendor/golang.org/x/sys/CONTRIBUTORS
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# This source code was written by the Go contributors.
|
||||
# The master list of contributors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/CONTRIBUTORS.
|
||||
27
vendor/golang.org/x/sys/LICENSE
generated
vendored
Normal file
27
vendor/golang.org/x/sys/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
22
vendor/golang.org/x/sys/PATENTS
generated
vendored
Normal file
22
vendor/golang.org/x/sys/PATENTS
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
Additional IP Rights Grant (Patents)
|
||||
|
||||
"This implementation" means the copyrightable works distributed by
|
||||
Google as part of the Go project.
|
||||
|
||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||
patent license to make, have made, use, offer to sell, sell, import,
|
||||
transfer and otherwise run, modify and propagate the contents of this
|
||||
implementation of Go, where such license applies only to those patent
|
||||
claims, both currently owned or controlled by Google and acquired in
|
||||
the future, licensable by Google that are necessarily infringed by this
|
||||
implementation of Go. This grant does not include claims that would be
|
||||
infringed only as a consequence of further modification of this
|
||||
implementation. If you or your agent or exclusive licensee institute or
|
||||
order or agree to the institution of patent litigation against any
|
||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that this implementation of Go or any code incorporated within this
|
||||
implementation of Go constitutes direct or contributory patent
|
||||
infringement, or inducement of patent infringement, then any patent
|
||||
rights granted to you under this License for this implementation of Go
|
||||
shall terminate as of the date such litigation is filed.
|
||||
2
vendor/golang.org/x/sys/unix/.gitignore
generated
vendored
Normal file
2
vendor/golang.org/x/sys/unix/.gitignore
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
_obj/
|
||||
unix.test
|
||||
173
vendor/golang.org/x/sys/unix/README.md
generated
vendored
Normal file
173
vendor/golang.org/x/sys/unix/README.md
generated
vendored
Normal file
@ -0,0 +1,173 @@
|
||||
# Building `sys/unix`
|
||||
|
||||
The sys/unix package provides access to the raw system call interface of the
|
||||
underlying operating system. See: https://godoc.org/golang.org/x/sys/unix
|
||||
|
||||
Porting Go to a new architecture/OS combination or adding syscalls, types, or
|
||||
constants to an existing architecture/OS pair requires some manual effort;
|
||||
however, there are tools that automate much of the process.
|
||||
|
||||
## Build Systems
|
||||
|
||||
There are currently two ways we generate the necessary files. We are currently
|
||||
migrating the build system to use containers so the builds are reproducible.
|
||||
This is being done on an OS-by-OS basis. Please update this documentation as
|
||||
components of the build system change.
|
||||
|
||||
### Old Build System (currently for `GOOS != "Linux" || GOARCH == "sparc64"`)
|
||||
|
||||
The old build system generates the Go files based on the C header files
|
||||
present on your system. This means that files
|
||||
for a given GOOS/GOARCH pair must be generated on a system with that OS and
|
||||
architecture. This also means that the generated code can differ from system
|
||||
to system, based on differences in the header files.
|
||||
|
||||
To avoid this, if you are using the old build system, only generate the Go
|
||||
files on an installation with unmodified header files. It is also important to
|
||||
keep track of which version of the OS the files were generated from (ex.
|
||||
Darwin 14 vs Darwin 15). This makes it easier to track the progress of changes
|
||||
and have each OS upgrade correspond to a single change.
|
||||
|
||||
To build the files for your current OS and architecture, make sure GOOS and
|
||||
GOARCH are set correctly and run `mkall.sh`. This will generate the files for
|
||||
your specific system. Running `mkall.sh -n` shows the commands that will be run.
|
||||
|
||||
Requirements: bash, perl, go
|
||||
|
||||
### New Build System (currently for `GOOS == "Linux" && GOARCH != "sparc64"`)
|
||||
|
||||
The new build system uses a Docker container to generate the go files directly
|
||||
from source checkouts of the kernel and various system libraries. This means
|
||||
that on any platform that supports Docker, all the files using the new build
|
||||
system can be generated at once, and generated files will not change based on
|
||||
what the person running the scripts has installed on their computer.
|
||||
|
||||
The OS specific files for the new build system are located in the `${GOOS}`
|
||||
directory, and the build is coordinated by the `${GOOS}/mkall.go` program. When
|
||||
the kernel or system library updates, modify the Dockerfile at
|
||||
`${GOOS}/Dockerfile` to checkout the new release of the source.
|
||||
|
||||
To build all the files under the new build system, you must be on an amd64/Linux
|
||||
system and have your GOOS and GOARCH set accordingly. Running `mkall.sh` will
|
||||
then generate all of the files for all of the GOOS/GOARCH pairs in the new build
|
||||
system. Running `mkall.sh -n` shows the commands that will be run.
|
||||
|
||||
Requirements: bash, perl, go, docker
|
||||
|
||||
## Component files
|
||||
|
||||
This section describes the various files used in the code generation process.
|
||||
It also contains instructions on how to modify these files to add a new
|
||||
architecture/OS or to add additional syscalls, types, or constants. Note that
|
||||
if you are using the new build system, the scripts cannot be called normally.
|
||||
They must be called from within the docker container.
|
||||
|
||||
### asm files
|
||||
|
||||
The hand-written assembly file at `asm_${GOOS}_${GOARCH}.s` implements system
|
||||
call dispatch. There are three entry points:
|
||||
```
|
||||
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
||||
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
|
||||
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
||||
```
|
||||
The first and second are the standard ones; they differ only in how many
|
||||
arguments can be passed to the kernel. The third is for low-level use by the
|
||||
ForkExec wrapper. Unlike the first two, it does not call into the scheduler to
|
||||
let it know that a system call is running.
|
||||
|
||||
When porting Go to an new architecture/OS, this file must be implemented for
|
||||
each GOOS/GOARCH pair.
|
||||
|
||||
### mksysnum
|
||||
|
||||
Mksysnum is a script located at `${GOOS}/mksysnum.pl` (or `mksysnum_${GOOS}.pl`
|
||||
for the old system). This script takes in a list of header files containing the
|
||||
syscall number declarations and parses them to produce the corresponding list of
|
||||
Go numeric constants. See `zsysnum_${GOOS}_${GOARCH}.go` for the generated
|
||||
constants.
|
||||
|
||||
Adding new syscall numbers is mostly done by running the build on a sufficiently
|
||||
new installation of the target OS (or updating the source checkouts for the
|
||||
new build system). However, depending on the OS, you make need to update the
|
||||
parsing in mksysnum.
|
||||
|
||||
### mksyscall.pl
|
||||
|
||||
The `syscall.go`, `syscall_${GOOS}.go`, `syscall_${GOOS}_${GOARCH}.go` are
|
||||
hand-written Go files which implement system calls (for unix, the specific OS,
|
||||
or the specific OS/Architecture pair respectively) that need special handling
|
||||
and list `//sys` comments giving prototypes for ones that can be generated.
|
||||
|
||||
The mksyscall.pl script takes the `//sys` and `//sysnb` comments and converts
|
||||
them into syscalls. This requires the name of the prototype in the comment to
|
||||
match a syscall number in the `zsysnum_${GOOS}_${GOARCH}.go` file. The function
|
||||
prototype can be exported (capitalized) or not.
|
||||
|
||||
Adding a new syscall often just requires adding a new `//sys` function prototype
|
||||
with the desired arguments and a capitalized name so it is exported. However, if
|
||||
you want the interface to the syscall to be different, often one will make an
|
||||
unexported `//sys` prototype, an then write a custom wrapper in
|
||||
`syscall_${GOOS}.go`.
|
||||
|
||||
### types files
|
||||
|
||||
For each OS, there is a hand-written Go file at `${GOOS}/types.go` (or
|
||||
`types_${GOOS}.go` on the old system). This file includes standard C headers and
|
||||
creates Go type aliases to the corresponding C types. The file is then fed
|
||||
through godef to get the Go compatible definitions. Finally, the generated code
|
||||
is fed though mkpost.go to format the code correctly and remove any hidden or
|
||||
private identifiers. This cleaned-up code is written to
|
||||
`ztypes_${GOOS}_${GOARCH}.go`.
|
||||
|
||||
The hardest part about preparing this file is figuring out which headers to
|
||||
include and which symbols need to be `#define`d to get the actual data
|
||||
structures that pass through to the kernel system calls. Some C libraries
|
||||
preset alternate versions for binary compatibility and translate them on the
|
||||
way in and out of system calls, but there is almost always a `#define` that can
|
||||
get the real ones.
|
||||
See `types_darwin.go` and `linux/types.go` for examples.
|
||||
|
||||
To add a new type, add in the necessary include statement at the top of the
|
||||
file (if it is not already there) and add in a type alias line. Note that if
|
||||
your type is significantly different on different architectures, you may need
|
||||
some `#if/#elif` macros in your include statements.
|
||||
|
||||
### mkerrors.sh
|
||||
|
||||
This script is used to generate the system's various constants. This doesn't
|
||||
just include the error numbers and error strings, but also the signal numbers
|
||||
an a wide variety of miscellaneous constants. The constants come from the list
|
||||
of include files in the `includes_${uname}` variable. A regex then picks out
|
||||
the desired `#define` statements, and generates the corresponding Go constants.
|
||||
The error numbers and strings are generated from `#include <errno.h>`, and the
|
||||
signal numbers and strings are generated from `#include <signal.h>`. All of
|
||||
these constants are written to `zerrors_${GOOS}_${GOARCH}.go` via a C program,
|
||||
`_errors.c`, which prints out all the constants.
|
||||
|
||||
To add a constant, add the header that includes it to the appropriate variable.
|
||||
Then, edit the regex (if necessary) to match the desired constant. Avoid making
|
||||
the regex too broad to avoid matching unintended constants.
|
||||
|
||||
|
||||
## Generated files
|
||||
|
||||
### `zerror_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A file containing all of the system's generated error numbers, error strings,
|
||||
signal numbers, and constants. Generated by `mkerrors.sh` (see above).
|
||||
|
||||
### `zsyscall_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A file containing all the generated syscalls for a specific GOOS and GOARCH.
|
||||
Generated by `mksyscall.pl` (see above).
|
||||
|
||||
### `zsysnum_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A list of numeric constants for all the syscall number of the specific GOOS
|
||||
and GOARCH. Generated by mksysnum (see above).
|
||||
|
||||
### `ztypes_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A file containing Go types for passing into (or returning from) syscalls.
|
||||
Generated by godefs and the types file (see above).
|
||||
124
vendor/golang.org/x/sys/unix/affinity_linux.go
generated
vendored
Normal file
124
vendor/golang.org/x/sys/unix/affinity_linux.go
generated
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// CPU affinity functions
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const cpuSetSize = _CPU_SETSIZE / _NCPUBITS
|
||||
|
||||
// CPUSet represents a CPU affinity mask.
|
||||
type CPUSet [cpuSetSize]cpuMask
|
||||
|
||||
func schedAffinity(trap uintptr, pid int, set *CPUSet) error {
|
||||
_, _, e := RawSyscall(trap, uintptr(pid), uintptr(unsafe.Sizeof(*set)), uintptr(unsafe.Pointer(set)))
|
||||
if e != 0 {
|
||||
return errnoErr(e)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SchedGetaffinity gets the CPU affinity mask of the thread specified by pid.
|
||||
// If pid is 0 the calling thread is used.
|
||||
func SchedGetaffinity(pid int, set *CPUSet) error {
|
||||
return schedAffinity(SYS_SCHED_GETAFFINITY, pid, set)
|
||||
}
|
||||
|
||||
// SchedSetaffinity sets the CPU affinity mask of the thread specified by pid.
|
||||
// If pid is 0 the calling thread is used.
|
||||
func SchedSetaffinity(pid int, set *CPUSet) error {
|
||||
return schedAffinity(SYS_SCHED_SETAFFINITY, pid, set)
|
||||
}
|
||||
|
||||
// Zero clears the set s, so that it contains no CPUs.
|
||||
func (s *CPUSet) Zero() {
|
||||
for i := range s {
|
||||
s[i] = 0
|
||||
}
|
||||
}
|
||||
|
||||
func cpuBitsIndex(cpu int) int {
|
||||
return cpu / _NCPUBITS
|
||||
}
|
||||
|
||||
func cpuBitsMask(cpu int) cpuMask {
|
||||
return cpuMask(1 << (uint(cpu) % _NCPUBITS))
|
||||
}
|
||||
|
||||
// Set adds cpu to the set s.
|
||||
func (s *CPUSet) Set(cpu int) {
|
||||
i := cpuBitsIndex(cpu)
|
||||
if i < len(s) {
|
||||
s[i] |= cpuBitsMask(cpu)
|
||||
}
|
||||
}
|
||||
|
||||
// Clear removes cpu from the set s.
|
||||
func (s *CPUSet) Clear(cpu int) {
|
||||
i := cpuBitsIndex(cpu)
|
||||
if i < len(s) {
|
||||
s[i] &^= cpuBitsMask(cpu)
|
||||
}
|
||||
}
|
||||
|
||||
// IsSet reports whether cpu is in the set s.
|
||||
func (s *CPUSet) IsSet(cpu int) bool {
|
||||
i := cpuBitsIndex(cpu)
|
||||
if i < len(s) {
|
||||
return s[i]&cpuBitsMask(cpu) != 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Count returns the number of CPUs in the set s.
|
||||
func (s *CPUSet) Count() int {
|
||||
c := 0
|
||||
for _, b := range s {
|
||||
c += onesCount64(uint64(b))
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// onesCount64 is a copy of Go 1.9's math/bits.OnesCount64.
|
||||
// Once this package can require Go 1.9, we can delete this
|
||||
// and update the caller to use bits.OnesCount64.
|
||||
func onesCount64(x uint64) int {
|
||||
const m0 = 0x5555555555555555 // 01010101 ...
|
||||
const m1 = 0x3333333333333333 // 00110011 ...
|
||||
const m2 = 0x0f0f0f0f0f0f0f0f // 00001111 ...
|
||||
const m3 = 0x00ff00ff00ff00ff // etc.
|
||||
const m4 = 0x0000ffff0000ffff
|
||||
|
||||
// Implementation: Parallel summing of adjacent bits.
|
||||
// See "Hacker's Delight", Chap. 5: Counting Bits.
|
||||
// The following pattern shows the general approach:
|
||||
//
|
||||
// x = x>>1&(m0&m) + x&(m0&m)
|
||||
// x = x>>2&(m1&m) + x&(m1&m)
|
||||
// x = x>>4&(m2&m) + x&(m2&m)
|
||||
// x = x>>8&(m3&m) + x&(m3&m)
|
||||
// x = x>>16&(m4&m) + x&(m4&m)
|
||||
// x = x>>32&(m5&m) + x&(m5&m)
|
||||
// return int(x)
|
||||
//
|
||||
// Masking (& operations) can be left away when there's no
|
||||
// danger that a field's sum will carry over into the next
|
||||
// field: Since the result cannot be > 64, 8 bits is enough
|
||||
// and we can ignore the masks for the shifts by 8 and up.
|
||||
// Per "Hacker's Delight", the first line can be simplified
|
||||
// more, but it saves at best one instruction, so we leave
|
||||
// it alone for clarity.
|
||||
const m = 1<<64 - 1
|
||||
x = x>>1&(m0&m) + x&(m0&m)
|
||||
x = x>>2&(m1&m) + x&(m1&m)
|
||||
x = (x>>4 + x) & (m2 & m)
|
||||
x += x >> 8
|
||||
x += x >> 16
|
||||
x += x >> 32
|
||||
return int(x) & (1<<7 - 1)
|
||||
}
|
||||
14
vendor/golang.org/x/sys/unix/aliases.go
generated
vendored
Normal file
14
vendor/golang.org/x/sys/unix/aliases.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
// +build go1.9
|
||||
|
||||
package unix
|
||||
|
||||
import "syscall"
|
||||
|
||||
type Signal = syscall.Signal
|
||||
type Errno = syscall.Errno
|
||||
type SysProcAttr = syscall.SysProcAttr
|
||||
29
vendor/golang.org/x/sys/unix/asm_darwin_386.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_darwin_386.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for 386, Darwin
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
29
vendor/golang.org/x/sys/unix/asm_darwin_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_darwin_amd64.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for AMD64, Darwin
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
30
vendor/golang.org/x/sys/unix/asm_darwin_arm.s
generated
vendored
Normal file
30
vendor/golang.org/x/sys/unix/asm_darwin_arm.s
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
// +build arm,darwin
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for ARM, Darwin
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
B syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
B syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
B syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·RawSyscall6(SB)
|
||||
30
vendor/golang.org/x/sys/unix/asm_darwin_arm64.s
generated
vendored
Normal file
30
vendor/golang.org/x/sys/unix/asm_darwin_arm64.s
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
// +build arm64,darwin
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for AMD64, Darwin
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
B syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
B syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
B syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
B syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
B syscall·RawSyscall6(SB)
|
||||
29
vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for AMD64, DragonFly
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
29
vendor/golang.org/x/sys/unix/asm_freebsd_386.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_freebsd_386.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for 386, FreeBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
29
vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for AMD64, FreeBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
29
vendor/golang.org/x/sys/unix/asm_freebsd_arm.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_freebsd_arm.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for ARM, FreeBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
B syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
B syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
B syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·RawSyscall6(SB)
|
||||
65
vendor/golang.org/x/sys/unix/asm_linux_386.s
generated
vendored
Normal file
65
vendor/golang.org/x/sys/unix/asm_linux_386.s
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for 386, Linux
|
||||
//
|
||||
|
||||
// See ../runtime/sys_linux_386.s for the reason why we always use int 0x80
|
||||
// instead of the glibc-specific "CALL 0x10(GS)".
|
||||
#define INVOKE_SYSCALL INT $0x80
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-24
|
||||
CALL runtime·entersyscall(SB)
|
||||
MOVL trap+0(FP), AX // syscall entry
|
||||
MOVL a1+4(FP), BX
|
||||
MOVL a2+8(FP), CX
|
||||
MOVL a3+12(FP), DX
|
||||
MOVL $0, SI
|
||||
MOVL $0, DI
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, r1+16(FP)
|
||||
MOVL DX, r2+20(FP)
|
||||
CALL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24
|
||||
MOVL trap+0(FP), AX // syscall entry
|
||||
MOVL a1+4(FP), BX
|
||||
MOVL a2+8(FP), CX
|
||||
MOVL a3+12(FP), DX
|
||||
MOVL $0, SI
|
||||
MOVL $0, DI
|
||||
INVOKE_SYSCALL
|
||||
MOVL AX, r1+16(FP)
|
||||
MOVL DX, r2+20(FP)
|
||||
RET
|
||||
|
||||
TEXT ·socketcall(SB),NOSPLIT,$0-36
|
||||
JMP syscall·socketcall(SB)
|
||||
|
||||
TEXT ·rawsocketcall(SB),NOSPLIT,$0-36
|
||||
JMP syscall·rawsocketcall(SB)
|
||||
|
||||
TEXT ·seek(SB),NOSPLIT,$0-28
|
||||
JMP syscall·seek(SB)
|
||||
57
vendor/golang.org/x/sys/unix/asm_linux_amd64.s
generated
vendored
Normal file
57
vendor/golang.org/x/sys/unix/asm_linux_amd64.s
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for AMD64, Linux
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
||||
CALL runtime·entersyscall(SB)
|
||||
MOVQ a1+8(FP), DI
|
||||
MOVQ a2+16(FP), SI
|
||||
MOVQ a3+24(FP), DX
|
||||
MOVQ $0, R10
|
||||
MOVQ $0, R8
|
||||
MOVQ $0, R9
|
||||
MOVQ trap+0(FP), AX // syscall entry
|
||||
SYSCALL
|
||||
MOVQ AX, r1+32(FP)
|
||||
MOVQ DX, r2+40(FP)
|
||||
CALL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
||||
MOVQ a1+8(FP), DI
|
||||
MOVQ a2+16(FP), SI
|
||||
MOVQ a3+24(FP), DX
|
||||
MOVQ $0, R10
|
||||
MOVQ $0, R8
|
||||
MOVQ $0, R9
|
||||
MOVQ trap+0(FP), AX // syscall entry
|
||||
SYSCALL
|
||||
MOVQ AX, r1+32(FP)
|
||||
MOVQ DX, r2+40(FP)
|
||||
RET
|
||||
|
||||
TEXT ·gettimeofday(SB),NOSPLIT,$0-16
|
||||
JMP syscall·gettimeofday(SB)
|
||||
56
vendor/golang.org/x/sys/unix/asm_linux_arm.s
generated
vendored
Normal file
56
vendor/golang.org/x/sys/unix/asm_linux_arm.s
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for arm, Linux
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
B syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-24
|
||||
BL runtime·entersyscall(SB)
|
||||
MOVW trap+0(FP), R7
|
||||
MOVW a1+4(FP), R0
|
||||
MOVW a2+8(FP), R1
|
||||
MOVW a3+12(FP), R2
|
||||
MOVW $0, R3
|
||||
MOVW $0, R4
|
||||
MOVW $0, R5
|
||||
SWI $0
|
||||
MOVW R0, r1+16(FP)
|
||||
MOVW $0, R0
|
||||
MOVW R0, r2+20(FP)
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
B syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24
|
||||
MOVW trap+0(FP), R7 // syscall entry
|
||||
MOVW a1+4(FP), R0
|
||||
MOVW a2+8(FP), R1
|
||||
MOVW a3+12(FP), R2
|
||||
SWI $0
|
||||
MOVW R0, r1+16(FP)
|
||||
MOVW $0, R0
|
||||
MOVW R0, r2+20(FP)
|
||||
RET
|
||||
|
||||
TEXT ·seek(SB),NOSPLIT,$0-28
|
||||
B syscall·seek(SB)
|
||||
52
vendor/golang.org/x/sys/unix/asm_linux_arm64.s
generated
vendored
Normal file
52
vendor/golang.org/x/sys/unix/asm_linux_arm64.s
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux
|
||||
// +build arm64
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
B syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
B syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
||||
BL runtime·entersyscall(SB)
|
||||
MOVD a1+8(FP), R0
|
||||
MOVD a2+16(FP), R1
|
||||
MOVD a3+24(FP), R2
|
||||
MOVD $0, R3
|
||||
MOVD $0, R4
|
||||
MOVD $0, R5
|
||||
MOVD trap+0(FP), R8 // syscall entry
|
||||
SVC
|
||||
MOVD R0, r1+32(FP) // r1
|
||||
MOVD R1, r2+40(FP) // r2
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
B syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
B syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
||||
MOVD a1+8(FP), R0
|
||||
MOVD a2+16(FP), R1
|
||||
MOVD a3+24(FP), R2
|
||||
MOVD $0, R3
|
||||
MOVD $0, R4
|
||||
MOVD $0, R5
|
||||
MOVD trap+0(FP), R8 // syscall entry
|
||||
SVC
|
||||
MOVD R0, r1+32(FP)
|
||||
MOVD R1, r2+40(FP)
|
||||
RET
|
||||
56
vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
generated
vendored
Normal file
56
vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux
|
||||
// +build mips64 mips64le
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for mips64, Linux
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
||||
JAL runtime·entersyscall(SB)
|
||||
MOVV a1+8(FP), R4
|
||||
MOVV a2+16(FP), R5
|
||||
MOVV a3+24(FP), R6
|
||||
MOVV R0, R7
|
||||
MOVV R0, R8
|
||||
MOVV R0, R9
|
||||
MOVV trap+0(FP), R2 // syscall entry
|
||||
SYSCALL
|
||||
MOVV R2, r1+32(FP)
|
||||
MOVV R3, r2+40(FP)
|
||||
JAL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
||||
MOVV a1+8(FP), R4
|
||||
MOVV a2+16(FP), R5
|
||||
MOVV a3+24(FP), R6
|
||||
MOVV R0, R7
|
||||
MOVV R0, R8
|
||||
MOVV R0, R9
|
||||
MOVV trap+0(FP), R2 // syscall entry
|
||||
SYSCALL
|
||||
MOVV R2, r1+32(FP)
|
||||
MOVV R3, r2+40(FP)
|
||||
RET
|
||||
54
vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
generated
vendored
Normal file
54
vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux
|
||||
// +build mips mipsle
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for mips, Linux
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-24
|
||||
JAL runtime·entersyscall(SB)
|
||||
MOVW a1+4(FP), R4
|
||||
MOVW a2+8(FP), R5
|
||||
MOVW a3+12(FP), R6
|
||||
MOVW R0, R7
|
||||
MOVW trap+0(FP), R2 // syscall entry
|
||||
SYSCALL
|
||||
MOVW R2, r1+16(FP) // r1
|
||||
MOVW R3, r2+20(FP) // r2
|
||||
JAL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24
|
||||
MOVW a1+4(FP), R4
|
||||
MOVW a2+8(FP), R5
|
||||
MOVW a3+12(FP), R6
|
||||
MOVW trap+0(FP), R2 // syscall entry
|
||||
SYSCALL
|
||||
MOVW R2, r1+16(FP)
|
||||
MOVW R3, r2+20(FP)
|
||||
RET
|
||||
56
vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
generated
vendored
Normal file
56
vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux
|
||||
// +build ppc64 ppc64le
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for ppc64, Linux
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
BR syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
BR syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
||||
BL runtime·entersyscall(SB)
|
||||
MOVD a1+8(FP), R3
|
||||
MOVD a2+16(FP), R4
|
||||
MOVD a3+24(FP), R5
|
||||
MOVD R0, R6
|
||||
MOVD R0, R7
|
||||
MOVD R0, R8
|
||||
MOVD trap+0(FP), R9 // syscall entry
|
||||
SYSCALL R9
|
||||
MOVD R3, r1+32(FP)
|
||||
MOVD R4, r2+40(FP)
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
BR syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
BR syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
||||
MOVD a1+8(FP), R3
|
||||
MOVD a2+16(FP), R4
|
||||
MOVD a3+24(FP), R5
|
||||
MOVD R0, R6
|
||||
MOVD R0, R7
|
||||
MOVD R0, R8
|
||||
MOVD trap+0(FP), R9 // syscall entry
|
||||
SYSCALL R9
|
||||
MOVD R3, r1+32(FP)
|
||||
MOVD R4, r2+40(FP)
|
||||
RET
|
||||
56
vendor/golang.org/x/sys/unix/asm_linux_s390x.s
generated
vendored
Normal file
56
vendor/golang.org/x/sys/unix/asm_linux_s390x.s
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build s390x
|
||||
// +build linux
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for s390x, Linux
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
BR syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
BR syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
||||
BL runtime·entersyscall(SB)
|
||||
MOVD a1+8(FP), R2
|
||||
MOVD a2+16(FP), R3
|
||||
MOVD a3+24(FP), R4
|
||||
MOVD $0, R5
|
||||
MOVD $0, R6
|
||||
MOVD $0, R7
|
||||
MOVD trap+0(FP), R1 // syscall entry
|
||||
SYSCALL
|
||||
MOVD R2, r1+32(FP)
|
||||
MOVD R3, r2+40(FP)
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
BR syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
BR syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
||||
MOVD a1+8(FP), R2
|
||||
MOVD a2+16(FP), R3
|
||||
MOVD a3+24(FP), R4
|
||||
MOVD $0, R5
|
||||
MOVD $0, R6
|
||||
MOVD $0, R7
|
||||
MOVD trap+0(FP), R1 // syscall entry
|
||||
SYSCALL
|
||||
MOVD R2, r1+32(FP)
|
||||
MOVD R3, r2+40(FP)
|
||||
RET
|
||||
29
vendor/golang.org/x/sys/unix/asm_netbsd_386.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_netbsd_386.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for 386, NetBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
29
vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for AMD64, NetBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
29
vendor/golang.org/x/sys/unix/asm_netbsd_arm.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_netbsd_arm.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for ARM, NetBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
B syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
B syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
B syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·RawSyscall6(SB)
|
||||
29
vendor/golang.org/x/sys/unix/asm_openbsd_386.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_openbsd_386.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for 386, OpenBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
29
vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for AMD64, OpenBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
29
vendor/golang.org/x/sys/unix/asm_openbsd_arm.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_openbsd_arm.s
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for ARM, OpenBSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
B syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
B syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
B syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·RawSyscall6(SB)
|
||||
17
vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
generated
vendored
Normal file
17
vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go
|
||||
//
|
||||
|
||||
TEXT ·sysvicall6(SB),NOSPLIT,$0-88
|
||||
JMP syscall·sysvicall6(SB)
|
||||
|
||||
TEXT ·rawSysvicall6(SB),NOSPLIT,$0-88
|
||||
JMP syscall·rawSysvicall6(SB)
|
||||
35
vendor/golang.org/x/sys/unix/bluetooth_linux.go
generated
vendored
Normal file
35
vendor/golang.org/x/sys/unix/bluetooth_linux.go
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Bluetooth sockets and messages
|
||||
|
||||
package unix
|
||||
|
||||
// Bluetooth Protocols
|
||||
const (
|
||||
BTPROTO_L2CAP = 0
|
||||
BTPROTO_HCI = 1
|
||||
BTPROTO_SCO = 2
|
||||
BTPROTO_RFCOMM = 3
|
||||
BTPROTO_BNEP = 4
|
||||
BTPROTO_CMTP = 5
|
||||
BTPROTO_HIDP = 6
|
||||
BTPROTO_AVDTP = 7
|
||||
)
|
||||
|
||||
const (
|
||||
HCI_CHANNEL_RAW = 0
|
||||
HCI_CHANNEL_USER = 1
|
||||
HCI_CHANNEL_MONITOR = 2
|
||||
HCI_CHANNEL_CONTROL = 3
|
||||
)
|
||||
|
||||
// Socketoption Level
|
||||
const (
|
||||
SOL_BLUETOOTH = 0x112
|
||||
SOL_HCI = 0x0
|
||||
SOL_L2CAP = 0x6
|
||||
SOL_RFCOMM = 0x12
|
||||
SOL_SCO = 0x11
|
||||
)
|
||||
195
vendor/golang.org/x/sys/unix/cap_freebsd.go
generated
vendored
Normal file
195
vendor/golang.org/x/sys/unix/cap_freebsd.go
generated
vendored
Normal file
@ -0,0 +1,195 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build freebsd
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Go implementation of C mostly found in /usr/src/sys/kern/subr_capability.c
|
||||
|
||||
const (
|
||||
// This is the version of CapRights this package understands. See C implementation for parallels.
|
||||
capRightsGoVersion = CAP_RIGHTS_VERSION_00
|
||||
capArSizeMin = CAP_RIGHTS_VERSION_00 + 2
|
||||
capArSizeMax = capRightsGoVersion + 2
|
||||
)
|
||||
|
||||
var (
|
||||
bit2idx = []int{
|
||||
-1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1,
|
||||
4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
}
|
||||
)
|
||||
|
||||
func capidxbit(right uint64) int {
|
||||
return int((right >> 57) & 0x1f)
|
||||
}
|
||||
|
||||
func rightToIndex(right uint64) (int, error) {
|
||||
idx := capidxbit(right)
|
||||
if idx < 0 || idx >= len(bit2idx) {
|
||||
return -2, fmt.Errorf("index for right 0x%x out of range", right)
|
||||
}
|
||||
return bit2idx[idx], nil
|
||||
}
|
||||
|
||||
func caprver(right uint64) int {
|
||||
return int(right >> 62)
|
||||
}
|
||||
|
||||
func capver(rights *CapRights) int {
|
||||
return caprver(rights.Rights[0])
|
||||
}
|
||||
|
||||
func caparsize(rights *CapRights) int {
|
||||
return capver(rights) + 2
|
||||
}
|
||||
|
||||
// CapRightsSet sets the permissions in setrights in rights.
|
||||
func CapRightsSet(rights *CapRights, setrights []uint64) error {
|
||||
// This is essentially a copy of cap_rights_vset()
|
||||
if capver(rights) != CAP_RIGHTS_VERSION_00 {
|
||||
return fmt.Errorf("bad rights version %d", capver(rights))
|
||||
}
|
||||
|
||||
n := caparsize(rights)
|
||||
if n < capArSizeMin || n > capArSizeMax {
|
||||
return errors.New("bad rights size")
|
||||
}
|
||||
|
||||
for _, right := range setrights {
|
||||
if caprver(right) != CAP_RIGHTS_VERSION_00 {
|
||||
return errors.New("bad right version")
|
||||
}
|
||||
i, err := rightToIndex(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if i >= n {
|
||||
return errors.New("index overflow")
|
||||
}
|
||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
||||
return errors.New("index mismatch")
|
||||
}
|
||||
rights.Rights[i] |= right
|
||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
||||
return errors.New("index mismatch (after assign)")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CapRightsClear clears the permissions in clearrights from rights.
|
||||
func CapRightsClear(rights *CapRights, clearrights []uint64) error {
|
||||
// This is essentially a copy of cap_rights_vclear()
|
||||
if capver(rights) != CAP_RIGHTS_VERSION_00 {
|
||||
return fmt.Errorf("bad rights version %d", capver(rights))
|
||||
}
|
||||
|
||||
n := caparsize(rights)
|
||||
if n < capArSizeMin || n > capArSizeMax {
|
||||
return errors.New("bad rights size")
|
||||
}
|
||||
|
||||
for _, right := range clearrights {
|
||||
if caprver(right) != CAP_RIGHTS_VERSION_00 {
|
||||
return errors.New("bad right version")
|
||||
}
|
||||
i, err := rightToIndex(right)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if i >= n {
|
||||
return errors.New("index overflow")
|
||||
}
|
||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
||||
return errors.New("index mismatch")
|
||||
}
|
||||
rights.Rights[i] &= ^(right & 0x01FFFFFFFFFFFFFF)
|
||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
||||
return errors.New("index mismatch (after assign)")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CapRightsIsSet checks whether all the permissions in setrights are present in rights.
|
||||
func CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) {
|
||||
// This is essentially a copy of cap_rights_is_vset()
|
||||
if capver(rights) != CAP_RIGHTS_VERSION_00 {
|
||||
return false, fmt.Errorf("bad rights version %d", capver(rights))
|
||||
}
|
||||
|
||||
n := caparsize(rights)
|
||||
if n < capArSizeMin || n > capArSizeMax {
|
||||
return false, errors.New("bad rights size")
|
||||
}
|
||||
|
||||
for _, right := range setrights {
|
||||
if caprver(right) != CAP_RIGHTS_VERSION_00 {
|
||||
return false, errors.New("bad right version")
|
||||
}
|
||||
i, err := rightToIndex(right)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if i >= n {
|
||||
return false, errors.New("index overflow")
|
||||
}
|
||||
if capidxbit(rights.Rights[i]) != capidxbit(right) {
|
||||
return false, errors.New("index mismatch")
|
||||
}
|
||||
if (rights.Rights[i] & right) != right {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func capright(idx uint64, bit uint64) uint64 {
|
||||
return ((1 << (57 + idx)) | bit)
|
||||
}
|
||||
|
||||
// CapRightsInit returns a pointer to an initialised CapRights structure filled with rights.
|
||||
// See man cap_rights_init(3) and rights(4).
|
||||
func CapRightsInit(rights []uint64) (*CapRights, error) {
|
||||
var r CapRights
|
||||
r.Rights[0] = (capRightsGoVersion << 62) | capright(0, 0)
|
||||
r.Rights[1] = capright(1, 0)
|
||||
|
||||
err := CapRightsSet(&r, rights)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
// CapRightsLimit reduces the operations permitted on fd to at most those contained in rights.
|
||||
// The capability rights on fd can never be increased by CapRightsLimit.
|
||||
// See man cap_rights_limit(2) and rights(4).
|
||||
func CapRightsLimit(fd uintptr, rights *CapRights) error {
|
||||
return capRightsLimit(int(fd), rights)
|
||||
}
|
||||
|
||||
// CapRightsGet returns a CapRights structure containing the operations permitted on fd.
|
||||
// See man cap_rights_get(3) and rights(4).
|
||||
func CapRightsGet(fd uintptr) (*CapRights, error) {
|
||||
r, err := CapRightsInit(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = capRightsGet(capRightsGoVersion, int(fd), r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
13
vendor/golang.org/x/sys/unix/constants.go
generated
vendored
Normal file
13
vendor/golang.org/x/sys/unix/constants.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
R_OK = 0x4
|
||||
W_OK = 0x2
|
||||
X_OK = 0x1
|
||||
)
|
||||
27
vendor/golang.org/x/sys/unix/dev_aix_ppc.go
generated
vendored
Normal file
27
vendor/golang.org/x/sys/unix/dev_aix_ppc.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix
|
||||
// +build ppc
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used by AIX.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of a Linux device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
return uint32((dev >> 16) & 0xffff)
|
||||
}
|
||||
|
||||
// Minor returns the minor component of a Linux device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
return uint32(dev & 0xffff)
|
||||
}
|
||||
|
||||
// Mkdev returns a Linux device number generated from the given major and minor
|
||||
// components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
return uint64(((major) << 16) | (minor))
|
||||
}
|
||||
29
vendor/golang.org/x/sys/unix/dev_aix_ppc64.go
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/dev_aix_ppc64.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix
|
||||
// +build ppc64
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used AIX.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of a Linux device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
return uint32((dev & 0x3fffffff00000000) >> 32)
|
||||
}
|
||||
|
||||
// Minor returns the minor component of a Linux device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
return uint32((dev & 0x00000000ffffffff) >> 0)
|
||||
}
|
||||
|
||||
// Mkdev returns a Linux device number generated from the given major and minor
|
||||
// components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
var DEVNO64 uint64
|
||||
DEVNO64 = 0x8000000000000000
|
||||
return ((uint64(major) << 32) | (uint64(minor) & 0x00000000FFFFFFFF) | DEVNO64)
|
||||
}
|
||||
24
vendor/golang.org/x/sys/unix/dev_darwin.go
generated
vendored
Normal file
24
vendor/golang.org/x/sys/unix/dev_darwin.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used in Darwin's sys/types.h header.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of a Darwin device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
return uint32((dev >> 24) & 0xff)
|
||||
}
|
||||
|
||||
// Minor returns the minor component of a Darwin device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
return uint32(dev & 0xffffff)
|
||||
}
|
||||
|
||||
// Mkdev returns a Darwin device number generated from the given major and minor
|
||||
// components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
return (uint64(major) << 24) | uint64(minor)
|
||||
}
|
||||
30
vendor/golang.org/x/sys/unix/dev_dragonfly.go
generated
vendored
Normal file
30
vendor/golang.org/x/sys/unix/dev_dragonfly.go
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used in Dragonfly's sys/types.h header.
|
||||
//
|
||||
// The information below is extracted and adapted from sys/types.h:
|
||||
//
|
||||
// Minor gives a cookie instead of an index since in order to avoid changing the
|
||||
// meanings of bits 0-15 or wasting time and space shifting bits 16-31 for
|
||||
// devices that don't use them.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of a DragonFlyBSD device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
return uint32((dev >> 8) & 0xff)
|
||||
}
|
||||
|
||||
// Minor returns the minor component of a DragonFlyBSD device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
return uint32(dev & 0xffff00ff)
|
||||
}
|
||||
|
||||
// Mkdev returns a DragonFlyBSD device number generated from the given major and
|
||||
// minor components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
return (uint64(major) << 8) | uint64(minor)
|
||||
}
|
||||
30
vendor/golang.org/x/sys/unix/dev_freebsd.go
generated
vendored
Normal file
30
vendor/golang.org/x/sys/unix/dev_freebsd.go
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used in FreeBSD's sys/types.h header.
|
||||
//
|
||||
// The information below is extracted and adapted from sys/types.h:
|
||||
//
|
||||
// Minor gives a cookie instead of an index since in order to avoid changing the
|
||||
// meanings of bits 0-15 or wasting time and space shifting bits 16-31 for
|
||||
// devices that don't use them.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of a FreeBSD device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
return uint32((dev >> 8) & 0xff)
|
||||
}
|
||||
|
||||
// Minor returns the minor component of a FreeBSD device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
return uint32(dev & 0xffff00ff)
|
||||
}
|
||||
|
||||
// Mkdev returns a FreeBSD device number generated from the given major and
|
||||
// minor components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
return (uint64(major) << 8) | uint64(minor)
|
||||
}
|
||||
42
vendor/golang.org/x/sys/unix/dev_linux.go
generated
vendored
Normal file
42
vendor/golang.org/x/sys/unix/dev_linux.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used by the Linux kernel and glibc.
|
||||
//
|
||||
// The information below is extracted and adapted from bits/sysmacros.h in the
|
||||
// glibc sources:
|
||||
//
|
||||
// dev_t in glibc is 64-bit, with 32-bit major and minor numbers. glibc's
|
||||
// default encoding is MMMM Mmmm mmmM MMmm, where M is a hex digit of the major
|
||||
// number and m is a hex digit of the minor number. This is backward compatible
|
||||
// with legacy systems where dev_t is 16 bits wide, encoded as MMmm. It is also
|
||||
// backward compatible with the Linux kernel, which for some architectures uses
|
||||
// 32-bit dev_t, encoded as mmmM MMmm.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of a Linux device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
major := uint32((dev & 0x00000000000fff00) >> 8)
|
||||
major |= uint32((dev & 0xfffff00000000000) >> 32)
|
||||
return major
|
||||
}
|
||||
|
||||
// Minor returns the minor component of a Linux device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
minor := uint32((dev & 0x00000000000000ff) >> 0)
|
||||
minor |= uint32((dev & 0x00000ffffff00000) >> 12)
|
||||
return minor
|
||||
}
|
||||
|
||||
// Mkdev returns a Linux device number generated from the given major and minor
|
||||
// components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
dev := (uint64(major) & 0x00000fff) << 8
|
||||
dev |= (uint64(major) & 0xfffff000) << 32
|
||||
dev |= (uint64(minor) & 0x000000ff) << 0
|
||||
dev |= (uint64(minor) & 0xffffff00) << 12
|
||||
return dev
|
||||
}
|
||||
29
vendor/golang.org/x/sys/unix/dev_netbsd.go
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/dev_netbsd.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used in NetBSD's sys/types.h header.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of a NetBSD device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
return uint32((dev & 0x000fff00) >> 8)
|
||||
}
|
||||
|
||||
// Minor returns the minor component of a NetBSD device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
minor := uint32((dev & 0x000000ff) >> 0)
|
||||
minor |= uint32((dev & 0xfff00000) >> 12)
|
||||
return minor
|
||||
}
|
||||
|
||||
// Mkdev returns a NetBSD device number generated from the given major and minor
|
||||
// components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
dev := (uint64(major) << 8) & 0x000fff00
|
||||
dev |= (uint64(minor) << 12) & 0xfff00000
|
||||
dev |= (uint64(minor) << 0) & 0x000000ff
|
||||
return dev
|
||||
}
|
||||
29
vendor/golang.org/x/sys/unix/dev_openbsd.go
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/dev_openbsd.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used in OpenBSD's sys/types.h header.
|
||||
|
||||
package unix
|
||||
|
||||
// Major returns the major component of an OpenBSD device number.
|
||||
func Major(dev uint64) uint32 {
|
||||
return uint32((dev & 0x0000ff00) >> 8)
|
||||
}
|
||||
|
||||
// Minor returns the minor component of an OpenBSD device number.
|
||||
func Minor(dev uint64) uint32 {
|
||||
minor := uint32((dev & 0x000000ff) >> 0)
|
||||
minor |= uint32((dev & 0xffff0000) >> 8)
|
||||
return minor
|
||||
}
|
||||
|
||||
// Mkdev returns an OpenBSD device number generated from the given major and minor
|
||||
// components.
|
||||
func Mkdev(major, minor uint32) uint64 {
|
||||
dev := (uint64(major) << 8) & 0x0000ff00
|
||||
dev |= (uint64(minor) << 8) & 0xffff0000
|
||||
dev |= (uint64(minor) << 0) & 0x000000ff
|
||||
return dev
|
||||
}
|
||||
17
vendor/golang.org/x/sys/unix/dirent.go
generated
vendored
Normal file
17
vendor/golang.org/x/sys/unix/dirent.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux nacl netbsd openbsd solaris
|
||||
|
||||
package unix
|
||||
|
||||
import "syscall"
|
||||
|
||||
// ParseDirent parses up to max directory entries in buf,
|
||||
// appending the names to names. It returns the number of
|
||||
// bytes consumed from buf, the number of entries added
|
||||
// to names, and the new names slice.
|
||||
func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
|
||||
return syscall.ParseDirent(buf, max, names)
|
||||
}
|
||||
9
vendor/golang.org/x/sys/unix/endian_big.go
generated
vendored
Normal file
9
vendor/golang.org/x/sys/unix/endian_big.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
//
|
||||
// +build ppc64 s390x mips mips64
|
||||
|
||||
package unix
|
||||
|
||||
const isBigEndian = true
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user