From 42a9d102dd3aeba48bd0091ec0870a7de12a29d9 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 9 Mar 2017 19:44:40 +0100 Subject: [PATCH 1/4] Remove gost itself from vendored packages --- vendor/github.com/ginuerzh/gost/LICENSE | 21 - vendor/github.com/ginuerzh/gost/README.md | 358 --------- vendor/github.com/ginuerzh/gost/README_en.md | 362 --------- vendor/github.com/ginuerzh/gost/chain.go | 473 ----------- vendor/github.com/ginuerzh/gost/conn.go | 292 ------- vendor/github.com/ginuerzh/gost/forward.go | 689 ---------------- vendor/github.com/ginuerzh/gost/gost.go | 162 ---- vendor/github.com/ginuerzh/gost/http.go | 410 ---------- vendor/github.com/ginuerzh/gost/kcp.go | 408 ---------- vendor/github.com/ginuerzh/gost/node.go | 161 ---- vendor/github.com/ginuerzh/gost/quic.go | 81 -- vendor/github.com/ginuerzh/gost/redirect.go | 103 --- .../github.com/ginuerzh/gost/redirect_win.go | 17 - vendor/github.com/ginuerzh/gost/server.go | 284 ------- vendor/github.com/ginuerzh/gost/signal.go | 5 - .../github.com/ginuerzh/gost/signal_unix.go | 23 - vendor/github.com/ginuerzh/gost/socks.go | 746 ------------------ vendor/github.com/ginuerzh/gost/ss.go | 353 --------- vendor/github.com/ginuerzh/gost/ssh.go | 236 ------ vendor/github.com/ginuerzh/gost/ws.go | 142 ---- vendor/vendor.json | 6 - 21 files changed, 5332 deletions(-) delete mode 100644 vendor/github.com/ginuerzh/gost/LICENSE delete mode 100644 vendor/github.com/ginuerzh/gost/README.md delete mode 100644 vendor/github.com/ginuerzh/gost/README_en.md delete mode 100644 vendor/github.com/ginuerzh/gost/chain.go delete mode 100644 vendor/github.com/ginuerzh/gost/conn.go delete mode 100644 vendor/github.com/ginuerzh/gost/forward.go delete mode 100644 vendor/github.com/ginuerzh/gost/gost.go delete mode 100644 vendor/github.com/ginuerzh/gost/http.go delete mode 100644 vendor/github.com/ginuerzh/gost/kcp.go delete mode 100644 vendor/github.com/ginuerzh/gost/node.go delete mode 100644 vendor/github.com/ginuerzh/gost/quic.go delete mode 100644 vendor/github.com/ginuerzh/gost/redirect.go delete mode 100644 vendor/github.com/ginuerzh/gost/redirect_win.go delete mode 100644 vendor/github.com/ginuerzh/gost/server.go delete mode 100644 vendor/github.com/ginuerzh/gost/signal.go delete mode 100644 vendor/github.com/ginuerzh/gost/signal_unix.go delete mode 100644 vendor/github.com/ginuerzh/gost/socks.go delete mode 100644 vendor/github.com/ginuerzh/gost/ss.go delete mode 100644 vendor/github.com/ginuerzh/gost/ssh.go delete mode 100644 vendor/github.com/ginuerzh/gost/ws.go diff --git a/vendor/github.com/ginuerzh/gost/LICENSE b/vendor/github.com/ginuerzh/gost/LICENSE deleted file mode 100644 index 2033b3a..0000000 --- a/vendor/github.com/ginuerzh/gost/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 ginuerzh - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/ginuerzh/gost/README.md b/vendor/github.com/ginuerzh/gost/README.md deleted file mode 100644 index 3b8eb53..0000000 --- a/vendor/github.com/ginuerzh/gost/README.md +++ /dev/null @@ -1,358 +0,0 @@ -gost - GO Simple Tunnel -====== - -### GO语言实现的安全隧道 - -[English README](README_en.md) - -特性 ------- -* 可同时监听多端口 -* 可设置转发代理,支持多级转发(代理链) -* 支持标准HTTP/HTTPS/SOCKS4(A)/SOCKS5代理协议 -* SOCKS5代理支持TLS协商加密 -* Tunnel UDP over TCP -* 支持Shadowsocks协议 (OTA: 2.2+,UDP: 2.4+) -* 支持本地/远程端口转发 (2.1+) -* 支持HTTP 2.0 (2.2+) -* 实验性支持QUIC (2.3+) -* 支持KCP协议 (2.3+) -* 透明代理 (2.3+) -* SSH隧道 (2.4+) - -二进制文件下载:https://github.com/ginuerzh/gost/releases - -Google讨论组: https://groups.google.com/d/forum/go-gost - -在gost中,gost与其他代理服务都被看作是代理节点,gost可以自己处理请求,或者将请求转发给任意一个或多个代理节点。 - -参数说明 ------- -#### 代理及代理链 - -适用于-L和-F参数 - -```bash -[scheme://][user:pass@host]:port -``` -scheme分为两部分: protocol+transport - -protocol: 代理协议类型(http, socks4(a), socks5, shadowsocks), transport: 数据传输方式(ws, wss, tls, http2, quic, kcp, pht), 二者可以任意组合,或单独使用: - -> http - HTTP代理: http://:8080 - -> http+tls - HTTPS代理(可能需要提供受信任的证书): http+tls://:443或https://:443 - -> http2 - HTTP2代理并向下兼容HTTPS代理: http2://:443 - -> socks4(a) - 标准SOCKS4(A)代理: socks4://:1080或socks4a://:1080 - -> socks - 标准SOCKS5代理(支持TLS协商加密): socks://:1080 - -> socks+wss - SOCKS5代理,使用websocket传输数据: socks+wss://:1080 - -> tls - HTTPS/SOCKS5代理,使用TLS传输数据: tls://:443 - -> ss - Shadowsocks代理,ss://chacha20:123456@:8338 - -> ssu - Shadowsocks UDP relay,ssu://chacha20:123456@:8338 - -> quic - QUIC代理,quic://:6121 - -> kcp - KCP通道,kcp://:8388或kcp://aes:123456@:8388 - -> pht - 普通HTTP通道,pht://:8080 - -> redirect - 透明代理,redirect://:12345 - -> ssh - SSH转发隧道,ssh://admin:123456@:2222 - -#### 端口转发 - -适用于-L参数 - -```bash -scheme://[bind_address]:port/[host]:hostport -``` -> scheme - 端口转发模式, 本地端口转发: tcp, udp; 远程端口转发: rtcp, rudp - -> bind_address:port - 本地/远程绑定地址 - -> host:hostport - 目标访问地址 - -#### 配置文件 - -> -C : 指定配置文件路径 - -配置文件为标准json格式: -```json -{ - "ServeNodes": [ - ":8080", - "ss://chacha20:12345678@:8338" - ], - "ChainNodes": [ - "http://192.168.1.1:8080", - "https://10.0.2.1:443" - ] -} -``` - -ServeNodes等同于-L参数,ChainNodes等同于-F参数 - -#### 开启日志 - -> -logtostderr : 输出到控制台 - -> -v=3 : 日志级别(1-5),级别越高,日志越详细(级别5将开启http2 debug) - -> -log_dir=/log/dir/path : 输出到目录/log/dir/path - - -使用方法 ------- -#### 不设置转发代理 - - - -* 作为标准HTTP/SOCKS5代理 -```bash -gost -L=:8080 -``` - -* 设置代理认证信息 -```bash -gost -L=admin:123456@localhost:8080 -``` - -* 多组认证信息 -```bash -gost -L=localhost:8080?secrets=secrets.txt -``` - -通过secrets参数可以为HTTP/SOCKS5代理设置多组认证信息,格式为: -```plain -# username password - -test001 123456 -test002 12345678 -``` - -* 多端口监听 -```bash -gost -L=http2://:443 -L=socks://:1080 -L=ss://aes-128-cfb:123456@:8338 -``` - -#### 设置转发代理 - - -```bash -gost -L=:8080 -F=192.168.1.1:8081 -``` - -* 转发代理认证 -```bash -gost -L=:8080 -F=http://admin:123456@192.168.1.1:8081 -``` - -#### 设置多级转发代理(代理链) - - -```bash -gost -L=:8080 -F=http+tls://192.168.1.1:443 -F=socks+ws://192.168.1.2:1080 -F=ss://aes-128-cfb:123456@192.168.1.3:8338 -F=a.b.c.d:NNNN -``` -gost按照-F设置的顺序通过代理链将请求最终转发给a.b.c.d:NNNN处理,每一个转发代理可以是任意HTTP/HTTPS/HTTP2/SOCKS5/Shadowsocks类型代理。 - -#### 本地端口转发(TCP) - -```bash -gost -L=tcp://:2222/192.168.1.1:22 -F=... -``` -将本地TCP端口2222上的数据(通过代理链)转发到192.168.1.1:22上。当代理链末端(最后一个-F参数)为SSH类型时,gost会直接使用SSH的本地端口转发功能。 -#### 本地端口转发(UDP) - -```bash -gost -L=udp://:5353/192.168.1.1:53?ttl=60 -F=... -``` -将本地UDP端口5353上的数据(通过代理链)转发到192.168.1.1:53上。 -每条转发通道都有超时时间,当超过此时间,且在此时间段内无任何数据交互,则此通道将关闭。可以通过`ttl`参数来设置超时时间,默认值为60秒。 - -**注:** 转发UDP数据时,如果有代理链,则代理链的末端(最后一个-F参数)必须是gost SOCKS5类型代理。 - -#### 远程端口转发(TCP) - -```bash -gost -L=rtcp://:2222/192.168.1.1:22 -F=... -F=socks://172.24.10.1:1080 -``` -将172.24.10.1:2222上的数据(通过代理链)转发到192.168.1.1:22上。当代理链末端(最后一个-F参数)为SSH类型时,gost会直接使用SSH的远程端口转发功能。 - -#### 远程端口转发(UDP) - -```bash -gost -L=rudp://:5353/192.168.1.1:53 -F=... -F=socks://172.24.10.1:1080 -``` -将172.24.10.1:5353上的数据(通过代理链)转发到192.168.1.1:53上。 - -**注:** 若要使用远程端口转发功能,代理链不能为空(至少要设置一个-F参数),且代理链的末端(最后一个-F参数)必须是gost SOCKS5类型代理。 - -#### HTTP2 -gost的HTTP2支持两种模式并自适应: -* 作为标准的HTTP2代理,并向下兼容HTTPS代理。 -* 作为transport(类似于wss),传输其他协议。 - -服务端: -```bash -gost -L=http2://:443 -``` -客户端: -```bash -gost -L=:8080 -F=http2://server_ip:443?ping=30 -``` - -客户端支持`ping`参数开启心跳检测(默认不开启),参数值代表心跳间隔秒数。 - -**注:** gost的代理链仅支持一个HTTP2代理节点,采用就近原则,会将第一个遇到的HTTP2代理节点视为HTTP2代理,其他HTTP2代理节点则被视为HTTPS代理。 - -#### QUIC -gost对QUIC的支持是基于[quic-go](https://github.com/lucas-clemente/quic-go)库。 - -服务端: -```bash -gost -L=quic://:6121 -``` - -客户端(Chrome): -```bash -chrome --enable-quic --proxy-server=quic://server_ip:6121 -``` - -**注:** 由于Chrome自身的限制,目前只能通过QUIC访问HTTP网站,无法访问HTTPS网站。 - -#### KCP -gost对KCP的支持是基于[kcp-go](https://github.com/xtaci/kcp-go)和[kcptun](https://github.com/xtaci/kcptun)库。 - -服务端: -```bash -gost -L=kcp://:8388 -``` - -客户端: -```bash -gost -L=:8080 -F=kcp://server_ip:8388 -``` - -或者手动指定加密方法和密码(手动指定的加密方法和密码会覆盖配置文件中的相应值) - -服务端: -```bash -gost -L=kcp://aes:123456@:8388 -``` - -客户端: -```bash -gost -L=:8080 -F=kcp://aes:123456@server_ip:8388 -``` - -gost会自动加载当前工作目录中的kcp.json(如果存在)配置文件,或者可以手动通过参数指定配置文件路径: -```bash -gost -L=kcp://:8388?c=/path/to/conf/file -``` - -**注:** 客户端若要开启KCP转发,当且仅当代理链不为空且首个代理节点(第一个-F参数)为kcp类型。 - -#### 透明代理 -基于iptables的透明代理。 - -```bash -gost -L=redirect://:12345 -F=http2://server_ip:443 -``` - -加密机制 ------- -#### HTTP -对于HTTP可以使用TLS加密整个通讯过程,即HTTPS代理: - -服务端: -```bash -gost -L=http+tls://:443 -``` -客户端: -```bash -gost -L=:8080 -F=http+tls://server_ip:443 -``` - -#### HTTP2 -gost仅支持使用TLS加密的HTTP2协议,不支持明文HTTP2传输。 - - -#### SOCKS5 -gost支持标准SOCKS5协议的no-auth(0x00)和user/pass(0x02)方法,并在此基础上扩展了两个:tls(0x80)和tls-auth(0x82),用于数据加密。 - -服务端: -```bash -gost -L=socks://:1080 -``` -客户端: -```bash -gost -L=:8080 -F=socks://server_ip:1080 -``` - -如果两端都是gost(如上)则数据传输会被加密(协商使用tls或tls-auth方法),否则使用标准SOCKS5进行通讯(no-auth或user/pass方法)。 - -**注:** 如果transport已经支持加密(wss, tls, http2, kcp),则SOCKS5不会再使用加密方法,防止不必要的双重加密。 - -#### Shadowsocks -gost对shadowsocks的支持是基于[shadowsocks-go](https://github.com/shadowsocks/shadowsocks-go)库。 - -服务端(可以通过ota参数开启OTA强制模式,开启后客户端必须使用OTA模式): -```bash -gost -L=ss://aes-128-cfb:123456@:8338?ota=1 -``` -客户端(可以通过ota参数开启OTA模式): -```bash -gost -L=:8080 -F=ss://aes-128-cfb:123456@server_ip:8338?ota=1 -``` - -##### Shadowsocks UDP relay - -目前仅服务端支持UDP,且仅支持OTA模式。 - -服务端: -```bash -gost -L=ssu://aes-128-cfb:123456@:8338 -``` - -#### TLS -gost内置了TLS证书,如果需要使用其他TLS证书,有两种方法: -* 在gost运行目录放置cert.pem(公钥)和key.pem(私钥)两个文件即可,gost会自动加载运行目录下的cert.pem和key.pem文件。 -* 使用参数指定证书文件路径: -```bash -gost -L="http2://:443?cert=/path/to/my/cert/file&key=/path/to/my/key/file" -``` - -SOCKS5 UDP数据处理 ------- -#### 不设置转发代理 - - - -gost作为标准SOCKS5代理处理UDP数据 - -#### 设置转发代理 - - - -#### 设置多个转发代理(代理链) - - - -当设置转发代理时,gost会使用UDP-over-TCP方式转发UDP数据。proxy1 - proxyN可以为任意HTTP/HTTPS/HTTP2/SOCKS5/Shadowsocks类型代理。 - -限制条件 ------- -代理链中的HTTP代理节点必须支持CONNECT方法。 - -如果要转发SOCKS5的BIND和UDP请求,代理链的末端(最后一个-F参数)必须支持gost SOCKS5类型代理。 - - - diff --git a/vendor/github.com/ginuerzh/gost/README_en.md b/vendor/github.com/ginuerzh/gost/README_en.md deleted file mode 100644 index 6c8e7e3..0000000 --- a/vendor/github.com/ginuerzh/gost/README_en.md +++ /dev/null @@ -1,362 +0,0 @@ -gost - GO Simple Tunnel -====== - -### A simple security tunnel written in Golang - -Features ------- -* Listening on multiple ports -* Multi-level forward proxy - proxy chain -* Standard HTTP/HTTPS/SOCKS4(A)/SOCKS5 proxy protocols support -* TLS encryption via negotiation support for SOCKS5 proxy -* Tunnel UDP over TCP -* Shadowsocks protocol support (OTA: 2.2+, UDP: 2.4+) -* Local/remote port forwarding (2.1+) -* HTTP 2.0 support (2.2+) -* Experimental QUIC support (2.3+) -* KCP protocol support (2.3+) -* Transparent proxy (2.3+) -* SSH tunnel (2.4+) - -Binary file download:https://github.com/ginuerzh/gost/releases - -Google group: https://groups.google.com/d/forum/go-gost - -Gost and other proxy services are considered to be proxy nodes, -gost can handle the request itself, or forward the request to any one or more proxy nodes. - -Parameter Description ------- -#### Proxy and proxy chain - -Effective for the -L and -F parameters - -```bash -[scheme://][user:pass@host]:port -``` -scheme can be divided into two parts: protocol+transport - -protocol: proxy protocol types (http, socks4(a), socks5, shadowsocks), -transport: data transmission mode (ws, wss, tls, http2, quic, kcp, pht), may be used in any combination or individually: - -> http - standard HTTP proxy: http://:8080 - -> http+tls - standard HTTPS proxy (may need to provide a trusted certificate): http+tls://:443 or https://:443 - -> http2 - HTTP2 proxy and backwards-compatible with HTTPS proxy: http2://:443 - -> socks4(a) - standard SOCKS4(A) proxy: socks4://:1080 or socks4a://:1080 - -> socks - standard SOCKS5 proxy: socks://:1080 - -> socks+wss - SOCKS5 over websocket: socks+wss://:1080 - -> tls - HTTPS/SOCKS5 over TLS: tls://:443 - -> ss - standard shadowsocks proxy, ss://chacha20:123456@:8338 - -> ssu - shadowsocks UDP relay,ssu://chacha20:123456@:8338 - -> quic - standard QUIC proxy, quic://:6121 - -> kcp - standard KCP tunnel,kcp://:8388 or kcp://aes:123456@:8388 - -> pht - plain HTTP tunnel, pht://:8080 - -> redirect - transparent proxy,redirect://:12345 - -> ssh - SSH tunnel, ssh://admin:123456@:2222 - -#### Port forwarding - -Effective for the -L parameter - -```bash -scheme://[bind_address]:port/[host]:hostport -``` -> scheme - forward mode, local: tcp, udp; remote: rtcp, rudp - -> bind_address:port - local/remote binding address - -> host:hostport - target address - -#### Configuration file - -> -C : specifies the configuration file path - -The configuration file is in standard JSON format: -```json -{ - "ServeNodes": [ - ":8080", - "ss://chacha20:12345678@:8338" - ], - "ChainNodes": [ - "http://192.168.1.1:8080", - "https://10.0.2.1:443" - ] -} -``` - -ServeNodes is equivalent to the -L parameter, ChainNodes is equivalent to the -F parameter. - -#### Logging - -> -logtostderr : log to console - -> -v=3 : log level (1-5),The higher the level, the more detailed the log (level 5 will enable HTTP2 debug) - -> -log_dir=/log/dir/path : log to directory /log/dir/path - -Usage ------- -#### No forward proxy - - - -* Standard HTTP/SOCKS5 proxy -```bash -gost -L=:8080 -``` - -* Proxy authentication -```bash -gost -L=admin:123456@localhost:8080 -``` - -* Multiple sets of authentication information -```bash -gost -L=localhost:8080?secrets=secrets.txt -``` - -The secrets parameter allows you to set multiple authentication information for HTTP/SOCKS5 proxies, the format is: -```plain -# username password - -test001 123456 -test002 12345678 -``` - -* Listen on multiple ports -```bash -gost -L=http2://:443 -L=socks://:1080 -L=ss://aes-128-cfb:123456@:8338 -``` - -#### Forward proxy - - -```bash -gost -L=:8080 -F=192.168.1.1:8081 -``` - -* Forward proxy authentication -```bash -gost -L=:8080 -F=http://admin:123456@192.168.1.1:8081 -``` - -#### Multi-level forward proxy - - -```bash -gost -L=:8080 -F=http+tls://192.168.1.1:443 -F=socks+ws://192.168.1.2:1080 -F=ss://aes-128-cfb:123456@192.168.1.3:8338 -F=a.b.c.d:NNNN -``` -Gost forwards the request to a.b.c.d:NNNN through the proxy chain in the order set by -F, -each forward proxy can be any HTTP/HTTPS/HTTP2/SOCKS5/Shadowsocks type. - -#### Local TCP port forwarding - -```bash -gost -L=tcp://:2222/192.168.1.1:22 -F=... -``` -The data on the local TCP port 2222 is forwarded to 192.168.1.1:22 (through the proxy chain). If the last node of the chain (the last -F parameter) is a SSH tunnel, then gost will use the local port forwarding function of SSH directly. - -#### Local UDP port forwarding - -```bash -gost -L=udp://:5353/192.168.1.1:53?ttl=60 -F=... -``` -The data on the local UDP port 5353 is forwarded to 192.168.1.1:53 (through the proxy chain). -Each forwarding channel has a timeout period. When this time is exceeded and there is no data interaction during this time period, the channel will be closed. The timeout value can be set by the `ttl` parameter. The default value is 60 seconds. - -**NOTE:** When forwarding UDP data, if there is a proxy chain, the end of the chain (the last -F parameter) must be gost SOCKS5 proxy. - -#### Remote TCP port forwarding - -```bash -gost -L=rtcp://:2222/192.168.1.1:22 -F=... -F=socks://172.24.10.1:1080 -``` -The data on 172.24.10.1:2222 is forwarded to 192.168.1.1:22 (through the proxy chain). If the last node of the chain (the last -F parameter) is a SSH tunnel, then gost will use the remote port forwarding function of SSH directly. - -#### Remote UDP port forwarding - -```bash -gost -L=rudp://:5353/192.168.1.1:53 -F=... -F=socks://172.24.10.1:1080 -``` -The data on 172.24.10.1:5353 is forwarded to 192.168.1.1:53 (through the proxy chain). - -**NOTE:** To use the remote port forwarding feature, the proxy chain can not be empty (at least one -F parameter is set) -and the end of the chain (last -F parameter) must be gost SOCKS5 proxy. - -#### HTTP2 -Gost HTTP2 supports two modes and self-adapting: -* As a standard HTTP2 proxy, and backwards-compatible with the HTTPS proxy. -* As transport (similar to wss), tunnel other protocol. - -Server: -```bash -gost -L=http2://:443 -``` -Client: -```bash -gost -L=:8080 -F=http2://server_ip:443?ping=30 -``` - -The client supports the `ping` parameter to enable heartbeat detection (which is disabled by default). -Parameter value represents heartbeat interval seconds. - -**NOTE:** The proxy chain of gost supports only one HTTP2 proxy node and the nearest rule applies, -the first HTTP2 proxy node is treated as an HTTP2 proxy, and the other HTTP2 proxy nodes are treated as HTTPS proxies. - -#### QUIC -Support for QUIC is based on library [quic-go](https://github.com/lucas-clemente/quic-go). - -Server: -```bash -gost -L=quic://:6121 -``` -Client(Chrome): -```bash -chrome --enable-quic --proxy-server=quic://server_ip:6121 -``` - -**NOTE:** Due to Chrome's limitations, it is currently only possible to access the HTTP (but not HTTPS) site through QUIC. - -#### KCP -Support for KCP is based on libraries [kcp-go](https://github.com/xtaci/kcp-go) and [kcptun](https://github.com/xtaci/kcptun). - -Server: -```bash -gost -L=kcp://:8388 -``` -Client: -```bash -gost -L=:8080 -F=kcp://server_ip:8388 -``` - -Or manually specify the encryption method and password (Manually specifying the encryption method and password overwrites the corresponding value in the configuration file) - -Server: -```bash -gost -L=kcp://aes:123456@:8388 -``` - -Client: -```bash -gost -L=:8080 -F=kcp://aes:123456@server_ip:8388 -``` - -Gost will automatically load kcp.json configuration file from current working directory if exists, -or you can use the parameter to specify the path to the file. -```bash -gost -L=kcp://:8388?c=/path/to/conf/file -``` - -**NOTE:** KCP will be enabled if and only if the proxy chain is not empty and the first proxy node (the first -F parameter) is of type KCP. - -#### Transparent proxy -Iptables-based transparent proxy - -```bash -gost -L=redirect://:12345 -F=http2://server_ip:443 -``` - -Encryption Mechanism ------- -#### HTTP -For HTTP, you can use TLS to encrypt the entire communication process, the HTTPS proxy: - -Server: -```bash -gost -L=http+tls://:443 -``` -Client: -```bash -gost -L=:8080 -F=http+tls://server_ip:443 -``` - -#### HTTP2 -Gost supports only the HTTP2 protocol that uses TLS encryption (h2) and does not support plaintext HTTP2 (h2c) transport. - - -#### SOCKS5 -Gost supports the standard SOCKS5 protocol methods: no-auth (0x00) and user/pass (0x02), -and extends two methods for data encryption: tls(0x80) and tls-auth(0x82). - -Server: -```bash -gost -L=socks://:1080 -``` -Client: -```bash -gost -L=:8080 -F=socks://server_ip:1080 -``` - -If both ends are gosts (as example above), the data transfer will be encrypted (using tls or tls-auth). -Otherwise, use standard SOCKS5 for communication (no-auth or user/pass). - -**NOTE:** If transport already supports encryption (wss, tls, http2, kcp), SOCKS5 will no longer use the encryption method to prevent unnecessary double encryption. - -#### Shadowsocks -Support for shadowsocks is based on library [shadowsocks-go](https://github.com/shadowsocks/shadowsocks-go). - -Server (The OTA mode can be enabled by the ota parameter. When enabled, the client must use OTA mode): -```bash -gost -L=ss://aes-128-cfb:123456@:8338?ota=1 -``` -Client (The OTA mode can be enabled by the ota parameter): -```bash -gost -L=:8080 -F=ss://aes-128-cfb:123456@server_ip:8338?ota=1 -``` - -##### Shadowsocks UDP relay -Currently, only the server supports UDP, and only OTA mode is supported. - -Server: -```bash -gost -L=ssu://aes-128-cfb:123456@:8338 -``` - -#### TLS -There is built-in TLS certificate in gost, if you need to use other TLS certificate, there are two ways: -* Place two files cert.pem (public key) and key.pem (private key) in the current working directory, gost will automatically load them. -* Use the parameter to specify the path to the certificate file: -```bash -gost -L="http2://:443?cert=/path/to/my/cert/file&key=/path/to/my/key/file" -``` - -SOCKS5 UDP Data Processing ------- -#### No forward proxy - - - -Gost acts as the standard SOCKS5 proxy for UDP relay. - -#### Forward proxy - - - -#### Multi-level forward proxy - - - -When forward proxies are set, gost uses UDP-over-TCP to forward UDP data, proxy1 to proxyN can be any HTTP/HTTPS/HTTP2/SOCKS5/Shadowsocks type. - -Limitation ------- -The HTTP proxy node in the proxy chain must support the CONNECT method. - -If the BIND and UDP requests for SOCKS5 are to be forwarded, the end of the chain (the last -F parameter) must be the gost SOCKS5 proxy. - - - diff --git a/vendor/github.com/ginuerzh/gost/chain.go b/vendor/github.com/ginuerzh/gost/chain.go deleted file mode 100644 index 306c697..0000000 --- a/vendor/github.com/ginuerzh/gost/chain.go +++ /dev/null @@ -1,473 +0,0 @@ -package gost - -import ( - "crypto/rand" - "crypto/tls" - "encoding/base64" - "errors" - "github.com/ginuerzh/pht" - "github.com/golang/glog" - "github.com/lucas-clemente/quic-go/h2quic" - "golang.org/x/net/http2" - "io" - "net" - "net/http" - "net/http/httputil" - "net/url" - "strconv" - "strings" - "sync" - "time" -) - -// Proxy chain holds a list of proxy nodes -type ProxyChain struct { - nodes []ProxyNode - lastNode *ProxyNode - http2NodeIndex int - http2Enabled bool - http2Client *http.Client - kcpEnabled bool - kcpConfig *KCPConfig - kcpSession *KCPSession - kcpMutex sync.Mutex - phtClient *pht.Client - quicClient *http.Client -} - -func NewProxyChain(nodes ...ProxyNode) *ProxyChain { - chain := &ProxyChain{nodes: nodes, http2NodeIndex: -1} - return chain -} - -func (c *ProxyChain) AddProxyNode(node ...ProxyNode) { - c.nodes = append(c.nodes, node...) -} - -func (c *ProxyChain) AddProxyNodeString(snode ...string) error { - for _, sn := range snode { - node, err := ParseProxyNode(sn) - if err != nil { - return err - } - c.AddProxyNode(node) - } - return nil -} - -func (c *ProxyChain) Nodes() []ProxyNode { - return c.nodes -} - -func (c *ProxyChain) GetNode(index int) *ProxyNode { - if index < len(c.nodes) { - return &c.nodes[index] - } - return nil -} - -func (c *ProxyChain) SetNode(index int, node ProxyNode) { - if index < len(c.nodes) { - c.nodes[index] = node - } -} - -// Init initialize the proxy chain. -// KCP will be enabled if the first proxy node is KCP proxy (transport == kcp). -// HTTP2 will be enabled when at least one HTTP2 proxy node (scheme == http2) is present. -// -// NOTE: Should be called immediately when proxy nodes are ready. -func (c *ProxyChain) Init() { - length := len(c.nodes) - if length == 0 { - return - } - - c.lastNode = &c.nodes[length-1] - - // HTTP2 restrict: HTTP2 will be enabled when at least one HTTP2 proxy node is present. - for i, node := range c.nodes { - if node.Transport == "http2" { - glog.V(LINFO).Infoln("HTTP2 is enabled") - cfg := &tls.Config{ - InsecureSkipVerify: node.insecureSkipVerify(), - ServerName: node.serverName, - } - c.http2NodeIndex = i - c.initHttp2Client(cfg, c.nodes[:i]...) - break // shortest chain for HTTP2 - } - } - - for i, node := range c.nodes { - if (node.Transport == "kcp" || node.Transport == "pht" || node.Transport == "quic") && i > 0 { - glog.Fatal("KCP/PHT/QUIC must be the first node in the proxy chain") - } - } - - if c.nodes[0].Transport == "kcp" { - glog.V(LINFO).Infoln("KCP is enabled") - c.kcpEnabled = true - config, err := ParseKCPConfig(c.nodes[0].Get("c")) - if err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - if config == nil { - config = DefaultKCPConfig - } - if c.nodes[0].Users != nil { - config.Crypt = c.nodes[0].Users[0].Username() - config.Key, _ = c.nodes[0].Users[0].Password() - } - c.kcpConfig = config - go snmpLogger(config.SnmpLog, config.SnmpPeriod) - go kcpSigHandler() - - return - } - - if c.nodes[0].Transport == "quic" { - glog.V(LINFO).Infoln("QUIC is enabled") - c.quicClient = &http.Client{ - Transport: &h2quic.QuicRoundTripper{ - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: c.nodes[0].insecureSkipVerify(), - ServerName: c.nodes[0].serverName, - }, - }, - } - } - - if c.nodes[0].Transport == "pht" { - glog.V(LINFO).Infoln("Pure HTTP mode is enabled") - c.phtClient = pht.NewClient(c.nodes[0].Addr, c.nodes[0].Get("key")) - } -} - -func (c *ProxyChain) KCPEnabled() bool { - return c.kcpEnabled -} - -func (c *ProxyChain) Http2Enabled() bool { - return c.http2Enabled -} - -func (c *ProxyChain) initHttp2Client(config *tls.Config, nodes ...ProxyNode) { - if c.http2NodeIndex < 0 || c.http2NodeIndex >= len(c.nodes) { - return - } - http2Node := c.nodes[c.http2NodeIndex] - - tr := http2.Transport{ - TLSClientConfig: config, - DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { - // replace the default dialer with our proxy chain. - conn, err := c.dialWithNodes(false, http2Node.Addr, nodes...) - if err != nil { - return conn, err - } - conn = tls.Client(conn, cfg) - - // enable HTTP2 ping-pong - pingIntvl, _ := strconv.Atoi(http2Node.Get("ping")) - if pingIntvl > 0 { - enablePing(conn, time.Duration(pingIntvl)*time.Second) - } - - return conn, nil - }, - } - c.http2Client = &http.Client{Transport: &tr} - c.http2Enabled = true - -} - -func enablePing(conn net.Conn, interval time.Duration) { - if conn == nil || interval == 0 { - return - } - - glog.V(LINFO).Infoln("[http2] ping enabled, interval:", interval) - go func() { - t := time.NewTicker(interval) - var framer *http2.Framer - for { - select { - case <-t.C: - if framer == nil { - framer = http2.NewFramer(conn, conn) - } - - var p [8]byte - rand.Read(p[:]) - err := framer.WritePing(false, p) - if err != nil { - t.Stop() - framer = nil - glog.V(LWARNING).Infoln("[http2] ping:", err) - return - } - } - } - }() -} - -// Connect to addr through proxy chain -func (c *ProxyChain) Dial(addr string) (net.Conn, error) { - if !strings.Contains(addr, ":") { - addr += ":80" - } - return c.dialWithNodes(true, addr, c.nodes...) -} - -// GetConn initializes a proxy chain connection, -// if no proxy nodes on this chain, it will return error -func (c *ProxyChain) GetConn() (net.Conn, error) { - nodes := c.nodes - if len(nodes) == 0 { - return nil, ErrEmptyChain - } - - if c.Http2Enabled() { - nodes = nodes[c.http2NodeIndex+1:] - if len(nodes) == 0 { - header := make(http.Header) - header.Set("Proxy-Switch", "gost") // Flag header to indicate server to switch to HTTP2 transport mode - conn, err := c.getHttp2Conn(header) - if err != nil { - return nil, err - } - http2Node := c.nodes[c.http2NodeIndex] - if http2Node.Transport == "http2" { - http2Node.Transport = "h2" - } - if http2Node.Protocol == "http2" { - http2Node.Protocol = "socks5" // assume it as socks5 protocol, so we can do much more things. - } - pc := NewProxyConn(conn, http2Node) - if err := pc.Handshake(); err != nil { - conn.Close() - return nil, err - } - return pc, nil - } - } - return c.travelNodes(true, nodes...) -} - -func (c *ProxyChain) dialWithNodes(withHttp2 bool, addr string, nodes ...ProxyNode) (conn net.Conn, err error) { - if len(nodes) == 0 { - return net.DialTimeout("tcp", addr, DialTimeout) - } - - if withHttp2 && c.Http2Enabled() { - nodes = nodes[c.http2NodeIndex+1:] - if len(nodes) == 0 { - return c.http2Connect(addr) - } - } - - if nodes[0].Transport == "quic" { - glog.V(LINFO).Infoln("Dial with QUIC") - return c.quicConnect(addr) - } - - pc, err := c.travelNodes(withHttp2, nodes...) - if err != nil { - return - } - if err = pc.Connect(addr); err != nil { - pc.Close() - return - } - conn = pc - return -} - -func (c *ProxyChain) travelNodes(withHttp2 bool, nodes ...ProxyNode) (conn *ProxyConn, err error) { - defer func() { - if err != nil && conn != nil { - conn.Close() - conn = nil - } - }() - - var cc net.Conn - node := nodes[0] - - if withHttp2 && c.Http2Enabled() { - cc, err = c.http2Connect(node.Addr) - } else if node.Transport == "kcp" { - cc, err = c.getKCPConn() - } else if node.Transport == "pht" { - cc, err = c.phtClient.Dial() - } else { - cc, err = net.DialTimeout("tcp", node.Addr, DialTimeout) - } - if err != nil { - return - } - setKeepAlive(cc, KeepAliveTime) - - pc := NewProxyConn(cc, node) - conn = pc - if err = pc.Handshake(); err != nil { - return - } - - for _, node := range nodes[1:] { - if err = conn.Connect(node.Addr); err != nil { - return - } - pc := NewProxyConn(conn, node) - conn = pc - if err = pc.Handshake(); err != nil { - return - } - } - return -} - -func (c *ProxyChain) initKCPSession() (err error) { - c.kcpMutex.Lock() - defer c.kcpMutex.Unlock() - - if c.kcpSession == nil || c.kcpSession.IsClosed() { - glog.V(LINFO).Infoln("[kcp] new kcp session") - c.kcpSession, err = DialKCP(c.nodes[0].Addr, c.kcpConfig) - } - return -} - -func (c *ProxyChain) getKCPConn() (conn net.Conn, err error) { - if !c.KCPEnabled() { - return nil, errors.New("KCP is not enabled") - } - - if err = c.initKCPSession(); err != nil { - return nil, err - } - return c.kcpSession.GetConn() -} - -// Initialize an HTTP2 transport if HTTP2 is enabled. -func (c *ProxyChain) getHttp2Conn(header http.Header) (net.Conn, error) { - if !c.Http2Enabled() { - return nil, errors.New("HTTP2 is not enabled") - } - http2Node := c.nodes[c.http2NodeIndex] - pr, pw := io.Pipe() - - if header == nil { - header = make(http.Header) - } - - req := http.Request{ - Method: http.MethodConnect, - URL: &url.URL{Scheme: "https", Host: http2Node.Addr}, - Header: header, - Proto: "HTTP/2.0", - ProtoMajor: 2, - ProtoMinor: 0, - Body: pr, - Host: http2Node.Addr, - ContentLength: -1, - } - if glog.V(LDEBUG) { - dump, _ := httputil.DumpRequest(&req, false) - glog.Infoln(string(dump)) - } - resp, err := c.http2Client.Do(&req) - if err != nil { - return nil, err - } - if glog.V(LDEBUG) { - dump, _ := httputil.DumpResponse(resp, false) - glog.Infoln(string(dump)) - } - if resp.StatusCode != http.StatusOK { - resp.Body.Close() - return nil, errors.New(resp.Status) - } - conn := &http2Conn{r: resp.Body, w: pw} - conn.remoteAddr, _ = net.ResolveTCPAddr("tcp", http2Node.Addr) - return conn, nil -} - -// Use HTTP2 as transport to connect target addr. -// -// BUG: SOCKS5 is ignored, only HTTP supported -func (c *ProxyChain) http2Connect(addr string) (net.Conn, error) { - if !c.Http2Enabled() { - return nil, errors.New("HTTP2 is not enabled") - } - http2Node := c.nodes[c.http2NodeIndex] - - header := make(http.Header) - header.Set("Gost-Target", addr) // Flag header to indicate the address that server connected to - if http2Node.Users != nil { - header.Set("Proxy-Authorization", - "Basic "+base64.StdEncoding.EncodeToString([]byte(http2Node.Users[0].String()))) - } - return c.getHttp2Conn(header) -} - -func (c *ProxyChain) quicConnect(addr string) (net.Conn, error) { - quicNode := c.nodes[0] - header := make(http.Header) - header.Set("Gost-Target", addr) // Flag header to indicate the address that server connected to - if quicNode.Users != nil { - header.Set("Proxy-Authorization", - "Basic "+base64.StdEncoding.EncodeToString([]byte(quicNode.Users[0].String()))) - } - return c.getQuicConn(header) -} - -func (c *ProxyChain) getQuicConn(header http.Header) (net.Conn, error) { - quicNode := c.nodes[0] - pr, pw := io.Pipe() - - if header == nil { - header = make(http.Header) - } - - /* - req := http.Request{ - Method: http.MethodGet, - URL: &url.URL{Scheme: "https", Host: quicNode.Addr}, - Header: header, - Proto: "HTTP/2.0", - ProtoMajor: 2, - ProtoMinor: 0, - Body: pr, - Host: quicNode.Addr, - ContentLength: -1, - } - */ - req, err := http.NewRequest(http.MethodPost, "https://"+quicNode.Addr, pr) - if err != nil { - return nil, err - } - req.ContentLength = -1 - req.Header = header - - if glog.V(LDEBUG) { - dump, _ := httputil.DumpRequest(req, false) - glog.Infoln(string(dump)) - } - resp, err := c.quicClient.Do(req) - if err != nil { - return nil, err - } - if glog.V(LDEBUG) { - dump, _ := httputil.DumpResponse(resp, false) - glog.Infoln(string(dump)) - } - if resp.StatusCode != http.StatusOK { - resp.Body.Close() - return nil, errors.New(resp.Status) - } - conn := &http2Conn{r: resp.Body, w: pw} - conn.remoteAddr, _ = net.ResolveUDPAddr("udp", quicNode.Addr) - return conn, nil -} diff --git a/vendor/github.com/ginuerzh/gost/conn.go b/vendor/github.com/ginuerzh/gost/conn.go deleted file mode 100644 index 3a6259a..0000000 --- a/vendor/github.com/ginuerzh/gost/conn.go +++ /dev/null @@ -1,292 +0,0 @@ -package gost - -import ( - "bufio" - "crypto/tls" - "encoding/base64" - "errors" - "fmt" - "github.com/ginuerzh/gosocks4" - "github.com/ginuerzh/gosocks5" - "github.com/golang/glog" - ss "github.com/shadowsocks/shadowsocks-go/shadowsocks" - "net" - "net/http" - "net/http/httputil" - "net/url" - "strconv" - "strings" - "sync" - "time" -) - -type ProxyConn struct { - conn net.Conn - Node ProxyNode - handshaked bool - handshakeMutex sync.Mutex - handshakeErr error -} - -func NewProxyConn(conn net.Conn, node ProxyNode) *ProxyConn { - return &ProxyConn{ - conn: conn, - Node: node, - } -} - -// Handshake handshake with this proxy node based on the proxy node info: transport, protocol, authentication, etc. -// -// NOTE: any HTTP2 scheme will be treated as http (for protocol) or tls (for transport). -func (c *ProxyConn) Handshake() error { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - - if err := c.handshakeErr; err != nil { - return err - } - if c.handshaked { - return nil - } - c.handshakeErr = c.handshake() - return c.handshakeErr -} - -func (c *ProxyConn) handshake() error { - var tlsUsed bool - - switch c.Node.Transport { - case "ws": // websocket connection - u := url.URL{Scheme: "ws", Host: c.Node.Addr, Path: "/ws"} - conn, err := WebsocketClientConn(u.String(), c.conn, nil) - if err != nil { - return err - } - c.conn = conn - case "wss": // websocket security - tlsUsed = true - u := url.URL{Scheme: "wss", Host: c.Node.Addr, Path: "/ws"} - config := &tls.Config{ - InsecureSkipVerify: c.Node.insecureSkipVerify(), - ServerName: c.Node.serverName, - } - conn, err := WebsocketClientConn(u.String(), c.conn, config) - if err != nil { - return err - } - c.conn = conn - case "tls", "http2": // tls connection - tlsUsed = true - cfg := &tls.Config{ - InsecureSkipVerify: c.Node.insecureSkipVerify(), - ServerName: c.Node.serverName, - } - c.conn = tls.Client(c.conn, cfg) - case "h2": // same as http2, but just set a flag for later using. - tlsUsed = true - case "kcp": // kcp connection - tlsUsed = true - default: - } - - switch c.Node.Protocol { - case "socks", "socks5": // socks5 handshake with auth and tls supported - selector := &clientSelector{ - methods: []uint8{ - gosocks5.MethodNoAuth, - gosocks5.MethodUserPass, - //MethodTLS, - }, - } - - if len(c.Node.Users) > 0 { - selector.user = c.Node.Users[0] - } - - if !tlsUsed { // if transport is not security, enable security socks5 - selector.methods = append(selector.methods, MethodTLS) - selector.tlsConfig = &tls.Config{ - InsecureSkipVerify: c.Node.insecureSkipVerify(), - ServerName: c.Node.serverName, - } - } - - conn := gosocks5.ClientConn(c.conn, selector) - if err := conn.Handleshake(); err != nil { - return err - } - c.conn = conn - case "ss": // shadowsocks - // nothing to do - case "http", "http2": - fallthrough - default: - } - - c.handshaked = true - - return nil -} - -// Connect connect to addr through this proxy node -func (c *ProxyConn) Connect(addr string) error { - switch c.Node.Protocol { - case "ss": // shadowsocks - rawaddr, err := ss.RawAddr(addr) - if err != nil { - return err - } - - var method, password string - if len(c.Node.Users) > 0 { - method = c.Node.Users[0].Username() - password, _ = c.Node.Users[0].Password() - } - if c.Node.getBool("ota") && !strings.HasSuffix(method, "-auth") { - method += "-auth" - } - - cipher, err := ss.NewCipher(method, password) - if err != nil { - return err - } - - ssc, err := ss.DialWithRawAddrConn(rawaddr, c.conn, cipher) - if err != nil { - return err - } - c.conn = &shadowConn{conn: ssc} - return nil - case "socks", "socks5": - host, port, err := net.SplitHostPort(addr) - if err != nil { - return err - } - p, _ := strconv.Atoi(port) - req := gosocks5.NewRequest(gosocks5.CmdConnect, &gosocks5.Addr{ - Type: gosocks5.AddrDomain, - Host: host, - Port: uint16(p), - }) - if err := req.Write(c); err != nil { - return err - } - glog.V(LDEBUG).Infoln("[socks5]", req) - - reply, err := gosocks5.ReadReply(c) - if err != nil { - return err - } - glog.V(LDEBUG).Infoln("[socks5]", reply) - if reply.Rep != gosocks5.Succeeded { - return errors.New("Service unavailable") - } - case "socks4", "socks4a": - atype := gosocks4.AddrDomain - host, port, err := net.SplitHostPort(addr) - if err != nil { - return err - } - p, _ := strconv.Atoi(port) - - if c.Node.Protocol == "socks4" { - taddr, err := net.ResolveTCPAddr("tcp4", addr) - if err != nil { - return err - } - host = taddr.IP.String() - p = taddr.Port - atype = gosocks4.AddrIPv4 - } - req := gosocks4.NewRequest(gosocks4.CmdConnect, - &gosocks4.Addr{Type: atype, Host: host, Port: uint16(p)}, nil) - if err := req.Write(c); err != nil { - return err - } - glog.V(LDEBUG).Infof("[%s] %s", c.Node.Protocol, req) - - reply, err := gosocks4.ReadReply(c) - if err != nil { - return err - } - glog.V(LDEBUG).Infof("[%s] %s", c.Node.Protocol, reply) - - if reply.Code != gosocks4.Granted { - return errors.New(fmt.Sprintf("%s: code=%d", c.Node.Protocol, reply.Code)) - } - case "http": - fallthrough - default: - req := &http.Request{ - Method: http.MethodConnect, - URL: &url.URL{Host: addr}, - Host: addr, - ProtoMajor: 1, - ProtoMinor: 1, - Header: make(http.Header), - } - req.Header.Set("Proxy-Connection", "keep-alive") - if len(c.Node.Users) > 0 { - user := c.Node.Users[0] - s := user.String() - if _, set := user.Password(); !set { - s += ":" - } - req.Header.Set("Proxy-Authorization", - "Basic "+base64.StdEncoding.EncodeToString([]byte(s))) - } - if err := req.Write(c); err != nil { - return err - } - if glog.V(LDEBUG) { - dump, _ := httputil.DumpRequest(req, false) - glog.Infoln(string(dump)) - } - - resp, err := http.ReadResponse(bufio.NewReader(c), req) - if err != nil { - return err - } - if glog.V(LDEBUG) { - dump, _ := httputil.DumpResponse(resp, false) - glog.Infoln(string(dump)) - } - if resp.StatusCode != http.StatusOK { - return errors.New(resp.Status) - } - } - - return nil -} - -func (c *ProxyConn) Read(b []byte) (n int, err error) { - return c.conn.Read(b) -} - -func (c *ProxyConn) Write(b []byte) (n int, err error) { - return c.conn.Write(b) -} - -func (c *ProxyConn) Close() error { - return c.conn.Close() -} - -func (c *ProxyConn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -func (c *ProxyConn) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -func (c *ProxyConn) SetDeadline(t time.Time) error { - return c.conn.SetDeadline(t) -} - -func (c *ProxyConn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -func (c *ProxyConn) SetWriteDeadline(t time.Time) error { - return c.conn.SetWriteDeadline(t) -} diff --git a/vendor/github.com/ginuerzh/gost/forward.go b/vendor/github.com/ginuerzh/gost/forward.go deleted file mode 100644 index 5d545c8..0000000 --- a/vendor/github.com/ginuerzh/gost/forward.go +++ /dev/null @@ -1,689 +0,0 @@ -package gost - -import ( - "errors" - "fmt" - "github.com/ginuerzh/gosocks5" - "github.com/golang/glog" - "golang.org/x/crypto/ssh" - "net" - "strconv" - "time" -) - -type TcpForwardServer struct { - Base *ProxyServer - sshClient *ssh.Client - Handler func(conn net.Conn, raddr *net.TCPAddr) -} - -func NewTcpForwardServer(base *ProxyServer) *TcpForwardServer { - return &TcpForwardServer{Base: base} -} - -func (s *TcpForwardServer) ListenAndServe() error { - raddr, err := net.ResolveTCPAddr("tcp", s.Base.Node.Remote) - if err != nil { - return err - } - - ln, err := net.Listen("tcp", s.Base.Node.Addr) - if err != nil { - return err - } - defer ln.Close() - - if s.Handler == nil { - s.Handler = s.handleTcpForward - } - - quit := make(chan interface{}) - close(quit) - - for { - start: - conn, err := ln.Accept() - if err != nil { - glog.V(LWARNING).Infoln("[tcp]", err) - continue - } - setKeepAlive(conn, KeepAliveTime) - - select { - case <-quit: - if s.Base.Chain.lastNode == nil || s.Base.Chain.lastNode.Transport != "ssh" { - break - } - if err := s.initSSHClient(); err != nil { - glog.V(LWARNING).Infoln("[tcp]", err) - conn.Close() - goto start - } - quit = make(chan interface{}) - go func(ch chan interface{}) { - s.sshClient.Wait() - glog.V(LINFO).Infoln("[tcp] connection closed") - close(ch) - }(quit) - - default: - } - - go s.Handler(conn, raddr) - } -} - -func (s *TcpForwardServer) initSSHClient() error { - if s.sshClient != nil { - s.sshClient.Close() - s.sshClient = nil - } - - sshNode := s.Base.Chain.lastNode - c, err := s.Base.Chain.GetConn() - if err != nil { - return err - } - var user, password string - if len(sshNode.Users) > 0 { - user = sshNode.Users[0].Username() - password, _ = sshNode.Users[0].Password() - } - config := ssh.ClientConfig{ - User: user, - Auth: []ssh.AuthMethod{ - ssh.Password(password), - }, - } - sshConn, chans, reqs, err := ssh.NewClientConn(c, sshNode.Addr, &config) - if err != nil { - return err - } - s.sshClient = ssh.NewClient(sshConn, chans, reqs) - s.Handler = s.handleTcpForwardSSH - - return nil -} - -func (s *TcpForwardServer) handleTcpForward(conn net.Conn, raddr *net.TCPAddr) { - defer conn.Close() - - glog.V(LINFO).Infof("[tcp] %s - %s", conn.RemoteAddr(), raddr) - cc, err := s.Base.Chain.Dial(raddr.String()) - if err != nil { - glog.V(LWARNING).Infof("[tcp] %s -> %s : %s", conn.RemoteAddr(), raddr, err) - return - } - defer cc.Close() - - glog.V(LINFO).Infof("[tcp] %s <-> %s", conn.RemoteAddr(), raddr) - s.Base.transport(conn, cc) - glog.V(LINFO).Infof("[tcp] %s >-< %s", conn.RemoteAddr(), raddr) -} - -func (s *TcpForwardServer) handleTcpForwardSSH(conn net.Conn, raddr *net.TCPAddr) { - defer conn.Close() - - if s.sshClient == nil { - return - } - - rc, err := s.sshClient.DialTCP("tcp", nil, raddr) - if err != nil { - glog.V(LWARNING).Infof("[tcp] %s -> %s : %s", conn.RemoteAddr(), raddr, err) - return - } - defer rc.Close() - - glog.V(LINFO).Infof("[tcp] %s <-> %s", conn.RemoteAddr(), raddr) - Transport(conn, rc) - glog.V(LINFO).Infof("[tcp] %s >-< %s", conn.RemoteAddr(), raddr) -} - -type packet struct { - srcAddr string // src address - dstAddr string // dest address - data []byte -} - -type cnode struct { - chain *ProxyChain - conn net.Conn - srcAddr, dstAddr string - rChan, wChan chan *packet - err error - ttl time.Duration -} - -func (node *cnode) getUDPTunnel() (net.Conn, error) { - conn, err := node.chain.GetConn() - if err != nil { - return nil, err - } - - conn.SetWriteDeadline(time.Now().Add(WriteTimeout)) - if err = gosocks5.NewRequest(CmdUdpTun, nil).Write(conn); err != nil { - conn.Close() - return nil, err - } - conn.SetWriteDeadline(time.Time{}) - - conn.SetReadDeadline(time.Now().Add(ReadTimeout)) - reply, err := gosocks5.ReadReply(conn) - if err != nil { - conn.Close() - return nil, err - } - conn.SetReadDeadline(time.Time{}) - - if reply.Rep != gosocks5.Succeeded { - conn.Close() - return nil, errors.New("UDP tunnel failure") - } - - return conn, nil -} - -func (node *cnode) run() { - if len(node.chain.Nodes()) == 0 { - lconn, err := net.ListenUDP("udp", nil) - if err != nil { - glog.V(LWARNING).Infof("[udp] %s -> %s : %s", node.srcAddr, node.dstAddr, err) - node.err = err - return - } - node.conn = lconn - } else { - tc, err := node.getUDPTunnel() - if err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s -> %s : %s", node.srcAddr, node.dstAddr, err) - node.err = err - return - } - node.conn = tc - } - - defer node.conn.Close() - - timer := time.NewTimer(node.ttl) - errChan := make(chan error, 2) - - go func() { - for { - switch c := node.conn.(type) { - case *net.UDPConn: - b := make([]byte, MediumBufferSize) - n, addr, err := c.ReadFromUDP(b) - if err != nil { - glog.V(LWARNING).Infof("[udp] %s <- %s : %s", node.srcAddr, node.dstAddr, err) - node.err = err - errChan <- err - return - } - - timer.Reset(node.ttl) - glog.V(LDEBUG).Infof("[udp] %s <<< %s : length %d", node.srcAddr, addr, n) - - select { - // swap srcAddr with dstAddr - case node.rChan <- &packet{srcAddr: addr.String(), dstAddr: node.srcAddr, data: b[:n]}: - case <-time.After(time.Second * 3): - glog.V(LWARNING).Infof("[udp] %s <- %s : %s", node.srcAddr, node.dstAddr, "recv queue is full, discard") - } - - default: - dgram, err := gosocks5.ReadUDPDatagram(c) - if err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s <- %s : %s", node.srcAddr, node.dstAddr, err) - node.err = err - errChan <- err - return - } - - timer.Reset(node.ttl) - glog.V(LDEBUG).Infof("[udp-tun] %s <<< %s : length %d", node.srcAddr, dgram.Header.Addr.String(), len(dgram.Data)) - - select { - // swap srcAddr with dstAddr - case node.rChan <- &packet{srcAddr: dgram.Header.Addr.String(), dstAddr: node.srcAddr, data: dgram.Data}: - case <-time.After(time.Second * 3): - glog.V(LWARNING).Infof("[udp-tun] %s <- %s : %s", node.srcAddr, node.dstAddr, "recv queue is full, discard") - } - } - } - }() - - go func() { - for pkt := range node.wChan { - timer.Reset(node.ttl) - - dstAddr, err := net.ResolveUDPAddr("udp", pkt.dstAddr) - if err != nil { - glog.V(LWARNING).Infof("[udp] %s -> %s : %s", pkt.srcAddr, pkt.dstAddr, err) - continue - } - - switch c := node.conn.(type) { - case *net.UDPConn: - if _, err := c.WriteToUDP(pkt.data, dstAddr); err != nil { - glog.V(LWARNING).Infof("[udp] %s -> %s : %s", pkt.srcAddr, pkt.dstAddr, err) - node.err = err - errChan <- err - return - } - glog.V(LDEBUG).Infof("[udp] %s >>> %s : length %d", pkt.srcAddr, pkt.dstAddr, len(pkt.data)) - - default: - dgram := gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(uint16(len(pkt.data)), 0, ToSocksAddr(dstAddr)), pkt.data) - if err := dgram.Write(c); err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s -> %s : %s", pkt.srcAddr, pkt.dstAddr, err) - node.err = err - errChan <- err - return - } - glog.V(LDEBUG).Infof("[udp-tun] %s >>> %s : length %d", pkt.srcAddr, pkt.dstAddr, len(pkt.data)) - } - } - }() - - select { - case <-errChan: - case <-timer.C: - } -} - -type UdpForwardServer struct { - Base *ProxyServer - TTL int -} - -func NewUdpForwardServer(base *ProxyServer, ttl int) *UdpForwardServer { - return &UdpForwardServer{Base: base, TTL: ttl} -} - -func (s *UdpForwardServer) ListenAndServe() error { - laddr, err := net.ResolveUDPAddr("udp", s.Base.Node.Addr) - if err != nil { - return err - } - - raddr, err := net.ResolveUDPAddr("udp", s.Base.Node.Remote) - if err != nil { - return err - } - - conn, err := net.ListenUDP("udp", laddr) - if err != nil { - glog.V(LWARNING).Infof("[udp] %s -> %s : %s", laddr, raddr, err) - return err - } - defer conn.Close() - - rChan, wChan := make(chan *packet, 128), make(chan *packet, 128) - // start send queue - go func(ch chan<- *packet) { - for { - b := make([]byte, MediumBufferSize) - n, addr, err := conn.ReadFromUDP(b) - if err != nil { - glog.V(LWARNING).Infof("[udp] %s -> %s : %s", laddr, raddr, err) - continue - } - - select { - case ch <- &packet{srcAddr: addr.String(), dstAddr: raddr.String(), data: b[:n]}: - case <-time.After(time.Second * 3): - glog.V(LWARNING).Infof("[udp] %s -> %s : %s", addr, raddr, "send queue is full, discard") - } - } - }(wChan) - // start recv queue - go func(ch <-chan *packet) { - for pkt := range ch { - dstAddr, err := net.ResolveUDPAddr("udp", pkt.dstAddr) - if err != nil { - glog.V(LWARNING).Infof("[udp] %s <- %s : %s", pkt.dstAddr, pkt.srcAddr, err) - continue - } - if _, err := conn.WriteToUDP(pkt.data, dstAddr); err != nil { - glog.V(LWARNING).Infof("[udp] %s <- %s : %s", pkt.dstAddr, pkt.srcAddr, err) - return - } - } - }(rChan) - - // mapping client to node - m := make(map[string]*cnode) - - // start dispatcher - for pkt := range wChan { - // clear obsolete nodes - for k, node := range m { - if node != nil && node.err != nil { - close(node.wChan) - delete(m, k) - glog.V(LINFO).Infof("[udp] clear node %s", k) - } - } - - node, ok := m[pkt.srcAddr] - if !ok { - node = &cnode{ - chain: s.Base.Chain, - srcAddr: pkt.srcAddr, - dstAddr: pkt.dstAddr, - rChan: rChan, - wChan: make(chan *packet, 32), - ttl: time.Duration(s.TTL) * time.Second, - } - m[pkt.srcAddr] = node - go node.run() - glog.V(LINFO).Infof("[udp] %s -> %s : new client (%d)", pkt.srcAddr, pkt.dstAddr, len(m)) - } - - select { - case node.wChan <- pkt: - case <-time.After(time.Second * 3): - glog.V(LWARNING).Infof("[udp] %s -> %s : %s", pkt.srcAddr, pkt.dstAddr, "node send queue is full, discard") - } - } - - return nil -} - -type RTcpForwardServer struct { - Base *ProxyServer -} - -func NewRTcpForwardServer(base *ProxyServer) *RTcpForwardServer { - return &RTcpForwardServer{Base: base} -} - -func (s *RTcpForwardServer) Serve() error { - if len(s.Base.Chain.nodes) == 0 { - return errors.New("rtcp: at least one -F must be assigned") - } - - laddr, err := net.ResolveTCPAddr("tcp", s.Base.Node.Addr) - if err != nil { - return err - } - raddr, err := net.ResolveTCPAddr("tcp", s.Base.Node.Remote) - if err != nil { - return err - } - - retry := 0 - for { - conn, err := s.Base.Chain.GetConn() - if err != nil { - glog.V(LWARNING).Infof("[rtcp] %s - %s : %s", laddr, raddr, err) - time.Sleep((1 << uint(retry)) * time.Second) - if retry < 5 { - retry++ - } - continue - } - retry = 0 - - glog.V(LINFO).Infof("[rtcp] %s - %s", laddr, raddr) - - lastNode := s.Base.Chain.lastNode - if lastNode != nil && lastNode.Transport == "ssh" { - s.connectRTcpForwardSSH(conn, lastNode, laddr, raddr) - } else { - if err := s.connectRTcpForward(conn, laddr, raddr); err != nil { - conn.Close() - } - } - time.Sleep(3 * time.Second) - } -} - -func (s *RTcpForwardServer) connectRTcpForwardSSH(conn net.Conn, sshNode *ProxyNode, laddr, raddr net.Addr) error { - defer conn.Close() - - var user, password string - if len(sshNode.Users) > 0 { - user = sshNode.Users[0].Username() - password, _ = sshNode.Users[0].Password() - } - config := ssh.ClientConfig{ - User: user, - Auth: []ssh.AuthMethod{ - ssh.Password(password), - }, - } - c, chans, reqs, err := ssh.NewClientConn(conn, sshNode.Addr, &config) - if err != nil { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : %s", laddr, raddr, err) - return err - } - client := ssh.NewClient(c, chans, reqs) - - quit := make(chan interface{}) - defer close(quit) - - go func() { - defer client.Close() - - var c <-chan time.Time - - ping, _ := strconv.Atoi(sshNode.Get("ping")) - if ping > 0 { - d := time.Second * time.Duration(ping) - glog.V(LINFO).Infoln("[rtcp] ping is enabled:", d) - t := time.NewTicker(d) - defer t.Stop() - c = t.C - } - - for { - select { - case <-c: - _, _, err := client.SendRequest("ping", true, nil) - if err != nil { - glog.V(LWARNING).Infoln("[rtcp] ping", err) - return - } - glog.V(LDEBUG).Infoln("[rtcp] heartbeat OK") - - case <-quit: - glog.V(LWARNING).Infoln("[rtcp] ssh connection closed") - return - } - } - }() - - ln, err := client.Listen("tcp", laddr.String()) - if err != nil { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : %s", laddr, raddr, err) - return err - } - defer ln.Close() - - for { - rc, err := ln.Accept() - if err != nil { - return err - } - - go func(c net.Conn) { - defer c.Close() - - tc, err := net.DialTimeout("tcp", raddr.String(), time.Second*30) - if err != nil { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : %s", laddr, raddr, err) - return - } - defer tc.Close() - - glog.V(LINFO).Infof("[rtcp] %s <-> %s", c.RemoteAddr(), c.LocalAddr()) - Transport(c, tc) - glog.V(LINFO).Infof("[rtcp] %s >-< %s", c.RemoteAddr(), c.LocalAddr()) - }(rc) - } -} - -func (s *RTcpForwardServer) connectRTcpForward(conn net.Conn, laddr, raddr net.Addr) error { - req := gosocks5.NewRequest(gosocks5.CmdBind, ToSocksAddr(laddr)) - if err := req.Write(conn); err != nil { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : %s", laddr, raddr, err) - return err - } - - // first reply, bind status - conn.SetReadDeadline(time.Now().Add(ReadTimeout)) - rep, err := gosocks5.ReadReply(conn) - if err != nil { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : %s", laddr, raddr, err) - return err - } - conn.SetReadDeadline(time.Time{}) - if rep.Rep != gosocks5.Succeeded { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : bind on %s failure", laddr, raddr, laddr) - return errors.New("Bind on " + laddr.String() + " failure") - } - glog.V(LINFO).Infof("[rtcp] %s - %s BIND ON %s OK", laddr, raddr, rep.Addr) - - // second reply, peer connection - rep, err = gosocks5.ReadReply(conn) - if err != nil { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : %s", laddr, raddr, err) - return err - } - if rep.Rep != gosocks5.Succeeded { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : peer connect failure", laddr, raddr) - return errors.New("peer connect failure") - } - - glog.V(LINFO).Infof("[rtcp] %s -> %s PEER %s CONNECTED", laddr, raddr, rep.Addr) - - go func() { - defer conn.Close() - - lconn, err := net.DialTimeout("tcp", raddr.String(), time.Second*30) - if err != nil { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : %s", rep.Addr, raddr, err) - return - } - defer lconn.Close() - - glog.V(LINFO).Infof("[rtcp] %s <-> %s", rep.Addr, lconn.RemoteAddr()) - s.Base.transport(lconn, conn) - glog.V(LINFO).Infof("[rtcp] %s >-< %s", rep.Addr, lconn.RemoteAddr()) - }() - - return nil -} - -type RUdpForwardServer struct { - Base *ProxyServer -} - -func NewRUdpForwardServer(base *ProxyServer) *RUdpForwardServer { - return &RUdpForwardServer{Base: base} -} - -func (s *RUdpForwardServer) Serve() error { - if len(s.Base.Chain.nodes) == 0 { - return errors.New("rudp: at least one -F must be assigned") - } - - laddr, err := net.ResolveUDPAddr("udp", s.Base.Node.Addr) - if err != nil { - return err - } - raddr, err := net.ResolveUDPAddr("udp", s.Base.Node.Remote) - if err != nil { - return err - } - - retry := 0 - for { - conn, err := s.Base.Chain.GetConn() - if err != nil { - glog.V(LWARNING).Infof("[rudp] %s - %s : %s", laddr, raddr, err) - time.Sleep((1 << uint(retry)) * time.Second) - if retry < 5 { - retry++ - } - continue - } - retry = 0 - - if err := s.connectRUdpForward(conn, laddr, raddr); err != nil { - conn.Close() - time.Sleep(6 * time.Second) - } - } -} - -func (s *RUdpForwardServer) connectRUdpForward(conn net.Conn, laddr, raddr *net.UDPAddr) error { - glog.V(LINFO).Infof("[rudp] %s - %s", laddr, raddr) - - req := gosocks5.NewRequest(CmdUdpTun, ToSocksAddr(laddr)) - conn.SetWriteDeadline(time.Now().Add(WriteTimeout)) - if err := req.Write(conn); err != nil { - glog.V(LWARNING).Infof("[rudp] %s -> %s : %s", laddr, raddr, err) - return err - } - conn.SetWriteDeadline(time.Time{}) - - conn.SetReadDeadline(time.Now().Add(ReadTimeout)) - rep, err := gosocks5.ReadReply(conn) - if err != nil { - glog.V(LWARNING).Infof("[rudp] %s <- %s : %s", laddr, raddr, err) - return err - } - conn.SetReadDeadline(time.Time{}) - - if rep.Rep != gosocks5.Succeeded { - glog.V(LWARNING).Infof("[rudp] %s <- %s : bind on %s failure", laddr, raddr, laddr) - return errors.New(fmt.Sprintf("bind on %s failure", laddr)) - } - - glog.V(LINFO).Infof("[rudp] %s - %s BIND ON %s OK", laddr, raddr, rep.Addr) - - for { - dgram, err := gosocks5.ReadUDPDatagram(conn) - if err != nil { - glog.V(LWARNING).Infof("[rudp] %s <- %s : %s", laddr, raddr, err) - return err - } - - go func() { - b := make([]byte, MediumBufferSize) - - relay, err := net.DialUDP("udp", nil, raddr) - if err != nil { - glog.V(LWARNING).Infof("[rudp] %s -> %s : %s", laddr, raddr, err) - return - } - defer relay.Close() - - if _, err := relay.Write(dgram.Data); err != nil { - glog.V(LWARNING).Infof("[rudp] %s -> %s : %s", laddr, raddr, err) - return - } - glog.V(LDEBUG).Infof("[rudp] %s >>> %s length: %d", laddr, raddr, len(dgram.Data)) - - relay.SetReadDeadline(time.Now().Add(ReadTimeout)) - n, err := relay.Read(b) - if err != nil { - glog.V(LWARNING).Infof("[rudp] %s <- %s : %s", laddr, raddr, err) - return - } - relay.SetReadDeadline(time.Time{}) - - glog.V(LDEBUG).Infof("[rudp] %s <<< %s length: %d", laddr, raddr, n) - - conn.SetWriteDeadline(time.Now().Add(WriteTimeout)) - if err := gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(uint16(n), 0, dgram.Header.Addr), b[:n]).Write(conn); err != nil { - glog.V(LWARNING).Infof("[rudp] %s <- %s : %s", laddr, raddr, err) - return - } - conn.SetWriteDeadline(time.Time{}) - }() - } -} diff --git a/vendor/github.com/ginuerzh/gost/gost.go b/vendor/github.com/ginuerzh/gost/gost.go deleted file mode 100644 index 50f4085..0000000 --- a/vendor/github.com/ginuerzh/gost/gost.go +++ /dev/null @@ -1,162 +0,0 @@ -package gost - -import ( - "crypto/tls" - "encoding/base64" - "errors" - "github.com/golang/glog" - "io" - "net" - "strings" - "time" -) - -const ( - Version = "2.4-dev20170303" -) - -// Log level for glog -const ( - LFATAL = iota - LERROR - LWARNING - LINFO - LDEBUG -) - -var ( - KeepAliveTime = 180 * time.Second - DialTimeout = 30 * time.Second - ReadTimeout = 90 * time.Second - WriteTimeout = 90 * time.Second - - DefaultTTL = 60 // default udp node TTL in second for udp port forwarding -) - -var ( - SmallBufferSize = 1 * 1024 // 1KB small buffer - MediumBufferSize = 8 * 1024 // 8KB medium buffer - LargeBufferSize = 32 * 1024 // 32KB large buffer -) - -var ( - DefaultCertFile = "cert.pem" - DefaultKeyFile = "key.pem" - - // This is the default cert and key data for convenience, providing your own cert is recommended. - defaultRawCert = []byte(`-----BEGIN CERTIFICATE----- -MIIC5jCCAdCgAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD -bzAeFw0xNDAzMTcwNjIwNTFaFw0xNTAzMTcwNjIwNTFaMBIxEDAOBgNVBAoTB0Fj -bWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDccNO1xmd4lWSf -d/0/QS3E93cYIWHw831i/IKxigdRD/XMZonLdEHywW6lOiXazaP8e6CqPGSmnl0x -5k/3dvGCMj2JCVxM6+z7NpL+AiwvXmvkj/TOciCgwqssCwYS2CiVwjfazRjx1ZUJ -VDC5qiyRsfktQ2fVHrpnJGVSRagmiQgwGWBilVG9B8QvRtpQKN/GQGq17oIQm8aK -kOdPt93g93ojMIg7YJpgDgOirvVz/hDn7YD4ryrtPos9CMafFkJprymKpRHyvz7P -8a3+OkuPjFjPnwOHQ5u1U3+8vC44vfb1ExWzDLoT8Xp8Gndx39k0f7MVOol3GnYu -MN/dvNUdAgMBAAGjSzBJMA4GA1UdDwEB/wQEAwIAoDATBgNVHSUEDDAKBggrBgEF -BQcDATAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDALBgkqhkiG -9w0BAQUDggEBAIG8CJqvTIgJnNOK+i5/IUc/3yF/mSCWuG8qP+Fmo2t6T0PVOtc0 -8wiWH5iWtCAhjn0MRY9l/hIjWm6gUZGHCGuEgsOPpJDYGoNLjH9Xwokm4y3LFNRK -UBrrrDbKRNibApBHCapPf6gC5sXcjOwx7P2/kiHDgY7YH47jfcRhtAPNsM4gjsEO -RmwENY+hRUFHIRfQTyalqND+x6PWhRo3K6hpHs4DQEYPq4P2kFPqUqSBymH+Ny5/ -BcQ3wdMNmC6Bm/oiL1QV0M+/InOsAgQk/EDd0kmoU1ZT2lYHQduGmP099bOlHNpS -uqO3vXF3q8SPPr/A9TqSs7BKkBQbe0+cdsA= ------END CERTIFICATE-----`) - defaultRawKey = []byte(`-----BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEA3HDTtcZneJVkn3f9P0EtxPd3GCFh8PN9YvyCsYoHUQ/1zGaJ -y3RB8sFupTol2s2j/Hugqjxkpp5dMeZP93bxgjI9iQlcTOvs+zaS/gIsL15r5I/0 -znIgoMKrLAsGEtgolcI32s0Y8dWVCVQwuaoskbH5LUNn1R66ZyRlUkWoJokIMBlg -YpVRvQfEL0baUCjfxkBqte6CEJvGipDnT7fd4Pd6IzCIO2CaYA4Doq71c/4Q5+2A -+K8q7T6LPQjGnxZCaa8piqUR8r8+z/Gt/jpLj4xYz58Dh0ObtVN/vLwuOL329RMV -swy6E/F6fBp3cd/ZNH+zFTqJdxp2LjDf3bzVHQIDAQABAoIBAHal26147nQ+pHwY -jxwers3XDCjWvup7g79lfcqlKi79UiUEA6KYHm7UogMYewt7p4nb2KwH+XycvDiB -aAUf5flXpTs+6IkWauUDiLZi4PlV7uiEexUq5FjirlL0U/6MjbudX4bK4WQ4uxDc -WaV07Kw2iJFOOHLDKT0en9JaX5jtJNc4ZnE9efFoQ5jfypPWtRw65G1rULEg6nvc -GDh+1ce+4foCkpLRC9c24xAwJONZG6x3UqrSS9qfAsb73nWRQrTfUcO3nhoN8VvL -kL9skn1+S06NyUN0KoEtyRBp+RcpXSsBWAo6qZmo/WqhB/gjzWrxVwn20+yJSm35 -ZsMc6QECgYEA8GS+Mp9xfB2szWHz6YTOO1Uu4lHM1ccZMwS1G+dL0KO3uGAiPdvp -woVot6v6w88t7onXsLo5pgz7SYug0CpkF3K/MRd1Ar4lH7PK7IBQ6rFr9ppVxDbx -AEWRswUoPbKCr7W6HU8LbQHDavsDlEIwc6+DiwnL4BzlKjb7RpgQEz0CgYEA6sB5 -uHvx3Y5FDcGk1n73leQSAcq14l3ZLNpjrs8msoREDil/j5WmuSN58/7PGMiMgHEi -1vLm3H796JmvGr9OBvspOjHyk07ui2/We/j9Hoxm1VWhyi8HkLNDj70HKalTTFMz -RHO4O+0xCva+h9mKZrRMVktXr2jjdFn/0MYIZ2ECgYAIIsC1IeRLWQ3CHbCNlKsO -IwHlMvOFwKk/qsceXKOaOhA7szU1dr3gkXdL0Aw6mEZrrkqYdpUA46uVf54/rU+Z -445I8QxKvXiwK/uQKX+TkdGflPWWIG3jnnch4ejMvb/ihnn4B/bRB6A/fKNQXzUY -lTYUfI5j1VaEKTwz1W2l2QKBgByFCcSp+jZqhGUpc3dDsZyaOr3Q/Mvlju7uEVI5 -hIAHpaT60a6GBd1UPAqymEJwivFHzW3D0NxU6VAK68UaHMaoWNfjHY9b9YsnKS2i -kE3XzN56Ks+/avHfdYPO+UHMenw5V28nh+hv5pdoZrlmanQTz3pkaOC8o3WNQZEB -nh/BAoGBAMY5z2f1pmMhrvtPDSlEVjgjELbaInxFaxPLR4Pdyzn83gtIIU14+R8X -2LPs6PPwrNjWnIgrUSVXncIFL3pa45B+Mx1pYCpOAB1+nCZjIBQmpeo4Y0dwA/XH -85EthKPvoszm+OPbyI16OcePV5ocX7lupRYuAo0pek7bomhmHWHz ------END RSA PRIVATE KEY-----`) -) - -var ( - ErrEmptyChain = errors.New("empty chain") -) - -func setKeepAlive(conn net.Conn, d time.Duration) error { - c, ok := conn.(*net.TCPConn) - if !ok { - return errors.New("Not a TCP connection") - } - if err := c.SetKeepAlive(true); err != nil { - return err - } - if err := c.SetKeepAlivePeriod(d); err != nil { - return err - } - return nil -} - -// Load the certificate from cert and key files, will use the default certificate if the provided info are invalid. -func LoadCertificate(certFile, keyFile string) (tls.Certificate, error) { - tlsCert, err := tls.LoadX509KeyPair(certFile, keyFile) - if err == nil { - return tlsCert, nil - } - glog.V(LWARNING).Infoln(err) - return tls.X509KeyPair(defaultRawCert, defaultRawKey) -} - -// Replace the default certificate by your own -func SetDefaultCertificate(rawCert, rawKey []byte) { - defaultRawCert = rawCert - defaultRawKey = rawKey -} - -func basicProxyAuth(proxyAuth string) (username, password string, ok bool) { - if proxyAuth == "" { - return - } - - if !strings.HasPrefix(proxyAuth, "Basic ") { - return - } - c, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(proxyAuth, "Basic ")) - if err != nil { - return - } - cs := string(c) - s := strings.IndexByte(cs, ':') - if s < 0 { - return - } - - return cs[:s], cs[s+1:], true -} - -func Transport(rw1, rw2 io.ReadWriter) error { - errc := make(chan error, 1) - go func() { - _, err := io.Copy(rw1, rw2) - errc <- err - }() - - go func() { - _, err := io.Copy(rw2, rw1) - errc <- err - }() - - return <-errc -} diff --git a/vendor/github.com/ginuerzh/gost/http.go b/vendor/github.com/ginuerzh/gost/http.go deleted file mode 100644 index c0ef87f..0000000 --- a/vendor/github.com/ginuerzh/gost/http.go +++ /dev/null @@ -1,410 +0,0 @@ -package gost - -import ( - "bufio" - "crypto/tls" - "encoding/base64" - "errors" - "github.com/ginuerzh/pht" - "github.com/golang/glog" - "golang.org/x/net/http2" - "io" - "net" - "net/http" - "net/http/httputil" - "time" -) - -type HttpServer struct { - conn net.Conn - Base *ProxyServer -} - -func NewHttpServer(conn net.Conn, base *ProxyServer) *HttpServer { - return &HttpServer{ - conn: conn, - Base: base, - } -} - -// Default HTTP server handler -func (s *HttpServer) HandleRequest(req *http.Request) { - glog.V(LINFO).Infof("[http] %s %s - %s %s", req.Method, s.conn.RemoteAddr(), req.Host, req.Proto) - - if glog.V(LDEBUG) { - dump, _ := httputil.DumpRequest(req, false) - glog.Infoln(string(dump)) - } - - if req.Method == "PRI" && req.ProtoMajor == 2 { - glog.V(LWARNING).Infof("[http] %s <- %s : Not an HTTP2 server", s.conn.RemoteAddr(), req.Host) - resp := "HTTP/1.1 400 Bad Request\r\n" + - "Proxy-Agent: gost/" + Version + "\r\n\r\n" - s.conn.Write([]byte(resp)) - return - } - - valid := false - u, p, _ := basicProxyAuth(req.Header.Get("Proxy-Authorization")) - for _, user := range s.Base.Node.Users { - username := user.Username() - password, _ := user.Password() - if (u == username && p == password) || - (u == username && password == "") || - (username == "" && p == password) { - valid = true - break - } - } - - if len(s.Base.Node.Users) > 0 && !valid { - glog.V(LWARNING).Infof("[http] %s <- %s : proxy authentication required", s.conn.RemoteAddr(), req.Host) - resp := "HTTP/1.1 407 Proxy Authentication Required\r\n" + - "Proxy-Authenticate: Basic realm=\"gost\"\r\n" + - "Proxy-Agent: gost/" + Version + "\r\n\r\n" - s.conn.Write([]byte(resp)) - return - } - - req.Header.Del("Proxy-Authorization") - - // forward http request - lastNode := s.Base.Chain.lastNode - if lastNode != nil && lastNode.Transport == "" && (lastNode.Protocol == "http" || lastNode.Protocol == "") { - s.forwardRequest(req) - return - } - - c, err := s.Base.Chain.Dial(req.Host) - if err != nil { - glog.V(LWARNING).Infof("[http] %s -> %s : %s", s.conn.RemoteAddr(), req.Host, err) - - b := []byte("HTTP/1.1 503 Service unavailable\r\n" + - "Proxy-Agent: gost/" + Version + "\r\n\r\n") - glog.V(LDEBUG).Infof("[http] %s <- %s\n%s", s.conn.RemoteAddr(), req.Host, string(b)) - s.conn.Write(b) - return - } - defer c.Close() - - if req.Method == http.MethodConnect { - b := []byte("HTTP/1.1 200 Connection established\r\n" + - "Proxy-Agent: gost/" + Version + "\r\n\r\n") - glog.V(LDEBUG).Infof("[http] %s <- %s\n%s", s.conn.RemoteAddr(), req.Host, string(b)) - s.conn.Write(b) - } else { - req.Header.Del("Proxy-Connection") - req.Header.Set("Connection", "Keep-Alive") - - if err = req.Write(c); err != nil { - glog.V(LWARNING).Infof("[http] %s -> %s : %s", s.conn.RemoteAddr(), req.Host, err) - return - } - } - - glog.V(LINFO).Infof("[http] %s <-> %s", s.conn.RemoteAddr(), req.Host) - s.Base.transport(s.conn, c) - glog.V(LINFO).Infof("[http] %s >-< %s", s.conn.RemoteAddr(), req.Host) -} - -func (s *HttpServer) forwardRequest(req *http.Request) { - last := s.Base.Chain.lastNode - if last == nil { - return - } - cc, err := s.Base.Chain.GetConn() - if err != nil { - glog.V(LWARNING).Infof("[http] %s -> %s : %s", s.conn.RemoteAddr(), last.Addr, err) - - b := []byte("HTTP/1.1 503 Service unavailable\r\n" + - "Proxy-Agent: gost/" + Version + "\r\n\r\n") - glog.V(LDEBUG).Infof("[http] %s <- %s\n%s", s.conn.RemoteAddr(), last.Addr, string(b)) - s.conn.Write(b) - return - } - defer cc.Close() - - if len(last.Users) > 0 { - user := last.Users[0] - s := user.String() - if _, set := user.Password(); !set { - s += ":" - } - req.Header.Set("Proxy-Authorization", - "Basic "+base64.StdEncoding.EncodeToString([]byte(s))) - } - - cc.SetWriteDeadline(time.Now().Add(WriteTimeout)) - if err = req.WriteProxy(cc); err != nil { - glog.V(LWARNING).Infof("[http] %s -> %s : %s", s.conn.RemoteAddr(), req.Host, err) - return - } - cc.SetWriteDeadline(time.Time{}) - - glog.V(LINFO).Infof("[http] %s <-> %s", s.conn.RemoteAddr(), req.Host) - s.Base.transport(s.conn, cc) - glog.V(LINFO).Infof("[http] %s >-< %s", s.conn.RemoteAddr(), req.Host) - return -} - -type Http2Server struct { - Base *ProxyServer - Handler http.Handler - TLSConfig *tls.Config -} - -func NewHttp2Server(base *ProxyServer) *Http2Server { - return &Http2Server{Base: base} -} - -func (s *Http2Server) ListenAndServeTLS(config *tls.Config) error { - srv := http.Server{ - Addr: s.Base.Node.Addr, - Handler: s.Handler, - TLSConfig: config, - } - if srv.Handler == nil { - srv.Handler = http.HandlerFunc(s.HandleRequest) - } - http2.ConfigureServer(&srv, nil) - return srv.ListenAndServeTLS("", "") -} - -// Default HTTP2 server handler -func (s *Http2Server) HandleRequest(w http.ResponseWriter, req *http.Request) { - target := req.Header.Get("Gost-Target") - if target == "" { - target = req.Host - } - glog.V(LINFO).Infof("[http2] %s %s - %s %s", req.Method, req.RemoteAddr, target, req.Proto) - if glog.V(LDEBUG) { - dump, _ := httputil.DumpRequest(req, false) - glog.Infoln(string(dump)) - } - - w.Header().Set("Proxy-Agent", "gost/"+Version) - - // HTTP2 as transport - if req.Header.Get("Proxy-Switch") == "gost" { - conn, err := s.Upgrade(w, req) - if err != nil { - glog.V(LINFO).Infof("[http2] %s -> %s : %s", req.RemoteAddr, target, err) - return - } - glog.V(LINFO).Infof("[http2] %s - %s : switch to HTTP2 transport mode OK", req.RemoteAddr, target) - s.Base.handleConn(conn) - return - } - - valid := false - u, p, _ := basicProxyAuth(req.Header.Get("Proxy-Authorization")) - for _, user := range s.Base.Node.Users { - username := user.Username() - password, _ := user.Password() - if (u == username && p == password) || - (u == username && password == "") || - (username == "" && p == password) { - valid = true - break - } - } - if len(s.Base.Node.Users) > 0 && !valid { - glog.V(LWARNING).Infof("[http2] %s <- %s : proxy authentication required", req.RemoteAddr, target) - w.WriteHeader(http.StatusProxyAuthRequired) - return - } - - req.Header.Del("Proxy-Authorization") - req.Header.Del("Proxy-Connection") - - c, err := s.Base.Chain.Dial(target) - if err != nil { - glog.V(LWARNING).Infof("[http2] %s -> %s : %s", req.RemoteAddr, target, err) - w.WriteHeader(http.StatusServiceUnavailable) - return - } - defer c.Close() - - glog.V(LINFO).Infof("[http2] %s <-> %s", req.RemoteAddr, target) - - if req.Method == http.MethodConnect { - w.WriteHeader(http.StatusOK) - if fw, ok := w.(http.Flusher); ok { - fw.Flush() - } - - // compatible with HTTP1.x - if hj, ok := w.(http.Hijacker); ok && req.ProtoMajor == 1 { - // we take over the underly connection - conn, _, err := hj.Hijack() - if err != nil { - glog.V(LWARNING).Infof("[http2] %s -> %s : %s", req.RemoteAddr, target, err) - w.WriteHeader(http.StatusInternalServerError) - return - } - defer conn.Close() - glog.V(LINFO).Infof("[http2] %s -> %s : downgrade to HTTP/1.1", req.RemoteAddr, target) - s.Base.transport(conn, c) - return - } - - errc := make(chan error, 2) - go func() { - _, err := io.Copy(c, req.Body) - errc <- err - }() - go func() { - _, err := io.Copy(flushWriter{w}, c) - errc <- err - }() - - select { - case <-errc: - // glog.V(LWARNING).Infoln("exit", err) - } - glog.V(LINFO).Infof("[http2] %s >-< %s", req.RemoteAddr, target) - return - } - - req.Header.Set("Connection", "Keep-Alive") - if err = req.Write(c); err != nil { - glog.V(LWARNING).Infof("[http2] %s -> %s : %s", req.RemoteAddr, target, err) - return - } - - resp, err := http.ReadResponse(bufio.NewReader(c), req) - if err != nil { - glog.V(LWARNING).Infoln("[http2] %s -> %s : %s", req.RemoteAddr, target, err) - return - } - defer resp.Body.Close() - - for k, v := range resp.Header { - for _, vv := range v { - w.Header().Add(k, vv) - } - } - w.WriteHeader(resp.StatusCode) - if _, err := io.Copy(flushWriter{w}, resp.Body); err != nil { - glog.V(LWARNING).Infof("[http2] %s <- %s : %s", req.RemoteAddr, target, err) - } - glog.V(LINFO).Infof("[http2] %s >-< %s", req.RemoteAddr, target) -} - -// Upgrade upgrade an HTTP2 request to a bidirectional connection that preparing for tunneling other protocol, just like a websocket connection. -func (s *Http2Server) Upgrade(w http.ResponseWriter, r *http.Request) (net.Conn, error) { - if r.Method != http.MethodConnect { - w.WriteHeader(http.StatusMethodNotAllowed) - return nil, errors.New("Method not allowed") - } - - w.WriteHeader(http.StatusOK) - - if fw, ok := w.(http.Flusher); ok { - fw.Flush() - } - - conn := &http2Conn{r: r.Body, w: flushWriter{w}} - conn.remoteAddr, _ = net.ResolveTCPAddr("tcp", r.RemoteAddr) - conn.localAddr, _ = net.ResolveTCPAddr("tcp", r.Host) - return conn, nil -} - -// HTTP2 client connection, wrapped up just like a net.Conn -type http2Conn struct { - r io.Reader - w io.Writer - remoteAddr net.Addr - localAddr net.Addr -} - -func (c *http2Conn) Read(b []byte) (n int, err error) { - return c.r.Read(b) -} - -func (c *http2Conn) Write(b []byte) (n int, err error) { - return c.w.Write(b) -} - -func (c *http2Conn) Close() (err error) { - if rc, ok := c.r.(io.Closer); ok { - err = rc.Close() - } - if w, ok := c.w.(io.Closer); ok { - err = w.Close() - } - return -} - -func (c *http2Conn) LocalAddr() net.Addr { - return c.localAddr -} - -func (c *http2Conn) RemoteAddr() net.Addr { - return c.remoteAddr -} - -func (c *http2Conn) SetDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "http2", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} - -func (c *http2Conn) SetReadDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "http2", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} - -func (c *http2Conn) SetWriteDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "http2", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} - -type flushWriter struct { - w io.Writer -} - -func (fw flushWriter) Write(p []byte) (n int, err error) { - defer func() { - if r := recover(); r != nil { - if s, ok := r.(string); ok { - err = errors.New(s) - return - } - err = r.(error) - } - }() - - n, err = fw.w.Write(p) - if err != nil { - // glog.V(LWARNING).Infoln("flush writer:", err) - return - } - if f, ok := fw.w.(http.Flusher); ok { - f.Flush() - } - return -} - -type PureHttpServer struct { - Base *ProxyServer - Handler func(net.Conn) -} - -func NewPureHttpServer(base *ProxyServer) *PureHttpServer { - return &PureHttpServer{ - Base: base, - } -} - -func (s *PureHttpServer) ListenAndServe() error { - server := pht.Server{ - Addr: s.Base.Node.Addr, - Key: s.Base.Node.Get("key"), - } - if server.Handler == nil { - server.Handler = s.handleConn - } - return server.ListenAndServe() -} - -func (s *PureHttpServer) handleConn(conn net.Conn) { - glog.V(LINFO).Infof("[pht] %s - %s", conn.RemoteAddr(), conn.LocalAddr()) - s.Base.handleConn(conn) -} diff --git a/vendor/github.com/ginuerzh/gost/kcp.go b/vendor/github.com/ginuerzh/gost/kcp.go deleted file mode 100644 index 1980942..0000000 --- a/vendor/github.com/ginuerzh/gost/kcp.go +++ /dev/null @@ -1,408 +0,0 @@ -// KCP feature is based on https://github.com/xtaci/kcptun - -package gost - -import ( - "crypto/sha1" - "encoding/csv" - "encoding/json" - "fmt" - "github.com/golang/glog" - "github.com/klauspost/compress/snappy" - "golang.org/x/crypto/pbkdf2" - "gopkg.in/xtaci/kcp-go.v2" - "gopkg.in/xtaci/smux.v1" - "net" - "os" - "time" -) - -const ( - DefaultKCPConfigFile = "kcp.json" -) - -var ( - SALT = "kcp-go" -) - -type KCPConfig struct { - Key string `json:"key"` - Crypt string `json:"crypt"` - Mode string `json:"mode"` - MTU int `json:"mtu"` - SndWnd int `json:"sndwnd"` - RcvWnd int `json:"rcvwnd"` - DataShard int `json:"datashard"` - ParityShard int `json:"parityshard"` - DSCP int `json:"dscp"` - NoComp bool `json:"nocomp"` - AckNodelay bool `json:"acknodelay"` - NoDelay int `json:"nodelay"` - Interval int `json:"interval"` - Resend int `json:"resend"` - NoCongestion int `json:"nc"` - SockBuf int `json:"sockbuf"` - KeepAlive int `json:"keepalive"` - SnmpLog string `json:"snmplog"` - SnmpPeriod int `json:"snmpperiod"` -} - -func ParseKCPConfig(configFile string) (*KCPConfig, error) { - if configFile == "" { - configFile = DefaultKCPConfigFile - } - file, err := os.Open(configFile) - if err != nil { - return nil, err - } - defer file.Close() - - config := &KCPConfig{} - if err = json.NewDecoder(file).Decode(config); err != nil { - return nil, err - } - return config, nil -} - -func (c *KCPConfig) Init() { - switch c.Mode { - case "normal": - c.NoDelay, c.Interval, c.Resend, c.NoCongestion = 0, 50, 2, 1 - case "fast2": - c.NoDelay, c.Interval, c.Resend, c.NoCongestion = 1, 30, 2, 1 - case "fast3": - c.NoDelay, c.Interval, c.Resend, c.NoCongestion = 1, 20, 2, 1 - case "fast": - fallthrough - default: - c.NoDelay, c.Interval, c.Resend, c.NoCongestion = 0, 40, 2, 1 - } -} - -var ( - DefaultKCPConfig = &KCPConfig{ - Key: "it's a secrect", - Crypt: "aes", - Mode: "fast", - MTU: 1350, - SndWnd: 1024, - RcvWnd: 1024, - DataShard: 10, - ParityShard: 3, - DSCP: 0, - NoComp: false, - AckNodelay: false, - NoDelay: 0, - Interval: 50, - Resend: 0, - NoCongestion: 0, - SockBuf: 4194304, - KeepAlive: 10, - SnmpLog: "", - SnmpPeriod: 60, - } -) - -type KCPServer struct { - Base *ProxyServer - Config *KCPConfig -} - -func NewKCPServer(base *ProxyServer, config *KCPConfig) *KCPServer { - return &KCPServer{Base: base, Config: config} -} - -func (s *KCPServer) ListenAndServe() (err error) { - if s.Config == nil { - s.Config = DefaultKCPConfig - } - s.Config.Init() - - ln, err := kcp.ListenWithOptions(s.Base.Node.Addr, - blockCrypt(s.Config.Key, s.Config.Crypt, SALT), s.Config.DataShard, s.Config.ParityShard) - if err != nil { - return err - } - if err = ln.SetDSCP(s.Config.DSCP); err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - if err = ln.SetReadBuffer(s.Config.SockBuf); err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - if err = ln.SetWriteBuffer(s.Config.SockBuf); err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - - go snmpLogger(s.Config.SnmpLog, s.Config.SnmpPeriod) - go kcpSigHandler() - for { - conn, err := ln.AcceptKCP() - if err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - continue - } - - conn.SetStreamMode(true) - conn.SetNoDelay(s.Config.NoDelay, s.Config.Interval, s.Config.Resend, s.Config.NoCongestion) - conn.SetMtu(s.Config.MTU) - conn.SetWindowSize(s.Config.SndWnd, s.Config.RcvWnd) - conn.SetACKNoDelay(s.Config.AckNodelay) - conn.SetKeepAlive(s.Config.KeepAlive) - - go s.handleMux(conn) - } -} - -func (s *KCPServer) handleMux(conn net.Conn) { - smuxConfig := smux.DefaultConfig() - smuxConfig.MaxReceiveBuffer = s.Config.SockBuf - - glog.V(LINFO).Infof("[kcp] %s - %s", conn.RemoteAddr(), s.Base.Node.Addr) - - if !s.Config.NoComp { - conn = newCompStreamConn(conn) - } - - mux, err := smux.Server(conn, smuxConfig) - if err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - return - } - defer mux.Close() - - glog.V(LINFO).Infof("[kcp] %s <-> %s", conn.RemoteAddr(), s.Base.Node.Addr) - defer glog.V(LINFO).Infof("[kcp] %s >-< %s", conn.RemoteAddr(), s.Base.Node.Addr) - - for { - stream, err := mux.AcceptStream() - if err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - return - } - go s.Base.handleConn(NewKCPConn(conn, stream)) - } -} - -func blockCrypt(key, crypt, salt string) (block kcp.BlockCrypt) { - pass := pbkdf2.Key([]byte(key), []byte(salt), 4096, 32, sha1.New) - - switch crypt { - case "tea": - block, _ = kcp.NewTEABlockCrypt(pass[:16]) - case "xor": - block, _ = kcp.NewSimpleXORBlockCrypt(pass) - case "none": - block, _ = kcp.NewNoneBlockCrypt(pass) - case "aes-128": - block, _ = kcp.NewAESBlockCrypt(pass[:16]) - case "aes-192": - block, _ = kcp.NewAESBlockCrypt(pass[:24]) - case "blowfish": - block, _ = kcp.NewBlowfishBlockCrypt(pass) - case "twofish": - block, _ = kcp.NewTwofishBlockCrypt(pass) - case "cast5": - block, _ = kcp.NewCast5BlockCrypt(pass[:16]) - case "3des": - block, _ = kcp.NewTripleDESBlockCrypt(pass[:24]) - case "xtea": - block, _ = kcp.NewXTEABlockCrypt(pass[:16]) - case "salsa20": - block, _ = kcp.NewSalsa20BlockCrypt(pass) - case "aes": - fallthrough - default: // aes - block, _ = kcp.NewAESBlockCrypt(pass) - } - return -} - -func snmpLogger(path string, interval int) { - if path == "" || interval == 0 { - return - } - ticker := time.NewTicker(time.Duration(interval) * time.Second) - defer ticker.Stop() - for { - select { - case <-ticker.C: - f, err := os.OpenFile(time.Now().Format(path), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) - if err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - return - } - w := csv.NewWriter(f) - // write header in empty file - if stat, err := f.Stat(); err == nil && stat.Size() == 0 { - if err := w.Write(append([]string{"Unix"}, kcp.DefaultSnmp.Header()...)); err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - } - if err := w.Write(append([]string{fmt.Sprint(time.Now().Unix())}, kcp.DefaultSnmp.ToSlice()...)); err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - kcp.DefaultSnmp.Reset() - w.Flush() - f.Close() - } - } -} - -type KCPSession struct { - conn net.Conn - session *smux.Session -} - -func DialKCP(addr string, config *KCPConfig) (*KCPSession, error) { - if config == nil { - config = DefaultKCPConfig - } - config.Init() - - kcpconn, err := kcp.DialWithOptions(addr, - blockCrypt(config.Key, config.Crypt, SALT), config.DataShard, config.ParityShard) - if err != nil { - return nil, err - } - - kcpconn.SetStreamMode(true) - kcpconn.SetNoDelay(config.NoDelay, config.Interval, config.Resend, config.NoCongestion) - kcpconn.SetWindowSize(config.SndWnd, config.RcvWnd) - kcpconn.SetMtu(config.MTU) - kcpconn.SetACKNoDelay(config.AckNodelay) - kcpconn.SetKeepAlive(config.KeepAlive) - - if err := kcpconn.SetDSCP(config.DSCP); err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - if err := kcpconn.SetReadBuffer(config.SockBuf); err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - if err := kcpconn.SetWriteBuffer(config.SockBuf); err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - - // stream multiplex - smuxConfig := smux.DefaultConfig() - smuxConfig.MaxReceiveBuffer = config.SockBuf - var conn net.Conn = kcpconn - if !config.NoComp { - conn = newCompStreamConn(kcpconn) - } - session, err := smux.Client(conn, smuxConfig) - if err != nil { - conn.Close() - return nil, err - } - return &KCPSession{conn: conn, session: session}, nil -} - -func (session *KCPSession) GetConn() (*KCPConn, error) { - stream, err := session.session.OpenStream() - if err != nil { - session.Close() - return nil, err - } - return NewKCPConn(session.conn, stream), nil -} - -func (session *KCPSession) Close() error { - return session.session.Close() -} - -func (session *KCPSession) IsClosed() bool { - return session.session.IsClosed() -} - -func (session *KCPSession) NumStreams() int { - return session.session.NumStreams() -} - -type KCPConn struct { - conn net.Conn - stream *smux.Stream -} - -func NewKCPConn(conn net.Conn, stream *smux.Stream) *KCPConn { - return &KCPConn{conn: conn, stream: stream} -} - -func (c *KCPConn) Read(b []byte) (n int, err error) { - return c.stream.Read(b) -} - -func (c *KCPConn) Write(b []byte) (n int, err error) { - return c.stream.Write(b) -} - -func (c *KCPConn) Close() error { - return c.stream.Close() -} - -func (c *KCPConn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -func (c *KCPConn) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -func (c *KCPConn) SetDeadline(t time.Time) error { - return c.conn.SetDeadline(t) -} - -func (c *KCPConn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -func (c *KCPConn) SetWriteDeadline(t time.Time) error { - return c.conn.SetWriteDeadline(t) -} - -type compStreamConn struct { - conn net.Conn - w *snappy.Writer - r *snappy.Reader -} - -func newCompStreamConn(conn net.Conn) *compStreamConn { - c := new(compStreamConn) - c.conn = conn - c.w = snappy.NewBufferedWriter(conn) - c.r = snappy.NewReader(conn) - return c -} - -func (c *compStreamConn) Read(b []byte) (n int, err error) { - return c.r.Read(b) -} - -func (c *compStreamConn) Write(b []byte) (n int, err error) { - n, err = c.w.Write(b) - err = c.w.Flush() - return n, err -} - -func (c *compStreamConn) Close() error { - return c.conn.Close() -} - -func (c *compStreamConn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -func (c *compStreamConn) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -func (c *compStreamConn) SetDeadline(t time.Time) error { - return c.conn.SetDeadline(t) -} - -func (c *compStreamConn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -func (c *compStreamConn) SetWriteDeadline(t time.Time) error { - return c.conn.SetWriteDeadline(t) -} diff --git a/vendor/github.com/ginuerzh/gost/node.go b/vendor/github.com/ginuerzh/gost/node.go deleted file mode 100644 index f9398f5..0000000 --- a/vendor/github.com/ginuerzh/gost/node.go +++ /dev/null @@ -1,161 +0,0 @@ -package gost - -import ( - "bufio" - "fmt" - "github.com/golang/glog" - "net" - "net/url" - "os" - "strconv" - "strings" -) - -// Proxy node represent a proxy -type ProxyNode struct { - Addr string // [host]:port - Protocol string // protocol: http/socks5/ss - Transport string // transport: ws/wss/tls/http2/tcp/udp/rtcp/rudp - Remote string // remote address, used by tcp/udp port forwarding - Users []*url.Userinfo // authentication for proxy - values url.Values - serverName string - conn net.Conn -} - -// The proxy node string pattern is [scheme://][user:pass@host]:port. -// -// Scheme can be devided into two parts by character '+', such as: http+tls. -func ParseProxyNode(s string) (node ProxyNode, err error) { - if !strings.Contains(s, "://") { - s = "gost://" + s - } - u, err := url.Parse(s) - if err != nil { - return - } - - node = ProxyNode{ - Addr: u.Host, - values: u.Query(), - serverName: u.Host, - } - - if u.User != nil { - node.Users = append(node.Users, u.User) - } - - users, er := parseUsers(node.Get("secrets")) - if users != nil { - node.Users = append(node.Users, users...) - } - if er != nil { - glog.V(LWARNING).Infoln("secrets:", er) - } - - if strings.Contains(u.Host, ":") { - node.serverName, _, _ = net.SplitHostPort(u.Host) - if node.serverName == "" { - node.serverName = "localhost" // default server name - } - } - - schemes := strings.Split(u.Scheme, "+") - if len(schemes) == 1 { - node.Protocol = schemes[0] - node.Transport = schemes[0] - } - if len(schemes) == 2 { - node.Protocol = schemes[0] - node.Transport = schemes[1] - } - - switch node.Transport { - case "ws", "wss", "tls", "http2", "quic", "kcp", "redirect", "ssu", "pht", "ssh": - case "https": - node.Protocol = "http" - node.Transport = "tls" - case "tcp", "udp": // started from v2.1, tcp and udp are for local port forwarding - node.Remote = strings.Trim(u.EscapedPath(), "/") - case "rtcp", "rudp": // started from v2.1, rtcp and rudp are for remote port forwarding - node.Remote = strings.Trim(u.EscapedPath(), "/") - default: - node.Transport = "" - } - - switch node.Protocol { - case "http", "http2", "socks", "socks4", "socks4a", "socks5", "ss": - default: - node.Protocol = "" - } - - return -} - -func parseUsers(authFile string) (users []*url.Userinfo, err error) { - if authFile == "" { - return - } - - file, err := os.Open(authFile) - if err != nil { - return - } - scanner := bufio.NewScanner(file) - for scanner.Scan() { - line := strings.TrimSpace(scanner.Text()) - if line == "" || strings.HasPrefix(line, "#") { - continue - } - - s := strings.SplitN(line, " ", 2) - if len(s) == 1 { - users = append(users, url.User(strings.TrimSpace(s[0]))) - } else if len(s) == 2 { - users = append(users, url.UserPassword(strings.TrimSpace(s[0]), strings.TrimSpace(s[1]))) - } - } - - err = scanner.Err() - return -} - -// Get get node parameter by key -func (node *ProxyNode) Get(key string) string { - return node.values.Get(key) -} - -func (node *ProxyNode) getBool(key string) bool { - s := node.Get(key) - if b, _ := strconv.ParseBool(s); b { - return b - } - n, _ := strconv.Atoi(s) - return n > 0 -} - -func (node *ProxyNode) Set(key, value string) { - node.values.Set(key, value) -} - -func (node *ProxyNode) insecureSkipVerify() bool { - return !node.getBool("secure") -} - -func (node *ProxyNode) certFile() string { - if cert := node.Get("cert"); cert != "" { - return cert - } - return DefaultCertFile -} - -func (node *ProxyNode) keyFile() string { - if key := node.Get("key"); key != "" { - return key - } - return DefaultKeyFile -} - -func (node ProxyNode) String() string { - return fmt.Sprintf("transport: %s, protocol: %s, addr: %s", node.Transport, node.Protocol, node.Addr) -} diff --git a/vendor/github.com/ginuerzh/gost/quic.go b/vendor/github.com/ginuerzh/gost/quic.go deleted file mode 100644 index 446acf2..0000000 --- a/vendor/github.com/ginuerzh/gost/quic.go +++ /dev/null @@ -1,81 +0,0 @@ -package gost - -import ( - "bufio" - "crypto/tls" - "github.com/golang/glog" - "github.com/lucas-clemente/quic-go/h2quic" - "io" - "net/http" - "net/http/httputil" -) - -type QuicServer struct { - Base *ProxyServer - Handler http.Handler - TLSConfig *tls.Config -} - -func NewQuicServer(base *ProxyServer) *QuicServer { - return &QuicServer{Base: base} -} - -func (s *QuicServer) ListenAndServeTLS(config *tls.Config) error { - server := &h2quic.Server{ - Server: &http.Server{ - Addr: s.Base.Node.Addr, - Handler: s.Handler, - TLSConfig: config, - }, - } - if server.Handler == nil { - // server.Handler = http.HandlerFunc(s.HandleRequest) - server.Handler = http.HandlerFunc(NewHttp2Server(s.Base).HandleRequest) - } - return server.ListenAndServe() -} - -func (s *QuicServer) HandleRequest(w http.ResponseWriter, req *http.Request) { - target := req.Host - glog.V(LINFO).Infof("[quic] %s %s - %s %s", req.Method, req.RemoteAddr, target, req.Proto) - - if glog.V(LDEBUG) { - dump, _ := httputil.DumpRequest(req, false) - glog.Infoln(string(dump)) - } - - c, err := s.Base.Chain.Dial(target) - if err != nil { - glog.V(LWARNING).Infof("[quic] %s -> %s : %s", req.RemoteAddr, target, err) - w.WriteHeader(http.StatusServiceUnavailable) - return - } - defer c.Close() - - glog.V(LINFO).Infof("[quic] %s <-> %s", req.RemoteAddr, target) - - req.Header.Set("Connection", "Keep-Alive") - if err = req.Write(c); err != nil { - glog.V(LWARNING).Infof("[quic] %s -> %s : %s", req.RemoteAddr, target, err) - return - } - - resp, err := http.ReadResponse(bufio.NewReader(c), req) - if err != nil { - glog.V(LWARNING).Infoln(err) - return - } - defer resp.Body.Close() - - for k, v := range resp.Header { - for _, vv := range v { - w.Header().Add(k, vv) - } - } - w.WriteHeader(resp.StatusCode) - if _, err := io.Copy(flushWriter{w}, resp.Body); err != nil { - glog.V(LWARNING).Infof("[quic] %s <- %s : %s", req.RemoteAddr, target, err) - } - - glog.V(LINFO).Infof("[quic] %s >-< %s", req.RemoteAddr, target) -} diff --git a/vendor/github.com/ginuerzh/gost/redirect.go b/vendor/github.com/ginuerzh/gost/redirect.go deleted file mode 100644 index 7524418..0000000 --- a/vendor/github.com/ginuerzh/gost/redirect.go +++ /dev/null @@ -1,103 +0,0 @@ -// +build !windows - -package gost - -import ( - "errors" - "fmt" - "github.com/golang/glog" - "net" - "syscall" -) - -const ( - SO_ORIGINAL_DST = 80 -) - -type RedsocksTCPServer struct { - Base *ProxyServer -} - -func NewRedsocksTCPServer(base *ProxyServer) *RedsocksTCPServer { - return &RedsocksTCPServer{ - Base: base, - } -} - -func (s *RedsocksTCPServer) ListenAndServe() error { - laddr, err := net.ResolveTCPAddr("tcp", s.Base.Node.Addr) - if err != nil { - return err - } - ln, err := net.ListenTCP("tcp", laddr) - if err != nil { - return err - } - - defer ln.Close() - for { - conn, err := ln.AcceptTCP() - if err != nil { - glog.V(LWARNING).Infoln(err) - continue - } - go s.handleRedirectTCP(conn) - } -} - -func (s *RedsocksTCPServer) handleRedirectTCP(conn *net.TCPConn) { - srcAddr := conn.RemoteAddr() - dstAddr, conn, err := getOriginalDstAddr(conn) - if err != nil { - glog.V(LWARNING).Infof("[red-tcp] %s -> %s : %s", srcAddr, dstAddr, err) - return - } - defer conn.Close() - - glog.V(LINFO).Infof("[red-tcp] %s -> %s", srcAddr, dstAddr) - - cc, err := s.Base.Chain.Dial(dstAddr.String()) - if err != nil { - glog.V(LWARNING).Infof("[red-tcp] %s -> %s : %s", srcAddr, dstAddr, err) - return - } - defer cc.Close() - - glog.V(LINFO).Infof("[red-tcp] %s <-> %s", srcAddr, dstAddr) - s.Base.transport(conn, cc) - glog.V(LINFO).Infof("[red-tcp] %s >-< %s", srcAddr, dstAddr) -} - -func getOriginalDstAddr(conn *net.TCPConn) (addr net.Addr, c *net.TCPConn, err error) { - defer conn.Close() - - fc, err := conn.File() - if err != nil { - return - } - defer fc.Close() - - mreq, err := syscall.GetsockoptIPv6Mreq(int(fc.Fd()), syscall.IPPROTO_IP, SO_ORIGINAL_DST) - if err != nil { - return - } - - // only ipv4 support - ip := net.IPv4(mreq.Multiaddr[4], mreq.Multiaddr[5], mreq.Multiaddr[6], mreq.Multiaddr[7]) - port := uint16(mreq.Multiaddr[2])<<8 + uint16(mreq.Multiaddr[3]) - addr, err = net.ResolveTCPAddr("tcp4", fmt.Sprintf("%s:%d", ip.String(), port)) - if err != nil { - return - } - - cc, err := net.FileConn(fc) - if err != nil { - return - } - - c, ok := cc.(*net.TCPConn) - if !ok { - err = errors.New("not a TCP connection") - } - return -} diff --git a/vendor/github.com/ginuerzh/gost/redirect_win.go b/vendor/github.com/ginuerzh/gost/redirect_win.go deleted file mode 100644 index 116bdd8..0000000 --- a/vendor/github.com/ginuerzh/gost/redirect_win.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build windows - -package gost - -import ( - "errors" -) - -type RedsocksTCPServer struct{} - -func NewRedsocksTCPServer(base *ProxyServer) *RedsocksTCPServer { - return &RedsocksTCPServer{} -} - -func (s *RedsocksTCPServer) ListenAndServe() error { - return errors.New("Not supported") -} diff --git a/vendor/github.com/ginuerzh/gost/server.go b/vendor/github.com/ginuerzh/gost/server.go deleted file mode 100644 index 5e1f0e8..0000000 --- a/vendor/github.com/ginuerzh/gost/server.go +++ /dev/null @@ -1,284 +0,0 @@ -package gost - -import ( - "bufio" - "crypto/tls" - "github.com/ginuerzh/gosocks4" - "github.com/ginuerzh/gosocks5" - "github.com/golang/glog" - ss "github.com/shadowsocks/shadowsocks-go/shadowsocks" - "golang.org/x/crypto/ssh" - "io" - "io/ioutil" - "net" - "net/http" - "strconv" - "strings" -) - -type ProxyServer struct { - Node ProxyNode - Chain *ProxyChain - TLSConfig *tls.Config - selector *serverSelector - cipher *ss.Cipher - ota bool -} - -func NewProxyServer(node ProxyNode, chain *ProxyChain, config *tls.Config) *ProxyServer { - if chain == nil { - chain = NewProxyChain() - } - if config == nil { - config = &tls.Config{} - } - - var cipher *ss.Cipher - var ota bool - if node.Protocol == "ss" || node.Transport == "ssu" { - var err error - var method, password string - - if len(node.Users) > 0 { - method = node.Users[0].Username() - password, _ = node.Users[0].Password() - } - ota = node.getBool("ota") - if strings.HasSuffix(method, "-auth") { - ota = true - method = strings.TrimSuffix(method, "-auth") - } - cipher, err = ss.NewCipher(method, password) - if err != nil { - glog.Fatal(err) - } - } - return &ProxyServer{ - Node: node, - Chain: chain, - TLSConfig: config, - selector: &serverSelector{ // socks5 server selector - // methods that socks5 server supported - methods: []uint8{ - gosocks5.MethodNoAuth, - gosocks5.MethodUserPass, - MethodTLS, - MethodTLSAuth, - }, - users: node.Users, - tlsConfig: config, - }, - cipher: cipher, - ota: ota, - } -} - -func (s *ProxyServer) Serve() error { - var ln net.Listener - var err error - node := s.Node - - switch node.Transport { - case "ws": // websocket connection - return NewWebsocketServer(s).ListenAndServe() - case "wss": // websocket security connection - return NewWebsocketServer(s).ListenAndServeTLS(s.TLSConfig) - case "tls": // tls connection - ln, err = tls.Listen("tcp", node.Addr, s.TLSConfig) - case "http2": // Standard HTTP2 proxy server, compatible with HTTP1.x. - server := NewHttp2Server(s) - server.Handler = http.HandlerFunc(server.HandleRequest) - return server.ListenAndServeTLS(s.TLSConfig) - case "tcp": // Local TCP port forwarding - return NewTcpForwardServer(s).ListenAndServe() - case "udp": // Local UDP port forwarding - ttl, _ := strconv.Atoi(s.Node.Get("ttl")) - if ttl <= 0 { - ttl = DefaultTTL - } - return NewUdpForwardServer(s, ttl).ListenAndServe() - case "rtcp": // Remote TCP port forwarding - return NewRTcpForwardServer(s).Serve() - case "rudp": // Remote UDP port forwarding - return NewRUdpForwardServer(s).Serve() - case "quic": - return NewQuicServer(s).ListenAndServeTLS(s.TLSConfig) - case "kcp": - config, err := ParseKCPConfig(s.Node.Get("c")) - if err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - if config == nil { - config = DefaultKCPConfig - } - // override crypt and key if specified explicitly - if s.Node.Users != nil { - config.Crypt = s.Node.Users[0].Username() - config.Key, _ = s.Node.Users[0].Password() - } - return NewKCPServer(s, config).ListenAndServe() - case "redirect": - return NewRedsocksTCPServer(s).ListenAndServe() - case "ssu": // shadowsocks udp relay - ttl, _ := strconv.Atoi(s.Node.Get("ttl")) - if ttl <= 0 { - ttl = DefaultTTL - } - return NewShadowUdpServer(s, ttl).ListenAndServe() - case "pht": // pure http tunnel - return NewPureHttpServer(s).ListenAndServe() - case "ssh": // SSH tunnel - key := s.Node.Get("key") - privateBytes, err := ioutil.ReadFile(key) - if err != nil { - glog.V(LWARNING).Infoln("[ssh]", err) - privateBytes = defaultRawKey - } - private, err := ssh.ParsePrivateKey(privateBytes) - if err != nil { - return err - } - config := ssh.ServerConfig{ - PasswordCallback: DefaultPasswordCallback(s.Node.Users), - } - if len(s.Node.Users) == 0 { - config.NoClientAuth = true - } - - config.AddHostKey(private) - s := &SSHServer{ - Addr: node.Addr, - Base: s, - Config: &config, - } - return s.ListenAndServe() - default: - ln, err = net.Listen("tcp", node.Addr) - } - - if err != nil { - return err - } - - defer ln.Close() - - for { - conn, err := ln.Accept() - if err != nil { - glog.V(LWARNING).Infoln(err) - continue - } - - setKeepAlive(conn, KeepAliveTime) - - go s.handleConn(conn) - } -} - -func (s *ProxyServer) handleConn(conn net.Conn) { - defer conn.Close() - - switch s.Node.Protocol { - case "ss": // shadowsocks - server := NewShadowServer(ss.NewConn(conn, s.cipher.Copy()), s) - server.OTA = s.ota - server.Serve() - return - case "http": - req, err := http.ReadRequest(bufio.NewReader(conn)) - if err != nil { - glog.V(LWARNING).Infoln("[http]", err) - return - } - NewHttpServer(conn, s).HandleRequest(req) - return - case "socks", "socks5": - conn = gosocks5.ServerConn(conn, s.selector) - req, err := gosocks5.ReadRequest(conn) - if err != nil { - glog.V(LWARNING).Infoln("[socks5]", err) - return - } - NewSocks5Server(conn, s).HandleRequest(req) - return - case "socks4", "socks4a": - req, err := gosocks4.ReadRequest(conn) - if err != nil { - glog.V(LWARNING).Infoln("[socks4]", err) - return - } - NewSocks4Server(conn, s).HandleRequest(req) - return - } - - br := bufio.NewReader(conn) - b, err := br.Peek(1) - if err != nil { - glog.V(LWARNING).Infoln(err) - return - } - - switch b[0] { - case gosocks4.Ver4: - req, err := gosocks4.ReadRequest(br) - if err != nil { - glog.V(LWARNING).Infoln("[socks4]", err) - return - } - NewSocks4Server(conn, s).HandleRequest(req) - - case gosocks5.Ver5: - methods, err := gosocks5.ReadMethods(br) - if err != nil { - glog.V(LWARNING).Infoln("[socks5]", err) - return - } - method := s.selector.Select(methods...) - if _, err := conn.Write([]byte{gosocks5.Ver5, method}); err != nil { - glog.V(LWARNING).Infoln("[socks5] select:", err) - return - } - c, err := s.selector.OnSelected(method, conn) - if err != nil { - glog.V(LWARNING).Infoln("[socks5] onselected:", err) - return - } - conn = c - - req, err := gosocks5.ReadRequest(conn) - if err != nil { - glog.V(LWARNING).Infoln("[socks5] request:", err) - return - } - NewSocks5Server(conn, s).HandleRequest(req) - - default: // http - req, err := http.ReadRequest(br) - if err != nil { - glog.V(LWARNING).Infoln("[http]", err) - return - } - NewHttpServer(conn, s).HandleRequest(req) - } -} - -func (_ *ProxyServer) transport(conn1, conn2 net.Conn) (err error) { - errc := make(chan error, 2) - - go func() { - _, err := io.Copy(conn1, conn2) - errc <- err - }() - - go func() { - _, err := io.Copy(conn2, conn1) - errc <- err - }() - - select { - case err = <-errc: - // glog.V(LWARNING).Infoln("transport exit", err) - } - - return -} diff --git a/vendor/github.com/ginuerzh/gost/signal.go b/vendor/github.com/ginuerzh/gost/signal.go deleted file mode 100644 index f12e902..0000000 --- a/vendor/github.com/ginuerzh/gost/signal.go +++ /dev/null @@ -1,5 +0,0 @@ -// +build windows - -package gost - -func kcpSigHandler() {} diff --git a/vendor/github.com/ginuerzh/gost/signal_unix.go b/vendor/github.com/ginuerzh/gost/signal_unix.go deleted file mode 100644 index f46b394..0000000 --- a/vendor/github.com/ginuerzh/gost/signal_unix.go +++ /dev/null @@ -1,23 +0,0 @@ -// +build !windows - -package gost - -import ( - "github.com/golang/glog" - "gopkg.in/xtaci/kcp-go.v2" - "os" - "os/signal" - "syscall" -) - -func kcpSigHandler() { - ch := make(chan os.Signal, 1) - signal.Notify(ch, syscall.SIGUSR1) - - for { - switch <-ch { - case syscall.SIGUSR1: - glog.V(LINFO).Infof("[kcp] SNMP: %+v", kcp.DefaultSnmp.Copy()) - } - } -} diff --git a/vendor/github.com/ginuerzh/gost/socks.go b/vendor/github.com/ginuerzh/gost/socks.go deleted file mode 100644 index 7727286..0000000 --- a/vendor/github.com/ginuerzh/gost/socks.go +++ /dev/null @@ -1,746 +0,0 @@ -package gost - -import ( - "bytes" - "crypto/tls" - "github.com/ginuerzh/gosocks4" - "github.com/ginuerzh/gosocks5" - "github.com/golang/glog" - "net" - "net/url" - "strconv" - "time" -) - -const ( - MethodTLS uint8 = 0x80 // extended method for tls - MethodTLSAuth uint8 = 0x82 // extended method for tls+auth -) - -const ( - CmdUdpTun uint8 = 0xF3 // extended method for udp over tcp -) - -type clientSelector struct { - methods []uint8 - user *url.Userinfo - tlsConfig *tls.Config -} - -func (selector *clientSelector) Methods() []uint8 { - return selector.methods -} - -func (selector *clientSelector) Select(methods ...uint8) (method uint8) { - return -} - -func (selector *clientSelector) OnSelected(method uint8, conn net.Conn) (net.Conn, error) { - switch method { - case MethodTLS: - conn = tls.Client(conn, selector.tlsConfig) - - case gosocks5.MethodUserPass, MethodTLSAuth: - if method == MethodTLSAuth { - conn = tls.Client(conn, selector.tlsConfig) - } - - var username, password string - if selector.user != nil { - username = selector.user.Username() - password, _ = selector.user.Password() - } - - req := gosocks5.NewUserPassRequest(gosocks5.UserPassVer, username, password) - if err := req.Write(conn); err != nil { - glog.V(LWARNING).Infoln("socks5 auth:", err) - return nil, err - } - glog.V(LDEBUG).Infoln(req) - - resp, err := gosocks5.ReadUserPassResponse(conn) - if err != nil { - glog.V(LWARNING).Infoln("socks5 auth:", err) - return nil, err - } - glog.V(LDEBUG).Infoln(resp) - - if resp.Status != gosocks5.Succeeded { - return nil, gosocks5.ErrAuthFailure - } - case gosocks5.MethodNoAcceptable: - return nil, gosocks5.ErrBadMethod - } - - return conn, nil -} - -type serverSelector struct { - methods []uint8 - users []*url.Userinfo - tlsConfig *tls.Config -} - -func (selector *serverSelector) Methods() []uint8 { - return selector.methods -} - -func (selector *serverSelector) Select(methods ...uint8) (method uint8) { - glog.V(LDEBUG).Infof("%d %d %v", gosocks5.Ver5, len(methods), methods) - - method = gosocks5.MethodNoAuth - for _, m := range methods { - if m == MethodTLS { - method = m - break - } - } - - // when user/pass is set, auth is mandatory - if selector.users != nil { - if method == gosocks5.MethodNoAuth { - method = gosocks5.MethodUserPass - } - if method == MethodTLS { - method = MethodTLSAuth - } - } - - return -} - -func (selector *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Conn, error) { - glog.V(LDEBUG).Infof("%d %d", gosocks5.Ver5, method) - - switch method { - case MethodTLS: - conn = tls.Server(conn, selector.tlsConfig) - - case gosocks5.MethodUserPass, MethodTLSAuth: - if method == MethodTLSAuth { - conn = tls.Server(conn, selector.tlsConfig) - } - - req, err := gosocks5.ReadUserPassRequest(conn) - if err != nil { - glog.V(LWARNING).Infoln("[socks5-auth]", err) - return nil, err - } - glog.V(LDEBUG).Infoln("[socks5]", req.String()) - - valid := false - for _, user := range selector.users { - username := user.Username() - password, _ := user.Password() - if (req.Username == username && req.Password == password) || - (req.Username == username && password == "") || - (username == "" && req.Password == password) { - valid = true - break - } - } - if len(selector.users) > 0 && !valid { - resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Failure) - if err := resp.Write(conn); err != nil { - glog.V(LWARNING).Infoln("[socks5-auth]", err) - return nil, err - } - glog.V(LDEBUG).Infoln("[socks5]", resp) - glog.V(LWARNING).Infoln("[socks5-auth] proxy authentication required") - - return nil, gosocks5.ErrAuthFailure - } - - resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Succeeded) - if err := resp.Write(conn); err != nil { - glog.V(LWARNING).Infoln("[socks5-auth]", err) - return nil, err - } - glog.V(LDEBUG).Infoln(resp) - - case gosocks5.MethodNoAcceptable: - return nil, gosocks5.ErrBadMethod - } - - return conn, nil -} - -type Socks5Server struct { - conn net.Conn - Base *ProxyServer -} - -func NewSocks5Server(conn net.Conn, base *ProxyServer) *Socks5Server { - return &Socks5Server{conn: conn, Base: base} -} - -func (s *Socks5Server) HandleRequest(req *gosocks5.Request) { - glog.V(LDEBUG).Infof("[socks5] %s -> %s\n%s", s.conn.RemoteAddr(), req.Addr, req) - - switch req.Cmd { - case gosocks5.CmdConnect: - glog.V(LINFO).Infof("[socks5-connect] %s -> %s", s.conn.RemoteAddr(), req.Addr) - s.handleConnect(req) - - case gosocks5.CmdBind: - glog.V(LINFO).Infof("[socks5-bind] %s - %s", s.conn.RemoteAddr(), req.Addr) - s.handleBind(req) - - case gosocks5.CmdUdp: - glog.V(LINFO).Infof("[socks5-udp] %s - %s", s.conn.RemoteAddr(), req.Addr) - s.handleUDPRelay(req) - - case CmdUdpTun: - glog.V(LINFO).Infof("[socks5-udp] %s - %s", s.conn.RemoteAddr(), req.Addr) - s.handleUDPTunnel(req) - - default: - glog.V(LWARNING).Infoln("[socks5] Unrecognized request:", req.Cmd) - } -} - -func (s *Socks5Server) handleConnect(req *gosocks5.Request) { - cc, err := s.Base.Chain.Dial(req.Addr.String()) - if err != nil { - glog.V(LWARNING).Infof("[socks5-connect] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err) - rep := gosocks5.NewReply(gosocks5.HostUnreachable, nil) - rep.Write(s.conn) - glog.V(LDEBUG).Infof("[socks5-connect] %s <- %s\n%s", s.conn.RemoteAddr(), req.Addr, rep) - return - } - defer cc.Close() - - rep := gosocks5.NewReply(gosocks5.Succeeded, nil) - if err := rep.Write(s.conn); err != nil { - glog.V(LWARNING).Infof("[socks5-connect] %s <- %s : %s", s.conn.RemoteAddr(), req.Addr, err) - return - } - glog.V(LDEBUG).Infof("[socks5-connect] %s <- %s\n%s", s.conn.RemoteAddr(), req.Addr, rep) - - glog.V(LINFO).Infof("[socks5-connect] %s <-> %s", s.conn.RemoteAddr(), req.Addr) - //Transport(conn, cc) - s.Base.transport(s.conn, cc) - glog.V(LINFO).Infof("[socks5-connect] %s >-< %s", s.conn.RemoteAddr(), req.Addr) -} - -func (s *Socks5Server) handleBind(req *gosocks5.Request) { - cc, err := s.Base.Chain.GetConn() - - // connection error - if err != nil && err != ErrEmptyChain { - glog.V(LWARNING).Infof("[socks5-bind] %s <- %s : %s", s.conn.RemoteAddr(), req.Addr, err) - reply := gosocks5.NewReply(gosocks5.Failure, nil) - reply.Write(s.conn) - glog.V(LDEBUG).Infof("[socks5-bind] %s <- %s\n%s", s.conn.RemoteAddr(), req.Addr, reply) - return - } - // serve socks5 bind - if err == ErrEmptyChain { - s.bindOn(req.Addr.String()) - return - } - - defer cc.Close() - // forward request - req.Write(cc) - - glog.V(LINFO).Infof("[socks5-bind] %s <-> %s", s.conn.RemoteAddr(), cc.RemoteAddr()) - s.Base.transport(s.conn, cc) - glog.V(LINFO).Infof("[socks5-bind] %s >-< %s", s.conn.RemoteAddr(), cc.RemoteAddr()) -} - -func (s *Socks5Server) handleUDPRelay(req *gosocks5.Request) { - bindAddr, _ := net.ResolveUDPAddr("udp", req.Addr.String()) - relay, err := net.ListenUDP("udp", bindAddr) // udp associate, strict mode: if the port already in use, it will return error - if err != nil { - glog.V(LWARNING).Infof("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err) - reply := gosocks5.NewReply(gosocks5.Failure, nil) - reply.Write(s.conn) - glog.V(LDEBUG).Infof("[socks5-udp] %s <- %s\n%s", s.conn.RemoteAddr(), req.Addr, reply) - return - } - defer relay.Close() - - socksAddr := ToSocksAddr(relay.LocalAddr()) - socksAddr.Host, _, _ = net.SplitHostPort(s.conn.LocalAddr().String()) - reply := gosocks5.NewReply(gosocks5.Succeeded, socksAddr) - if err := reply.Write(s.conn); err != nil { - glog.V(LWARNING).Infof("[socks5-udp] %s <- %s : %s", s.conn.RemoteAddr(), req.Addr, err) - return - } - glog.V(LDEBUG).Infof("[socks5-udp] %s <- %s\n%s", s.conn.RemoteAddr(), reply.Addr, reply) - glog.V(LINFO).Infof("[socks5-udp] %s - %s BIND ON %s OK", s.conn.RemoteAddr(), req.Addr, socksAddr) - - cc, err := s.Base.Chain.GetConn() - // connection error - if err != nil && err != ErrEmptyChain { - glog.V(LWARNING).Infof("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), socksAddr, err) - return - } - - // serve as standard socks5 udp relay local <-> remote - if err == ErrEmptyChain { - peer, er := net.ListenUDP("udp", nil) - if er != nil { - glog.V(LWARNING).Infof("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), socksAddr, er) - return - } - defer peer.Close() - - go s.transportUDP(relay, peer) - } - - // forward udp local <-> tunnel - if err == nil { - defer cc.Close() - - cc.SetWriteDeadline(time.Now().Add(WriteTimeout)) - req := gosocks5.NewRequest(CmdUdpTun, nil) - if err := req.Write(cc); err != nil { - glog.V(LWARNING).Infoln("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), cc.RemoteAddr(), err) - return - } - cc.SetWriteDeadline(time.Time{}) - glog.V(LDEBUG).Infof("[socks5-udp] %s -> %s\n%s", s.conn.RemoteAddr(), cc.RemoteAddr(), req) - - cc.SetReadDeadline(time.Now().Add(ReadTimeout)) - reply, err = gosocks5.ReadReply(cc) - if err != nil { - glog.V(LWARNING).Infoln("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), cc.RemoteAddr(), err) - return - } - glog.V(LDEBUG).Infof("[socks5-udp] %s <- %s\n%s", s.conn.RemoteAddr(), cc.RemoteAddr(), reply) - - if reply.Rep != gosocks5.Succeeded { - glog.V(LWARNING).Infoln("[socks5-udp] %s <- %s : udp associate failed", s.conn.RemoteAddr(), cc.RemoteAddr()) - return - } - cc.SetReadDeadline(time.Time{}) - glog.V(LINFO).Infof("[socks5-udp] %s <-> %s [tun: %s]", s.conn.RemoteAddr(), socksAddr, reply.Addr) - - go s.tunnelClientUDP(relay, cc) - } - - glog.V(LINFO).Infof("[socks5-udp] %s <-> %s", s.conn.RemoteAddr(), socksAddr) - b := make([]byte, SmallBufferSize) - for { - _, err := s.conn.Read(b) // discard any data from tcp connection - if err != nil { - glog.V(LWARNING).Infof("[socks5-udp] %s - %s : %s", s.conn.RemoteAddr(), socksAddr, err) - break // client disconnected - } - } - glog.V(LINFO).Infof("[socks5-udp] %s >-< %s", s.conn.RemoteAddr(), socksAddr) -} - -func (s *Socks5Server) handleUDPTunnel(req *gosocks5.Request) { - cc, err := s.Base.Chain.GetConn() - - // connection error - if err != nil && err != ErrEmptyChain { - glog.V(LWARNING).Infof("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err) - reply := gosocks5.NewReply(gosocks5.Failure, nil) - reply.Write(s.conn) - glog.V(LDEBUG).Infof("[socks5-udp] %s -> %s\n%s", s.conn.RemoteAddr(), req.Addr, reply) - return - } - - // serve tunnel udp, tunnel <-> remote, handle tunnel udp request - if err == ErrEmptyChain { - bindAddr, _ := net.ResolveUDPAddr("udp", req.Addr.String()) - uc, err := net.ListenUDP("udp", bindAddr) - if err != nil { - glog.V(LWARNING).Infof("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err) - return - } - defer uc.Close() - - socksAddr := ToSocksAddr(uc.LocalAddr()) - socksAddr.Host, _, _ = net.SplitHostPort(s.conn.LocalAddr().String()) - reply := gosocks5.NewReply(gosocks5.Succeeded, socksAddr) - if err := reply.Write(s.conn); err != nil { - glog.V(LWARNING).Infof("[socks5-udp] %s <- %s : %s", s.conn.RemoteAddr(), socksAddr, err) - return - } - glog.V(LDEBUG).Infof("[socks5-udp] %s <- %s\n%s", s.conn.RemoteAddr(), socksAddr, reply) - - glog.V(LINFO).Infof("[socks5-udp] %s <-> %s", s.conn.RemoteAddr(), socksAddr) - s.tunnelServerUDP(s.conn, uc) - glog.V(LINFO).Infof("[socks5-udp] %s >-< %s", s.conn.RemoteAddr(), socksAddr) - return - } - - defer cc.Close() - - // tunnel <-> tunnel, direct forwarding - req.Write(cc) - - glog.V(LINFO).Infof("[socks5-udp] %s <-> %s [tun]", s.conn.RemoteAddr(), cc.RemoteAddr()) - s.Base.transport(s.conn, cc) - glog.V(LINFO).Infof("[socks5-udp] %s >-< %s [tun]", s.conn.RemoteAddr(), cc.RemoteAddr()) -} - -func (s *Socks5Server) bindOn(addr string) { - bindAddr, _ := net.ResolveTCPAddr("tcp", addr) - ln, err := net.ListenTCP("tcp", bindAddr) // strict mode: if the port already in use, it will return error - if err != nil { - glog.V(LWARNING).Infof("[socks5-bind] %s -> %s : %s", s.conn.RemoteAddr(), addr, err) - gosocks5.NewReply(gosocks5.Failure, nil).Write(s.conn) - return - } - - socksAddr := ToSocksAddr(ln.Addr()) - // Issue: may not reachable when host has multi-interface - socksAddr.Host, _, _ = net.SplitHostPort(s.conn.LocalAddr().String()) - reply := gosocks5.NewReply(gosocks5.Succeeded, socksAddr) - if err := reply.Write(s.conn); err != nil { - glog.V(LWARNING).Infof("[socks5-bind] %s <- %s : %s", s.conn.RemoteAddr(), addr, err) - ln.Close() - return - } - glog.V(LDEBUG).Infof("[socks5-bind] %s <- %s\n%s", s.conn.RemoteAddr(), addr, reply) - glog.V(LINFO).Infof("[socks5-bind] %s - %s BIND ON %s OK", s.conn.RemoteAddr(), addr, socksAddr) - - var pconn net.Conn - accept := func() <-chan error { - errc := make(chan error, 1) - - go func() { - defer close(errc) - defer ln.Close() - - c, err := ln.AcceptTCP() - if err != nil { - errc <- err - return - } - pconn = c - }() - - return errc - } - - pc1, pc2 := net.Pipe() - pipe := func() <-chan error { - errc := make(chan error, 1) - - go func() { - defer close(errc) - defer pc1.Close() - - errc <- s.Base.transport(s.conn, pc1) - }() - - return errc - } - - defer pc2.Close() - - for { - select { - case err := <-accept(): - if err != nil || pconn == nil { - glog.V(LWARNING).Infof("[socks5-bind] %s <- %s : %s", s.conn.RemoteAddr(), addr, err) - return - } - defer pconn.Close() - - reply := gosocks5.NewReply(gosocks5.Succeeded, ToSocksAddr(pconn.RemoteAddr())) - if err := reply.Write(pc2); err != nil { - glog.V(LWARNING).Infof("[socks5-bind] %s <- %s : %s", s.conn.RemoteAddr(), addr, err) - } - glog.V(LDEBUG).Infof("[socks5-bind] %s <- %s\n%s", s.conn.RemoteAddr(), addr, reply) - glog.V(LINFO).Infof("[socks5-bind] %s <- %s PEER %s ACCEPTED", s.conn.RemoteAddr(), socksAddr, pconn.RemoteAddr()) - - glog.V(LINFO).Infof("[socks5-bind] %s <-> %s", s.conn.RemoteAddr(), pconn.RemoteAddr()) - if err = s.Base.transport(pc2, pconn); err != nil { - glog.V(LWARNING).Infoln(err) - } - glog.V(LINFO).Infof("[socks5-bind] %s >-< %s", s.conn.RemoteAddr(), pconn.RemoteAddr()) - return - case err := <-pipe(): - glog.V(LWARNING).Infof("[socks5-bind] %s -> %s : %v", s.conn.RemoteAddr(), addr, err) - ln.Close() - return - } - } -} - -func (s *Socks5Server) transportUDP(relay, peer *net.UDPConn) (err error) { - errc := make(chan error, 2) - - var clientAddr *net.UDPAddr - - go func() { - b := make([]byte, LargeBufferSize) - - for { - n, laddr, err := relay.ReadFromUDP(b) - if err != nil { - errc <- err - return - } - if clientAddr == nil { - clientAddr = laddr - } - dgram, err := gosocks5.ReadUDPDatagram(bytes.NewReader(b[:n])) - if err != nil { - errc <- err - return - } - - raddr, err := net.ResolveUDPAddr("udp", dgram.Header.Addr.String()) - if err != nil { - continue // drop silently - } - if _, err := peer.WriteToUDP(dgram.Data, raddr); err != nil { - errc <- err - return - } - glog.V(LDEBUG).Infof("[socks5-udp] %s >>> %s length: %d", relay.LocalAddr(), raddr, len(dgram.Data)) - } - }() - - go func() { - b := make([]byte, LargeBufferSize) - - for { - n, raddr, err := peer.ReadFromUDP(b) - if err != nil { - errc <- err - return - } - if clientAddr == nil { - continue - } - buf := bytes.Buffer{} - dgram := gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(0, 0, ToSocksAddr(raddr)), b[:n]) - dgram.Write(&buf) - if _, err := relay.WriteToUDP(buf.Bytes(), clientAddr); err != nil { - errc <- err - return - } - glog.V(LDEBUG).Infof("[socks5-udp] %s <<< %s length: %d", relay.LocalAddr(), raddr, len(dgram.Data)) - } - }() - - select { - case err = <-errc: - //log.Println("w exit", err) - } - - return -} - -func (s *Socks5Server) tunnelClientUDP(uc *net.UDPConn, cc net.Conn) (err error) { - errc := make(chan error, 2) - - var clientAddr *net.UDPAddr - - go func() { - b := make([]byte, LargeBufferSize) - - for { - n, addr, err := uc.ReadFromUDP(b) - if err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s <- %s : %s", cc.RemoteAddr(), addr, err) - errc <- err - return - } - - // glog.V(LDEBUG).Infof("read udp %d, % #x", n, b[:n]) - // pipe from relay to tunnel - dgram, err := gosocks5.ReadUDPDatagram(bytes.NewReader(b[:n])) - if err != nil { - errc <- err - return - } - if clientAddr == nil { - clientAddr = addr - } - dgram.Header.Rsv = uint16(len(dgram.Data)) - if err := dgram.Write(cc); err != nil { - errc <- err - return - } - glog.V(LDEBUG).Infof("[udp-tun] %s >>> %s length: %d", uc.LocalAddr(), dgram.Header.Addr, len(dgram.Data)) - } - }() - - go func() { - for { - dgram, err := gosocks5.ReadUDPDatagram(cc) - if err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s -> 0 : %s", cc.RemoteAddr(), err) - errc <- err - return - } - - // pipe from tunnel to relay - if clientAddr == nil { - continue - } - dgram.Header.Rsv = 0 - - buf := bytes.Buffer{} - dgram.Write(&buf) - if _, err := uc.WriteToUDP(buf.Bytes(), clientAddr); err != nil { - errc <- err - return - } - glog.V(LDEBUG).Infof("[udp-tun] %s <<< %s length: %d", uc.LocalAddr(), dgram.Header.Addr, len(dgram.Data)) - } - }() - - select { - case err = <-errc: - } - - return -} - -func (s *Socks5Server) tunnelServerUDP(cc net.Conn, uc *net.UDPConn) (err error) { - errc := make(chan error, 2) - - go func() { - b := make([]byte, LargeBufferSize) - - for { - n, addr, err := uc.ReadFromUDP(b) - if err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s <- %s : %s", cc.RemoteAddr(), addr, err) - errc <- err - return - } - - // pipe from peer to tunnel - dgram := gosocks5.NewUDPDatagram( - gosocks5.NewUDPHeader(uint16(n), 0, ToSocksAddr(addr)), b[:n]) - if err := dgram.Write(cc); err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s <- %s : %s", cc.RemoteAddr(), dgram.Header.Addr, err) - errc <- err - return - } - glog.V(LDEBUG).Infof("[udp-tun] %s <<< %s length: %d", cc.RemoteAddr(), dgram.Header.Addr, len(dgram.Data)) - } - }() - - go func() { - for { - dgram, err := gosocks5.ReadUDPDatagram(cc) - if err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s -> 0 : %s", cc.RemoteAddr(), err) - errc <- err - return - } - - // pipe from tunnel to peer - addr, err := net.ResolveUDPAddr("udp", dgram.Header.Addr.String()) - if err != nil { - continue // drop silently - } - if _, err := uc.WriteToUDP(dgram.Data, addr); err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s -> %s : %s", cc.RemoteAddr(), addr, err) - errc <- err - return - } - glog.V(LDEBUG).Infof("[udp-tun] %s >>> %s length: %d", cc.RemoteAddr(), addr, len(dgram.Data)) - } - }() - - select { - case err = <-errc: - } - - return -} - -func ToSocksAddr(addr net.Addr) *gosocks5.Addr { - host := "0.0.0.0" - port := 0 - if addr != nil { - h, p, _ := net.SplitHostPort(addr.String()) - host = h - port, _ = strconv.Atoi(p) - } - return &gosocks5.Addr{ - Type: gosocks5.AddrIPv4, - Host: host, - Port: uint16(port), - } -} - -type Socks4Server struct { - conn net.Conn - Base *ProxyServer -} - -func NewSocks4Server(conn net.Conn, base *ProxyServer) *Socks4Server { - return &Socks4Server{conn: conn, Base: base} -} - -func (s *Socks4Server) HandleRequest(req *gosocks4.Request) { - glog.V(LDEBUG).Infof("[socks4] %s -> %s\n%s", s.conn.RemoteAddr(), req.Addr, req) - - switch req.Cmd { - case gosocks4.CmdConnect: - glog.V(LINFO).Infof("[socks4-connect] %s -> %s", s.conn.RemoteAddr(), req.Addr) - s.handleConnect(req) - - case gosocks4.CmdBind: - glog.V(LINFO).Infof("[socks4-bind] %s - %s", s.conn.RemoteAddr(), req.Addr) - s.handleBind(req) - - default: - glog.V(LWARNING).Infoln("[socks4] Unrecognized request:", req.Cmd) - } -} - -func (s *Socks4Server) handleConnect(req *gosocks4.Request) { - cc, err := s.Base.Chain.Dial(req.Addr.String()) - if err != nil { - glog.V(LWARNING).Infof("[socks4-connect] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err) - rep := gosocks4.NewReply(gosocks4.Failed, nil) - rep.Write(s.conn) - glog.V(LDEBUG).Infof("[socks4-connect] %s <- %s\n%s", s.conn.RemoteAddr(), req.Addr, rep) - return - } - defer cc.Close() - - rep := gosocks4.NewReply(gosocks4.Granted, nil) - if err := rep.Write(s.conn); err != nil { - glog.V(LWARNING).Infof("[socks4-connect] %s <- %s : %s", s.conn.RemoteAddr(), req.Addr, err) - return - } - glog.V(LDEBUG).Infof("[socks4-connect] %s <- %s\n%s", s.conn.RemoteAddr(), req.Addr, rep) - - glog.V(LINFO).Infof("[socks4-connect] %s <-> %s", s.conn.RemoteAddr(), req.Addr) - s.Base.transport(s.conn, cc) - glog.V(LINFO).Infof("[socks4-connect] %s >-< %s", s.conn.RemoteAddr(), req.Addr) -} - -func (s *Socks4Server) handleBind(req *gosocks4.Request) { - cc, err := s.Base.Chain.GetConn() - - // connection error - if err != nil && err != ErrEmptyChain { - glog.V(LWARNING).Infof("[socks4-bind] %s <- %s : %s", s.conn.RemoteAddr(), req.Addr, err) - reply := gosocks4.NewReply(gosocks4.Failed, nil) - reply.Write(s.conn) - glog.V(LDEBUG).Infof("[socks4-bind] %s <- %s\n%s", s.conn.RemoteAddr(), req.Addr, reply) - return - } - // TODO: serve socks4 bind - if err == ErrEmptyChain { - //s.bindOn(req.Addr.String()) - return - } - - defer cc.Close() - // forward request - req.Write(cc) - - glog.V(LINFO).Infof("[socks4-bind] %s <-> %s", s.conn.RemoteAddr(), cc.RemoteAddr()) - s.Base.transport(s.conn, cc) - glog.V(LINFO).Infof("[socks4-bind] %s >-< %s", s.conn.RemoteAddr(), cc.RemoteAddr()) -} diff --git a/vendor/github.com/ginuerzh/gost/ss.go b/vendor/github.com/ginuerzh/gost/ss.go deleted file mode 100644 index cf5eb47..0000000 --- a/vendor/github.com/ginuerzh/gost/ss.go +++ /dev/null @@ -1,353 +0,0 @@ -package gost - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "github.com/ginuerzh/gosocks5" - "github.com/golang/glog" - ss "github.com/shadowsocks/shadowsocks-go/shadowsocks" - "io" - "net" - "strconv" - "time" -) - -const ( - idType = 0 // address type index - idIP0 = 1 // ip addres start index - idDmLen = 1 // domain address length index - idDm0 = 2 // domain address start index - - typeIPv4 = 1 // type is ipv4 address - typeDm = 3 // type is domain address - typeIPv6 = 4 // type is ipv6 address - - lenIPv4 = net.IPv4len + 2 // ipv4 + 2port - lenIPv6 = net.IPv6len + 2 // ipv6 + 2port - lenDmBase = 2 // 1addrLen + 2port, plus addrLen - lenHmacSha1 = 10 -) - -type ShadowServer struct { - conn *ss.Conn - Base *ProxyServer - OTA bool // one time auth -} - -func NewShadowServer(conn *ss.Conn, base *ProxyServer) *ShadowServer { - return &ShadowServer{conn: conn, Base: base} -} - -func (s *ShadowServer) Serve() { - glog.V(LINFO).Infof("[ss] %s - %s", s.conn.RemoteAddr(), s.conn.LocalAddr()) - - addr, ota, err := s.getRequest() - if err != nil { - glog.V(LWARNING).Infof("[ss] %s - %s : %s", s.conn.RemoteAddr(), s.conn.LocalAddr(), err) - return - } - glog.V(LINFO).Infof("[ss] %s -> %s, ota: %v", s.conn.RemoteAddr(), addr, ota) - - cc, err := s.Base.Chain.Dial(addr) - if err != nil { - glog.V(LWARNING).Infof("[ss] %s -> %s : %s", s.conn.RemoteAddr(), addr, err) - return - } - defer cc.Close() - - glog.V(LINFO).Infof("[ss] %s <-> %s", s.conn.RemoteAddr(), addr) - if ota { - s.transportOTA(s.conn, cc) - } else { - s.Base.transport(&shadowConn{conn: s.conn}, cc) - } - glog.V(LINFO).Infof("[ss] %s >-< %s", s.conn.RemoteAddr(), addr) -} - -// This function is copied from shadowsocks library with some modification. -func (s *ShadowServer) getRequest() (host string, ota bool, err error) { - // buf size should at least have the same size with the largest possible - // request size (when addrType is 3, domain name has at most 256 bytes) - // 1(addrType) + 1(lenByte) + 256(max length address) + 2(port) - buf := make([]byte, SmallBufferSize) - - // read till we get possible domain length field - s.conn.SetReadDeadline(time.Now().Add(ReadTimeout)) - if _, err = io.ReadFull(s.conn, buf[:idType+1]); err != nil { - return - } - - var reqStart, reqEnd int - addrType := buf[idType] - switch addrType & ss.AddrMask { - case typeIPv4: - reqStart, reqEnd = idIP0, idIP0+lenIPv4 - case typeIPv6: - reqStart, reqEnd = idIP0, idIP0+lenIPv6 - case typeDm: - if _, err = io.ReadFull(s.conn, buf[idType+1:idDmLen+1]); err != nil { - return - } - reqStart, reqEnd = idDm0, int(idDm0+buf[idDmLen]+lenDmBase) - default: - err = fmt.Errorf("addr type %d not supported", addrType&ss.AddrMask) - return - } - - if _, err = io.ReadFull(s.conn, buf[reqStart:reqEnd]); err != nil { - return - } - - // Return string for typeIP is not most efficient, but browsers (Chrome, - // Safari, Firefox) all seems using typeDm exclusively. So this is not a - // big problem. - switch addrType & ss.AddrMask { - case typeIPv4: - host = net.IP(buf[idIP0 : idIP0+net.IPv4len]).String() - case typeIPv6: - host = net.IP(buf[idIP0 : idIP0+net.IPv6len]).String() - case typeDm: - host = string(buf[idDm0 : idDm0+buf[idDmLen]]) - } - // parse port - port := binary.BigEndian.Uint16(buf[reqEnd-2 : reqEnd]) - host = net.JoinHostPort(host, strconv.Itoa(int(port))) - // if specified one time auth enabled, we should verify this - if s.OTA || addrType&ss.OneTimeAuthMask > 0 { - ota = true - if _, err = io.ReadFull(s.conn, buf[reqEnd:reqEnd+lenHmacSha1]); err != nil { - return - } - iv := s.conn.GetIv() - key := s.conn.GetKey() - actualHmacSha1Buf := ss.HmacSha1(append(iv, key...), buf[:reqEnd]) - if !bytes.Equal(buf[reqEnd:reqEnd+lenHmacSha1], actualHmacSha1Buf) { - err = fmt.Errorf("verify one time auth failed, iv=%v key=%v data=%v", iv, key, buf[:reqEnd]) - return - } - } - return -} - -const ( - dataLenLen = 2 - hmacSha1Len = 10 - idxData0 = dataLenLen + hmacSha1Len -) - -// copyOta copies data from src to dst with ota verification. -// -// This function is copied from shadowsocks library with some modification. -func (s *ShadowServer) copyOta(dst net.Conn, src *ss.Conn) (int64, error) { - // sometimes it have to fill large block - buf := make([]byte, LargeBufferSize) - for { - src.SetReadDeadline(time.Now().Add(ReadTimeout)) - if n, err := io.ReadFull(src, buf[:dataLenLen+hmacSha1Len]); err != nil { - return int64(n), err - } - src.SetReadDeadline(time.Time{}) - - dataLen := binary.BigEndian.Uint16(buf[:dataLenLen]) - expectedHmacSha1 := buf[dataLenLen:idxData0] - - var dataBuf []byte - if len(buf) < int(idxData0+dataLen) { - dataBuf = make([]byte, dataLen) - } else { - dataBuf = buf[idxData0 : idxData0+dataLen] - } - if n, err := io.ReadFull(src, dataBuf); err != nil { - return int64(n), err - } - chunkIdBytes := make([]byte, 4) - chunkId := src.GetAndIncrChunkId() - binary.BigEndian.PutUint32(chunkIdBytes, chunkId) - actualHmacSha1 := ss.HmacSha1(append(src.GetIv(), chunkIdBytes...), dataBuf) - if !bytes.Equal(expectedHmacSha1, actualHmacSha1) { - return 0, errors.New("ota error: mismatch") - } - - if n, err := dst.Write(dataBuf); err != nil { - return int64(n), err - } - } -} - -func (s *ShadowServer) transportOTA(sc *ss.Conn, cc net.Conn) (err error) { - errc := make(chan error, 2) - - go func() { - _, err := io.Copy(&shadowConn{conn: sc}, cc) - errc <- err - }() - - go func() { - _, err := s.copyOta(cc, sc) - errc <- err - }() - - select { - case err = <-errc: - //glog.V(LWARNING).Infoln("transport exit", err) - } - - return -} - -// Due to in/out byte length is inconsistent of the shadowsocks.Conn.Write, -// we wrap around it to make io.Copy happy -type shadowConn struct { - conn *ss.Conn -} - -func (c *shadowConn) Read(b []byte) (n int, err error) { - return c.conn.Read(b) -} - -func (c *shadowConn) Write(b []byte) (n int, err error) { - n = len(b) // force byte length consistent - _, err = c.conn.Write(b) - return -} - -func (c *shadowConn) Close() error { - return c.conn.Close() -} - -func (c *shadowConn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -func (c *shadowConn) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -func (c *shadowConn) SetDeadline(t time.Time) error { - return c.conn.SetDeadline(t) -} - -func (c *shadowConn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -func (c *shadowConn) SetWriteDeadline(t time.Time) error { - return c.conn.SetWriteDeadline(t) -} - -type ShadowUdpServer struct { - Base *ProxyServer - TTL int -} - -func NewShadowUdpServer(base *ProxyServer, ttl int) *ShadowUdpServer { - return &ShadowUdpServer{Base: base, TTL: ttl} -} - -func (s *ShadowUdpServer) ListenAndServe() error { - laddr, err := net.ResolveUDPAddr("udp", s.Base.Node.Addr) - if err != nil { - return err - } - lconn, err := net.ListenUDP("udp", laddr) - if err != nil { - return err - } - defer lconn.Close() - - conn := ss.NewSecurePacketConn(lconn, s.Base.cipher.Copy(), true) // force OTA on - - rChan, wChan := make(chan *packet, 128), make(chan *packet, 128) - // start send queue - go func(ch chan<- *packet) { - for { - b := make([]byte, MediumBufferSize) - n, addr, err := conn.ReadFrom(b[3:]) // add rsv and frag fields to make it the standard SOCKS5 UDP datagram - if err != nil { - glog.V(LWARNING).Infof("[ssu] %s -> %s : %s", addr, laddr, err) - continue - } - - b[3] &= ss.AddrMask // remove OTA flag - dgram, err := gosocks5.ReadUDPDatagram(bytes.NewReader(b[:n+3])) - if err != nil { - glog.V(LWARNING).Infof("[ssu] %s -> %s : %s", addr, laddr, err) - continue - } - - select { - case ch <- &packet{srcAddr: addr.String(), dstAddr: dgram.Header.Addr.String(), data: dgram.Data}: - case <-time.After(time.Second * 3): - glog.V(LWARNING).Infof("[ssu] %s -> %s : %s", addr, dgram.Header.Addr.String(), "send queue is full, discard") - } - } - }(wChan) - // start recv queue - go func(ch <-chan *packet) { - for pkt := range ch { - srcAddr, err := net.ResolveUDPAddr("udp", pkt.srcAddr) - if err != nil { - glog.V(LWARNING).Infof("[ssu] %s <- %s : %s", pkt.dstAddr, pkt.srcAddr, err) - continue - } - dstAddr, err := net.ResolveUDPAddr("udp", pkt.dstAddr) - if err != nil { - glog.V(LWARNING).Infof("[ssu] %s <- %s : %s", pkt.dstAddr, pkt.srcAddr, err) - continue - } - - dgram := gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(0, 0, ToSocksAddr(srcAddr)), pkt.data) - b := bytes.Buffer{} - dgram.Write(&b) - if b.Len() < 10 { - glog.V(LWARNING).Infof("[ssu] %s <- %s : invalid udp datagram", pkt.dstAddr, pkt.srcAddr) - continue - } - - if _, err := conn.WriteTo(b.Bytes()[3:], dstAddr); err != nil { // remove rsv and frag fields to make it standard shadowsocks UDP datagram - glog.V(LWARNING).Infof("[ssu] %s <- %s : %s", pkt.dstAddr, pkt.srcAddr, err) - return - } - } - }(rChan) - - // mapping client to node - m := make(map[string]*cnode) - - // start dispatcher - for pkt := range wChan { - // clear obsolete nodes - for k, node := range m { - if node != nil && node.err != nil { - close(node.wChan) - delete(m, k) - glog.V(LINFO).Infof("[ssu] clear node %s", k) - } - } - - node, ok := m[pkt.srcAddr] - if !ok { - node = &cnode{ - chain: s.Base.Chain, - srcAddr: pkt.srcAddr, - dstAddr: pkt.dstAddr, - rChan: rChan, - wChan: make(chan *packet, 32), - ttl: time.Duration(s.TTL) * time.Second, - } - m[pkt.srcAddr] = node - go node.run() - glog.V(LINFO).Infof("[ssu] %s -> %s : new client (%d)", pkt.srcAddr, pkt.dstAddr, len(m)) - } - - select { - case node.wChan <- pkt: - case <-time.After(time.Second * 3): - glog.V(LWARNING).Infof("[ssu] %s -> %s : %s", pkt.srcAddr, pkt.dstAddr, "node send queue is full, discard") - } - } - - return nil -} diff --git a/vendor/github.com/ginuerzh/gost/ssh.go b/vendor/github.com/ginuerzh/gost/ssh.go deleted file mode 100644 index 4a838ef..0000000 --- a/vendor/github.com/ginuerzh/gost/ssh.go +++ /dev/null @@ -1,236 +0,0 @@ -// The ssh tunnel is inspired by easyssh(https://dev.justinjudd.org/justin/easyssh) - -package gost - -import ( - "encoding/binary" - "fmt" - "github.com/golang/glog" - "golang.org/x/crypto/ssh" - "net" - "net/url" - "strconv" -) - -// Applicaple SSH Request types for Port Forwarding - RFC 4254 7.X -const ( - DirectForwardRequest = "direct-tcpip" // RFC 4254 7.2 - RemoteForwardRequest = "tcpip-forward" // RFC 4254 7.1 - ForwardedTCPReturnRequest = "forwarded-tcpip" // RFC 4254 7.2 - CancelRemoteForwardRequest = "cancel-tcpip-forward" // RFC 4254 7.1 -) - -type SSHServer struct { - Addr string - Base *ProxyServer - Config *ssh.ServerConfig - Handler func(ssh.Conn, <-chan ssh.NewChannel, <-chan *ssh.Request) -} - -func (s *SSHServer) ListenAndServe() error { - ln, err := net.Listen("tcp", s.Addr) - if err != nil { - glog.V(LWARNING).Infoln("[ssh] Listen:", err) - return err - } - defer ln.Close() - - for { - conn, err := ln.Accept() - if err != nil { - glog.V(LWARNING).Infoln("[ssh] Accept:", err) - return err - } - - go func(conn net.Conn) { - sshConn, chans, reqs, err := ssh.NewServerConn(conn, s.Config) - if err != nil { - glog.V(LWARNING).Infof("[ssh] %s -> %s : %s", conn.RemoteAddr(), s.Addr, err) - return - } - defer sshConn.Close() - - if s.Handler == nil { - s.Handler = s.handleSSHConn - } - - glog.V(LINFO).Infof("[ssh] %s <-> %s", conn.RemoteAddr(), s.Addr) - s.Handler(sshConn, chans, reqs) - glog.V(LINFO).Infof("[ssh] %s >-< %s", conn.RemoteAddr(), s.Addr) - }(conn) - } -} - -func (s *SSHServer) handleSSHConn(conn ssh.Conn, chans <-chan ssh.NewChannel, reqs <-chan *ssh.Request) { - quit := make(chan interface{}) - go func() { - for req := range reqs { - switch req.Type { - case RemoteForwardRequest: - go s.tcpipForwardRequest(conn, req, quit) - default: - // glog.V(LWARNING).Infoln("unknown channel type:", req.Type) - if req.WantReply { - req.Reply(false, nil) - } - } - } - }() - - go func() { - for newChannel := range chans { - // Check the type of channel - t := newChannel.ChannelType() - switch t { - case DirectForwardRequest: - channel, requests, err := newChannel.Accept() - if err != nil { - glog.V(LINFO).Infoln("[ssh] Could not accept channel:", err) - continue - } - p := directForward{} - ssh.Unmarshal(newChannel.ExtraData(), &p) - - go ssh.DiscardRequests(requests) - go s.directPortForwardChannel(channel, fmt.Sprintf("%s:%d", p.Host1, p.Port1)) - default: - glog.V(LWARNING).Infoln("[ssh] Unknown channel type:", t) - newChannel.Reject(ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %s", t)) - } - } - }() - - conn.Wait() - close(quit) -} - -// directForward is structure for RFC 4254 7.2 - can be used for "forwarded-tcpip" and "direct-tcpip" -type directForward struct { - Host1 string - Port1 uint32 - Host2 string - Port2 uint32 -} - -func (p directForward) String() string { - return fmt.Sprintf("%s:%d -> %s:%d", p.Host2, p.Port2, p.Host1, p.Port1) -} - -func (s *SSHServer) directPortForwardChannel(channel ssh.Channel, raddr string) { - defer channel.Close() - - glog.V(LINFO).Infof("[ssh-tcp] %s - %s", s.Addr, raddr) - - conn, err := s.Base.Chain.Dial(raddr) - if err != nil { - glog.V(LINFO).Infof("[ssh-tcp] %s - %s : %s", s.Addr, raddr, err) - return - } - defer conn.Close() - - glog.V(LINFO).Infof("[ssh-tcp] %s <-> %s", s.Addr, raddr) - Transport(conn, channel) - glog.V(LINFO).Infof("[ssh-tcp] %s >-< %s", s.Addr, raddr) -} - -// tcpipForward is structure for RFC 4254 7.1 "tcpip-forward" request -type tcpipForward struct { - Host string - Port uint32 -} - -func (s *SSHServer) tcpipForwardRequest(sshConn ssh.Conn, req *ssh.Request, quit <-chan interface{}) { - t := tcpipForward{} - ssh.Unmarshal(req.Payload, &t) - addr := fmt.Sprintf("%s:%d", t.Host, t.Port) - glog.V(LINFO).Infoln("[ssh-rtcp] listening tcp", addr) - ln, err := net.Listen("tcp", addr) //tie to the client connection - if err != nil { - glog.V(LWARNING).Infoln("[ssh-rtcp]", err) - req.Reply(false, nil) - return - } - defer ln.Close() - - replyFunc := func() error { - if t.Port == 0 && req.WantReply { // Client sent port 0. let them know which port is actually being used - _, port, err := getHostPortFromAddr(ln.Addr()) - if err != nil { - return err - } - var b [4]byte - binary.BigEndian.PutUint32(b[:], uint32(port)) - t.Port = uint32(port) - return req.Reply(true, b[:]) - } - return req.Reply(true, nil) - } - if err := replyFunc(); err != nil { - glog.V(LWARNING).Infoln("[ssh-rtcp]", err) - return - } - - go func() { - for { - conn, err := ln.Accept() - if err != nil { // Unable to accept new connection - listener likely closed - return - } - - go func(conn net.Conn) { - defer conn.Close() - - p := directForward{} - var err error - - var portnum int - p.Host1 = t.Host - p.Port1 = t.Port - p.Host2, portnum, err = getHostPortFromAddr(conn.RemoteAddr()) - if err != nil { - return - } - - p.Port2 = uint32(portnum) - ch, reqs, err := sshConn.OpenChannel(ForwardedTCPReturnRequest, ssh.Marshal(p)) - if err != nil { - glog.V(1).Infoln("[ssh-rtcp] open forwarded channel:", err) - return - } - defer ch.Close() - go ssh.DiscardRequests(reqs) - - glog.V(LINFO).Infof("[ssh-rtcp] %s <-> %s", conn.RemoteAddr(), conn.LocalAddr()) - Transport(ch, conn) - glog.V(LINFO).Infof("[ssh-rtcp] %s >-< %s", conn.RemoteAddr(), conn.LocalAddr()) - }(conn) - } - }() - - <-quit -} - -func getHostPortFromAddr(addr net.Addr) (host string, port int, err error) { - host, portString, err := net.SplitHostPort(addr.String()) - if err != nil { - return - } - port, err = strconv.Atoi(portString) - return -} - -type PasswordCallbackFunc func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) - -func DefaultPasswordCallback(users []*url.Userinfo) PasswordCallbackFunc { - return func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { - for _, user := range users { - u := user.Username() - p, _ := user.Password() - if u == conn.User() && p == string(password) { - return nil, nil - } - } - glog.V(LINFO).Infof("[ssh] %s -> %s : password rejected for %s", conn.RemoteAddr(), conn.LocalAddr(), conn.User()) - return nil, fmt.Errorf("password rejected for %s", conn.User()) - } -} diff --git a/vendor/github.com/ginuerzh/gost/ws.go b/vendor/github.com/ginuerzh/gost/ws.go deleted file mode 100644 index da902e6..0000000 --- a/vendor/github.com/ginuerzh/gost/ws.go +++ /dev/null @@ -1,142 +0,0 @@ -package gost - -import ( - "crypto/tls" - "github.com/golang/glog" - "gopkg.in/gorilla/websocket.v1" - "net" - "net/http" - "net/http/httputil" - "time" -) - -type WebsocketServer struct { - Addr string - Base *ProxyServer - Handler http.Handler - upgrader websocket.Upgrader -} - -func NewWebsocketServer(base *ProxyServer) *WebsocketServer { - return &WebsocketServer{ - Addr: base.Node.Addr, - Base: base, - upgrader: websocket.Upgrader{ - ReadBufferSize: 1024, - WriteBufferSize: 1024, - CheckOrigin: func(r *http.Request) bool { return true }, - EnableCompression: true, - }, - } -} - -// Default websocket server handler -func (s *WebsocketServer) HandleRequest(w http.ResponseWriter, r *http.Request) { - glog.V(LINFO).Infof("[ws] %s - %s", r.RemoteAddr, s.Addr) - if glog.V(LDEBUG) { - dump, _ := httputil.DumpRequest(r, false) - glog.V(LDEBUG).Infof("[ws] %s - %s\n%s", r.RemoteAddr, s.Addr, string(dump)) - } - conn, err := s.upgrader.Upgrade(w, r, nil) - if err != nil { - glog.V(LERROR).Infof("[ws] %s - %s : %s", r.RemoteAddr, s.Addr, err) - return - } - s.Base.handleConn(WebsocketServerConn(conn)) -} - -func (s *WebsocketServer) ListenAndServe() error { - mux := http.NewServeMux() - if s.Handler == nil { - s.Handler = http.HandlerFunc(s.HandleRequest) - } - mux.Handle("/ws", s.Handler) - return http.ListenAndServe(s.Addr, mux) -} - -func (s *WebsocketServer) ListenAndServeTLS(config *tls.Config) error { - mux := http.NewServeMux() - if s.Handler == nil { - s.Handler = http.HandlerFunc(s.HandleRequest) - } - mux.Handle("/ws", s.Handler) - server := &http.Server{ - Addr: s.Addr, - Handler: mux, - TLSConfig: config, - } - return server.ListenAndServeTLS("", "") -} - -type WebsocketConn struct { - conn *websocket.Conn - rb []byte -} - -func WebsocketClientConn(url string, conn net.Conn, config *tls.Config) (*WebsocketConn, error) { - dialer := websocket.Dialer{ - ReadBufferSize: 1024, - WriteBufferSize: 1024, - TLSClientConfig: config, - HandshakeTimeout: DialTimeout, - EnableCompression: true, - NetDial: func(net, addr string) (net.Conn, error) { - return conn, nil - }, - } - - c, resp, err := dialer.Dial(url, nil) - if err != nil { - return nil, err - } - resp.Body.Close() - return &WebsocketConn{conn: c}, nil -} - -func WebsocketServerConn(conn *websocket.Conn) *WebsocketConn { - conn.EnableWriteCompression(true) - return &WebsocketConn{ - conn: conn, - } -} - -func (c *WebsocketConn) Read(b []byte) (n int, err error) { - if len(c.rb) == 0 { - _, c.rb, err = c.conn.ReadMessage() - } - n = copy(b, c.rb) - c.rb = c.rb[n:] - return -} - -func (c *WebsocketConn) Write(b []byte) (n int, err error) { - err = c.conn.WriteMessage(websocket.BinaryMessage, b) - n = len(b) - return -} - -func (c *WebsocketConn) Close() error { - return c.conn.Close() -} - -func (c *WebsocketConn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -func (c *WebsocketConn) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -func (conn *WebsocketConn) SetDeadline(t time.Time) error { - if err := conn.SetReadDeadline(t); err != nil { - return err - } - return conn.SetWriteDeadline(t) -} -func (c *WebsocketConn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -func (c *WebsocketConn) SetWriteDeadline(t time.Time) error { - return c.conn.SetWriteDeadline(t) -} diff --git a/vendor/vendor.json b/vendor/vendor.json index 0c00d25..953c78a 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -20,12 +20,6 @@ "revision": "0f737bddba2abd1496dc03c8b39b817cc5f33fa7", "revisionTime": "2017-01-19T05:34:58Z" }, - { - "checksumSHA1": "90Nj9KD5KzY15ZBn95Coz7G85+0=", - "path": "github.com/ginuerzh/gost", - "revision": "26f4e49f0538177eb5ec33c84a280afe2ae16042", - "revisionTime": "2017-03-03T13:33:05Z" - }, { "checksumSHA1": "+XIOnTW0rv8Kr/amkXgMraNeUr4=", "path": "github.com/ginuerzh/pht", From 60712a67b119bb1202ce6bcd91bb4f88a8034fe6 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 9 Mar 2017 23:25:36 +0100 Subject: [PATCH 2/4] Move handling of key and cert params to server.go --- cmd/gost/.gitignore | 1 + cmd/gost/main.go | 21 +++++---------------- gost.go | 3 ++- server.go | 28 +++++++++++++++++++--------- 4 files changed, 27 insertions(+), 26 deletions(-) create mode 100644 cmd/gost/.gitignore diff --git a/cmd/gost/.gitignore b/cmd/gost/.gitignore new file mode 100644 index 0000000..c4b36ef --- /dev/null +++ b/cmd/gost/.gitignore @@ -0,0 +1 @@ +gost diff --git a/cmd/gost/main.go b/cmd/gost/main.go index 6456987..0789afa 100644 --- a/cmd/gost/main.go +++ b/cmd/gost/main.go @@ -1,17 +1,17 @@ package main import ( - "crypto/tls" "encoding/json" "flag" "fmt" - "github.com/ginuerzh/gost" - "github.com/golang/glog" - "golang.org/x/net/http2" "io/ioutil" "os" "runtime" "sync" + + "github.com/ginuerzh/gost" + "github.com/golang/glog" + "golang.org/x/net/http2" ) var ( @@ -68,18 +68,7 @@ func main() { wg.Add(1) go func(node gost.ProxyNode) { defer wg.Done() - certFile, keyFile := node.Get("cert"), node.Get("key") - if certFile == "" { - certFile = gost.DefaultCertFile - } - if keyFile == "" { - keyFile = gost.DefaultKeyFile - } - cert, err := gost.LoadCertificate(certFile, keyFile) - if err != nil { - glog.Fatal(err) - } - server := gost.NewProxyServer(node, chain, &tls.Config{Certificates: []tls.Certificate{cert}}) + server := gost.NewProxyServer(node, chain) glog.Fatal(server.Serve()) }(serverNode) } diff --git a/gost.go b/gost.go index 50f4085..aa53bf6 100644 --- a/gost.go +++ b/gost.go @@ -4,11 +4,12 @@ import ( "crypto/tls" "encoding/base64" "errors" - "github.com/golang/glog" "io" "net" "strings" "time" + + "github.com/golang/glog" ) const ( diff --git a/server.go b/server.go index 5e1f0e8..b4867ee 100644 --- a/server.go +++ b/server.go @@ -3,17 +3,18 @@ package gost import ( "bufio" "crypto/tls" - "github.com/ginuerzh/gosocks4" - "github.com/ginuerzh/gosocks5" - "github.com/golang/glog" - ss "github.com/shadowsocks/shadowsocks-go/shadowsocks" - "golang.org/x/crypto/ssh" "io" "io/ioutil" "net" "net/http" "strconv" "strings" + + "github.com/ginuerzh/gosocks4" + "github.com/ginuerzh/gosocks5" + "github.com/golang/glog" + ss "github.com/shadowsocks/shadowsocks-go/shadowsocks" + "golang.org/x/crypto/ssh" ) type ProxyServer struct { @@ -25,13 +26,22 @@ type ProxyServer struct { ota bool } -func NewProxyServer(node ProxyNode, chain *ProxyChain, config *tls.Config) *ProxyServer { +func NewProxyServer(node ProxyNode, chain *ProxyChain) *ProxyServer { + certFile, keyFile := node.certFile(), node.keyFile() + + cert, err := LoadCertificate(certFile, keyFile) + + if err != nil { + glog.Fatal(err) + } + + config := &tls.Config{ + Certificates: []tls.Certificate{cert}, + } + if chain == nil { chain = NewProxyChain() } - if config == nil { - config = &tls.Config{} - } var cipher *ss.Cipher var ota bool From 1ed6f0baf39ea528a595d6a9d0aef1e48fc86a4d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 9 Mar 2017 19:36:09 +0100 Subject: [PATCH 3/4] Move vendor directory at top level --- .../github.com/Yawning/chacha20/LICENSE | 0 .../github.com/Yawning/chacha20/README.md | 0 .../github.com/Yawning/chacha20/chacha20.go | 0 .../github.com/Yawning/chacha20/chacha20_amd64.go | 0 .../github.com/Yawning/chacha20/chacha20_amd64.py | 0 .../github.com/Yawning/chacha20/chacha20_amd64.s | 0 .../github.com/Yawning/chacha20/chacha20_ref.go | 0 .../github.com/ginuerzh/gosocks4/LICENSE | 0 .../github.com/ginuerzh/gosocks4/README.md | 0 .../github.com/ginuerzh/gosocks4/socks4.go | 0 .../ginuerzh/gosocks4/socks4.protocol.txt | 0 .../ginuerzh/gosocks4/socks4a.protocol.txt | 0 .../github.com/ginuerzh/gosocks5/LICENSE | 0 .../github.com/ginuerzh/gosocks5/README.md | 0 .../github.com/ginuerzh/gosocks5/conn.go | 0 .../github.com/ginuerzh/gosocks5/rfc1928.txt | 0 .../github.com/ginuerzh/gosocks5/rfc1929.txt | 0 .../github.com/ginuerzh/gosocks5/socks5.go | 0 .../github.com/ginuerzh/gost/LICENSE | 0 .../github.com/ginuerzh/gost/README.md | 0 .../github.com/ginuerzh/gost/README_en.md | 0 .../github.com/ginuerzh/gost/chain.go | 0 .../github.com/ginuerzh/gost/conn.go | 0 .../github.com/ginuerzh/gost/forward.go | 0 .../github.com/ginuerzh/gost/gost.go | 0 .../github.com/ginuerzh/gost/http.go | 0 .../github.com/ginuerzh/gost/kcp.go | 0 .../github.com/ginuerzh/gost/node.go | 0 .../github.com/ginuerzh/gost/quic.go | 0 .../github.com/ginuerzh/gost/redirect.go | 0 .../github.com/ginuerzh/gost/redirect_win.go | 0 .../github.com/ginuerzh/gost/server.go | 0 .../github.com/ginuerzh/gost/signal.go | 0 .../github.com/ginuerzh/gost/signal_unix.go | 0 .../github.com/ginuerzh/gost/socks.go | 0 .../github.com/ginuerzh/gost/ss.go | 0 .../github.com/ginuerzh/gost/ssh.go | 0 .../github.com/ginuerzh/gost/ws.go | 0 .../github.com/ginuerzh/pht/LICENSE | 0 .../github.com/ginuerzh/pht/README.md | 0 .../github.com/ginuerzh/pht/client.go | 0 .../github.com/ginuerzh/pht/conn.go | 0 .../github.com/ginuerzh/pht/server.go | 0 .../github.com/ginuerzh/pht/session.go | 0 .../github.com/golang/glog/LICENSE | 0 .../vendor => vendor}/github.com/golang/glog/README | 0 .../github.com/golang/glog/glog.go | 0 .../github.com/golang/glog/glog_file.go | 0 .../github.com/hashicorp/golang-lru/2q.go | 0 .../github.com/hashicorp/golang-lru/LICENSE | 0 .../github.com/hashicorp/golang-lru/README.md | 0 .../github.com/hashicorp/golang-lru/arc.go | 0 .../github.com/hashicorp/golang-lru/lru.go | 0 .../hashicorp/golang-lru/simplelru/lru.go | 0 .../github.com/klauspost/compress/LICENSE | 0 .../github.com/klauspost/compress/snappy/AUTHORS | 0 .../klauspost/compress/snappy/CONTRIBUTORS | 0 .../github.com/klauspost/compress/snappy/LICENSE | 0 .../github.com/klauspost/compress/snappy/README | 0 .../github.com/klauspost/compress/snappy/decode.go | 0 .../klauspost/compress/snappy/decode_amd64.go | 0 .../klauspost/compress/snappy/decode_amd64.s | 0 .../klauspost/compress/snappy/decode_other.go | 0 .../github.com/klauspost/compress/snappy/encode.go | 0 .../klauspost/compress/snappy/encode_amd64.go | 0 .../klauspost/compress/snappy/encode_amd64.s | 0 .../klauspost/compress/snappy/encode_other.go | 0 .../klauspost/compress/snappy/runbench.cmd | 0 .../github.com/klauspost/compress/snappy/snappy.go | 0 .../github.com/klauspost/cpuid/LICENSE | 0 .../github.com/klauspost/cpuid/README.md | 0 .../github.com/klauspost/cpuid/cpuid.go | 0 .../github.com/klauspost/cpuid/cpuid_386.s | 0 .../github.com/klauspost/cpuid/cpuid_amd64.s | 0 .../github.com/klauspost/cpuid/detect_intel.go | 0 .../github.com/klauspost/cpuid/detect_ref.go | 0 .../github.com/klauspost/cpuid/generate.go | 0 .../github.com/klauspost/cpuid/private-gen.go | 0 .../github.com/klauspost/reedsolomon/LICENSE | 0 .../github.com/klauspost/reedsolomon/README.md | 0 .../github.com/klauspost/reedsolomon/appveyor.yml | 0 .../github.com/klauspost/reedsolomon/galois.go | 0 .../klauspost/reedsolomon/galois_amd64.go | 0 .../github.com/klauspost/reedsolomon/galois_amd64.s | 0 .../klauspost/reedsolomon/galois_noasm.go | 0 .../github.com/klauspost/reedsolomon/gentables.go | 0 .../klauspost/reedsolomon/inversion_tree.go | 0 .../github.com/klauspost/reedsolomon/matrix.go | 0 .../github.com/klauspost/reedsolomon/reedsolomon.go | 0 .../github.com/klauspost/reedsolomon/streaming.go | 0 .../github.com/lucas-clemente/aes12/LICENSE | 0 .../github.com/lucas-clemente/aes12/Readme.md | 0 .../github.com/lucas-clemente/aes12/aes_gcm.go | 0 .../github.com/lucas-clemente/aes12/asm_amd64.s | 0 .../github.com/lucas-clemente/aes12/block.go | 0 .../github.com/lucas-clemente/aes12/cipher.go | 0 .../github.com/lucas-clemente/aes12/cipher_2.go | 0 .../github.com/lucas-clemente/aes12/cipher_amd64.go | 0 .../lucas-clemente/aes12/cipher_generic.go | 0 .../github.com/lucas-clemente/aes12/const.go | 0 .../github.com/lucas-clemente/aes12/gcm.go | 0 .../github.com/lucas-clemente/aes12/gcm_amd64.s | 0 .../github.com/lucas-clemente/aes12/xor.go | 0 .../github.com/lucas-clemente/fnv128a/LICENSE | 0 .../github.com/lucas-clemente/fnv128a/README.md | 0 .../github.com/lucas-clemente/fnv128a/fnv128a.go | 0 .../lucas-clemente/quic-go-certificates/LICENSE | 0 .../lucas-clemente/quic-go-certificates/README.md | 0 .../quic-go-certificates/cert_set_2.go | 0 .../quic-go-certificates/cert_set_3.go | 0 .../quic-go-certificates/createCertSets.rb | 0 .../github.com/lucas-clemente/quic-go/LICENSE | 0 .../github.com/lucas-clemente/quic-go/README.md | 0 .../lucas-clemente/quic-go/ackhandler/_gen.go | 0 .../lucas-clemente/quic-go/ackhandler/interfaces.go | 0 .../lucas-clemente/quic-go/ackhandler/packet.go | 0 .../quic-go/ackhandler/packet_linkedlist.go | 0 .../quic-go/ackhandler/received_packet_handler.go | 0 .../quic-go/ackhandler/received_packet_history.go | 0 .../quic-go/ackhandler/sent_packet_handler.go | 0 .../quic-go/ackhandler/stop_waiting_manager.go | 0 .../github.com/lucas-clemente/quic-go/appveyor.yml | 0 .../lucas-clemente/quic-go/buffer_pool.go | 0 .../github.com/lucas-clemente/quic-go/client.go | 0 .../github.com/lucas-clemente/quic-go/codecov.yml | 0 .../lucas-clemente/quic-go/congestion/bandwidth.go | 0 .../lucas-clemente/quic-go/congestion/clock.go | 0 .../quic-go/congestion/congestion_vector.go | 0 .../lucas-clemente/quic-go/congestion/cubic.go | 0 .../quic-go/congestion/cubic_sender.go | 0 .../quic-go/congestion/hybrid_slow_start.go | 0 .../lucas-clemente/quic-go/congestion/interface.go | 0 .../lucas-clemente/quic-go/congestion/prr_sender.go | 0 .../lucas-clemente/quic-go/congestion/rtt_stats.go | 0 .../lucas-clemente/quic-go/congestion/stats.go | 0 .../lucas-clemente/quic-go/crypto/AEAD.go | 0 .../lucas-clemente/quic-go/crypto/aesgcm_aead.go | 0 .../lucas-clemente/quic-go/crypto/cert_cache.go | 0 .../lucas-clemente/quic-go/crypto/cert_chain.go | 0 .../quic-go/crypto/cert_compression.go | 0 .../lucas-clemente/quic-go/crypto/cert_dict.go | 0 .../lucas-clemente/quic-go/crypto/cert_manager.go | 0 .../lucas-clemente/quic-go/crypto/cert_sets.go | 0 .../quic-go/crypto/chacha20poly1305_aead.go | 0 .../quic-go/crypto/chacha20poly1305_aead_test.go | 0 .../lucas-clemente/quic-go/crypto/curve_25519.go | 0 .../lucas-clemente/quic-go/crypto/key_derivation.go | 0 .../lucas-clemente/quic-go/crypto/key_exchange.go | 0 .../lucas-clemente/quic-go/crypto/nonce.go | 0 .../lucas-clemente/quic-go/crypto/null_aead.go | 0 .../lucas-clemente/quic-go/crypto/server_proof.go | 0 .../quic-go/crypto/source_address_token.go | 0 .../quic-go/flowcontrol/flow_control_manager.go | 0 .../quic-go/flowcontrol/flow_controller.go | 0 .../lucas-clemente/quic-go/flowcontrol/interface.go | 0 .../lucas-clemente/quic-go/frames/ack_frame.go | 0 .../lucas-clemente/quic-go/frames/ack_range.go | 0 .../lucas-clemente/quic-go/frames/blocked_frame.go | 0 .../quic-go/frames/connection_close_frame.go | 0 .../lucas-clemente/quic-go/frames/frame.go | 0 .../lucas-clemente/quic-go/frames/goaway_frame.go | 0 .../github.com/lucas-clemente/quic-go/frames/log.go | 0 .../lucas-clemente/quic-go/frames/ping_frame.go | 0 .../quic-go/frames/rst_stream_frame.go | 0 .../quic-go/frames/stop_waiting_frame.go | 0 .../lucas-clemente/quic-go/frames/stream_frame.go | 0 .../quic-go/frames/window_update_frame.go | 0 .../lucas-clemente/quic-go/h2quic/client.go | 0 .../lucas-clemente/quic-go/h2quic/gzipreader.go | 0 .../lucas-clemente/quic-go/h2quic/request.go | 0 .../lucas-clemente/quic-go/h2quic/request_body.go | 0 .../lucas-clemente/quic-go/h2quic/request_writer.go | 0 .../lucas-clemente/quic-go/h2quic/response.go | 0 .../quic-go/h2quic/response_setuncompressed.go | 0 .../quic-go/h2quic/response_setuncompressed_go16.go | 0 .../quic-go/h2quic/response_writer.go | 0 .../lucas-clemente/quic-go/h2quic/roundtrip.go | 0 .../lucas-clemente/quic-go/h2quic/server.go | 0 .../handshake/connection_parameters_manager.go | 0 .../quic-go/handshake/crypto_setup_client.go | 0 .../quic-go/handshake/crypto_setup_interface.go | 0 .../quic-go/handshake/crypto_setup_server.go | 0 .../quic-go/handshake/ephermal_cache.go | 0 .../quic-go/handshake/handshake_message.go | 0 .../quic-go/handshake/server_config.go | 0 .../quic-go/handshake/server_config_client.go | 0 .../lucas-clemente/quic-go/handshake/tags.go | 0 .../quic-go/packet_number_generator.go | 0 .../lucas-clemente/quic-go/packet_packer.go | 0 .../lucas-clemente/quic-go/packet_unpacker.go | 0 .../quic-go/protocol/encryption_level.go | 0 .../quic-go/protocol/packet_number.go | 0 .../lucas-clemente/quic-go/protocol/perspective.go | 0 .../lucas-clemente/quic-go/protocol/protocol.go | 0 .../quic-go/protocol/server_parameters.go | 0 .../lucas-clemente/quic-go/protocol/version.go | 0 .../lucas-clemente/quic-go/public_header.go | 0 .../lucas-clemente/quic-go/public_reset.go | 0 .../lucas-clemente/quic-go/qerr/error_codes.go | 0 .../lucas-clemente/quic-go/qerr/errorcode_string.go | 0 .../lucas-clemente/quic-go/qerr/quic_error.go | 0 .../github.com/lucas-clemente/quic-go/server.go | 0 .../github.com/lucas-clemente/quic-go/session.go | 0 .../github.com/lucas-clemente/quic-go/stream.go | 0 .../lucas-clemente/quic-go/stream_frame_sorter.go | 0 .../lucas-clemente/quic-go/stream_framer.go | 0 .../lucas-clemente/quic-go/streams_map.go | 0 .../github.com/lucas-clemente/quic-go/udp_conn.go | 0 .../lucas-clemente/quic-go/unpacked_packet.go | 0 .../github.com/lucas-clemente/quic-go/utils/_gen.go | 0 .../lucas-clemente/quic-go/utils/atomic_bool.go | 0 .../quic-go/utils/byteinterval_linkedlist.go | 0 .../lucas-clemente/quic-go/utils/connection_id.go | 0 .../lucas-clemente/quic-go/utils/float16.go | 0 .../github.com/lucas-clemente/quic-go/utils/host.go | 0 .../github.com/lucas-clemente/quic-go/utils/log.go | 0 .../lucas-clemente/quic-go/utils/minmax.go | 0 .../lucas-clemente/quic-go/utils/packet_interval.go | 0 .../quic-go/utils/packetinterval_linkedlist.go | 0 .../lucas-clemente/quic-go/utils/stream.go | 0 .../quic-go/utils/streamframe_interval.go | 0 .../lucas-clemente/quic-go/utils/utils.go | 0 .../vendor => vendor}/github.com/pkg/errors/LICENSE | 0 .../github.com/pkg/errors/README.md | 0 .../github.com/pkg/errors/appveyor.yml | 0 .../github.com/pkg/errors/errors.go | 0 .../github.com/pkg/errors/stack.go | 0 .../github.com/shadowsocks/shadowsocks-go/LICENSE | 0 .../shadowsocks-go/shadowsocks/config.go | 0 .../shadowsocks/shadowsocks-go/shadowsocks/conn.go | 0 .../shadowsocks-go/shadowsocks/encrypt.go | 0 .../shadowsocks-go/shadowsocks/leakybuf.go | 0 .../shadowsocks/shadowsocks-go/shadowsocks/log.go | 0 .../shadowsocks-go/shadowsocks/mergesort.go | 0 .../shadowsocks/shadowsocks-go/shadowsocks/pipe.go | 0 .../shadowsocks/shadowsocks-go/shadowsocks/proxy.go | 0 .../shadowsocks/shadowsocks-go/shadowsocks/udp.go | 0 .../shadowsocks-go/shadowsocks/udprelay.go | 0 .../shadowsocks/shadowsocks-go/shadowsocks/util.go | 0 .../vendor => vendor}/golang.org/x/crypto/LICENSE | 0 .../vendor => vendor}/golang.org/x/crypto/PATENTS | 0 .../golang.org/x/crypto/blowfish/block.go | 0 .../golang.org/x/crypto/blowfish/cipher.go | 0 .../golang.org/x/crypto/blowfish/const.go | 0 .../golang.org/x/crypto/cast5/cast5.go | 0 .../golang.org/x/crypto/curve25519/const_amd64.h | 0 .../golang.org/x/crypto/curve25519/const_amd64.s | 0 .../golang.org/x/crypto/curve25519/cswap_amd64.s | 0 .../golang.org/x/crypto/curve25519/curve25519.go | 0 .../golang.org/x/crypto/curve25519/doc.go | 0 .../golang.org/x/crypto/curve25519/freeze_amd64.s | 0 .../x/crypto/curve25519/ladderstep_amd64.s | 0 .../x/crypto/curve25519/mont25519_amd64.go | 0 .../golang.org/x/crypto/curve25519/mul_amd64.s | 0 .../golang.org/x/crypto/curve25519/square_amd64.s | 0 .../golang.org/x/crypto/ed25519/ed25519.go | 0 .../x/crypto/ed25519/internal/edwards25519/const.go | 0 .../ed25519/internal/edwards25519/edwards25519.go | 0 .../golang.org/x/crypto/hkdf/hkdf.go | 0 .../golang.org/x/crypto/pbkdf2/pbkdf2.go | 0 .../golang.org/x/crypto/salsa20/salsa/hsalsa20.go | 0 .../x/crypto/salsa20/salsa/salsa2020_amd64.s | 0 .../golang.org/x/crypto/salsa20/salsa/salsa208.go | 0 .../x/crypto/salsa20/salsa/salsa20_amd64.go | 0 .../x/crypto/salsa20/salsa/salsa20_ref.go | 0 .../golang.org/x/crypto/salsa20/salsa20.go | 0 .../golang.org/x/crypto/ssh/buffer.go | 0 .../golang.org/x/crypto/ssh/certs.go | 0 .../golang.org/x/crypto/ssh/channel.go | 0 .../golang.org/x/crypto/ssh/cipher.go | 0 .../golang.org/x/crypto/ssh/client.go | 0 .../golang.org/x/crypto/ssh/client_auth.go | 0 .../golang.org/x/crypto/ssh/common.go | 0 .../golang.org/x/crypto/ssh/connection.go | 0 .../golang.org/x/crypto/ssh/doc.go | 0 .../golang.org/x/crypto/ssh/handshake.go | 0 .../golang.org/x/crypto/ssh/kex.go | 0 .../golang.org/x/crypto/ssh/keys.go | 0 .../golang.org/x/crypto/ssh/mac.go | 0 .../golang.org/x/crypto/ssh/messages.go | 0 .../golang.org/x/crypto/ssh/mux.go | 0 .../golang.org/x/crypto/ssh/server.go | 0 .../golang.org/x/crypto/ssh/session.go | 0 .../golang.org/x/crypto/ssh/tcpip.go | 0 .../golang.org/x/crypto/ssh/transport.go | 0 .../golang.org/x/crypto/tea/cipher.go | 0 .../golang.org/x/crypto/twofish/twofish.go | 0 .../golang.org/x/crypto/xtea/block.go | 0 .../golang.org/x/crypto/xtea/cipher.go | 0 .../gost/vendor => vendor}/golang.org/x/net/LICENSE | 0 .../gost/vendor => vendor}/golang.org/x/net/PATENTS | 0 .../vendor => vendor}/golang.org/x/net/bpf/asm.go | 0 .../golang.org/x/net/bpf/constants.go | 0 .../vendor => vendor}/golang.org/x/net/bpf/doc.go | 0 .../golang.org/x/net/bpf/instructions.go | 0 .../vendor => vendor}/golang.org/x/net/bpf/vm.go | 0 .../golang.org/x/net/bpf/vm_instructions.go | 0 .../golang.org/x/net/http2/Dockerfile | 0 .../golang.org/x/net/http2/Makefile | 0 .../vendor => vendor}/golang.org/x/net/http2/README | 0 .../golang.org/x/net/http2/client_conn_pool.go | 0 .../golang.org/x/net/http2/configure_transport.go | 0 .../golang.org/x/net/http2/errors.go | 0 .../golang.org/x/net/http2/fixed_buffer.go | 0 .../golang.org/x/net/http2/flow.go | 0 .../golang.org/x/net/http2/frame.go | 0 .../golang.org/x/net/http2/go16.go | 0 .../golang.org/x/net/http2/go17.go | 0 .../golang.org/x/net/http2/go17_not18.go | 0 .../golang.org/x/net/http2/go18.go | 0 .../golang.org/x/net/http2/gotrack.go | 0 .../golang.org/x/net/http2/headermap.go | 0 .../golang.org/x/net/http2/hpack/encode.go | 0 .../golang.org/x/net/http2/hpack/hpack.go | 0 .../golang.org/x/net/http2/hpack/huffman.go | 0 .../golang.org/x/net/http2/hpack/tables.go | 0 .../golang.org/x/net/http2/http2.go | 0 .../golang.org/x/net/http2/not_go16.go | 0 .../golang.org/x/net/http2/not_go17.go | 0 .../golang.org/x/net/http2/not_go18.go | 0 .../golang.org/x/net/http2/pipe.go | 0 .../golang.org/x/net/http2/server.go | 0 .../golang.org/x/net/http2/transport.go | 0 .../golang.org/x/net/http2/write.go | 0 .../golang.org/x/net/http2/writesched.go | 0 .../golang.org/x/net/http2/writesched_priority.go | 0 .../golang.org/x/net/http2/writesched_random.go | 0 .../vendor => vendor}/golang.org/x/net/idna/idna.go | 0 .../golang.org/x/net/idna/punycode.go | 0 .../golang.org/x/net/internal/iana/const.go | 0 .../golang.org/x/net/internal/iana/gen.go | 0 .../golang.org/x/net/internal/netreflect/socket.go | 0 .../x/net/internal/netreflect/socket_posix.go | 0 .../x/net/internal/netreflect/socket_stub.go | 0 .../golang.org/x/net/ipv4/bpfopt_linux.go | 0 .../golang.org/x/net/ipv4/bpfopt_stub.go | 0 .../golang.org/x/net/ipv4/control.go | 0 .../golang.org/x/net/ipv4/control_bsd.go | 0 .../golang.org/x/net/ipv4/control_pktinfo.go | 0 .../golang.org/x/net/ipv4/control_stub.go | 0 .../golang.org/x/net/ipv4/control_unix.go | 0 .../golang.org/x/net/ipv4/control_windows.go | 0 .../golang.org/x/net/ipv4/defs_darwin.go | 0 .../golang.org/x/net/ipv4/defs_dragonfly.go | 0 .../golang.org/x/net/ipv4/defs_freebsd.go | 0 .../golang.org/x/net/ipv4/defs_linux.go | 0 .../golang.org/x/net/ipv4/defs_netbsd.go | 0 .../golang.org/x/net/ipv4/defs_openbsd.go | 0 .../golang.org/x/net/ipv4/defs_solaris.go | 0 .../golang.org/x/net/ipv4/dgramopt_posix.go | 0 .../golang.org/x/net/ipv4/dgramopt_stub.go | 0 .../vendor => vendor}/golang.org/x/net/ipv4/doc.go | 0 .../golang.org/x/net/ipv4/endpoint.go | 0 .../vendor => vendor}/golang.org/x/net/ipv4/gen.go | 0 .../golang.org/x/net/ipv4/genericopt_posix.go | 0 .../golang.org/x/net/ipv4/genericopt_stub.go | 0 .../golang.org/x/net/ipv4/header.go | 0 .../golang.org/x/net/ipv4/helper.go | 0 .../vendor => vendor}/golang.org/x/net/ipv4/iana.go | 0 .../vendor => vendor}/golang.org/x/net/ipv4/icmp.go | 0 .../golang.org/x/net/ipv4/icmp_linux.go | 0 .../golang.org/x/net/ipv4/icmp_stub.go | 0 .../golang.org/x/net/ipv4/packet.go | 0 .../golang.org/x/net/ipv4/payload.go | 0 .../golang.org/x/net/ipv4/payload_cmsg.go | 0 .../golang.org/x/net/ipv4/payload_nocmsg.go | 0 .../golang.org/x/net/ipv4/sockopt.go | 0 .../golang.org/x/net/ipv4/sockopt_asmreq.go | 0 .../golang.org/x/net/ipv4/sockopt_asmreq_posix.go | 0 .../golang.org/x/net/ipv4/sockopt_asmreq_stub.go | 0 .../golang.org/x/net/ipv4/sockopt_asmreqn_stub.go | 0 .../golang.org/x/net/ipv4/sockopt_asmreqn_unix.go | 0 .../golang.org/x/net/ipv4/sockopt_posix.go | 0 .../golang.org/x/net/ipv4/sockopt_ssmreq_stub.go | 0 .../golang.org/x/net/ipv4/sockopt_ssmreq_unix.go | 0 .../golang.org/x/net/ipv4/sockopt_stub.go | 0 .../golang.org/x/net/ipv4/sys_bsd.go | 0 .../golang.org/x/net/ipv4/sys_darwin.go | 0 .../golang.org/x/net/ipv4/sys_freebsd.go | 0 .../golang.org/x/net/ipv4/sys_linux.go | 0 .../golang.org/x/net/ipv4/sys_linux_386.s | 0 .../golang.org/x/net/ipv4/sys_openbsd.go | 0 .../golang.org/x/net/ipv4/sys_solaris.go | 0 .../golang.org/x/net/ipv4/sys_solaris_amd64.s | 0 .../golang.org/x/net/ipv4/sys_stub.go | 0 .../golang.org/x/net/ipv4/sys_windows.go | 0 .../golang.org/x/net/ipv4/syscall_linux_386.go | 0 .../golang.org/x/net/ipv4/syscall_solaris.go | 0 .../golang.org/x/net/ipv4/syscall_unix.go | 0 .../golang.org/x/net/ipv4/syscall_windows.go | 0 .../golang.org/x/net/ipv4/zsys_darwin.go | 0 .../golang.org/x/net/ipv4/zsys_dragonfly.go | 0 .../golang.org/x/net/ipv4/zsys_freebsd_386.go | 0 .../golang.org/x/net/ipv4/zsys_freebsd_amd64.go | 0 .../golang.org/x/net/ipv4/zsys_freebsd_arm.go | 0 .../golang.org/x/net/ipv4/zsys_linux_386.go | 0 .../golang.org/x/net/ipv4/zsys_linux_amd64.go | 0 .../golang.org/x/net/ipv4/zsys_linux_arm.go | 0 .../golang.org/x/net/ipv4/zsys_linux_arm64.go | 0 .../golang.org/x/net/ipv4/zsys_linux_mips64.go | 0 .../golang.org/x/net/ipv4/zsys_linux_mips64le.go | 0 .../golang.org/x/net/ipv4/zsys_linux_ppc.go | 0 .../golang.org/x/net/ipv4/zsys_linux_ppc64.go | 0 .../golang.org/x/net/ipv4/zsys_linux_ppc64le.go | 0 .../golang.org/x/net/ipv4/zsys_linux_s390x.go | 0 .../golang.org/x/net/ipv4/zsys_netbsd.go | 0 .../golang.org/x/net/ipv4/zsys_openbsd.go | 0 .../golang.org/x/net/ipv4/zsys_solaris.go | 0 .../golang.org/x/net/lex/httplex/httplex.go | 0 .../gopkg.in/gorilla/websocket.v1/AUTHORS | 0 .../gopkg.in/gorilla/websocket.v1/LICENSE | 0 .../gopkg.in/gorilla/websocket.v1/README.md | 0 .../gopkg.in/gorilla/websocket.v1/client.go | 0 .../gopkg.in/gorilla/websocket.v1/compression.go | 0 .../gopkg.in/gorilla/websocket.v1/conn.go | 0 .../gopkg.in/gorilla/websocket.v1/conn_read.go | 0 .../gorilla/websocket.v1/conn_read_legacy.go | 0 .../gopkg.in/gorilla/websocket.v1/doc.go | 0 .../gopkg.in/gorilla/websocket.v1/json.go | 0 .../gopkg.in/gorilla/websocket.v1/mask.go | 0 .../gopkg.in/gorilla/websocket.v1/server.go | 0 .../gopkg.in/gorilla/websocket.v1/util.go | 0 .../gopkg.in/xtaci/kcp-go.v2/LICENSE | 0 .../gopkg.in/xtaci/kcp-go.v2/README.md | 0 .../gopkg.in/xtaci/kcp-go.v2/crypt.go | 0 .../gopkg.in/xtaci/kcp-go.v2/donate.png | Bin .../gopkg.in/xtaci/kcp-go.v2/fec.go | 0 .../gopkg.in/xtaci/kcp-go.v2/frame.png | Bin .../gopkg.in/xtaci/kcp-go.v2/kcp-go.png | Bin .../gopkg.in/xtaci/kcp-go.v2/kcp.go | 0 .../gopkg.in/xtaci/kcp-go.v2/sess.go | 0 .../gopkg.in/xtaci/kcp-go.v2/shannon.jpg | Bin .../gopkg.in/xtaci/kcp-go.v2/snmp.go | 0 .../gopkg.in/xtaci/kcp-go.v2/xor.go | 0 .../gopkg.in/xtaci/smux.v1/LICENSE | 0 .../gopkg.in/xtaci/smux.v1/README.md | 0 .../gopkg.in/xtaci/smux.v1/curve.jpg | Bin .../gopkg.in/xtaci/smux.v1/frame.go | 0 .../vendor => vendor}/gopkg.in/xtaci/smux.v1/mux.go | 0 .../gopkg.in/xtaci/smux.v1/mux.jpg | Bin .../gopkg.in/xtaci/smux.v1/session.go | 0 .../gopkg.in/xtaci/smux.v1/stream.go | 0 {cmd/gost/vendor => vendor}/vendor.json | 2 +- 443 files changed, 1 insertion(+), 1 deletion(-) rename {cmd/gost/vendor => vendor}/github.com/Yawning/chacha20/LICENSE (100%) rename {cmd/gost/vendor => vendor}/github.com/Yawning/chacha20/README.md (100%) rename {cmd/gost/vendor => vendor}/github.com/Yawning/chacha20/chacha20.go (100%) rename {cmd/gost/vendor => vendor}/github.com/Yawning/chacha20/chacha20_amd64.go (100%) rename {cmd/gost/vendor => vendor}/github.com/Yawning/chacha20/chacha20_amd64.py (100%) rename {cmd/gost/vendor => vendor}/github.com/Yawning/chacha20/chacha20_amd64.s (100%) rename {cmd/gost/vendor => vendor}/github.com/Yawning/chacha20/chacha20_ref.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gosocks4/LICENSE (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gosocks4/README.md (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gosocks4/socks4.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gosocks4/socks4.protocol.txt (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gosocks4/socks4a.protocol.txt (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gosocks5/LICENSE (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gosocks5/README.md (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gosocks5/conn.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gosocks5/rfc1928.txt (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gosocks5/rfc1929.txt (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gosocks5/socks5.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/LICENSE (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/README.md (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/README_en.md (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/chain.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/conn.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/forward.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/gost.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/http.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/kcp.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/node.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/quic.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/redirect.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/redirect_win.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/server.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/signal.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/signal_unix.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/socks.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/ss.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/ssh.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/gost/ws.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/pht/LICENSE (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/pht/README.md (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/pht/client.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/pht/conn.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/pht/server.go (100%) rename {cmd/gost/vendor => vendor}/github.com/ginuerzh/pht/session.go (100%) rename {cmd/gost/vendor => vendor}/github.com/golang/glog/LICENSE (100%) rename {cmd/gost/vendor => vendor}/github.com/golang/glog/README (100%) rename {cmd/gost/vendor => vendor}/github.com/golang/glog/glog.go (100%) rename {cmd/gost/vendor => vendor}/github.com/golang/glog/glog_file.go (100%) rename {cmd/gost/vendor => vendor}/github.com/hashicorp/golang-lru/2q.go (100%) rename {cmd/gost/vendor => vendor}/github.com/hashicorp/golang-lru/LICENSE (100%) rename {cmd/gost/vendor => vendor}/github.com/hashicorp/golang-lru/README.md (100%) rename {cmd/gost/vendor => vendor}/github.com/hashicorp/golang-lru/arc.go (100%) rename {cmd/gost/vendor => vendor}/github.com/hashicorp/golang-lru/lru.go (100%) rename {cmd/gost/vendor => vendor}/github.com/hashicorp/golang-lru/simplelru/lru.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/compress/LICENSE (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/compress/snappy/AUTHORS (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/compress/snappy/CONTRIBUTORS (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/compress/snappy/LICENSE (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/compress/snappy/README (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/compress/snappy/decode.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/compress/snappy/decode_amd64.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/compress/snappy/decode_amd64.s (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/compress/snappy/decode_other.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/compress/snappy/encode.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/compress/snappy/encode_amd64.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/compress/snappy/encode_amd64.s (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/compress/snappy/encode_other.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/compress/snappy/runbench.cmd (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/compress/snappy/snappy.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/cpuid/LICENSE (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/cpuid/README.md (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/cpuid/cpuid.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/cpuid/cpuid_386.s (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/cpuid/cpuid_amd64.s (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/cpuid/detect_intel.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/cpuid/detect_ref.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/cpuid/generate.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/cpuid/private-gen.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/reedsolomon/LICENSE (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/reedsolomon/README.md (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/reedsolomon/appveyor.yml (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/reedsolomon/galois.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/reedsolomon/galois_amd64.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/reedsolomon/galois_amd64.s (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/reedsolomon/galois_noasm.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/reedsolomon/gentables.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/reedsolomon/inversion_tree.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/reedsolomon/matrix.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/reedsolomon/reedsolomon.go (100%) rename {cmd/gost/vendor => vendor}/github.com/klauspost/reedsolomon/streaming.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/aes12/LICENSE (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/aes12/Readme.md (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/aes12/aes_gcm.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/aes12/asm_amd64.s (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/aes12/block.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/aes12/cipher.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/aes12/cipher_2.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/aes12/cipher_amd64.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/aes12/cipher_generic.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/aes12/const.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/aes12/gcm.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/aes12/gcm_amd64.s (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/aes12/xor.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/fnv128a/LICENSE (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/fnv128a/README.md (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/fnv128a/fnv128a.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go-certificates/LICENSE (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go-certificates/README.md (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go-certificates/cert_set_2.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go-certificates/cert_set_3.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go-certificates/createCertSets.rb (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/LICENSE (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/README.md (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/ackhandler/_gen.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/ackhandler/interfaces.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/ackhandler/packet.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/ackhandler/packet_linkedlist.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/ackhandler/received_packet_handler.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/ackhandler/received_packet_history.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/ackhandler/sent_packet_handler.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/ackhandler/stop_waiting_manager.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/appveyor.yml (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/buffer_pool.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/client.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/codecov.yml (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/congestion/bandwidth.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/congestion/clock.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/congestion/congestion_vector.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/congestion/cubic.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/congestion/cubic_sender.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/congestion/hybrid_slow_start.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/congestion/interface.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/congestion/prr_sender.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/congestion/rtt_stats.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/congestion/stats.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/crypto/AEAD.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/crypto/aesgcm_aead.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/crypto/cert_cache.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/crypto/cert_chain.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/crypto/cert_compression.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/crypto/cert_dict.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/crypto/cert_manager.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/crypto/cert_sets.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/crypto/chacha20poly1305_aead.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/crypto/chacha20poly1305_aead_test.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/crypto/curve_25519.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/crypto/key_derivation.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/crypto/key_exchange.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/crypto/nonce.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/crypto/null_aead.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/crypto/server_proof.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/crypto/source_address_token.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/flowcontrol/flow_control_manager.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/flowcontrol/flow_controller.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/flowcontrol/interface.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/frames/ack_frame.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/frames/ack_range.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/frames/blocked_frame.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/frames/connection_close_frame.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/frames/frame.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/frames/goaway_frame.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/frames/log.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/frames/ping_frame.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/frames/rst_stream_frame.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/frames/stop_waiting_frame.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/frames/stream_frame.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/frames/window_update_frame.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/h2quic/client.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/h2quic/gzipreader.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/h2quic/request.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/h2quic/request_body.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/h2quic/request_writer.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/h2quic/response.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/h2quic/response_setuncompressed.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/h2quic/response_setuncompressed_go16.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/h2quic/response_writer.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/h2quic/roundtrip.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/h2quic/server.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/handshake/connection_parameters_manager.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/handshake/crypto_setup_client.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/handshake/crypto_setup_interface.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/handshake/crypto_setup_server.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/handshake/ephermal_cache.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/handshake/handshake_message.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/handshake/server_config.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/handshake/server_config_client.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/handshake/tags.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/packet_number_generator.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/packet_packer.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/packet_unpacker.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/protocol/encryption_level.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/protocol/packet_number.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/protocol/perspective.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/protocol/protocol.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/protocol/server_parameters.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/protocol/version.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/public_header.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/public_reset.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/qerr/error_codes.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/qerr/errorcode_string.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/qerr/quic_error.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/server.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/session.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/stream.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/stream_frame_sorter.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/stream_framer.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/streams_map.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/udp_conn.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/unpacked_packet.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/utils/_gen.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/utils/atomic_bool.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/utils/byteinterval_linkedlist.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/utils/connection_id.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/utils/float16.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/utils/host.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/utils/log.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/utils/minmax.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/utils/packet_interval.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/utils/packetinterval_linkedlist.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/utils/stream.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/utils/streamframe_interval.go (100%) rename {cmd/gost/vendor => vendor}/github.com/lucas-clemente/quic-go/utils/utils.go (100%) rename {cmd/gost/vendor => vendor}/github.com/pkg/errors/LICENSE (100%) rename {cmd/gost/vendor => vendor}/github.com/pkg/errors/README.md (100%) rename {cmd/gost/vendor => vendor}/github.com/pkg/errors/appveyor.yml (100%) rename {cmd/gost/vendor => vendor}/github.com/pkg/errors/errors.go (100%) rename {cmd/gost/vendor => vendor}/github.com/pkg/errors/stack.go (100%) rename {cmd/gost/vendor => vendor}/github.com/shadowsocks/shadowsocks-go/LICENSE (100%) rename {cmd/gost/vendor => vendor}/github.com/shadowsocks/shadowsocks-go/shadowsocks/config.go (100%) rename {cmd/gost/vendor => vendor}/github.com/shadowsocks/shadowsocks-go/shadowsocks/conn.go (100%) rename {cmd/gost/vendor => vendor}/github.com/shadowsocks/shadowsocks-go/shadowsocks/encrypt.go (100%) rename {cmd/gost/vendor => vendor}/github.com/shadowsocks/shadowsocks-go/shadowsocks/leakybuf.go (100%) rename {cmd/gost/vendor => vendor}/github.com/shadowsocks/shadowsocks-go/shadowsocks/log.go (100%) rename {cmd/gost/vendor => vendor}/github.com/shadowsocks/shadowsocks-go/shadowsocks/mergesort.go (100%) rename {cmd/gost/vendor => vendor}/github.com/shadowsocks/shadowsocks-go/shadowsocks/pipe.go (100%) rename {cmd/gost/vendor => vendor}/github.com/shadowsocks/shadowsocks-go/shadowsocks/proxy.go (100%) rename {cmd/gost/vendor => vendor}/github.com/shadowsocks/shadowsocks-go/shadowsocks/udp.go (100%) rename {cmd/gost/vendor => vendor}/github.com/shadowsocks/shadowsocks-go/shadowsocks/udprelay.go (100%) rename {cmd/gost/vendor => vendor}/github.com/shadowsocks/shadowsocks-go/shadowsocks/util.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/LICENSE (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/PATENTS (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/blowfish/block.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/blowfish/cipher.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/blowfish/const.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/cast5/cast5.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/curve25519/const_amd64.h (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/curve25519/const_amd64.s (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/curve25519/cswap_amd64.s (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/curve25519/curve25519.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/curve25519/doc.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/curve25519/freeze_amd64.s (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/curve25519/ladderstep_amd64.s (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/curve25519/mont25519_amd64.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/curve25519/mul_amd64.s (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/curve25519/square_amd64.s (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ed25519/ed25519.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ed25519/internal/edwards25519/const.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/hkdf/hkdf.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/pbkdf2/pbkdf2.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/salsa20/salsa/hsalsa20.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/salsa20/salsa/salsa208.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/salsa20/salsa20.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/buffer.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/certs.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/channel.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/cipher.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/client.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/client_auth.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/common.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/connection.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/doc.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/handshake.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/kex.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/keys.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/mac.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/messages.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/mux.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/server.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/session.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/tcpip.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/ssh/transport.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/tea/cipher.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/twofish/twofish.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/xtea/block.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/crypto/xtea/cipher.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/LICENSE (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/PATENTS (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/bpf/asm.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/bpf/constants.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/bpf/doc.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/bpf/instructions.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/bpf/vm.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/bpf/vm_instructions.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/Dockerfile (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/Makefile (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/README (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/client_conn_pool.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/configure_transport.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/errors.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/fixed_buffer.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/flow.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/frame.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/go16.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/go17.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/go17_not18.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/go18.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/gotrack.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/headermap.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/hpack/encode.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/hpack/hpack.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/hpack/huffman.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/hpack/tables.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/http2.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/not_go16.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/not_go17.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/not_go18.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/pipe.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/server.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/transport.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/write.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/writesched.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/writesched_priority.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/http2/writesched_random.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/idna/idna.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/idna/punycode.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/internal/iana/const.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/internal/iana/gen.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/internal/netreflect/socket.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/internal/netreflect/socket_posix.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/internal/netreflect/socket_stub.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/bpfopt_linux.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/bpfopt_stub.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/control.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/control_bsd.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/control_pktinfo.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/control_stub.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/control_unix.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/control_windows.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/defs_darwin.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/defs_dragonfly.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/defs_freebsd.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/defs_linux.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/defs_netbsd.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/defs_openbsd.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/defs_solaris.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/dgramopt_posix.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/dgramopt_stub.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/doc.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/endpoint.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/gen.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/genericopt_posix.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/genericopt_stub.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/header.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/helper.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/iana.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/icmp.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/icmp_linux.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/icmp_stub.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/packet.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/payload.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/payload_cmsg.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/payload_nocmsg.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sockopt.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sockopt_asmreq.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sockopt_asmreq_posix.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sockopt_asmreq_stub.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sockopt_asmreqn_stub.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sockopt_asmreqn_unix.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sockopt_posix.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sockopt_ssmreq_stub.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sockopt_ssmreq_unix.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sockopt_stub.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sys_bsd.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sys_darwin.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sys_freebsd.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sys_linux.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sys_linux_386.s (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sys_openbsd.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sys_solaris.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sys_solaris_amd64.s (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sys_stub.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/sys_windows.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/syscall_linux_386.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/syscall_solaris.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/syscall_unix.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/syscall_windows.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_darwin.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_dragonfly.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_freebsd_386.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_freebsd_amd64.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_freebsd_arm.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_linux_386.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_linux_amd64.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_linux_arm.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_linux_arm64.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_linux_mips64.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_linux_mips64le.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_linux_ppc.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_linux_ppc64.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_linux_ppc64le.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_linux_s390x.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_netbsd.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_openbsd.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/ipv4/zsys_solaris.go (100%) rename {cmd/gost/vendor => vendor}/golang.org/x/net/lex/httplex/httplex.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/gorilla/websocket.v1/AUTHORS (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/gorilla/websocket.v1/LICENSE (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/gorilla/websocket.v1/README.md (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/gorilla/websocket.v1/client.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/gorilla/websocket.v1/compression.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/gorilla/websocket.v1/conn.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/gorilla/websocket.v1/conn_read.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/gorilla/websocket.v1/conn_read_legacy.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/gorilla/websocket.v1/doc.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/gorilla/websocket.v1/json.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/gorilla/websocket.v1/mask.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/gorilla/websocket.v1/server.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/gorilla/websocket.v1/util.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/kcp-go.v2/LICENSE (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/kcp-go.v2/README.md (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/kcp-go.v2/crypt.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/kcp-go.v2/donate.png (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/kcp-go.v2/fec.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/kcp-go.v2/frame.png (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/kcp-go.v2/kcp-go.png (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/kcp-go.v2/kcp.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/kcp-go.v2/sess.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/kcp-go.v2/shannon.jpg (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/kcp-go.v2/snmp.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/kcp-go.v2/xor.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/smux.v1/LICENSE (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/smux.v1/README.md (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/smux.v1/curve.jpg (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/smux.v1/frame.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/smux.v1/mux.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/smux.v1/mux.jpg (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/smux.v1/session.go (100%) rename {cmd/gost/vendor => vendor}/gopkg.in/xtaci/smux.v1/stream.go (100%) rename {cmd/gost/vendor => vendor}/vendor.json (99%) diff --git a/cmd/gost/vendor/github.com/Yawning/chacha20/LICENSE b/vendor/github.com/Yawning/chacha20/LICENSE similarity index 100% rename from cmd/gost/vendor/github.com/Yawning/chacha20/LICENSE rename to vendor/github.com/Yawning/chacha20/LICENSE diff --git a/cmd/gost/vendor/github.com/Yawning/chacha20/README.md b/vendor/github.com/Yawning/chacha20/README.md similarity index 100% rename from cmd/gost/vendor/github.com/Yawning/chacha20/README.md rename to vendor/github.com/Yawning/chacha20/README.md diff --git a/cmd/gost/vendor/github.com/Yawning/chacha20/chacha20.go b/vendor/github.com/Yawning/chacha20/chacha20.go similarity index 100% rename from cmd/gost/vendor/github.com/Yawning/chacha20/chacha20.go rename to vendor/github.com/Yawning/chacha20/chacha20.go diff --git a/cmd/gost/vendor/github.com/Yawning/chacha20/chacha20_amd64.go b/vendor/github.com/Yawning/chacha20/chacha20_amd64.go similarity index 100% rename from cmd/gost/vendor/github.com/Yawning/chacha20/chacha20_amd64.go rename to vendor/github.com/Yawning/chacha20/chacha20_amd64.go diff --git a/cmd/gost/vendor/github.com/Yawning/chacha20/chacha20_amd64.py b/vendor/github.com/Yawning/chacha20/chacha20_amd64.py similarity index 100% rename from cmd/gost/vendor/github.com/Yawning/chacha20/chacha20_amd64.py rename to vendor/github.com/Yawning/chacha20/chacha20_amd64.py diff --git a/cmd/gost/vendor/github.com/Yawning/chacha20/chacha20_amd64.s b/vendor/github.com/Yawning/chacha20/chacha20_amd64.s similarity index 100% rename from cmd/gost/vendor/github.com/Yawning/chacha20/chacha20_amd64.s rename to vendor/github.com/Yawning/chacha20/chacha20_amd64.s diff --git a/cmd/gost/vendor/github.com/Yawning/chacha20/chacha20_ref.go b/vendor/github.com/Yawning/chacha20/chacha20_ref.go similarity index 100% rename from cmd/gost/vendor/github.com/Yawning/chacha20/chacha20_ref.go rename to vendor/github.com/Yawning/chacha20/chacha20_ref.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gosocks4/LICENSE b/vendor/github.com/ginuerzh/gosocks4/LICENSE similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gosocks4/LICENSE rename to vendor/github.com/ginuerzh/gosocks4/LICENSE diff --git a/cmd/gost/vendor/github.com/ginuerzh/gosocks4/README.md b/vendor/github.com/ginuerzh/gosocks4/README.md similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gosocks4/README.md rename to vendor/github.com/ginuerzh/gosocks4/README.md diff --git a/cmd/gost/vendor/github.com/ginuerzh/gosocks4/socks4.go b/vendor/github.com/ginuerzh/gosocks4/socks4.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gosocks4/socks4.go rename to vendor/github.com/ginuerzh/gosocks4/socks4.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gosocks4/socks4.protocol.txt b/vendor/github.com/ginuerzh/gosocks4/socks4.protocol.txt similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gosocks4/socks4.protocol.txt rename to vendor/github.com/ginuerzh/gosocks4/socks4.protocol.txt diff --git a/cmd/gost/vendor/github.com/ginuerzh/gosocks4/socks4a.protocol.txt b/vendor/github.com/ginuerzh/gosocks4/socks4a.protocol.txt similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gosocks4/socks4a.protocol.txt rename to vendor/github.com/ginuerzh/gosocks4/socks4a.protocol.txt diff --git a/cmd/gost/vendor/github.com/ginuerzh/gosocks5/LICENSE b/vendor/github.com/ginuerzh/gosocks5/LICENSE similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gosocks5/LICENSE rename to vendor/github.com/ginuerzh/gosocks5/LICENSE diff --git a/cmd/gost/vendor/github.com/ginuerzh/gosocks5/README.md b/vendor/github.com/ginuerzh/gosocks5/README.md similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gosocks5/README.md rename to vendor/github.com/ginuerzh/gosocks5/README.md diff --git a/cmd/gost/vendor/github.com/ginuerzh/gosocks5/conn.go b/vendor/github.com/ginuerzh/gosocks5/conn.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gosocks5/conn.go rename to vendor/github.com/ginuerzh/gosocks5/conn.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gosocks5/rfc1928.txt b/vendor/github.com/ginuerzh/gosocks5/rfc1928.txt similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gosocks5/rfc1928.txt rename to vendor/github.com/ginuerzh/gosocks5/rfc1928.txt diff --git a/cmd/gost/vendor/github.com/ginuerzh/gosocks5/rfc1929.txt b/vendor/github.com/ginuerzh/gosocks5/rfc1929.txt similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gosocks5/rfc1929.txt rename to vendor/github.com/ginuerzh/gosocks5/rfc1929.txt diff --git a/cmd/gost/vendor/github.com/ginuerzh/gosocks5/socks5.go b/vendor/github.com/ginuerzh/gosocks5/socks5.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gosocks5/socks5.go rename to vendor/github.com/ginuerzh/gosocks5/socks5.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/LICENSE b/vendor/github.com/ginuerzh/gost/LICENSE similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/LICENSE rename to vendor/github.com/ginuerzh/gost/LICENSE diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/README.md b/vendor/github.com/ginuerzh/gost/README.md similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/README.md rename to vendor/github.com/ginuerzh/gost/README.md diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/README_en.md b/vendor/github.com/ginuerzh/gost/README_en.md similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/README_en.md rename to vendor/github.com/ginuerzh/gost/README_en.md diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/chain.go b/vendor/github.com/ginuerzh/gost/chain.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/chain.go rename to vendor/github.com/ginuerzh/gost/chain.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/conn.go b/vendor/github.com/ginuerzh/gost/conn.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/conn.go rename to vendor/github.com/ginuerzh/gost/conn.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/forward.go b/vendor/github.com/ginuerzh/gost/forward.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/forward.go rename to vendor/github.com/ginuerzh/gost/forward.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/gost.go b/vendor/github.com/ginuerzh/gost/gost.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/gost.go rename to vendor/github.com/ginuerzh/gost/gost.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/http.go b/vendor/github.com/ginuerzh/gost/http.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/http.go rename to vendor/github.com/ginuerzh/gost/http.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/kcp.go b/vendor/github.com/ginuerzh/gost/kcp.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/kcp.go rename to vendor/github.com/ginuerzh/gost/kcp.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/node.go b/vendor/github.com/ginuerzh/gost/node.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/node.go rename to vendor/github.com/ginuerzh/gost/node.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/quic.go b/vendor/github.com/ginuerzh/gost/quic.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/quic.go rename to vendor/github.com/ginuerzh/gost/quic.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/redirect.go b/vendor/github.com/ginuerzh/gost/redirect.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/redirect.go rename to vendor/github.com/ginuerzh/gost/redirect.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/redirect_win.go b/vendor/github.com/ginuerzh/gost/redirect_win.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/redirect_win.go rename to vendor/github.com/ginuerzh/gost/redirect_win.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/server.go b/vendor/github.com/ginuerzh/gost/server.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/server.go rename to vendor/github.com/ginuerzh/gost/server.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/signal.go b/vendor/github.com/ginuerzh/gost/signal.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/signal.go rename to vendor/github.com/ginuerzh/gost/signal.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/signal_unix.go b/vendor/github.com/ginuerzh/gost/signal_unix.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/signal_unix.go rename to vendor/github.com/ginuerzh/gost/signal_unix.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/socks.go b/vendor/github.com/ginuerzh/gost/socks.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/socks.go rename to vendor/github.com/ginuerzh/gost/socks.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/ss.go b/vendor/github.com/ginuerzh/gost/ss.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/ss.go rename to vendor/github.com/ginuerzh/gost/ss.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/ssh.go b/vendor/github.com/ginuerzh/gost/ssh.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/ssh.go rename to vendor/github.com/ginuerzh/gost/ssh.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/gost/ws.go b/vendor/github.com/ginuerzh/gost/ws.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/gost/ws.go rename to vendor/github.com/ginuerzh/gost/ws.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/pht/LICENSE b/vendor/github.com/ginuerzh/pht/LICENSE similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/pht/LICENSE rename to vendor/github.com/ginuerzh/pht/LICENSE diff --git a/cmd/gost/vendor/github.com/ginuerzh/pht/README.md b/vendor/github.com/ginuerzh/pht/README.md similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/pht/README.md rename to vendor/github.com/ginuerzh/pht/README.md diff --git a/cmd/gost/vendor/github.com/ginuerzh/pht/client.go b/vendor/github.com/ginuerzh/pht/client.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/pht/client.go rename to vendor/github.com/ginuerzh/pht/client.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/pht/conn.go b/vendor/github.com/ginuerzh/pht/conn.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/pht/conn.go rename to vendor/github.com/ginuerzh/pht/conn.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/pht/server.go b/vendor/github.com/ginuerzh/pht/server.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/pht/server.go rename to vendor/github.com/ginuerzh/pht/server.go diff --git a/cmd/gost/vendor/github.com/ginuerzh/pht/session.go b/vendor/github.com/ginuerzh/pht/session.go similarity index 100% rename from cmd/gost/vendor/github.com/ginuerzh/pht/session.go rename to vendor/github.com/ginuerzh/pht/session.go diff --git a/cmd/gost/vendor/github.com/golang/glog/LICENSE b/vendor/github.com/golang/glog/LICENSE similarity index 100% rename from cmd/gost/vendor/github.com/golang/glog/LICENSE rename to vendor/github.com/golang/glog/LICENSE diff --git a/cmd/gost/vendor/github.com/golang/glog/README b/vendor/github.com/golang/glog/README similarity index 100% rename from cmd/gost/vendor/github.com/golang/glog/README rename to vendor/github.com/golang/glog/README diff --git a/cmd/gost/vendor/github.com/golang/glog/glog.go b/vendor/github.com/golang/glog/glog.go similarity index 100% rename from cmd/gost/vendor/github.com/golang/glog/glog.go rename to vendor/github.com/golang/glog/glog.go diff --git a/cmd/gost/vendor/github.com/golang/glog/glog_file.go b/vendor/github.com/golang/glog/glog_file.go similarity index 100% rename from cmd/gost/vendor/github.com/golang/glog/glog_file.go rename to vendor/github.com/golang/glog/glog_file.go diff --git a/cmd/gost/vendor/github.com/hashicorp/golang-lru/2q.go b/vendor/github.com/hashicorp/golang-lru/2q.go similarity index 100% rename from cmd/gost/vendor/github.com/hashicorp/golang-lru/2q.go rename to vendor/github.com/hashicorp/golang-lru/2q.go diff --git a/cmd/gost/vendor/github.com/hashicorp/golang-lru/LICENSE b/vendor/github.com/hashicorp/golang-lru/LICENSE similarity index 100% rename from cmd/gost/vendor/github.com/hashicorp/golang-lru/LICENSE rename to vendor/github.com/hashicorp/golang-lru/LICENSE diff --git a/cmd/gost/vendor/github.com/hashicorp/golang-lru/README.md b/vendor/github.com/hashicorp/golang-lru/README.md similarity index 100% rename from cmd/gost/vendor/github.com/hashicorp/golang-lru/README.md rename to vendor/github.com/hashicorp/golang-lru/README.md diff --git a/cmd/gost/vendor/github.com/hashicorp/golang-lru/arc.go b/vendor/github.com/hashicorp/golang-lru/arc.go similarity index 100% rename from cmd/gost/vendor/github.com/hashicorp/golang-lru/arc.go rename to vendor/github.com/hashicorp/golang-lru/arc.go diff --git a/cmd/gost/vendor/github.com/hashicorp/golang-lru/lru.go b/vendor/github.com/hashicorp/golang-lru/lru.go similarity index 100% rename from cmd/gost/vendor/github.com/hashicorp/golang-lru/lru.go rename to vendor/github.com/hashicorp/golang-lru/lru.go diff --git a/cmd/gost/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go similarity index 100% rename from cmd/gost/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go rename to vendor/github.com/hashicorp/golang-lru/simplelru/lru.go diff --git a/cmd/gost/vendor/github.com/klauspost/compress/LICENSE b/vendor/github.com/klauspost/compress/LICENSE similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/compress/LICENSE rename to vendor/github.com/klauspost/compress/LICENSE diff --git a/cmd/gost/vendor/github.com/klauspost/compress/snappy/AUTHORS b/vendor/github.com/klauspost/compress/snappy/AUTHORS similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/compress/snappy/AUTHORS rename to vendor/github.com/klauspost/compress/snappy/AUTHORS diff --git a/cmd/gost/vendor/github.com/klauspost/compress/snappy/CONTRIBUTORS b/vendor/github.com/klauspost/compress/snappy/CONTRIBUTORS similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/compress/snappy/CONTRIBUTORS rename to vendor/github.com/klauspost/compress/snappy/CONTRIBUTORS diff --git a/cmd/gost/vendor/github.com/klauspost/compress/snappy/LICENSE b/vendor/github.com/klauspost/compress/snappy/LICENSE similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/compress/snappy/LICENSE rename to vendor/github.com/klauspost/compress/snappy/LICENSE diff --git a/cmd/gost/vendor/github.com/klauspost/compress/snappy/README b/vendor/github.com/klauspost/compress/snappy/README similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/compress/snappy/README rename to vendor/github.com/klauspost/compress/snappy/README diff --git a/cmd/gost/vendor/github.com/klauspost/compress/snappy/decode.go b/vendor/github.com/klauspost/compress/snappy/decode.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/compress/snappy/decode.go rename to vendor/github.com/klauspost/compress/snappy/decode.go diff --git a/cmd/gost/vendor/github.com/klauspost/compress/snappy/decode_amd64.go b/vendor/github.com/klauspost/compress/snappy/decode_amd64.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/compress/snappy/decode_amd64.go rename to vendor/github.com/klauspost/compress/snappy/decode_amd64.go diff --git a/cmd/gost/vendor/github.com/klauspost/compress/snappy/decode_amd64.s b/vendor/github.com/klauspost/compress/snappy/decode_amd64.s similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/compress/snappy/decode_amd64.s rename to vendor/github.com/klauspost/compress/snappy/decode_amd64.s diff --git a/cmd/gost/vendor/github.com/klauspost/compress/snappy/decode_other.go b/vendor/github.com/klauspost/compress/snappy/decode_other.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/compress/snappy/decode_other.go rename to vendor/github.com/klauspost/compress/snappy/decode_other.go diff --git a/cmd/gost/vendor/github.com/klauspost/compress/snappy/encode.go b/vendor/github.com/klauspost/compress/snappy/encode.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/compress/snappy/encode.go rename to vendor/github.com/klauspost/compress/snappy/encode.go diff --git a/cmd/gost/vendor/github.com/klauspost/compress/snappy/encode_amd64.go b/vendor/github.com/klauspost/compress/snappy/encode_amd64.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/compress/snappy/encode_amd64.go rename to vendor/github.com/klauspost/compress/snappy/encode_amd64.go diff --git a/cmd/gost/vendor/github.com/klauspost/compress/snappy/encode_amd64.s b/vendor/github.com/klauspost/compress/snappy/encode_amd64.s similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/compress/snappy/encode_amd64.s rename to vendor/github.com/klauspost/compress/snappy/encode_amd64.s diff --git a/cmd/gost/vendor/github.com/klauspost/compress/snappy/encode_other.go b/vendor/github.com/klauspost/compress/snappy/encode_other.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/compress/snappy/encode_other.go rename to vendor/github.com/klauspost/compress/snappy/encode_other.go diff --git a/cmd/gost/vendor/github.com/klauspost/compress/snappy/runbench.cmd b/vendor/github.com/klauspost/compress/snappy/runbench.cmd similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/compress/snappy/runbench.cmd rename to vendor/github.com/klauspost/compress/snappy/runbench.cmd diff --git a/cmd/gost/vendor/github.com/klauspost/compress/snappy/snappy.go b/vendor/github.com/klauspost/compress/snappy/snappy.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/compress/snappy/snappy.go rename to vendor/github.com/klauspost/compress/snappy/snappy.go diff --git a/cmd/gost/vendor/github.com/klauspost/cpuid/LICENSE b/vendor/github.com/klauspost/cpuid/LICENSE similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/cpuid/LICENSE rename to vendor/github.com/klauspost/cpuid/LICENSE diff --git a/cmd/gost/vendor/github.com/klauspost/cpuid/README.md b/vendor/github.com/klauspost/cpuid/README.md similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/cpuid/README.md rename to vendor/github.com/klauspost/cpuid/README.md diff --git a/cmd/gost/vendor/github.com/klauspost/cpuid/cpuid.go b/vendor/github.com/klauspost/cpuid/cpuid.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/cpuid/cpuid.go rename to vendor/github.com/klauspost/cpuid/cpuid.go diff --git a/cmd/gost/vendor/github.com/klauspost/cpuid/cpuid_386.s b/vendor/github.com/klauspost/cpuid/cpuid_386.s similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/cpuid/cpuid_386.s rename to vendor/github.com/klauspost/cpuid/cpuid_386.s diff --git a/cmd/gost/vendor/github.com/klauspost/cpuid/cpuid_amd64.s b/vendor/github.com/klauspost/cpuid/cpuid_amd64.s similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/cpuid/cpuid_amd64.s rename to vendor/github.com/klauspost/cpuid/cpuid_amd64.s diff --git a/cmd/gost/vendor/github.com/klauspost/cpuid/detect_intel.go b/vendor/github.com/klauspost/cpuid/detect_intel.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/cpuid/detect_intel.go rename to vendor/github.com/klauspost/cpuid/detect_intel.go diff --git a/cmd/gost/vendor/github.com/klauspost/cpuid/detect_ref.go b/vendor/github.com/klauspost/cpuid/detect_ref.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/cpuid/detect_ref.go rename to vendor/github.com/klauspost/cpuid/detect_ref.go diff --git a/cmd/gost/vendor/github.com/klauspost/cpuid/generate.go b/vendor/github.com/klauspost/cpuid/generate.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/cpuid/generate.go rename to vendor/github.com/klauspost/cpuid/generate.go diff --git a/cmd/gost/vendor/github.com/klauspost/cpuid/private-gen.go b/vendor/github.com/klauspost/cpuid/private-gen.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/cpuid/private-gen.go rename to vendor/github.com/klauspost/cpuid/private-gen.go diff --git a/cmd/gost/vendor/github.com/klauspost/reedsolomon/LICENSE b/vendor/github.com/klauspost/reedsolomon/LICENSE similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/reedsolomon/LICENSE rename to vendor/github.com/klauspost/reedsolomon/LICENSE diff --git a/cmd/gost/vendor/github.com/klauspost/reedsolomon/README.md b/vendor/github.com/klauspost/reedsolomon/README.md similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/reedsolomon/README.md rename to vendor/github.com/klauspost/reedsolomon/README.md diff --git a/cmd/gost/vendor/github.com/klauspost/reedsolomon/appveyor.yml b/vendor/github.com/klauspost/reedsolomon/appveyor.yml similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/reedsolomon/appveyor.yml rename to vendor/github.com/klauspost/reedsolomon/appveyor.yml diff --git a/cmd/gost/vendor/github.com/klauspost/reedsolomon/galois.go b/vendor/github.com/klauspost/reedsolomon/galois.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/reedsolomon/galois.go rename to vendor/github.com/klauspost/reedsolomon/galois.go diff --git a/cmd/gost/vendor/github.com/klauspost/reedsolomon/galois_amd64.go b/vendor/github.com/klauspost/reedsolomon/galois_amd64.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/reedsolomon/galois_amd64.go rename to vendor/github.com/klauspost/reedsolomon/galois_amd64.go diff --git a/cmd/gost/vendor/github.com/klauspost/reedsolomon/galois_amd64.s b/vendor/github.com/klauspost/reedsolomon/galois_amd64.s similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/reedsolomon/galois_amd64.s rename to vendor/github.com/klauspost/reedsolomon/galois_amd64.s diff --git a/cmd/gost/vendor/github.com/klauspost/reedsolomon/galois_noasm.go b/vendor/github.com/klauspost/reedsolomon/galois_noasm.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/reedsolomon/galois_noasm.go rename to vendor/github.com/klauspost/reedsolomon/galois_noasm.go diff --git a/cmd/gost/vendor/github.com/klauspost/reedsolomon/gentables.go b/vendor/github.com/klauspost/reedsolomon/gentables.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/reedsolomon/gentables.go rename to vendor/github.com/klauspost/reedsolomon/gentables.go diff --git a/cmd/gost/vendor/github.com/klauspost/reedsolomon/inversion_tree.go b/vendor/github.com/klauspost/reedsolomon/inversion_tree.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/reedsolomon/inversion_tree.go rename to vendor/github.com/klauspost/reedsolomon/inversion_tree.go diff --git a/cmd/gost/vendor/github.com/klauspost/reedsolomon/matrix.go b/vendor/github.com/klauspost/reedsolomon/matrix.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/reedsolomon/matrix.go rename to vendor/github.com/klauspost/reedsolomon/matrix.go diff --git a/cmd/gost/vendor/github.com/klauspost/reedsolomon/reedsolomon.go b/vendor/github.com/klauspost/reedsolomon/reedsolomon.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/reedsolomon/reedsolomon.go rename to vendor/github.com/klauspost/reedsolomon/reedsolomon.go diff --git a/cmd/gost/vendor/github.com/klauspost/reedsolomon/streaming.go b/vendor/github.com/klauspost/reedsolomon/streaming.go similarity index 100% rename from cmd/gost/vendor/github.com/klauspost/reedsolomon/streaming.go rename to vendor/github.com/klauspost/reedsolomon/streaming.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/aes12/LICENSE b/vendor/github.com/lucas-clemente/aes12/LICENSE similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/aes12/LICENSE rename to vendor/github.com/lucas-clemente/aes12/LICENSE diff --git a/cmd/gost/vendor/github.com/lucas-clemente/aes12/Readme.md b/vendor/github.com/lucas-clemente/aes12/Readme.md similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/aes12/Readme.md rename to vendor/github.com/lucas-clemente/aes12/Readme.md diff --git a/cmd/gost/vendor/github.com/lucas-clemente/aes12/aes_gcm.go b/vendor/github.com/lucas-clemente/aes12/aes_gcm.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/aes12/aes_gcm.go rename to vendor/github.com/lucas-clemente/aes12/aes_gcm.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/aes12/asm_amd64.s b/vendor/github.com/lucas-clemente/aes12/asm_amd64.s similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/aes12/asm_amd64.s rename to vendor/github.com/lucas-clemente/aes12/asm_amd64.s diff --git a/cmd/gost/vendor/github.com/lucas-clemente/aes12/block.go b/vendor/github.com/lucas-clemente/aes12/block.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/aes12/block.go rename to vendor/github.com/lucas-clemente/aes12/block.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/aes12/cipher.go b/vendor/github.com/lucas-clemente/aes12/cipher.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/aes12/cipher.go rename to vendor/github.com/lucas-clemente/aes12/cipher.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/aes12/cipher_2.go b/vendor/github.com/lucas-clemente/aes12/cipher_2.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/aes12/cipher_2.go rename to vendor/github.com/lucas-clemente/aes12/cipher_2.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/aes12/cipher_amd64.go b/vendor/github.com/lucas-clemente/aes12/cipher_amd64.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/aes12/cipher_amd64.go rename to vendor/github.com/lucas-clemente/aes12/cipher_amd64.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/aes12/cipher_generic.go b/vendor/github.com/lucas-clemente/aes12/cipher_generic.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/aes12/cipher_generic.go rename to vendor/github.com/lucas-clemente/aes12/cipher_generic.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/aes12/const.go b/vendor/github.com/lucas-clemente/aes12/const.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/aes12/const.go rename to vendor/github.com/lucas-clemente/aes12/const.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/aes12/gcm.go b/vendor/github.com/lucas-clemente/aes12/gcm.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/aes12/gcm.go rename to vendor/github.com/lucas-clemente/aes12/gcm.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/aes12/gcm_amd64.s b/vendor/github.com/lucas-clemente/aes12/gcm_amd64.s similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/aes12/gcm_amd64.s rename to vendor/github.com/lucas-clemente/aes12/gcm_amd64.s diff --git a/cmd/gost/vendor/github.com/lucas-clemente/aes12/xor.go b/vendor/github.com/lucas-clemente/aes12/xor.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/aes12/xor.go rename to vendor/github.com/lucas-clemente/aes12/xor.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/fnv128a/LICENSE b/vendor/github.com/lucas-clemente/fnv128a/LICENSE similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/fnv128a/LICENSE rename to vendor/github.com/lucas-clemente/fnv128a/LICENSE diff --git a/cmd/gost/vendor/github.com/lucas-clemente/fnv128a/README.md b/vendor/github.com/lucas-clemente/fnv128a/README.md similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/fnv128a/README.md rename to vendor/github.com/lucas-clemente/fnv128a/README.md diff --git a/cmd/gost/vendor/github.com/lucas-clemente/fnv128a/fnv128a.go b/vendor/github.com/lucas-clemente/fnv128a/fnv128a.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/fnv128a/fnv128a.go rename to vendor/github.com/lucas-clemente/fnv128a/fnv128a.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go-certificates/LICENSE b/vendor/github.com/lucas-clemente/quic-go-certificates/LICENSE similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go-certificates/LICENSE rename to vendor/github.com/lucas-clemente/quic-go-certificates/LICENSE diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go-certificates/README.md b/vendor/github.com/lucas-clemente/quic-go-certificates/README.md similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go-certificates/README.md rename to vendor/github.com/lucas-clemente/quic-go-certificates/README.md diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go-certificates/cert_set_2.go b/vendor/github.com/lucas-clemente/quic-go-certificates/cert_set_2.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go-certificates/cert_set_2.go rename to vendor/github.com/lucas-clemente/quic-go-certificates/cert_set_2.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go-certificates/cert_set_3.go b/vendor/github.com/lucas-clemente/quic-go-certificates/cert_set_3.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go-certificates/cert_set_3.go rename to vendor/github.com/lucas-clemente/quic-go-certificates/cert_set_3.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go-certificates/createCertSets.rb b/vendor/github.com/lucas-clemente/quic-go-certificates/createCertSets.rb similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go-certificates/createCertSets.rb rename to vendor/github.com/lucas-clemente/quic-go-certificates/createCertSets.rb diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/LICENSE b/vendor/github.com/lucas-clemente/quic-go/LICENSE similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/LICENSE rename to vendor/github.com/lucas-clemente/quic-go/LICENSE diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/README.md b/vendor/github.com/lucas-clemente/quic-go/README.md similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/README.md rename to vendor/github.com/lucas-clemente/quic-go/README.md diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/ackhandler/_gen.go b/vendor/github.com/lucas-clemente/quic-go/ackhandler/_gen.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/ackhandler/_gen.go rename to vendor/github.com/lucas-clemente/quic-go/ackhandler/_gen.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/ackhandler/interfaces.go b/vendor/github.com/lucas-clemente/quic-go/ackhandler/interfaces.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/ackhandler/interfaces.go rename to vendor/github.com/lucas-clemente/quic-go/ackhandler/interfaces.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/ackhandler/packet.go b/vendor/github.com/lucas-clemente/quic-go/ackhandler/packet.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/ackhandler/packet.go rename to vendor/github.com/lucas-clemente/quic-go/ackhandler/packet.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/ackhandler/packet_linkedlist.go b/vendor/github.com/lucas-clemente/quic-go/ackhandler/packet_linkedlist.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/ackhandler/packet_linkedlist.go rename to vendor/github.com/lucas-clemente/quic-go/ackhandler/packet_linkedlist.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/ackhandler/received_packet_handler.go b/vendor/github.com/lucas-clemente/quic-go/ackhandler/received_packet_handler.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/ackhandler/received_packet_handler.go rename to vendor/github.com/lucas-clemente/quic-go/ackhandler/received_packet_handler.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/ackhandler/received_packet_history.go b/vendor/github.com/lucas-clemente/quic-go/ackhandler/received_packet_history.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/ackhandler/received_packet_history.go rename to vendor/github.com/lucas-clemente/quic-go/ackhandler/received_packet_history.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/ackhandler/sent_packet_handler.go b/vendor/github.com/lucas-clemente/quic-go/ackhandler/sent_packet_handler.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/ackhandler/sent_packet_handler.go rename to vendor/github.com/lucas-clemente/quic-go/ackhandler/sent_packet_handler.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/ackhandler/stop_waiting_manager.go b/vendor/github.com/lucas-clemente/quic-go/ackhandler/stop_waiting_manager.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/ackhandler/stop_waiting_manager.go rename to vendor/github.com/lucas-clemente/quic-go/ackhandler/stop_waiting_manager.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/appveyor.yml b/vendor/github.com/lucas-clemente/quic-go/appveyor.yml similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/appveyor.yml rename to vendor/github.com/lucas-clemente/quic-go/appveyor.yml diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/buffer_pool.go b/vendor/github.com/lucas-clemente/quic-go/buffer_pool.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/buffer_pool.go rename to vendor/github.com/lucas-clemente/quic-go/buffer_pool.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/client.go b/vendor/github.com/lucas-clemente/quic-go/client.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/client.go rename to vendor/github.com/lucas-clemente/quic-go/client.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/codecov.yml b/vendor/github.com/lucas-clemente/quic-go/codecov.yml similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/codecov.yml rename to vendor/github.com/lucas-clemente/quic-go/codecov.yml diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/bandwidth.go b/vendor/github.com/lucas-clemente/quic-go/congestion/bandwidth.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/bandwidth.go rename to vendor/github.com/lucas-clemente/quic-go/congestion/bandwidth.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/clock.go b/vendor/github.com/lucas-clemente/quic-go/congestion/clock.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/clock.go rename to vendor/github.com/lucas-clemente/quic-go/congestion/clock.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/congestion_vector.go b/vendor/github.com/lucas-clemente/quic-go/congestion/congestion_vector.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/congestion_vector.go rename to vendor/github.com/lucas-clemente/quic-go/congestion/congestion_vector.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/cubic.go b/vendor/github.com/lucas-clemente/quic-go/congestion/cubic.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/cubic.go rename to vendor/github.com/lucas-clemente/quic-go/congestion/cubic.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/cubic_sender.go b/vendor/github.com/lucas-clemente/quic-go/congestion/cubic_sender.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/cubic_sender.go rename to vendor/github.com/lucas-clemente/quic-go/congestion/cubic_sender.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/hybrid_slow_start.go b/vendor/github.com/lucas-clemente/quic-go/congestion/hybrid_slow_start.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/hybrid_slow_start.go rename to vendor/github.com/lucas-clemente/quic-go/congestion/hybrid_slow_start.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/interface.go b/vendor/github.com/lucas-clemente/quic-go/congestion/interface.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/interface.go rename to vendor/github.com/lucas-clemente/quic-go/congestion/interface.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/prr_sender.go b/vendor/github.com/lucas-clemente/quic-go/congestion/prr_sender.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/prr_sender.go rename to vendor/github.com/lucas-clemente/quic-go/congestion/prr_sender.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/rtt_stats.go b/vendor/github.com/lucas-clemente/quic-go/congestion/rtt_stats.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/rtt_stats.go rename to vendor/github.com/lucas-clemente/quic-go/congestion/rtt_stats.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/stats.go b/vendor/github.com/lucas-clemente/quic-go/congestion/stats.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/congestion/stats.go rename to vendor/github.com/lucas-clemente/quic-go/congestion/stats.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/AEAD.go b/vendor/github.com/lucas-clemente/quic-go/crypto/AEAD.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/AEAD.go rename to vendor/github.com/lucas-clemente/quic-go/crypto/AEAD.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/aesgcm_aead.go b/vendor/github.com/lucas-clemente/quic-go/crypto/aesgcm_aead.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/aesgcm_aead.go rename to vendor/github.com/lucas-clemente/quic-go/crypto/aesgcm_aead.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/cert_cache.go b/vendor/github.com/lucas-clemente/quic-go/crypto/cert_cache.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/cert_cache.go rename to vendor/github.com/lucas-clemente/quic-go/crypto/cert_cache.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/cert_chain.go b/vendor/github.com/lucas-clemente/quic-go/crypto/cert_chain.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/cert_chain.go rename to vendor/github.com/lucas-clemente/quic-go/crypto/cert_chain.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/cert_compression.go b/vendor/github.com/lucas-clemente/quic-go/crypto/cert_compression.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/cert_compression.go rename to vendor/github.com/lucas-clemente/quic-go/crypto/cert_compression.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/cert_dict.go b/vendor/github.com/lucas-clemente/quic-go/crypto/cert_dict.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/cert_dict.go rename to vendor/github.com/lucas-clemente/quic-go/crypto/cert_dict.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/cert_manager.go b/vendor/github.com/lucas-clemente/quic-go/crypto/cert_manager.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/cert_manager.go rename to vendor/github.com/lucas-clemente/quic-go/crypto/cert_manager.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/cert_sets.go b/vendor/github.com/lucas-clemente/quic-go/crypto/cert_sets.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/cert_sets.go rename to vendor/github.com/lucas-clemente/quic-go/crypto/cert_sets.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/chacha20poly1305_aead.go b/vendor/github.com/lucas-clemente/quic-go/crypto/chacha20poly1305_aead.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/chacha20poly1305_aead.go rename to vendor/github.com/lucas-clemente/quic-go/crypto/chacha20poly1305_aead.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/chacha20poly1305_aead_test.go b/vendor/github.com/lucas-clemente/quic-go/crypto/chacha20poly1305_aead_test.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/chacha20poly1305_aead_test.go rename to vendor/github.com/lucas-clemente/quic-go/crypto/chacha20poly1305_aead_test.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/curve_25519.go b/vendor/github.com/lucas-clemente/quic-go/crypto/curve_25519.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/curve_25519.go rename to vendor/github.com/lucas-clemente/quic-go/crypto/curve_25519.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/key_derivation.go b/vendor/github.com/lucas-clemente/quic-go/crypto/key_derivation.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/key_derivation.go rename to vendor/github.com/lucas-clemente/quic-go/crypto/key_derivation.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/key_exchange.go b/vendor/github.com/lucas-clemente/quic-go/crypto/key_exchange.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/key_exchange.go rename to vendor/github.com/lucas-clemente/quic-go/crypto/key_exchange.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/nonce.go b/vendor/github.com/lucas-clemente/quic-go/crypto/nonce.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/nonce.go rename to vendor/github.com/lucas-clemente/quic-go/crypto/nonce.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/null_aead.go b/vendor/github.com/lucas-clemente/quic-go/crypto/null_aead.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/null_aead.go rename to vendor/github.com/lucas-clemente/quic-go/crypto/null_aead.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/server_proof.go b/vendor/github.com/lucas-clemente/quic-go/crypto/server_proof.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/server_proof.go rename to vendor/github.com/lucas-clemente/quic-go/crypto/server_proof.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/source_address_token.go b/vendor/github.com/lucas-clemente/quic-go/crypto/source_address_token.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/crypto/source_address_token.go rename to vendor/github.com/lucas-clemente/quic-go/crypto/source_address_token.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/flowcontrol/flow_control_manager.go b/vendor/github.com/lucas-clemente/quic-go/flowcontrol/flow_control_manager.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/flowcontrol/flow_control_manager.go rename to vendor/github.com/lucas-clemente/quic-go/flowcontrol/flow_control_manager.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/flowcontrol/flow_controller.go b/vendor/github.com/lucas-clemente/quic-go/flowcontrol/flow_controller.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/flowcontrol/flow_controller.go rename to vendor/github.com/lucas-clemente/quic-go/flowcontrol/flow_controller.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/flowcontrol/interface.go b/vendor/github.com/lucas-clemente/quic-go/flowcontrol/interface.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/flowcontrol/interface.go rename to vendor/github.com/lucas-clemente/quic-go/flowcontrol/interface.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/ack_frame.go b/vendor/github.com/lucas-clemente/quic-go/frames/ack_frame.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/ack_frame.go rename to vendor/github.com/lucas-clemente/quic-go/frames/ack_frame.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/ack_range.go b/vendor/github.com/lucas-clemente/quic-go/frames/ack_range.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/ack_range.go rename to vendor/github.com/lucas-clemente/quic-go/frames/ack_range.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/blocked_frame.go b/vendor/github.com/lucas-clemente/quic-go/frames/blocked_frame.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/blocked_frame.go rename to vendor/github.com/lucas-clemente/quic-go/frames/blocked_frame.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/connection_close_frame.go b/vendor/github.com/lucas-clemente/quic-go/frames/connection_close_frame.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/connection_close_frame.go rename to vendor/github.com/lucas-clemente/quic-go/frames/connection_close_frame.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/frame.go b/vendor/github.com/lucas-clemente/quic-go/frames/frame.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/frame.go rename to vendor/github.com/lucas-clemente/quic-go/frames/frame.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/goaway_frame.go b/vendor/github.com/lucas-clemente/quic-go/frames/goaway_frame.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/goaway_frame.go rename to vendor/github.com/lucas-clemente/quic-go/frames/goaway_frame.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/log.go b/vendor/github.com/lucas-clemente/quic-go/frames/log.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/log.go rename to vendor/github.com/lucas-clemente/quic-go/frames/log.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/ping_frame.go b/vendor/github.com/lucas-clemente/quic-go/frames/ping_frame.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/ping_frame.go rename to vendor/github.com/lucas-clemente/quic-go/frames/ping_frame.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/rst_stream_frame.go b/vendor/github.com/lucas-clemente/quic-go/frames/rst_stream_frame.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/rst_stream_frame.go rename to vendor/github.com/lucas-clemente/quic-go/frames/rst_stream_frame.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/stop_waiting_frame.go b/vendor/github.com/lucas-clemente/quic-go/frames/stop_waiting_frame.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/stop_waiting_frame.go rename to vendor/github.com/lucas-clemente/quic-go/frames/stop_waiting_frame.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/stream_frame.go b/vendor/github.com/lucas-clemente/quic-go/frames/stream_frame.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/stream_frame.go rename to vendor/github.com/lucas-clemente/quic-go/frames/stream_frame.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/window_update_frame.go b/vendor/github.com/lucas-clemente/quic-go/frames/window_update_frame.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/frames/window_update_frame.go rename to vendor/github.com/lucas-clemente/quic-go/frames/window_update_frame.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/client.go b/vendor/github.com/lucas-clemente/quic-go/h2quic/client.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/client.go rename to vendor/github.com/lucas-clemente/quic-go/h2quic/client.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/gzipreader.go b/vendor/github.com/lucas-clemente/quic-go/h2quic/gzipreader.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/gzipreader.go rename to vendor/github.com/lucas-clemente/quic-go/h2quic/gzipreader.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/request.go b/vendor/github.com/lucas-clemente/quic-go/h2quic/request.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/request.go rename to vendor/github.com/lucas-clemente/quic-go/h2quic/request.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/request_body.go b/vendor/github.com/lucas-clemente/quic-go/h2quic/request_body.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/request_body.go rename to vendor/github.com/lucas-clemente/quic-go/h2quic/request_body.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/request_writer.go b/vendor/github.com/lucas-clemente/quic-go/h2quic/request_writer.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/request_writer.go rename to vendor/github.com/lucas-clemente/quic-go/h2quic/request_writer.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/response.go b/vendor/github.com/lucas-clemente/quic-go/h2quic/response.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/response.go rename to vendor/github.com/lucas-clemente/quic-go/h2quic/response.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/response_setuncompressed.go b/vendor/github.com/lucas-clemente/quic-go/h2quic/response_setuncompressed.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/response_setuncompressed.go rename to vendor/github.com/lucas-clemente/quic-go/h2quic/response_setuncompressed.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/response_setuncompressed_go16.go b/vendor/github.com/lucas-clemente/quic-go/h2quic/response_setuncompressed_go16.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/response_setuncompressed_go16.go rename to vendor/github.com/lucas-clemente/quic-go/h2quic/response_setuncompressed_go16.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/response_writer.go b/vendor/github.com/lucas-clemente/quic-go/h2quic/response_writer.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/response_writer.go rename to vendor/github.com/lucas-clemente/quic-go/h2quic/response_writer.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/roundtrip.go b/vendor/github.com/lucas-clemente/quic-go/h2quic/roundtrip.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/roundtrip.go rename to vendor/github.com/lucas-clemente/quic-go/h2quic/roundtrip.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/server.go b/vendor/github.com/lucas-clemente/quic-go/h2quic/server.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/h2quic/server.go rename to vendor/github.com/lucas-clemente/quic-go/h2quic/server.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/connection_parameters_manager.go b/vendor/github.com/lucas-clemente/quic-go/handshake/connection_parameters_manager.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/connection_parameters_manager.go rename to vendor/github.com/lucas-clemente/quic-go/handshake/connection_parameters_manager.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/crypto_setup_client.go b/vendor/github.com/lucas-clemente/quic-go/handshake/crypto_setup_client.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/crypto_setup_client.go rename to vendor/github.com/lucas-clemente/quic-go/handshake/crypto_setup_client.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/crypto_setup_interface.go b/vendor/github.com/lucas-clemente/quic-go/handshake/crypto_setup_interface.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/crypto_setup_interface.go rename to vendor/github.com/lucas-clemente/quic-go/handshake/crypto_setup_interface.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/crypto_setup_server.go b/vendor/github.com/lucas-clemente/quic-go/handshake/crypto_setup_server.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/crypto_setup_server.go rename to vendor/github.com/lucas-clemente/quic-go/handshake/crypto_setup_server.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/ephermal_cache.go b/vendor/github.com/lucas-clemente/quic-go/handshake/ephermal_cache.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/ephermal_cache.go rename to vendor/github.com/lucas-clemente/quic-go/handshake/ephermal_cache.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/handshake_message.go b/vendor/github.com/lucas-clemente/quic-go/handshake/handshake_message.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/handshake_message.go rename to vendor/github.com/lucas-clemente/quic-go/handshake/handshake_message.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/server_config.go b/vendor/github.com/lucas-clemente/quic-go/handshake/server_config.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/server_config.go rename to vendor/github.com/lucas-clemente/quic-go/handshake/server_config.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/server_config_client.go b/vendor/github.com/lucas-clemente/quic-go/handshake/server_config_client.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/server_config_client.go rename to vendor/github.com/lucas-clemente/quic-go/handshake/server_config_client.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/tags.go b/vendor/github.com/lucas-clemente/quic-go/handshake/tags.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/handshake/tags.go rename to vendor/github.com/lucas-clemente/quic-go/handshake/tags.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/packet_number_generator.go b/vendor/github.com/lucas-clemente/quic-go/packet_number_generator.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/packet_number_generator.go rename to vendor/github.com/lucas-clemente/quic-go/packet_number_generator.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/packet_packer.go b/vendor/github.com/lucas-clemente/quic-go/packet_packer.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/packet_packer.go rename to vendor/github.com/lucas-clemente/quic-go/packet_packer.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/packet_unpacker.go b/vendor/github.com/lucas-clemente/quic-go/packet_unpacker.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/packet_unpacker.go rename to vendor/github.com/lucas-clemente/quic-go/packet_unpacker.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/protocol/encryption_level.go b/vendor/github.com/lucas-clemente/quic-go/protocol/encryption_level.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/protocol/encryption_level.go rename to vendor/github.com/lucas-clemente/quic-go/protocol/encryption_level.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/protocol/packet_number.go b/vendor/github.com/lucas-clemente/quic-go/protocol/packet_number.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/protocol/packet_number.go rename to vendor/github.com/lucas-clemente/quic-go/protocol/packet_number.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/protocol/perspective.go b/vendor/github.com/lucas-clemente/quic-go/protocol/perspective.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/protocol/perspective.go rename to vendor/github.com/lucas-clemente/quic-go/protocol/perspective.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/protocol/protocol.go b/vendor/github.com/lucas-clemente/quic-go/protocol/protocol.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/protocol/protocol.go rename to vendor/github.com/lucas-clemente/quic-go/protocol/protocol.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/protocol/server_parameters.go b/vendor/github.com/lucas-clemente/quic-go/protocol/server_parameters.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/protocol/server_parameters.go rename to vendor/github.com/lucas-clemente/quic-go/protocol/server_parameters.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/protocol/version.go b/vendor/github.com/lucas-clemente/quic-go/protocol/version.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/protocol/version.go rename to vendor/github.com/lucas-clemente/quic-go/protocol/version.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/public_header.go b/vendor/github.com/lucas-clemente/quic-go/public_header.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/public_header.go rename to vendor/github.com/lucas-clemente/quic-go/public_header.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/public_reset.go b/vendor/github.com/lucas-clemente/quic-go/public_reset.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/public_reset.go rename to vendor/github.com/lucas-clemente/quic-go/public_reset.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/qerr/error_codes.go b/vendor/github.com/lucas-clemente/quic-go/qerr/error_codes.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/qerr/error_codes.go rename to vendor/github.com/lucas-clemente/quic-go/qerr/error_codes.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/qerr/errorcode_string.go b/vendor/github.com/lucas-clemente/quic-go/qerr/errorcode_string.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/qerr/errorcode_string.go rename to vendor/github.com/lucas-clemente/quic-go/qerr/errorcode_string.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/qerr/quic_error.go b/vendor/github.com/lucas-clemente/quic-go/qerr/quic_error.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/qerr/quic_error.go rename to vendor/github.com/lucas-clemente/quic-go/qerr/quic_error.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/server.go b/vendor/github.com/lucas-clemente/quic-go/server.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/server.go rename to vendor/github.com/lucas-clemente/quic-go/server.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/session.go b/vendor/github.com/lucas-clemente/quic-go/session.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/session.go rename to vendor/github.com/lucas-clemente/quic-go/session.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/stream.go b/vendor/github.com/lucas-clemente/quic-go/stream.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/stream.go rename to vendor/github.com/lucas-clemente/quic-go/stream.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/stream_frame_sorter.go b/vendor/github.com/lucas-clemente/quic-go/stream_frame_sorter.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/stream_frame_sorter.go rename to vendor/github.com/lucas-clemente/quic-go/stream_frame_sorter.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/stream_framer.go b/vendor/github.com/lucas-clemente/quic-go/stream_framer.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/stream_framer.go rename to vendor/github.com/lucas-clemente/quic-go/stream_framer.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/streams_map.go b/vendor/github.com/lucas-clemente/quic-go/streams_map.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/streams_map.go rename to vendor/github.com/lucas-clemente/quic-go/streams_map.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/udp_conn.go b/vendor/github.com/lucas-clemente/quic-go/udp_conn.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/udp_conn.go rename to vendor/github.com/lucas-clemente/quic-go/udp_conn.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/unpacked_packet.go b/vendor/github.com/lucas-clemente/quic-go/unpacked_packet.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/unpacked_packet.go rename to vendor/github.com/lucas-clemente/quic-go/unpacked_packet.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/_gen.go b/vendor/github.com/lucas-clemente/quic-go/utils/_gen.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/_gen.go rename to vendor/github.com/lucas-clemente/quic-go/utils/_gen.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/atomic_bool.go b/vendor/github.com/lucas-clemente/quic-go/utils/atomic_bool.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/atomic_bool.go rename to vendor/github.com/lucas-clemente/quic-go/utils/atomic_bool.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/byteinterval_linkedlist.go b/vendor/github.com/lucas-clemente/quic-go/utils/byteinterval_linkedlist.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/byteinterval_linkedlist.go rename to vendor/github.com/lucas-clemente/quic-go/utils/byteinterval_linkedlist.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/connection_id.go b/vendor/github.com/lucas-clemente/quic-go/utils/connection_id.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/connection_id.go rename to vendor/github.com/lucas-clemente/quic-go/utils/connection_id.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/float16.go b/vendor/github.com/lucas-clemente/quic-go/utils/float16.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/float16.go rename to vendor/github.com/lucas-clemente/quic-go/utils/float16.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/host.go b/vendor/github.com/lucas-clemente/quic-go/utils/host.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/host.go rename to vendor/github.com/lucas-clemente/quic-go/utils/host.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/log.go b/vendor/github.com/lucas-clemente/quic-go/utils/log.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/log.go rename to vendor/github.com/lucas-clemente/quic-go/utils/log.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/minmax.go b/vendor/github.com/lucas-clemente/quic-go/utils/minmax.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/minmax.go rename to vendor/github.com/lucas-clemente/quic-go/utils/minmax.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/packet_interval.go b/vendor/github.com/lucas-clemente/quic-go/utils/packet_interval.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/packet_interval.go rename to vendor/github.com/lucas-clemente/quic-go/utils/packet_interval.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/packetinterval_linkedlist.go b/vendor/github.com/lucas-clemente/quic-go/utils/packetinterval_linkedlist.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/packetinterval_linkedlist.go rename to vendor/github.com/lucas-clemente/quic-go/utils/packetinterval_linkedlist.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/stream.go b/vendor/github.com/lucas-clemente/quic-go/utils/stream.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/stream.go rename to vendor/github.com/lucas-clemente/quic-go/utils/stream.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/streamframe_interval.go b/vendor/github.com/lucas-clemente/quic-go/utils/streamframe_interval.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/streamframe_interval.go rename to vendor/github.com/lucas-clemente/quic-go/utils/streamframe_interval.go diff --git a/cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/utils.go b/vendor/github.com/lucas-clemente/quic-go/utils/utils.go similarity index 100% rename from cmd/gost/vendor/github.com/lucas-clemente/quic-go/utils/utils.go rename to vendor/github.com/lucas-clemente/quic-go/utils/utils.go diff --git a/cmd/gost/vendor/github.com/pkg/errors/LICENSE b/vendor/github.com/pkg/errors/LICENSE similarity index 100% rename from cmd/gost/vendor/github.com/pkg/errors/LICENSE rename to vendor/github.com/pkg/errors/LICENSE diff --git a/cmd/gost/vendor/github.com/pkg/errors/README.md b/vendor/github.com/pkg/errors/README.md similarity index 100% rename from cmd/gost/vendor/github.com/pkg/errors/README.md rename to vendor/github.com/pkg/errors/README.md diff --git a/cmd/gost/vendor/github.com/pkg/errors/appveyor.yml b/vendor/github.com/pkg/errors/appveyor.yml similarity index 100% rename from cmd/gost/vendor/github.com/pkg/errors/appveyor.yml rename to vendor/github.com/pkg/errors/appveyor.yml diff --git a/cmd/gost/vendor/github.com/pkg/errors/errors.go b/vendor/github.com/pkg/errors/errors.go similarity index 100% rename from cmd/gost/vendor/github.com/pkg/errors/errors.go rename to vendor/github.com/pkg/errors/errors.go diff --git a/cmd/gost/vendor/github.com/pkg/errors/stack.go b/vendor/github.com/pkg/errors/stack.go similarity index 100% rename from cmd/gost/vendor/github.com/pkg/errors/stack.go rename to vendor/github.com/pkg/errors/stack.go diff --git a/cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/LICENSE b/vendor/github.com/shadowsocks/shadowsocks-go/LICENSE similarity index 100% rename from cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/LICENSE rename to vendor/github.com/shadowsocks/shadowsocks-go/LICENSE diff --git a/cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/config.go b/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/config.go similarity index 100% rename from cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/config.go rename to vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/config.go diff --git a/cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/conn.go b/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/conn.go similarity index 100% rename from cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/conn.go rename to vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/conn.go diff --git a/cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/encrypt.go b/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/encrypt.go similarity index 100% rename from cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/encrypt.go rename to vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/encrypt.go diff --git a/cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/leakybuf.go b/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/leakybuf.go similarity index 100% rename from cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/leakybuf.go rename to vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/leakybuf.go diff --git a/cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/log.go b/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/log.go similarity index 100% rename from cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/log.go rename to vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/log.go diff --git a/cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/mergesort.go b/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/mergesort.go similarity index 100% rename from cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/mergesort.go rename to vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/mergesort.go diff --git a/cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/pipe.go b/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/pipe.go similarity index 100% rename from cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/pipe.go rename to vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/pipe.go diff --git a/cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/proxy.go b/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/proxy.go similarity index 100% rename from cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/proxy.go rename to vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/proxy.go diff --git a/cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/udp.go b/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/udp.go similarity index 100% rename from cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/udp.go rename to vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/udp.go diff --git a/cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/udprelay.go b/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/udprelay.go similarity index 100% rename from cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/udprelay.go rename to vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/udprelay.go diff --git a/cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/util.go b/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/util.go similarity index 100% rename from cmd/gost/vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/util.go rename to vendor/github.com/shadowsocks/shadowsocks-go/shadowsocks/util.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/LICENSE b/vendor/golang.org/x/crypto/LICENSE similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/LICENSE rename to vendor/golang.org/x/crypto/LICENSE diff --git a/cmd/gost/vendor/golang.org/x/crypto/PATENTS b/vendor/golang.org/x/crypto/PATENTS similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/PATENTS rename to vendor/golang.org/x/crypto/PATENTS diff --git a/cmd/gost/vendor/golang.org/x/crypto/blowfish/block.go b/vendor/golang.org/x/crypto/blowfish/block.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/blowfish/block.go rename to vendor/golang.org/x/crypto/blowfish/block.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/blowfish/cipher.go b/vendor/golang.org/x/crypto/blowfish/cipher.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/blowfish/cipher.go rename to vendor/golang.org/x/crypto/blowfish/cipher.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/blowfish/const.go b/vendor/golang.org/x/crypto/blowfish/const.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/blowfish/const.go rename to vendor/golang.org/x/crypto/blowfish/const.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/cast5/cast5.go b/vendor/golang.org/x/crypto/cast5/cast5.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/cast5/cast5.go rename to vendor/golang.org/x/crypto/cast5/cast5.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/curve25519/const_amd64.h b/vendor/golang.org/x/crypto/curve25519/const_amd64.h similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/curve25519/const_amd64.h rename to vendor/golang.org/x/crypto/curve25519/const_amd64.h diff --git a/cmd/gost/vendor/golang.org/x/crypto/curve25519/const_amd64.s b/vendor/golang.org/x/crypto/curve25519/const_amd64.s similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/curve25519/const_amd64.s rename to vendor/golang.org/x/crypto/curve25519/const_amd64.s diff --git a/cmd/gost/vendor/golang.org/x/crypto/curve25519/cswap_amd64.s b/vendor/golang.org/x/crypto/curve25519/cswap_amd64.s similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/curve25519/cswap_amd64.s rename to vendor/golang.org/x/crypto/curve25519/cswap_amd64.s diff --git a/cmd/gost/vendor/golang.org/x/crypto/curve25519/curve25519.go b/vendor/golang.org/x/crypto/curve25519/curve25519.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/curve25519/curve25519.go rename to vendor/golang.org/x/crypto/curve25519/curve25519.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/curve25519/doc.go b/vendor/golang.org/x/crypto/curve25519/doc.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/curve25519/doc.go rename to vendor/golang.org/x/crypto/curve25519/doc.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/curve25519/freeze_amd64.s b/vendor/golang.org/x/crypto/curve25519/freeze_amd64.s similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/curve25519/freeze_amd64.s rename to vendor/golang.org/x/crypto/curve25519/freeze_amd64.s diff --git a/cmd/gost/vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s b/vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s rename to vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s diff --git a/cmd/gost/vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go b/vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go rename to vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/curve25519/mul_amd64.s b/vendor/golang.org/x/crypto/curve25519/mul_amd64.s similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/curve25519/mul_amd64.s rename to vendor/golang.org/x/crypto/curve25519/mul_amd64.s diff --git a/cmd/gost/vendor/golang.org/x/crypto/curve25519/square_amd64.s b/vendor/golang.org/x/crypto/curve25519/square_amd64.s similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/curve25519/square_amd64.s rename to vendor/golang.org/x/crypto/curve25519/square_amd64.s diff --git a/cmd/gost/vendor/golang.org/x/crypto/ed25519/ed25519.go b/vendor/golang.org/x/crypto/ed25519/ed25519.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ed25519/ed25519.go rename to vendor/golang.org/x/crypto/ed25519/ed25519.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go b/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go rename to vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go b/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go rename to vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/hkdf/hkdf.go b/vendor/golang.org/x/crypto/hkdf/hkdf.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/hkdf/hkdf.go rename to vendor/golang.org/x/crypto/hkdf/hkdf.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go rename to vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go b/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go rename to vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s b/vendor/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s rename to vendor/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s diff --git a/cmd/gost/vendor/golang.org/x/crypto/salsa20/salsa/salsa208.go b/vendor/golang.org/x/crypto/salsa20/salsa/salsa208.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/salsa20/salsa/salsa208.go rename to vendor/golang.org/x/crypto/salsa20/salsa/salsa208.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go rename to vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go b/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go rename to vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/salsa20/salsa20.go b/vendor/golang.org/x/crypto/salsa20/salsa20.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/salsa20/salsa20.go rename to vendor/golang.org/x/crypto/salsa20/salsa20.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/buffer.go b/vendor/golang.org/x/crypto/ssh/buffer.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/buffer.go rename to vendor/golang.org/x/crypto/ssh/buffer.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/certs.go b/vendor/golang.org/x/crypto/ssh/certs.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/certs.go rename to vendor/golang.org/x/crypto/ssh/certs.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/channel.go b/vendor/golang.org/x/crypto/ssh/channel.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/channel.go rename to vendor/golang.org/x/crypto/ssh/channel.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/cipher.go b/vendor/golang.org/x/crypto/ssh/cipher.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/cipher.go rename to vendor/golang.org/x/crypto/ssh/cipher.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/client.go b/vendor/golang.org/x/crypto/ssh/client.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/client.go rename to vendor/golang.org/x/crypto/ssh/client.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/client_auth.go b/vendor/golang.org/x/crypto/ssh/client_auth.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/client_auth.go rename to vendor/golang.org/x/crypto/ssh/client_auth.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/common.go b/vendor/golang.org/x/crypto/ssh/common.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/common.go rename to vendor/golang.org/x/crypto/ssh/common.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/connection.go b/vendor/golang.org/x/crypto/ssh/connection.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/connection.go rename to vendor/golang.org/x/crypto/ssh/connection.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/doc.go b/vendor/golang.org/x/crypto/ssh/doc.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/doc.go rename to vendor/golang.org/x/crypto/ssh/doc.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/handshake.go rename to vendor/golang.org/x/crypto/ssh/handshake.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/kex.go b/vendor/golang.org/x/crypto/ssh/kex.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/kex.go rename to vendor/golang.org/x/crypto/ssh/kex.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/keys.go b/vendor/golang.org/x/crypto/ssh/keys.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/keys.go rename to vendor/golang.org/x/crypto/ssh/keys.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/mac.go b/vendor/golang.org/x/crypto/ssh/mac.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/mac.go rename to vendor/golang.org/x/crypto/ssh/mac.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/messages.go b/vendor/golang.org/x/crypto/ssh/messages.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/messages.go rename to vendor/golang.org/x/crypto/ssh/messages.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/mux.go b/vendor/golang.org/x/crypto/ssh/mux.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/mux.go rename to vendor/golang.org/x/crypto/ssh/mux.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/server.go rename to vendor/golang.org/x/crypto/ssh/server.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/session.go b/vendor/golang.org/x/crypto/ssh/session.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/session.go rename to vendor/golang.org/x/crypto/ssh/session.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/tcpip.go b/vendor/golang.org/x/crypto/ssh/tcpip.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/tcpip.go rename to vendor/golang.org/x/crypto/ssh/tcpip.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/ssh/transport.go b/vendor/golang.org/x/crypto/ssh/transport.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/ssh/transport.go rename to vendor/golang.org/x/crypto/ssh/transport.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/tea/cipher.go b/vendor/golang.org/x/crypto/tea/cipher.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/tea/cipher.go rename to vendor/golang.org/x/crypto/tea/cipher.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/twofish/twofish.go b/vendor/golang.org/x/crypto/twofish/twofish.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/twofish/twofish.go rename to vendor/golang.org/x/crypto/twofish/twofish.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/xtea/block.go b/vendor/golang.org/x/crypto/xtea/block.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/xtea/block.go rename to vendor/golang.org/x/crypto/xtea/block.go diff --git a/cmd/gost/vendor/golang.org/x/crypto/xtea/cipher.go b/vendor/golang.org/x/crypto/xtea/cipher.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/crypto/xtea/cipher.go rename to vendor/golang.org/x/crypto/xtea/cipher.go diff --git a/cmd/gost/vendor/golang.org/x/net/LICENSE b/vendor/golang.org/x/net/LICENSE similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/LICENSE rename to vendor/golang.org/x/net/LICENSE diff --git a/cmd/gost/vendor/golang.org/x/net/PATENTS b/vendor/golang.org/x/net/PATENTS similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/PATENTS rename to vendor/golang.org/x/net/PATENTS diff --git a/cmd/gost/vendor/golang.org/x/net/bpf/asm.go b/vendor/golang.org/x/net/bpf/asm.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/bpf/asm.go rename to vendor/golang.org/x/net/bpf/asm.go diff --git a/cmd/gost/vendor/golang.org/x/net/bpf/constants.go b/vendor/golang.org/x/net/bpf/constants.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/bpf/constants.go rename to vendor/golang.org/x/net/bpf/constants.go diff --git a/cmd/gost/vendor/golang.org/x/net/bpf/doc.go b/vendor/golang.org/x/net/bpf/doc.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/bpf/doc.go rename to vendor/golang.org/x/net/bpf/doc.go diff --git a/cmd/gost/vendor/golang.org/x/net/bpf/instructions.go b/vendor/golang.org/x/net/bpf/instructions.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/bpf/instructions.go rename to vendor/golang.org/x/net/bpf/instructions.go diff --git a/cmd/gost/vendor/golang.org/x/net/bpf/vm.go b/vendor/golang.org/x/net/bpf/vm.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/bpf/vm.go rename to vendor/golang.org/x/net/bpf/vm.go diff --git a/cmd/gost/vendor/golang.org/x/net/bpf/vm_instructions.go b/vendor/golang.org/x/net/bpf/vm_instructions.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/bpf/vm_instructions.go rename to vendor/golang.org/x/net/bpf/vm_instructions.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/Dockerfile b/vendor/golang.org/x/net/http2/Dockerfile similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/Dockerfile rename to vendor/golang.org/x/net/http2/Dockerfile diff --git a/cmd/gost/vendor/golang.org/x/net/http2/Makefile b/vendor/golang.org/x/net/http2/Makefile similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/Makefile rename to vendor/golang.org/x/net/http2/Makefile diff --git a/cmd/gost/vendor/golang.org/x/net/http2/README b/vendor/golang.org/x/net/http2/README similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/README rename to vendor/golang.org/x/net/http2/README diff --git a/cmd/gost/vendor/golang.org/x/net/http2/client_conn_pool.go b/vendor/golang.org/x/net/http2/client_conn_pool.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/client_conn_pool.go rename to vendor/golang.org/x/net/http2/client_conn_pool.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/configure_transport.go b/vendor/golang.org/x/net/http2/configure_transport.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/configure_transport.go rename to vendor/golang.org/x/net/http2/configure_transport.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/errors.go b/vendor/golang.org/x/net/http2/errors.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/errors.go rename to vendor/golang.org/x/net/http2/errors.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/fixed_buffer.go b/vendor/golang.org/x/net/http2/fixed_buffer.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/fixed_buffer.go rename to vendor/golang.org/x/net/http2/fixed_buffer.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/flow.go b/vendor/golang.org/x/net/http2/flow.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/flow.go rename to vendor/golang.org/x/net/http2/flow.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/frame.go rename to vendor/golang.org/x/net/http2/frame.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/go16.go b/vendor/golang.org/x/net/http2/go16.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/go16.go rename to vendor/golang.org/x/net/http2/go16.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/go17.go b/vendor/golang.org/x/net/http2/go17.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/go17.go rename to vendor/golang.org/x/net/http2/go17.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/go17_not18.go b/vendor/golang.org/x/net/http2/go17_not18.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/go17_not18.go rename to vendor/golang.org/x/net/http2/go17_not18.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/go18.go b/vendor/golang.org/x/net/http2/go18.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/go18.go rename to vendor/golang.org/x/net/http2/go18.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/gotrack.go b/vendor/golang.org/x/net/http2/gotrack.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/gotrack.go rename to vendor/golang.org/x/net/http2/gotrack.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/headermap.go b/vendor/golang.org/x/net/http2/headermap.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/headermap.go rename to vendor/golang.org/x/net/http2/headermap.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/hpack/encode.go b/vendor/golang.org/x/net/http2/hpack/encode.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/hpack/encode.go rename to vendor/golang.org/x/net/http2/hpack/encode.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/hpack/hpack.go b/vendor/golang.org/x/net/http2/hpack/hpack.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/hpack/hpack.go rename to vendor/golang.org/x/net/http2/hpack/hpack.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/hpack/huffman.go b/vendor/golang.org/x/net/http2/hpack/huffman.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/hpack/huffman.go rename to vendor/golang.org/x/net/http2/hpack/huffman.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/hpack/tables.go b/vendor/golang.org/x/net/http2/hpack/tables.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/hpack/tables.go rename to vendor/golang.org/x/net/http2/hpack/tables.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/http2.go rename to vendor/golang.org/x/net/http2/http2.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/not_go16.go b/vendor/golang.org/x/net/http2/not_go16.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/not_go16.go rename to vendor/golang.org/x/net/http2/not_go16.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/not_go17.go b/vendor/golang.org/x/net/http2/not_go17.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/not_go17.go rename to vendor/golang.org/x/net/http2/not_go17.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/not_go18.go b/vendor/golang.org/x/net/http2/not_go18.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/not_go18.go rename to vendor/golang.org/x/net/http2/not_go18.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/pipe.go b/vendor/golang.org/x/net/http2/pipe.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/pipe.go rename to vendor/golang.org/x/net/http2/pipe.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/server.go rename to vendor/golang.org/x/net/http2/server.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/transport.go rename to vendor/golang.org/x/net/http2/transport.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/write.go b/vendor/golang.org/x/net/http2/write.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/write.go rename to vendor/golang.org/x/net/http2/write.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/writesched.go b/vendor/golang.org/x/net/http2/writesched.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/writesched.go rename to vendor/golang.org/x/net/http2/writesched.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/writesched_priority.go b/vendor/golang.org/x/net/http2/writesched_priority.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/writesched_priority.go rename to vendor/golang.org/x/net/http2/writesched_priority.go diff --git a/cmd/gost/vendor/golang.org/x/net/http2/writesched_random.go b/vendor/golang.org/x/net/http2/writesched_random.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/http2/writesched_random.go rename to vendor/golang.org/x/net/http2/writesched_random.go diff --git a/cmd/gost/vendor/golang.org/x/net/idna/idna.go b/vendor/golang.org/x/net/idna/idna.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/idna/idna.go rename to vendor/golang.org/x/net/idna/idna.go diff --git a/cmd/gost/vendor/golang.org/x/net/idna/punycode.go b/vendor/golang.org/x/net/idna/punycode.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/idna/punycode.go rename to vendor/golang.org/x/net/idna/punycode.go diff --git a/cmd/gost/vendor/golang.org/x/net/internal/iana/const.go b/vendor/golang.org/x/net/internal/iana/const.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/internal/iana/const.go rename to vendor/golang.org/x/net/internal/iana/const.go diff --git a/cmd/gost/vendor/golang.org/x/net/internal/iana/gen.go b/vendor/golang.org/x/net/internal/iana/gen.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/internal/iana/gen.go rename to vendor/golang.org/x/net/internal/iana/gen.go diff --git a/cmd/gost/vendor/golang.org/x/net/internal/netreflect/socket.go b/vendor/golang.org/x/net/internal/netreflect/socket.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/internal/netreflect/socket.go rename to vendor/golang.org/x/net/internal/netreflect/socket.go diff --git a/cmd/gost/vendor/golang.org/x/net/internal/netreflect/socket_posix.go b/vendor/golang.org/x/net/internal/netreflect/socket_posix.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/internal/netreflect/socket_posix.go rename to vendor/golang.org/x/net/internal/netreflect/socket_posix.go diff --git a/cmd/gost/vendor/golang.org/x/net/internal/netreflect/socket_stub.go b/vendor/golang.org/x/net/internal/netreflect/socket_stub.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/internal/netreflect/socket_stub.go rename to vendor/golang.org/x/net/internal/netreflect/socket_stub.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/bpfopt_linux.go b/vendor/golang.org/x/net/ipv4/bpfopt_linux.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/bpfopt_linux.go rename to vendor/golang.org/x/net/ipv4/bpfopt_linux.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/bpfopt_stub.go b/vendor/golang.org/x/net/ipv4/bpfopt_stub.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/bpfopt_stub.go rename to vendor/golang.org/x/net/ipv4/bpfopt_stub.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/control.go b/vendor/golang.org/x/net/ipv4/control.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/control.go rename to vendor/golang.org/x/net/ipv4/control.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/control_bsd.go b/vendor/golang.org/x/net/ipv4/control_bsd.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/control_bsd.go rename to vendor/golang.org/x/net/ipv4/control_bsd.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/control_pktinfo.go b/vendor/golang.org/x/net/ipv4/control_pktinfo.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/control_pktinfo.go rename to vendor/golang.org/x/net/ipv4/control_pktinfo.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/control_stub.go b/vendor/golang.org/x/net/ipv4/control_stub.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/control_stub.go rename to vendor/golang.org/x/net/ipv4/control_stub.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/control_unix.go b/vendor/golang.org/x/net/ipv4/control_unix.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/control_unix.go rename to vendor/golang.org/x/net/ipv4/control_unix.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/control_windows.go b/vendor/golang.org/x/net/ipv4/control_windows.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/control_windows.go rename to vendor/golang.org/x/net/ipv4/control_windows.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/defs_darwin.go b/vendor/golang.org/x/net/ipv4/defs_darwin.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/defs_darwin.go rename to vendor/golang.org/x/net/ipv4/defs_darwin.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/defs_dragonfly.go b/vendor/golang.org/x/net/ipv4/defs_dragonfly.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/defs_dragonfly.go rename to vendor/golang.org/x/net/ipv4/defs_dragonfly.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/defs_freebsd.go b/vendor/golang.org/x/net/ipv4/defs_freebsd.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/defs_freebsd.go rename to vendor/golang.org/x/net/ipv4/defs_freebsd.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/defs_linux.go b/vendor/golang.org/x/net/ipv4/defs_linux.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/defs_linux.go rename to vendor/golang.org/x/net/ipv4/defs_linux.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/defs_netbsd.go b/vendor/golang.org/x/net/ipv4/defs_netbsd.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/defs_netbsd.go rename to vendor/golang.org/x/net/ipv4/defs_netbsd.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/defs_openbsd.go b/vendor/golang.org/x/net/ipv4/defs_openbsd.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/defs_openbsd.go rename to vendor/golang.org/x/net/ipv4/defs_openbsd.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/defs_solaris.go b/vendor/golang.org/x/net/ipv4/defs_solaris.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/defs_solaris.go rename to vendor/golang.org/x/net/ipv4/defs_solaris.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/dgramopt_posix.go b/vendor/golang.org/x/net/ipv4/dgramopt_posix.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/dgramopt_posix.go rename to vendor/golang.org/x/net/ipv4/dgramopt_posix.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/dgramopt_stub.go b/vendor/golang.org/x/net/ipv4/dgramopt_stub.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/dgramopt_stub.go rename to vendor/golang.org/x/net/ipv4/dgramopt_stub.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/doc.go b/vendor/golang.org/x/net/ipv4/doc.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/doc.go rename to vendor/golang.org/x/net/ipv4/doc.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/endpoint.go b/vendor/golang.org/x/net/ipv4/endpoint.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/endpoint.go rename to vendor/golang.org/x/net/ipv4/endpoint.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/gen.go b/vendor/golang.org/x/net/ipv4/gen.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/gen.go rename to vendor/golang.org/x/net/ipv4/gen.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/genericopt_posix.go b/vendor/golang.org/x/net/ipv4/genericopt_posix.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/genericopt_posix.go rename to vendor/golang.org/x/net/ipv4/genericopt_posix.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/genericopt_stub.go b/vendor/golang.org/x/net/ipv4/genericopt_stub.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/genericopt_stub.go rename to vendor/golang.org/x/net/ipv4/genericopt_stub.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/header.go b/vendor/golang.org/x/net/ipv4/header.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/header.go rename to vendor/golang.org/x/net/ipv4/header.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/helper.go b/vendor/golang.org/x/net/ipv4/helper.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/helper.go rename to vendor/golang.org/x/net/ipv4/helper.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/iana.go b/vendor/golang.org/x/net/ipv4/iana.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/iana.go rename to vendor/golang.org/x/net/ipv4/iana.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/icmp.go b/vendor/golang.org/x/net/ipv4/icmp.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/icmp.go rename to vendor/golang.org/x/net/ipv4/icmp.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/icmp_linux.go b/vendor/golang.org/x/net/ipv4/icmp_linux.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/icmp_linux.go rename to vendor/golang.org/x/net/ipv4/icmp_linux.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/icmp_stub.go b/vendor/golang.org/x/net/ipv4/icmp_stub.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/icmp_stub.go rename to vendor/golang.org/x/net/ipv4/icmp_stub.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/packet.go b/vendor/golang.org/x/net/ipv4/packet.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/packet.go rename to vendor/golang.org/x/net/ipv4/packet.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/payload.go b/vendor/golang.org/x/net/ipv4/payload.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/payload.go rename to vendor/golang.org/x/net/ipv4/payload.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/payload_cmsg.go b/vendor/golang.org/x/net/ipv4/payload_cmsg.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/payload_cmsg.go rename to vendor/golang.org/x/net/ipv4/payload_cmsg.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/payload_nocmsg.go b/vendor/golang.org/x/net/ipv4/payload_nocmsg.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/payload_nocmsg.go rename to vendor/golang.org/x/net/ipv4/payload_nocmsg.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sockopt.go b/vendor/golang.org/x/net/ipv4/sockopt.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sockopt.go rename to vendor/golang.org/x/net/ipv4/sockopt.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_asmreq.go b/vendor/golang.org/x/net/ipv4/sockopt_asmreq.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_asmreq.go rename to vendor/golang.org/x/net/ipv4/sockopt_asmreq.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_asmreq_posix.go b/vendor/golang.org/x/net/ipv4/sockopt_asmreq_posix.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_asmreq_posix.go rename to vendor/golang.org/x/net/ipv4/sockopt_asmreq_posix.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_asmreq_stub.go b/vendor/golang.org/x/net/ipv4/sockopt_asmreq_stub.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_asmreq_stub.go rename to vendor/golang.org/x/net/ipv4/sockopt_asmreq_stub.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_asmreqn_stub.go b/vendor/golang.org/x/net/ipv4/sockopt_asmreqn_stub.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_asmreqn_stub.go rename to vendor/golang.org/x/net/ipv4/sockopt_asmreqn_stub.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_asmreqn_unix.go b/vendor/golang.org/x/net/ipv4/sockopt_asmreqn_unix.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_asmreqn_unix.go rename to vendor/golang.org/x/net/ipv4/sockopt_asmreqn_unix.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_posix.go b/vendor/golang.org/x/net/ipv4/sockopt_posix.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_posix.go rename to vendor/golang.org/x/net/ipv4/sockopt_posix.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_ssmreq_stub.go b/vendor/golang.org/x/net/ipv4/sockopt_ssmreq_stub.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_ssmreq_stub.go rename to vendor/golang.org/x/net/ipv4/sockopt_ssmreq_stub.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_ssmreq_unix.go b/vendor/golang.org/x/net/ipv4/sockopt_ssmreq_unix.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_ssmreq_unix.go rename to vendor/golang.org/x/net/ipv4/sockopt_ssmreq_unix.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_stub.go b/vendor/golang.org/x/net/ipv4/sockopt_stub.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sockopt_stub.go rename to vendor/golang.org/x/net/ipv4/sockopt_stub.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sys_bsd.go b/vendor/golang.org/x/net/ipv4/sys_bsd.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sys_bsd.go rename to vendor/golang.org/x/net/ipv4/sys_bsd.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sys_darwin.go b/vendor/golang.org/x/net/ipv4/sys_darwin.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sys_darwin.go rename to vendor/golang.org/x/net/ipv4/sys_darwin.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sys_freebsd.go b/vendor/golang.org/x/net/ipv4/sys_freebsd.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sys_freebsd.go rename to vendor/golang.org/x/net/ipv4/sys_freebsd.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sys_linux.go b/vendor/golang.org/x/net/ipv4/sys_linux.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sys_linux.go rename to vendor/golang.org/x/net/ipv4/sys_linux.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sys_linux_386.s b/vendor/golang.org/x/net/ipv4/sys_linux_386.s similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sys_linux_386.s rename to vendor/golang.org/x/net/ipv4/sys_linux_386.s diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sys_openbsd.go b/vendor/golang.org/x/net/ipv4/sys_openbsd.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sys_openbsd.go rename to vendor/golang.org/x/net/ipv4/sys_openbsd.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sys_solaris.go b/vendor/golang.org/x/net/ipv4/sys_solaris.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sys_solaris.go rename to vendor/golang.org/x/net/ipv4/sys_solaris.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sys_solaris_amd64.s b/vendor/golang.org/x/net/ipv4/sys_solaris_amd64.s similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sys_solaris_amd64.s rename to vendor/golang.org/x/net/ipv4/sys_solaris_amd64.s diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sys_stub.go b/vendor/golang.org/x/net/ipv4/sys_stub.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sys_stub.go rename to vendor/golang.org/x/net/ipv4/sys_stub.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/sys_windows.go b/vendor/golang.org/x/net/ipv4/sys_windows.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/sys_windows.go rename to vendor/golang.org/x/net/ipv4/sys_windows.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/syscall_linux_386.go b/vendor/golang.org/x/net/ipv4/syscall_linux_386.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/syscall_linux_386.go rename to vendor/golang.org/x/net/ipv4/syscall_linux_386.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/syscall_solaris.go b/vendor/golang.org/x/net/ipv4/syscall_solaris.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/syscall_solaris.go rename to vendor/golang.org/x/net/ipv4/syscall_solaris.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/syscall_unix.go b/vendor/golang.org/x/net/ipv4/syscall_unix.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/syscall_unix.go rename to vendor/golang.org/x/net/ipv4/syscall_unix.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/syscall_windows.go b/vendor/golang.org/x/net/ipv4/syscall_windows.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/syscall_windows.go rename to vendor/golang.org/x/net/ipv4/syscall_windows.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_darwin.go b/vendor/golang.org/x/net/ipv4/zsys_darwin.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_darwin.go rename to vendor/golang.org/x/net/ipv4/zsys_darwin.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go b/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go rename to vendor/golang.org/x/net/ipv4/zsys_dragonfly.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go rename to vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go rename to vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go rename to vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_386.go b/vendor/golang.org/x/net/ipv4/zsys_linux_386.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_386.go rename to vendor/golang.org/x/net/ipv4/zsys_linux_386.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go rename to vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go b/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go rename to vendor/golang.org/x/net/ipv4/zsys_linux_arm.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go rename to vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go rename to vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go rename to vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go rename to vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go rename to vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go rename to vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go b/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go rename to vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_netbsd.go b/vendor/golang.org/x/net/ipv4/zsys_netbsd.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_netbsd.go rename to vendor/golang.org/x/net/ipv4/zsys_netbsd.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_openbsd.go b/vendor/golang.org/x/net/ipv4/zsys_openbsd.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_openbsd.go rename to vendor/golang.org/x/net/ipv4/zsys_openbsd.go diff --git a/cmd/gost/vendor/golang.org/x/net/ipv4/zsys_solaris.go b/vendor/golang.org/x/net/ipv4/zsys_solaris.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/ipv4/zsys_solaris.go rename to vendor/golang.org/x/net/ipv4/zsys_solaris.go diff --git a/cmd/gost/vendor/golang.org/x/net/lex/httplex/httplex.go b/vendor/golang.org/x/net/lex/httplex/httplex.go similarity index 100% rename from cmd/gost/vendor/golang.org/x/net/lex/httplex/httplex.go rename to vendor/golang.org/x/net/lex/httplex/httplex.go diff --git a/cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/AUTHORS b/vendor/gopkg.in/gorilla/websocket.v1/AUTHORS similarity index 100% rename from cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/AUTHORS rename to vendor/gopkg.in/gorilla/websocket.v1/AUTHORS diff --git a/cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/LICENSE b/vendor/gopkg.in/gorilla/websocket.v1/LICENSE similarity index 100% rename from cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/LICENSE rename to vendor/gopkg.in/gorilla/websocket.v1/LICENSE diff --git a/cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/README.md b/vendor/gopkg.in/gorilla/websocket.v1/README.md similarity index 100% rename from cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/README.md rename to vendor/gopkg.in/gorilla/websocket.v1/README.md diff --git a/cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/client.go b/vendor/gopkg.in/gorilla/websocket.v1/client.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/client.go rename to vendor/gopkg.in/gorilla/websocket.v1/client.go diff --git a/cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/compression.go b/vendor/gopkg.in/gorilla/websocket.v1/compression.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/compression.go rename to vendor/gopkg.in/gorilla/websocket.v1/compression.go diff --git a/cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/conn.go b/vendor/gopkg.in/gorilla/websocket.v1/conn.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/conn.go rename to vendor/gopkg.in/gorilla/websocket.v1/conn.go diff --git a/cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/conn_read.go b/vendor/gopkg.in/gorilla/websocket.v1/conn_read.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/conn_read.go rename to vendor/gopkg.in/gorilla/websocket.v1/conn_read.go diff --git a/cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/conn_read_legacy.go b/vendor/gopkg.in/gorilla/websocket.v1/conn_read_legacy.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/conn_read_legacy.go rename to vendor/gopkg.in/gorilla/websocket.v1/conn_read_legacy.go diff --git a/cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/doc.go b/vendor/gopkg.in/gorilla/websocket.v1/doc.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/doc.go rename to vendor/gopkg.in/gorilla/websocket.v1/doc.go diff --git a/cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/json.go b/vendor/gopkg.in/gorilla/websocket.v1/json.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/json.go rename to vendor/gopkg.in/gorilla/websocket.v1/json.go diff --git a/cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/mask.go b/vendor/gopkg.in/gorilla/websocket.v1/mask.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/mask.go rename to vendor/gopkg.in/gorilla/websocket.v1/mask.go diff --git a/cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/server.go b/vendor/gopkg.in/gorilla/websocket.v1/server.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/server.go rename to vendor/gopkg.in/gorilla/websocket.v1/server.go diff --git a/cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/util.go b/vendor/gopkg.in/gorilla/websocket.v1/util.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/gorilla/websocket.v1/util.go rename to vendor/gopkg.in/gorilla/websocket.v1/util.go diff --git a/cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/LICENSE b/vendor/gopkg.in/xtaci/kcp-go.v2/LICENSE similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/LICENSE rename to vendor/gopkg.in/xtaci/kcp-go.v2/LICENSE diff --git a/cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/README.md b/vendor/gopkg.in/xtaci/kcp-go.v2/README.md similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/README.md rename to vendor/gopkg.in/xtaci/kcp-go.v2/README.md diff --git a/cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/crypt.go b/vendor/gopkg.in/xtaci/kcp-go.v2/crypt.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/crypt.go rename to vendor/gopkg.in/xtaci/kcp-go.v2/crypt.go diff --git a/cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/donate.png b/vendor/gopkg.in/xtaci/kcp-go.v2/donate.png similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/donate.png rename to vendor/gopkg.in/xtaci/kcp-go.v2/donate.png diff --git a/cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/fec.go b/vendor/gopkg.in/xtaci/kcp-go.v2/fec.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/fec.go rename to vendor/gopkg.in/xtaci/kcp-go.v2/fec.go diff --git a/cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/frame.png b/vendor/gopkg.in/xtaci/kcp-go.v2/frame.png similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/frame.png rename to vendor/gopkg.in/xtaci/kcp-go.v2/frame.png diff --git a/cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/kcp-go.png b/vendor/gopkg.in/xtaci/kcp-go.v2/kcp-go.png similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/kcp-go.png rename to vendor/gopkg.in/xtaci/kcp-go.v2/kcp-go.png diff --git a/cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/kcp.go b/vendor/gopkg.in/xtaci/kcp-go.v2/kcp.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/kcp.go rename to vendor/gopkg.in/xtaci/kcp-go.v2/kcp.go diff --git a/cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/sess.go b/vendor/gopkg.in/xtaci/kcp-go.v2/sess.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/sess.go rename to vendor/gopkg.in/xtaci/kcp-go.v2/sess.go diff --git a/cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/shannon.jpg b/vendor/gopkg.in/xtaci/kcp-go.v2/shannon.jpg similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/shannon.jpg rename to vendor/gopkg.in/xtaci/kcp-go.v2/shannon.jpg diff --git a/cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/snmp.go b/vendor/gopkg.in/xtaci/kcp-go.v2/snmp.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/snmp.go rename to vendor/gopkg.in/xtaci/kcp-go.v2/snmp.go diff --git a/cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/xor.go b/vendor/gopkg.in/xtaci/kcp-go.v2/xor.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/kcp-go.v2/xor.go rename to vendor/gopkg.in/xtaci/kcp-go.v2/xor.go diff --git a/cmd/gost/vendor/gopkg.in/xtaci/smux.v1/LICENSE b/vendor/gopkg.in/xtaci/smux.v1/LICENSE similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/smux.v1/LICENSE rename to vendor/gopkg.in/xtaci/smux.v1/LICENSE diff --git a/cmd/gost/vendor/gopkg.in/xtaci/smux.v1/README.md b/vendor/gopkg.in/xtaci/smux.v1/README.md similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/smux.v1/README.md rename to vendor/gopkg.in/xtaci/smux.v1/README.md diff --git a/cmd/gost/vendor/gopkg.in/xtaci/smux.v1/curve.jpg b/vendor/gopkg.in/xtaci/smux.v1/curve.jpg similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/smux.v1/curve.jpg rename to vendor/gopkg.in/xtaci/smux.v1/curve.jpg diff --git a/cmd/gost/vendor/gopkg.in/xtaci/smux.v1/frame.go b/vendor/gopkg.in/xtaci/smux.v1/frame.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/smux.v1/frame.go rename to vendor/gopkg.in/xtaci/smux.v1/frame.go diff --git a/cmd/gost/vendor/gopkg.in/xtaci/smux.v1/mux.go b/vendor/gopkg.in/xtaci/smux.v1/mux.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/smux.v1/mux.go rename to vendor/gopkg.in/xtaci/smux.v1/mux.go diff --git a/cmd/gost/vendor/gopkg.in/xtaci/smux.v1/mux.jpg b/vendor/gopkg.in/xtaci/smux.v1/mux.jpg similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/smux.v1/mux.jpg rename to vendor/gopkg.in/xtaci/smux.v1/mux.jpg diff --git a/cmd/gost/vendor/gopkg.in/xtaci/smux.v1/session.go b/vendor/gopkg.in/xtaci/smux.v1/session.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/smux.v1/session.go rename to vendor/gopkg.in/xtaci/smux.v1/session.go diff --git a/cmd/gost/vendor/gopkg.in/xtaci/smux.v1/stream.go b/vendor/gopkg.in/xtaci/smux.v1/stream.go similarity index 100% rename from cmd/gost/vendor/gopkg.in/xtaci/smux.v1/stream.go rename to vendor/gopkg.in/xtaci/smux.v1/stream.go diff --git a/cmd/gost/vendor/vendor.json b/vendor/vendor.json similarity index 99% rename from cmd/gost/vendor/vendor.json rename to vendor/vendor.json index 8d80d1a..0c00d25 100644 --- a/cmd/gost/vendor/vendor.json +++ b/vendor/vendor.json @@ -309,5 +309,5 @@ "revisionTime": "2016-11-29T15:03:00Z" } ], - "rootPath": "github.com/ginuerzh/gost/cmd/gost" + "rootPath": "github.com/ginuerzh/gost" } From e6adca2a12a47807abddc2247a7a4f7d611cd2c9 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 9 Mar 2017 19:44:40 +0100 Subject: [PATCH 4/4] Remove gost itself from vendored packages --- vendor/github.com/ginuerzh/gost/LICENSE | 21 - vendor/github.com/ginuerzh/gost/README.md | 358 --------- vendor/github.com/ginuerzh/gost/README_en.md | 362 --------- vendor/github.com/ginuerzh/gost/chain.go | 473 ----------- vendor/github.com/ginuerzh/gost/conn.go | 292 ------- vendor/github.com/ginuerzh/gost/forward.go | 689 ---------------- vendor/github.com/ginuerzh/gost/gost.go | 162 ---- vendor/github.com/ginuerzh/gost/http.go | 410 ---------- vendor/github.com/ginuerzh/gost/kcp.go | 408 ---------- vendor/github.com/ginuerzh/gost/node.go | 161 ---- vendor/github.com/ginuerzh/gost/quic.go | 81 -- vendor/github.com/ginuerzh/gost/redirect.go | 103 --- .../github.com/ginuerzh/gost/redirect_win.go | 17 - vendor/github.com/ginuerzh/gost/server.go | 284 ------- vendor/github.com/ginuerzh/gost/signal.go | 5 - .../github.com/ginuerzh/gost/signal_unix.go | 23 - vendor/github.com/ginuerzh/gost/socks.go | 746 ------------------ vendor/github.com/ginuerzh/gost/ss.go | 353 --------- vendor/github.com/ginuerzh/gost/ssh.go | 236 ------ vendor/github.com/ginuerzh/gost/ws.go | 142 ---- vendor/vendor.json | 6 - 21 files changed, 5332 deletions(-) delete mode 100644 vendor/github.com/ginuerzh/gost/LICENSE delete mode 100644 vendor/github.com/ginuerzh/gost/README.md delete mode 100644 vendor/github.com/ginuerzh/gost/README_en.md delete mode 100644 vendor/github.com/ginuerzh/gost/chain.go delete mode 100644 vendor/github.com/ginuerzh/gost/conn.go delete mode 100644 vendor/github.com/ginuerzh/gost/forward.go delete mode 100644 vendor/github.com/ginuerzh/gost/gost.go delete mode 100644 vendor/github.com/ginuerzh/gost/http.go delete mode 100644 vendor/github.com/ginuerzh/gost/kcp.go delete mode 100644 vendor/github.com/ginuerzh/gost/node.go delete mode 100644 vendor/github.com/ginuerzh/gost/quic.go delete mode 100644 vendor/github.com/ginuerzh/gost/redirect.go delete mode 100644 vendor/github.com/ginuerzh/gost/redirect_win.go delete mode 100644 vendor/github.com/ginuerzh/gost/server.go delete mode 100644 vendor/github.com/ginuerzh/gost/signal.go delete mode 100644 vendor/github.com/ginuerzh/gost/signal_unix.go delete mode 100644 vendor/github.com/ginuerzh/gost/socks.go delete mode 100644 vendor/github.com/ginuerzh/gost/ss.go delete mode 100644 vendor/github.com/ginuerzh/gost/ssh.go delete mode 100644 vendor/github.com/ginuerzh/gost/ws.go diff --git a/vendor/github.com/ginuerzh/gost/LICENSE b/vendor/github.com/ginuerzh/gost/LICENSE deleted file mode 100644 index 2033b3a..0000000 --- a/vendor/github.com/ginuerzh/gost/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 ginuerzh - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/ginuerzh/gost/README.md b/vendor/github.com/ginuerzh/gost/README.md deleted file mode 100644 index 3b8eb53..0000000 --- a/vendor/github.com/ginuerzh/gost/README.md +++ /dev/null @@ -1,358 +0,0 @@ -gost - GO Simple Tunnel -====== - -### GO语言实现的安全隧道 - -[English README](README_en.md) - -特性 ------- -* 可同时监听多端口 -* 可设置转发代理,支持多级转发(代理链) -* 支持标准HTTP/HTTPS/SOCKS4(A)/SOCKS5代理协议 -* SOCKS5代理支持TLS协商加密 -* Tunnel UDP over TCP -* 支持Shadowsocks协议 (OTA: 2.2+,UDP: 2.4+) -* 支持本地/远程端口转发 (2.1+) -* 支持HTTP 2.0 (2.2+) -* 实验性支持QUIC (2.3+) -* 支持KCP协议 (2.3+) -* 透明代理 (2.3+) -* SSH隧道 (2.4+) - -二进制文件下载:https://github.com/ginuerzh/gost/releases - -Google讨论组: https://groups.google.com/d/forum/go-gost - -在gost中,gost与其他代理服务都被看作是代理节点,gost可以自己处理请求,或者将请求转发给任意一个或多个代理节点。 - -参数说明 ------- -#### 代理及代理链 - -适用于-L和-F参数 - -```bash -[scheme://][user:pass@host]:port -``` -scheme分为两部分: protocol+transport - -protocol: 代理协议类型(http, socks4(a), socks5, shadowsocks), transport: 数据传输方式(ws, wss, tls, http2, quic, kcp, pht), 二者可以任意组合,或单独使用: - -> http - HTTP代理: http://:8080 - -> http+tls - HTTPS代理(可能需要提供受信任的证书): http+tls://:443或https://:443 - -> http2 - HTTP2代理并向下兼容HTTPS代理: http2://:443 - -> socks4(a) - 标准SOCKS4(A)代理: socks4://:1080或socks4a://:1080 - -> socks - 标准SOCKS5代理(支持TLS协商加密): socks://:1080 - -> socks+wss - SOCKS5代理,使用websocket传输数据: socks+wss://:1080 - -> tls - HTTPS/SOCKS5代理,使用TLS传输数据: tls://:443 - -> ss - Shadowsocks代理,ss://chacha20:123456@:8338 - -> ssu - Shadowsocks UDP relay,ssu://chacha20:123456@:8338 - -> quic - QUIC代理,quic://:6121 - -> kcp - KCP通道,kcp://:8388或kcp://aes:123456@:8388 - -> pht - 普通HTTP通道,pht://:8080 - -> redirect - 透明代理,redirect://:12345 - -> ssh - SSH转发隧道,ssh://admin:123456@:2222 - -#### 端口转发 - -适用于-L参数 - -```bash -scheme://[bind_address]:port/[host]:hostport -``` -> scheme - 端口转发模式, 本地端口转发: tcp, udp; 远程端口转发: rtcp, rudp - -> bind_address:port - 本地/远程绑定地址 - -> host:hostport - 目标访问地址 - -#### 配置文件 - -> -C : 指定配置文件路径 - -配置文件为标准json格式: -```json -{ - "ServeNodes": [ - ":8080", - "ss://chacha20:12345678@:8338" - ], - "ChainNodes": [ - "http://192.168.1.1:8080", - "https://10.0.2.1:443" - ] -} -``` - -ServeNodes等同于-L参数,ChainNodes等同于-F参数 - -#### 开启日志 - -> -logtostderr : 输出到控制台 - -> -v=3 : 日志级别(1-5),级别越高,日志越详细(级别5将开启http2 debug) - -> -log_dir=/log/dir/path : 输出到目录/log/dir/path - - -使用方法 ------- -#### 不设置转发代理 - - - -* 作为标准HTTP/SOCKS5代理 -```bash -gost -L=:8080 -``` - -* 设置代理认证信息 -```bash -gost -L=admin:123456@localhost:8080 -``` - -* 多组认证信息 -```bash -gost -L=localhost:8080?secrets=secrets.txt -``` - -通过secrets参数可以为HTTP/SOCKS5代理设置多组认证信息,格式为: -```plain -# username password - -test001 123456 -test002 12345678 -``` - -* 多端口监听 -```bash -gost -L=http2://:443 -L=socks://:1080 -L=ss://aes-128-cfb:123456@:8338 -``` - -#### 设置转发代理 - - -```bash -gost -L=:8080 -F=192.168.1.1:8081 -``` - -* 转发代理认证 -```bash -gost -L=:8080 -F=http://admin:123456@192.168.1.1:8081 -``` - -#### 设置多级转发代理(代理链) - - -```bash -gost -L=:8080 -F=http+tls://192.168.1.1:443 -F=socks+ws://192.168.1.2:1080 -F=ss://aes-128-cfb:123456@192.168.1.3:8338 -F=a.b.c.d:NNNN -``` -gost按照-F设置的顺序通过代理链将请求最终转发给a.b.c.d:NNNN处理,每一个转发代理可以是任意HTTP/HTTPS/HTTP2/SOCKS5/Shadowsocks类型代理。 - -#### 本地端口转发(TCP) - -```bash -gost -L=tcp://:2222/192.168.1.1:22 -F=... -``` -将本地TCP端口2222上的数据(通过代理链)转发到192.168.1.1:22上。当代理链末端(最后一个-F参数)为SSH类型时,gost会直接使用SSH的本地端口转发功能。 -#### 本地端口转发(UDP) - -```bash -gost -L=udp://:5353/192.168.1.1:53?ttl=60 -F=... -``` -将本地UDP端口5353上的数据(通过代理链)转发到192.168.1.1:53上。 -每条转发通道都有超时时间,当超过此时间,且在此时间段内无任何数据交互,则此通道将关闭。可以通过`ttl`参数来设置超时时间,默认值为60秒。 - -**注:** 转发UDP数据时,如果有代理链,则代理链的末端(最后一个-F参数)必须是gost SOCKS5类型代理。 - -#### 远程端口转发(TCP) - -```bash -gost -L=rtcp://:2222/192.168.1.1:22 -F=... -F=socks://172.24.10.1:1080 -``` -将172.24.10.1:2222上的数据(通过代理链)转发到192.168.1.1:22上。当代理链末端(最后一个-F参数)为SSH类型时,gost会直接使用SSH的远程端口转发功能。 - -#### 远程端口转发(UDP) - -```bash -gost -L=rudp://:5353/192.168.1.1:53 -F=... -F=socks://172.24.10.1:1080 -``` -将172.24.10.1:5353上的数据(通过代理链)转发到192.168.1.1:53上。 - -**注:** 若要使用远程端口转发功能,代理链不能为空(至少要设置一个-F参数),且代理链的末端(最后一个-F参数)必须是gost SOCKS5类型代理。 - -#### HTTP2 -gost的HTTP2支持两种模式并自适应: -* 作为标准的HTTP2代理,并向下兼容HTTPS代理。 -* 作为transport(类似于wss),传输其他协议。 - -服务端: -```bash -gost -L=http2://:443 -``` -客户端: -```bash -gost -L=:8080 -F=http2://server_ip:443?ping=30 -``` - -客户端支持`ping`参数开启心跳检测(默认不开启),参数值代表心跳间隔秒数。 - -**注:** gost的代理链仅支持一个HTTP2代理节点,采用就近原则,会将第一个遇到的HTTP2代理节点视为HTTP2代理,其他HTTP2代理节点则被视为HTTPS代理。 - -#### QUIC -gost对QUIC的支持是基于[quic-go](https://github.com/lucas-clemente/quic-go)库。 - -服务端: -```bash -gost -L=quic://:6121 -``` - -客户端(Chrome): -```bash -chrome --enable-quic --proxy-server=quic://server_ip:6121 -``` - -**注:** 由于Chrome自身的限制,目前只能通过QUIC访问HTTP网站,无法访问HTTPS网站。 - -#### KCP -gost对KCP的支持是基于[kcp-go](https://github.com/xtaci/kcp-go)和[kcptun](https://github.com/xtaci/kcptun)库。 - -服务端: -```bash -gost -L=kcp://:8388 -``` - -客户端: -```bash -gost -L=:8080 -F=kcp://server_ip:8388 -``` - -或者手动指定加密方法和密码(手动指定的加密方法和密码会覆盖配置文件中的相应值) - -服务端: -```bash -gost -L=kcp://aes:123456@:8388 -``` - -客户端: -```bash -gost -L=:8080 -F=kcp://aes:123456@server_ip:8388 -``` - -gost会自动加载当前工作目录中的kcp.json(如果存在)配置文件,或者可以手动通过参数指定配置文件路径: -```bash -gost -L=kcp://:8388?c=/path/to/conf/file -``` - -**注:** 客户端若要开启KCP转发,当且仅当代理链不为空且首个代理节点(第一个-F参数)为kcp类型。 - -#### 透明代理 -基于iptables的透明代理。 - -```bash -gost -L=redirect://:12345 -F=http2://server_ip:443 -``` - -加密机制 ------- -#### HTTP -对于HTTP可以使用TLS加密整个通讯过程,即HTTPS代理: - -服务端: -```bash -gost -L=http+tls://:443 -``` -客户端: -```bash -gost -L=:8080 -F=http+tls://server_ip:443 -``` - -#### HTTP2 -gost仅支持使用TLS加密的HTTP2协议,不支持明文HTTP2传输。 - - -#### SOCKS5 -gost支持标准SOCKS5协议的no-auth(0x00)和user/pass(0x02)方法,并在此基础上扩展了两个:tls(0x80)和tls-auth(0x82),用于数据加密。 - -服务端: -```bash -gost -L=socks://:1080 -``` -客户端: -```bash -gost -L=:8080 -F=socks://server_ip:1080 -``` - -如果两端都是gost(如上)则数据传输会被加密(协商使用tls或tls-auth方法),否则使用标准SOCKS5进行通讯(no-auth或user/pass方法)。 - -**注:** 如果transport已经支持加密(wss, tls, http2, kcp),则SOCKS5不会再使用加密方法,防止不必要的双重加密。 - -#### Shadowsocks -gost对shadowsocks的支持是基于[shadowsocks-go](https://github.com/shadowsocks/shadowsocks-go)库。 - -服务端(可以通过ota参数开启OTA强制模式,开启后客户端必须使用OTA模式): -```bash -gost -L=ss://aes-128-cfb:123456@:8338?ota=1 -``` -客户端(可以通过ota参数开启OTA模式): -```bash -gost -L=:8080 -F=ss://aes-128-cfb:123456@server_ip:8338?ota=1 -``` - -##### Shadowsocks UDP relay - -目前仅服务端支持UDP,且仅支持OTA模式。 - -服务端: -```bash -gost -L=ssu://aes-128-cfb:123456@:8338 -``` - -#### TLS -gost内置了TLS证书,如果需要使用其他TLS证书,有两种方法: -* 在gost运行目录放置cert.pem(公钥)和key.pem(私钥)两个文件即可,gost会自动加载运行目录下的cert.pem和key.pem文件。 -* 使用参数指定证书文件路径: -```bash -gost -L="http2://:443?cert=/path/to/my/cert/file&key=/path/to/my/key/file" -``` - -SOCKS5 UDP数据处理 ------- -#### 不设置转发代理 - - - -gost作为标准SOCKS5代理处理UDP数据 - -#### 设置转发代理 - - - -#### 设置多个转发代理(代理链) - - - -当设置转发代理时,gost会使用UDP-over-TCP方式转发UDP数据。proxy1 - proxyN可以为任意HTTP/HTTPS/HTTP2/SOCKS5/Shadowsocks类型代理。 - -限制条件 ------- -代理链中的HTTP代理节点必须支持CONNECT方法。 - -如果要转发SOCKS5的BIND和UDP请求,代理链的末端(最后一个-F参数)必须支持gost SOCKS5类型代理。 - - - diff --git a/vendor/github.com/ginuerzh/gost/README_en.md b/vendor/github.com/ginuerzh/gost/README_en.md deleted file mode 100644 index 6c8e7e3..0000000 --- a/vendor/github.com/ginuerzh/gost/README_en.md +++ /dev/null @@ -1,362 +0,0 @@ -gost - GO Simple Tunnel -====== - -### A simple security tunnel written in Golang - -Features ------- -* Listening on multiple ports -* Multi-level forward proxy - proxy chain -* Standard HTTP/HTTPS/SOCKS4(A)/SOCKS5 proxy protocols support -* TLS encryption via negotiation support for SOCKS5 proxy -* Tunnel UDP over TCP -* Shadowsocks protocol support (OTA: 2.2+, UDP: 2.4+) -* Local/remote port forwarding (2.1+) -* HTTP 2.0 support (2.2+) -* Experimental QUIC support (2.3+) -* KCP protocol support (2.3+) -* Transparent proxy (2.3+) -* SSH tunnel (2.4+) - -Binary file download:https://github.com/ginuerzh/gost/releases - -Google group: https://groups.google.com/d/forum/go-gost - -Gost and other proxy services are considered to be proxy nodes, -gost can handle the request itself, or forward the request to any one or more proxy nodes. - -Parameter Description ------- -#### Proxy and proxy chain - -Effective for the -L and -F parameters - -```bash -[scheme://][user:pass@host]:port -``` -scheme can be divided into two parts: protocol+transport - -protocol: proxy protocol types (http, socks4(a), socks5, shadowsocks), -transport: data transmission mode (ws, wss, tls, http2, quic, kcp, pht), may be used in any combination or individually: - -> http - standard HTTP proxy: http://:8080 - -> http+tls - standard HTTPS proxy (may need to provide a trusted certificate): http+tls://:443 or https://:443 - -> http2 - HTTP2 proxy and backwards-compatible with HTTPS proxy: http2://:443 - -> socks4(a) - standard SOCKS4(A) proxy: socks4://:1080 or socks4a://:1080 - -> socks - standard SOCKS5 proxy: socks://:1080 - -> socks+wss - SOCKS5 over websocket: socks+wss://:1080 - -> tls - HTTPS/SOCKS5 over TLS: tls://:443 - -> ss - standard shadowsocks proxy, ss://chacha20:123456@:8338 - -> ssu - shadowsocks UDP relay,ssu://chacha20:123456@:8338 - -> quic - standard QUIC proxy, quic://:6121 - -> kcp - standard KCP tunnel,kcp://:8388 or kcp://aes:123456@:8388 - -> pht - plain HTTP tunnel, pht://:8080 - -> redirect - transparent proxy,redirect://:12345 - -> ssh - SSH tunnel, ssh://admin:123456@:2222 - -#### Port forwarding - -Effective for the -L parameter - -```bash -scheme://[bind_address]:port/[host]:hostport -``` -> scheme - forward mode, local: tcp, udp; remote: rtcp, rudp - -> bind_address:port - local/remote binding address - -> host:hostport - target address - -#### Configuration file - -> -C : specifies the configuration file path - -The configuration file is in standard JSON format: -```json -{ - "ServeNodes": [ - ":8080", - "ss://chacha20:12345678@:8338" - ], - "ChainNodes": [ - "http://192.168.1.1:8080", - "https://10.0.2.1:443" - ] -} -``` - -ServeNodes is equivalent to the -L parameter, ChainNodes is equivalent to the -F parameter. - -#### Logging - -> -logtostderr : log to console - -> -v=3 : log level (1-5),The higher the level, the more detailed the log (level 5 will enable HTTP2 debug) - -> -log_dir=/log/dir/path : log to directory /log/dir/path - -Usage ------- -#### No forward proxy - - - -* Standard HTTP/SOCKS5 proxy -```bash -gost -L=:8080 -``` - -* Proxy authentication -```bash -gost -L=admin:123456@localhost:8080 -``` - -* Multiple sets of authentication information -```bash -gost -L=localhost:8080?secrets=secrets.txt -``` - -The secrets parameter allows you to set multiple authentication information for HTTP/SOCKS5 proxies, the format is: -```plain -# username password - -test001 123456 -test002 12345678 -``` - -* Listen on multiple ports -```bash -gost -L=http2://:443 -L=socks://:1080 -L=ss://aes-128-cfb:123456@:8338 -``` - -#### Forward proxy - - -```bash -gost -L=:8080 -F=192.168.1.1:8081 -``` - -* Forward proxy authentication -```bash -gost -L=:8080 -F=http://admin:123456@192.168.1.1:8081 -``` - -#### Multi-level forward proxy - - -```bash -gost -L=:8080 -F=http+tls://192.168.1.1:443 -F=socks+ws://192.168.1.2:1080 -F=ss://aes-128-cfb:123456@192.168.1.3:8338 -F=a.b.c.d:NNNN -``` -Gost forwards the request to a.b.c.d:NNNN through the proxy chain in the order set by -F, -each forward proxy can be any HTTP/HTTPS/HTTP2/SOCKS5/Shadowsocks type. - -#### Local TCP port forwarding - -```bash -gost -L=tcp://:2222/192.168.1.1:22 -F=... -``` -The data on the local TCP port 2222 is forwarded to 192.168.1.1:22 (through the proxy chain). If the last node of the chain (the last -F parameter) is a SSH tunnel, then gost will use the local port forwarding function of SSH directly. - -#### Local UDP port forwarding - -```bash -gost -L=udp://:5353/192.168.1.1:53?ttl=60 -F=... -``` -The data on the local UDP port 5353 is forwarded to 192.168.1.1:53 (through the proxy chain). -Each forwarding channel has a timeout period. When this time is exceeded and there is no data interaction during this time period, the channel will be closed. The timeout value can be set by the `ttl` parameter. The default value is 60 seconds. - -**NOTE:** When forwarding UDP data, if there is a proxy chain, the end of the chain (the last -F parameter) must be gost SOCKS5 proxy. - -#### Remote TCP port forwarding - -```bash -gost -L=rtcp://:2222/192.168.1.1:22 -F=... -F=socks://172.24.10.1:1080 -``` -The data on 172.24.10.1:2222 is forwarded to 192.168.1.1:22 (through the proxy chain). If the last node of the chain (the last -F parameter) is a SSH tunnel, then gost will use the remote port forwarding function of SSH directly. - -#### Remote UDP port forwarding - -```bash -gost -L=rudp://:5353/192.168.1.1:53 -F=... -F=socks://172.24.10.1:1080 -``` -The data on 172.24.10.1:5353 is forwarded to 192.168.1.1:53 (through the proxy chain). - -**NOTE:** To use the remote port forwarding feature, the proxy chain can not be empty (at least one -F parameter is set) -and the end of the chain (last -F parameter) must be gost SOCKS5 proxy. - -#### HTTP2 -Gost HTTP2 supports two modes and self-adapting: -* As a standard HTTP2 proxy, and backwards-compatible with the HTTPS proxy. -* As transport (similar to wss), tunnel other protocol. - -Server: -```bash -gost -L=http2://:443 -``` -Client: -```bash -gost -L=:8080 -F=http2://server_ip:443?ping=30 -``` - -The client supports the `ping` parameter to enable heartbeat detection (which is disabled by default). -Parameter value represents heartbeat interval seconds. - -**NOTE:** The proxy chain of gost supports only one HTTP2 proxy node and the nearest rule applies, -the first HTTP2 proxy node is treated as an HTTP2 proxy, and the other HTTP2 proxy nodes are treated as HTTPS proxies. - -#### QUIC -Support for QUIC is based on library [quic-go](https://github.com/lucas-clemente/quic-go). - -Server: -```bash -gost -L=quic://:6121 -``` -Client(Chrome): -```bash -chrome --enable-quic --proxy-server=quic://server_ip:6121 -``` - -**NOTE:** Due to Chrome's limitations, it is currently only possible to access the HTTP (but not HTTPS) site through QUIC. - -#### KCP -Support for KCP is based on libraries [kcp-go](https://github.com/xtaci/kcp-go) and [kcptun](https://github.com/xtaci/kcptun). - -Server: -```bash -gost -L=kcp://:8388 -``` -Client: -```bash -gost -L=:8080 -F=kcp://server_ip:8388 -``` - -Or manually specify the encryption method and password (Manually specifying the encryption method and password overwrites the corresponding value in the configuration file) - -Server: -```bash -gost -L=kcp://aes:123456@:8388 -``` - -Client: -```bash -gost -L=:8080 -F=kcp://aes:123456@server_ip:8388 -``` - -Gost will automatically load kcp.json configuration file from current working directory if exists, -or you can use the parameter to specify the path to the file. -```bash -gost -L=kcp://:8388?c=/path/to/conf/file -``` - -**NOTE:** KCP will be enabled if and only if the proxy chain is not empty and the first proxy node (the first -F parameter) is of type KCP. - -#### Transparent proxy -Iptables-based transparent proxy - -```bash -gost -L=redirect://:12345 -F=http2://server_ip:443 -``` - -Encryption Mechanism ------- -#### HTTP -For HTTP, you can use TLS to encrypt the entire communication process, the HTTPS proxy: - -Server: -```bash -gost -L=http+tls://:443 -``` -Client: -```bash -gost -L=:8080 -F=http+tls://server_ip:443 -``` - -#### HTTP2 -Gost supports only the HTTP2 protocol that uses TLS encryption (h2) and does not support plaintext HTTP2 (h2c) transport. - - -#### SOCKS5 -Gost supports the standard SOCKS5 protocol methods: no-auth (0x00) and user/pass (0x02), -and extends two methods for data encryption: tls(0x80) and tls-auth(0x82). - -Server: -```bash -gost -L=socks://:1080 -``` -Client: -```bash -gost -L=:8080 -F=socks://server_ip:1080 -``` - -If both ends are gosts (as example above), the data transfer will be encrypted (using tls or tls-auth). -Otherwise, use standard SOCKS5 for communication (no-auth or user/pass). - -**NOTE:** If transport already supports encryption (wss, tls, http2, kcp), SOCKS5 will no longer use the encryption method to prevent unnecessary double encryption. - -#### Shadowsocks -Support for shadowsocks is based on library [shadowsocks-go](https://github.com/shadowsocks/shadowsocks-go). - -Server (The OTA mode can be enabled by the ota parameter. When enabled, the client must use OTA mode): -```bash -gost -L=ss://aes-128-cfb:123456@:8338?ota=1 -``` -Client (The OTA mode can be enabled by the ota parameter): -```bash -gost -L=:8080 -F=ss://aes-128-cfb:123456@server_ip:8338?ota=1 -``` - -##### Shadowsocks UDP relay -Currently, only the server supports UDP, and only OTA mode is supported. - -Server: -```bash -gost -L=ssu://aes-128-cfb:123456@:8338 -``` - -#### TLS -There is built-in TLS certificate in gost, if you need to use other TLS certificate, there are two ways: -* Place two files cert.pem (public key) and key.pem (private key) in the current working directory, gost will automatically load them. -* Use the parameter to specify the path to the certificate file: -```bash -gost -L="http2://:443?cert=/path/to/my/cert/file&key=/path/to/my/key/file" -``` - -SOCKS5 UDP Data Processing ------- -#### No forward proxy - - - -Gost acts as the standard SOCKS5 proxy for UDP relay. - -#### Forward proxy - - - -#### Multi-level forward proxy - - - -When forward proxies are set, gost uses UDP-over-TCP to forward UDP data, proxy1 to proxyN can be any HTTP/HTTPS/HTTP2/SOCKS5/Shadowsocks type. - -Limitation ------- -The HTTP proxy node in the proxy chain must support the CONNECT method. - -If the BIND and UDP requests for SOCKS5 are to be forwarded, the end of the chain (the last -F parameter) must be the gost SOCKS5 proxy. - - - diff --git a/vendor/github.com/ginuerzh/gost/chain.go b/vendor/github.com/ginuerzh/gost/chain.go deleted file mode 100644 index 306c697..0000000 --- a/vendor/github.com/ginuerzh/gost/chain.go +++ /dev/null @@ -1,473 +0,0 @@ -package gost - -import ( - "crypto/rand" - "crypto/tls" - "encoding/base64" - "errors" - "github.com/ginuerzh/pht" - "github.com/golang/glog" - "github.com/lucas-clemente/quic-go/h2quic" - "golang.org/x/net/http2" - "io" - "net" - "net/http" - "net/http/httputil" - "net/url" - "strconv" - "strings" - "sync" - "time" -) - -// Proxy chain holds a list of proxy nodes -type ProxyChain struct { - nodes []ProxyNode - lastNode *ProxyNode - http2NodeIndex int - http2Enabled bool - http2Client *http.Client - kcpEnabled bool - kcpConfig *KCPConfig - kcpSession *KCPSession - kcpMutex sync.Mutex - phtClient *pht.Client - quicClient *http.Client -} - -func NewProxyChain(nodes ...ProxyNode) *ProxyChain { - chain := &ProxyChain{nodes: nodes, http2NodeIndex: -1} - return chain -} - -func (c *ProxyChain) AddProxyNode(node ...ProxyNode) { - c.nodes = append(c.nodes, node...) -} - -func (c *ProxyChain) AddProxyNodeString(snode ...string) error { - for _, sn := range snode { - node, err := ParseProxyNode(sn) - if err != nil { - return err - } - c.AddProxyNode(node) - } - return nil -} - -func (c *ProxyChain) Nodes() []ProxyNode { - return c.nodes -} - -func (c *ProxyChain) GetNode(index int) *ProxyNode { - if index < len(c.nodes) { - return &c.nodes[index] - } - return nil -} - -func (c *ProxyChain) SetNode(index int, node ProxyNode) { - if index < len(c.nodes) { - c.nodes[index] = node - } -} - -// Init initialize the proxy chain. -// KCP will be enabled if the first proxy node is KCP proxy (transport == kcp). -// HTTP2 will be enabled when at least one HTTP2 proxy node (scheme == http2) is present. -// -// NOTE: Should be called immediately when proxy nodes are ready. -func (c *ProxyChain) Init() { - length := len(c.nodes) - if length == 0 { - return - } - - c.lastNode = &c.nodes[length-1] - - // HTTP2 restrict: HTTP2 will be enabled when at least one HTTP2 proxy node is present. - for i, node := range c.nodes { - if node.Transport == "http2" { - glog.V(LINFO).Infoln("HTTP2 is enabled") - cfg := &tls.Config{ - InsecureSkipVerify: node.insecureSkipVerify(), - ServerName: node.serverName, - } - c.http2NodeIndex = i - c.initHttp2Client(cfg, c.nodes[:i]...) - break // shortest chain for HTTP2 - } - } - - for i, node := range c.nodes { - if (node.Transport == "kcp" || node.Transport == "pht" || node.Transport == "quic") && i > 0 { - glog.Fatal("KCP/PHT/QUIC must be the first node in the proxy chain") - } - } - - if c.nodes[0].Transport == "kcp" { - glog.V(LINFO).Infoln("KCP is enabled") - c.kcpEnabled = true - config, err := ParseKCPConfig(c.nodes[0].Get("c")) - if err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - if config == nil { - config = DefaultKCPConfig - } - if c.nodes[0].Users != nil { - config.Crypt = c.nodes[0].Users[0].Username() - config.Key, _ = c.nodes[0].Users[0].Password() - } - c.kcpConfig = config - go snmpLogger(config.SnmpLog, config.SnmpPeriod) - go kcpSigHandler() - - return - } - - if c.nodes[0].Transport == "quic" { - glog.V(LINFO).Infoln("QUIC is enabled") - c.quicClient = &http.Client{ - Transport: &h2quic.QuicRoundTripper{ - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: c.nodes[0].insecureSkipVerify(), - ServerName: c.nodes[0].serverName, - }, - }, - } - } - - if c.nodes[0].Transport == "pht" { - glog.V(LINFO).Infoln("Pure HTTP mode is enabled") - c.phtClient = pht.NewClient(c.nodes[0].Addr, c.nodes[0].Get("key")) - } -} - -func (c *ProxyChain) KCPEnabled() bool { - return c.kcpEnabled -} - -func (c *ProxyChain) Http2Enabled() bool { - return c.http2Enabled -} - -func (c *ProxyChain) initHttp2Client(config *tls.Config, nodes ...ProxyNode) { - if c.http2NodeIndex < 0 || c.http2NodeIndex >= len(c.nodes) { - return - } - http2Node := c.nodes[c.http2NodeIndex] - - tr := http2.Transport{ - TLSClientConfig: config, - DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { - // replace the default dialer with our proxy chain. - conn, err := c.dialWithNodes(false, http2Node.Addr, nodes...) - if err != nil { - return conn, err - } - conn = tls.Client(conn, cfg) - - // enable HTTP2 ping-pong - pingIntvl, _ := strconv.Atoi(http2Node.Get("ping")) - if pingIntvl > 0 { - enablePing(conn, time.Duration(pingIntvl)*time.Second) - } - - return conn, nil - }, - } - c.http2Client = &http.Client{Transport: &tr} - c.http2Enabled = true - -} - -func enablePing(conn net.Conn, interval time.Duration) { - if conn == nil || interval == 0 { - return - } - - glog.V(LINFO).Infoln("[http2] ping enabled, interval:", interval) - go func() { - t := time.NewTicker(interval) - var framer *http2.Framer - for { - select { - case <-t.C: - if framer == nil { - framer = http2.NewFramer(conn, conn) - } - - var p [8]byte - rand.Read(p[:]) - err := framer.WritePing(false, p) - if err != nil { - t.Stop() - framer = nil - glog.V(LWARNING).Infoln("[http2] ping:", err) - return - } - } - } - }() -} - -// Connect to addr through proxy chain -func (c *ProxyChain) Dial(addr string) (net.Conn, error) { - if !strings.Contains(addr, ":") { - addr += ":80" - } - return c.dialWithNodes(true, addr, c.nodes...) -} - -// GetConn initializes a proxy chain connection, -// if no proxy nodes on this chain, it will return error -func (c *ProxyChain) GetConn() (net.Conn, error) { - nodes := c.nodes - if len(nodes) == 0 { - return nil, ErrEmptyChain - } - - if c.Http2Enabled() { - nodes = nodes[c.http2NodeIndex+1:] - if len(nodes) == 0 { - header := make(http.Header) - header.Set("Proxy-Switch", "gost") // Flag header to indicate server to switch to HTTP2 transport mode - conn, err := c.getHttp2Conn(header) - if err != nil { - return nil, err - } - http2Node := c.nodes[c.http2NodeIndex] - if http2Node.Transport == "http2" { - http2Node.Transport = "h2" - } - if http2Node.Protocol == "http2" { - http2Node.Protocol = "socks5" // assume it as socks5 protocol, so we can do much more things. - } - pc := NewProxyConn(conn, http2Node) - if err := pc.Handshake(); err != nil { - conn.Close() - return nil, err - } - return pc, nil - } - } - return c.travelNodes(true, nodes...) -} - -func (c *ProxyChain) dialWithNodes(withHttp2 bool, addr string, nodes ...ProxyNode) (conn net.Conn, err error) { - if len(nodes) == 0 { - return net.DialTimeout("tcp", addr, DialTimeout) - } - - if withHttp2 && c.Http2Enabled() { - nodes = nodes[c.http2NodeIndex+1:] - if len(nodes) == 0 { - return c.http2Connect(addr) - } - } - - if nodes[0].Transport == "quic" { - glog.V(LINFO).Infoln("Dial with QUIC") - return c.quicConnect(addr) - } - - pc, err := c.travelNodes(withHttp2, nodes...) - if err != nil { - return - } - if err = pc.Connect(addr); err != nil { - pc.Close() - return - } - conn = pc - return -} - -func (c *ProxyChain) travelNodes(withHttp2 bool, nodes ...ProxyNode) (conn *ProxyConn, err error) { - defer func() { - if err != nil && conn != nil { - conn.Close() - conn = nil - } - }() - - var cc net.Conn - node := nodes[0] - - if withHttp2 && c.Http2Enabled() { - cc, err = c.http2Connect(node.Addr) - } else if node.Transport == "kcp" { - cc, err = c.getKCPConn() - } else if node.Transport == "pht" { - cc, err = c.phtClient.Dial() - } else { - cc, err = net.DialTimeout("tcp", node.Addr, DialTimeout) - } - if err != nil { - return - } - setKeepAlive(cc, KeepAliveTime) - - pc := NewProxyConn(cc, node) - conn = pc - if err = pc.Handshake(); err != nil { - return - } - - for _, node := range nodes[1:] { - if err = conn.Connect(node.Addr); err != nil { - return - } - pc := NewProxyConn(conn, node) - conn = pc - if err = pc.Handshake(); err != nil { - return - } - } - return -} - -func (c *ProxyChain) initKCPSession() (err error) { - c.kcpMutex.Lock() - defer c.kcpMutex.Unlock() - - if c.kcpSession == nil || c.kcpSession.IsClosed() { - glog.V(LINFO).Infoln("[kcp] new kcp session") - c.kcpSession, err = DialKCP(c.nodes[0].Addr, c.kcpConfig) - } - return -} - -func (c *ProxyChain) getKCPConn() (conn net.Conn, err error) { - if !c.KCPEnabled() { - return nil, errors.New("KCP is not enabled") - } - - if err = c.initKCPSession(); err != nil { - return nil, err - } - return c.kcpSession.GetConn() -} - -// Initialize an HTTP2 transport if HTTP2 is enabled. -func (c *ProxyChain) getHttp2Conn(header http.Header) (net.Conn, error) { - if !c.Http2Enabled() { - return nil, errors.New("HTTP2 is not enabled") - } - http2Node := c.nodes[c.http2NodeIndex] - pr, pw := io.Pipe() - - if header == nil { - header = make(http.Header) - } - - req := http.Request{ - Method: http.MethodConnect, - URL: &url.URL{Scheme: "https", Host: http2Node.Addr}, - Header: header, - Proto: "HTTP/2.0", - ProtoMajor: 2, - ProtoMinor: 0, - Body: pr, - Host: http2Node.Addr, - ContentLength: -1, - } - if glog.V(LDEBUG) { - dump, _ := httputil.DumpRequest(&req, false) - glog.Infoln(string(dump)) - } - resp, err := c.http2Client.Do(&req) - if err != nil { - return nil, err - } - if glog.V(LDEBUG) { - dump, _ := httputil.DumpResponse(resp, false) - glog.Infoln(string(dump)) - } - if resp.StatusCode != http.StatusOK { - resp.Body.Close() - return nil, errors.New(resp.Status) - } - conn := &http2Conn{r: resp.Body, w: pw} - conn.remoteAddr, _ = net.ResolveTCPAddr("tcp", http2Node.Addr) - return conn, nil -} - -// Use HTTP2 as transport to connect target addr. -// -// BUG: SOCKS5 is ignored, only HTTP supported -func (c *ProxyChain) http2Connect(addr string) (net.Conn, error) { - if !c.Http2Enabled() { - return nil, errors.New("HTTP2 is not enabled") - } - http2Node := c.nodes[c.http2NodeIndex] - - header := make(http.Header) - header.Set("Gost-Target", addr) // Flag header to indicate the address that server connected to - if http2Node.Users != nil { - header.Set("Proxy-Authorization", - "Basic "+base64.StdEncoding.EncodeToString([]byte(http2Node.Users[0].String()))) - } - return c.getHttp2Conn(header) -} - -func (c *ProxyChain) quicConnect(addr string) (net.Conn, error) { - quicNode := c.nodes[0] - header := make(http.Header) - header.Set("Gost-Target", addr) // Flag header to indicate the address that server connected to - if quicNode.Users != nil { - header.Set("Proxy-Authorization", - "Basic "+base64.StdEncoding.EncodeToString([]byte(quicNode.Users[0].String()))) - } - return c.getQuicConn(header) -} - -func (c *ProxyChain) getQuicConn(header http.Header) (net.Conn, error) { - quicNode := c.nodes[0] - pr, pw := io.Pipe() - - if header == nil { - header = make(http.Header) - } - - /* - req := http.Request{ - Method: http.MethodGet, - URL: &url.URL{Scheme: "https", Host: quicNode.Addr}, - Header: header, - Proto: "HTTP/2.0", - ProtoMajor: 2, - ProtoMinor: 0, - Body: pr, - Host: quicNode.Addr, - ContentLength: -1, - } - */ - req, err := http.NewRequest(http.MethodPost, "https://"+quicNode.Addr, pr) - if err != nil { - return nil, err - } - req.ContentLength = -1 - req.Header = header - - if glog.V(LDEBUG) { - dump, _ := httputil.DumpRequest(req, false) - glog.Infoln(string(dump)) - } - resp, err := c.quicClient.Do(req) - if err != nil { - return nil, err - } - if glog.V(LDEBUG) { - dump, _ := httputil.DumpResponse(resp, false) - glog.Infoln(string(dump)) - } - if resp.StatusCode != http.StatusOK { - resp.Body.Close() - return nil, errors.New(resp.Status) - } - conn := &http2Conn{r: resp.Body, w: pw} - conn.remoteAddr, _ = net.ResolveUDPAddr("udp", quicNode.Addr) - return conn, nil -} diff --git a/vendor/github.com/ginuerzh/gost/conn.go b/vendor/github.com/ginuerzh/gost/conn.go deleted file mode 100644 index 3a6259a..0000000 --- a/vendor/github.com/ginuerzh/gost/conn.go +++ /dev/null @@ -1,292 +0,0 @@ -package gost - -import ( - "bufio" - "crypto/tls" - "encoding/base64" - "errors" - "fmt" - "github.com/ginuerzh/gosocks4" - "github.com/ginuerzh/gosocks5" - "github.com/golang/glog" - ss "github.com/shadowsocks/shadowsocks-go/shadowsocks" - "net" - "net/http" - "net/http/httputil" - "net/url" - "strconv" - "strings" - "sync" - "time" -) - -type ProxyConn struct { - conn net.Conn - Node ProxyNode - handshaked bool - handshakeMutex sync.Mutex - handshakeErr error -} - -func NewProxyConn(conn net.Conn, node ProxyNode) *ProxyConn { - return &ProxyConn{ - conn: conn, - Node: node, - } -} - -// Handshake handshake with this proxy node based on the proxy node info: transport, protocol, authentication, etc. -// -// NOTE: any HTTP2 scheme will be treated as http (for protocol) or tls (for transport). -func (c *ProxyConn) Handshake() error { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - - if err := c.handshakeErr; err != nil { - return err - } - if c.handshaked { - return nil - } - c.handshakeErr = c.handshake() - return c.handshakeErr -} - -func (c *ProxyConn) handshake() error { - var tlsUsed bool - - switch c.Node.Transport { - case "ws": // websocket connection - u := url.URL{Scheme: "ws", Host: c.Node.Addr, Path: "/ws"} - conn, err := WebsocketClientConn(u.String(), c.conn, nil) - if err != nil { - return err - } - c.conn = conn - case "wss": // websocket security - tlsUsed = true - u := url.URL{Scheme: "wss", Host: c.Node.Addr, Path: "/ws"} - config := &tls.Config{ - InsecureSkipVerify: c.Node.insecureSkipVerify(), - ServerName: c.Node.serverName, - } - conn, err := WebsocketClientConn(u.String(), c.conn, config) - if err != nil { - return err - } - c.conn = conn - case "tls", "http2": // tls connection - tlsUsed = true - cfg := &tls.Config{ - InsecureSkipVerify: c.Node.insecureSkipVerify(), - ServerName: c.Node.serverName, - } - c.conn = tls.Client(c.conn, cfg) - case "h2": // same as http2, but just set a flag for later using. - tlsUsed = true - case "kcp": // kcp connection - tlsUsed = true - default: - } - - switch c.Node.Protocol { - case "socks", "socks5": // socks5 handshake with auth and tls supported - selector := &clientSelector{ - methods: []uint8{ - gosocks5.MethodNoAuth, - gosocks5.MethodUserPass, - //MethodTLS, - }, - } - - if len(c.Node.Users) > 0 { - selector.user = c.Node.Users[0] - } - - if !tlsUsed { // if transport is not security, enable security socks5 - selector.methods = append(selector.methods, MethodTLS) - selector.tlsConfig = &tls.Config{ - InsecureSkipVerify: c.Node.insecureSkipVerify(), - ServerName: c.Node.serverName, - } - } - - conn := gosocks5.ClientConn(c.conn, selector) - if err := conn.Handleshake(); err != nil { - return err - } - c.conn = conn - case "ss": // shadowsocks - // nothing to do - case "http", "http2": - fallthrough - default: - } - - c.handshaked = true - - return nil -} - -// Connect connect to addr through this proxy node -func (c *ProxyConn) Connect(addr string) error { - switch c.Node.Protocol { - case "ss": // shadowsocks - rawaddr, err := ss.RawAddr(addr) - if err != nil { - return err - } - - var method, password string - if len(c.Node.Users) > 0 { - method = c.Node.Users[0].Username() - password, _ = c.Node.Users[0].Password() - } - if c.Node.getBool("ota") && !strings.HasSuffix(method, "-auth") { - method += "-auth" - } - - cipher, err := ss.NewCipher(method, password) - if err != nil { - return err - } - - ssc, err := ss.DialWithRawAddrConn(rawaddr, c.conn, cipher) - if err != nil { - return err - } - c.conn = &shadowConn{conn: ssc} - return nil - case "socks", "socks5": - host, port, err := net.SplitHostPort(addr) - if err != nil { - return err - } - p, _ := strconv.Atoi(port) - req := gosocks5.NewRequest(gosocks5.CmdConnect, &gosocks5.Addr{ - Type: gosocks5.AddrDomain, - Host: host, - Port: uint16(p), - }) - if err := req.Write(c); err != nil { - return err - } - glog.V(LDEBUG).Infoln("[socks5]", req) - - reply, err := gosocks5.ReadReply(c) - if err != nil { - return err - } - glog.V(LDEBUG).Infoln("[socks5]", reply) - if reply.Rep != gosocks5.Succeeded { - return errors.New("Service unavailable") - } - case "socks4", "socks4a": - atype := gosocks4.AddrDomain - host, port, err := net.SplitHostPort(addr) - if err != nil { - return err - } - p, _ := strconv.Atoi(port) - - if c.Node.Protocol == "socks4" { - taddr, err := net.ResolveTCPAddr("tcp4", addr) - if err != nil { - return err - } - host = taddr.IP.String() - p = taddr.Port - atype = gosocks4.AddrIPv4 - } - req := gosocks4.NewRequest(gosocks4.CmdConnect, - &gosocks4.Addr{Type: atype, Host: host, Port: uint16(p)}, nil) - if err := req.Write(c); err != nil { - return err - } - glog.V(LDEBUG).Infof("[%s] %s", c.Node.Protocol, req) - - reply, err := gosocks4.ReadReply(c) - if err != nil { - return err - } - glog.V(LDEBUG).Infof("[%s] %s", c.Node.Protocol, reply) - - if reply.Code != gosocks4.Granted { - return errors.New(fmt.Sprintf("%s: code=%d", c.Node.Protocol, reply.Code)) - } - case "http": - fallthrough - default: - req := &http.Request{ - Method: http.MethodConnect, - URL: &url.URL{Host: addr}, - Host: addr, - ProtoMajor: 1, - ProtoMinor: 1, - Header: make(http.Header), - } - req.Header.Set("Proxy-Connection", "keep-alive") - if len(c.Node.Users) > 0 { - user := c.Node.Users[0] - s := user.String() - if _, set := user.Password(); !set { - s += ":" - } - req.Header.Set("Proxy-Authorization", - "Basic "+base64.StdEncoding.EncodeToString([]byte(s))) - } - if err := req.Write(c); err != nil { - return err - } - if glog.V(LDEBUG) { - dump, _ := httputil.DumpRequest(req, false) - glog.Infoln(string(dump)) - } - - resp, err := http.ReadResponse(bufio.NewReader(c), req) - if err != nil { - return err - } - if glog.V(LDEBUG) { - dump, _ := httputil.DumpResponse(resp, false) - glog.Infoln(string(dump)) - } - if resp.StatusCode != http.StatusOK { - return errors.New(resp.Status) - } - } - - return nil -} - -func (c *ProxyConn) Read(b []byte) (n int, err error) { - return c.conn.Read(b) -} - -func (c *ProxyConn) Write(b []byte) (n int, err error) { - return c.conn.Write(b) -} - -func (c *ProxyConn) Close() error { - return c.conn.Close() -} - -func (c *ProxyConn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -func (c *ProxyConn) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -func (c *ProxyConn) SetDeadline(t time.Time) error { - return c.conn.SetDeadline(t) -} - -func (c *ProxyConn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -func (c *ProxyConn) SetWriteDeadline(t time.Time) error { - return c.conn.SetWriteDeadline(t) -} diff --git a/vendor/github.com/ginuerzh/gost/forward.go b/vendor/github.com/ginuerzh/gost/forward.go deleted file mode 100644 index 5d545c8..0000000 --- a/vendor/github.com/ginuerzh/gost/forward.go +++ /dev/null @@ -1,689 +0,0 @@ -package gost - -import ( - "errors" - "fmt" - "github.com/ginuerzh/gosocks5" - "github.com/golang/glog" - "golang.org/x/crypto/ssh" - "net" - "strconv" - "time" -) - -type TcpForwardServer struct { - Base *ProxyServer - sshClient *ssh.Client - Handler func(conn net.Conn, raddr *net.TCPAddr) -} - -func NewTcpForwardServer(base *ProxyServer) *TcpForwardServer { - return &TcpForwardServer{Base: base} -} - -func (s *TcpForwardServer) ListenAndServe() error { - raddr, err := net.ResolveTCPAddr("tcp", s.Base.Node.Remote) - if err != nil { - return err - } - - ln, err := net.Listen("tcp", s.Base.Node.Addr) - if err != nil { - return err - } - defer ln.Close() - - if s.Handler == nil { - s.Handler = s.handleTcpForward - } - - quit := make(chan interface{}) - close(quit) - - for { - start: - conn, err := ln.Accept() - if err != nil { - glog.V(LWARNING).Infoln("[tcp]", err) - continue - } - setKeepAlive(conn, KeepAliveTime) - - select { - case <-quit: - if s.Base.Chain.lastNode == nil || s.Base.Chain.lastNode.Transport != "ssh" { - break - } - if err := s.initSSHClient(); err != nil { - glog.V(LWARNING).Infoln("[tcp]", err) - conn.Close() - goto start - } - quit = make(chan interface{}) - go func(ch chan interface{}) { - s.sshClient.Wait() - glog.V(LINFO).Infoln("[tcp] connection closed") - close(ch) - }(quit) - - default: - } - - go s.Handler(conn, raddr) - } -} - -func (s *TcpForwardServer) initSSHClient() error { - if s.sshClient != nil { - s.sshClient.Close() - s.sshClient = nil - } - - sshNode := s.Base.Chain.lastNode - c, err := s.Base.Chain.GetConn() - if err != nil { - return err - } - var user, password string - if len(sshNode.Users) > 0 { - user = sshNode.Users[0].Username() - password, _ = sshNode.Users[0].Password() - } - config := ssh.ClientConfig{ - User: user, - Auth: []ssh.AuthMethod{ - ssh.Password(password), - }, - } - sshConn, chans, reqs, err := ssh.NewClientConn(c, sshNode.Addr, &config) - if err != nil { - return err - } - s.sshClient = ssh.NewClient(sshConn, chans, reqs) - s.Handler = s.handleTcpForwardSSH - - return nil -} - -func (s *TcpForwardServer) handleTcpForward(conn net.Conn, raddr *net.TCPAddr) { - defer conn.Close() - - glog.V(LINFO).Infof("[tcp] %s - %s", conn.RemoteAddr(), raddr) - cc, err := s.Base.Chain.Dial(raddr.String()) - if err != nil { - glog.V(LWARNING).Infof("[tcp] %s -> %s : %s", conn.RemoteAddr(), raddr, err) - return - } - defer cc.Close() - - glog.V(LINFO).Infof("[tcp] %s <-> %s", conn.RemoteAddr(), raddr) - s.Base.transport(conn, cc) - glog.V(LINFO).Infof("[tcp] %s >-< %s", conn.RemoteAddr(), raddr) -} - -func (s *TcpForwardServer) handleTcpForwardSSH(conn net.Conn, raddr *net.TCPAddr) { - defer conn.Close() - - if s.sshClient == nil { - return - } - - rc, err := s.sshClient.DialTCP("tcp", nil, raddr) - if err != nil { - glog.V(LWARNING).Infof("[tcp] %s -> %s : %s", conn.RemoteAddr(), raddr, err) - return - } - defer rc.Close() - - glog.V(LINFO).Infof("[tcp] %s <-> %s", conn.RemoteAddr(), raddr) - Transport(conn, rc) - glog.V(LINFO).Infof("[tcp] %s >-< %s", conn.RemoteAddr(), raddr) -} - -type packet struct { - srcAddr string // src address - dstAddr string // dest address - data []byte -} - -type cnode struct { - chain *ProxyChain - conn net.Conn - srcAddr, dstAddr string - rChan, wChan chan *packet - err error - ttl time.Duration -} - -func (node *cnode) getUDPTunnel() (net.Conn, error) { - conn, err := node.chain.GetConn() - if err != nil { - return nil, err - } - - conn.SetWriteDeadline(time.Now().Add(WriteTimeout)) - if err = gosocks5.NewRequest(CmdUdpTun, nil).Write(conn); err != nil { - conn.Close() - return nil, err - } - conn.SetWriteDeadline(time.Time{}) - - conn.SetReadDeadline(time.Now().Add(ReadTimeout)) - reply, err := gosocks5.ReadReply(conn) - if err != nil { - conn.Close() - return nil, err - } - conn.SetReadDeadline(time.Time{}) - - if reply.Rep != gosocks5.Succeeded { - conn.Close() - return nil, errors.New("UDP tunnel failure") - } - - return conn, nil -} - -func (node *cnode) run() { - if len(node.chain.Nodes()) == 0 { - lconn, err := net.ListenUDP("udp", nil) - if err != nil { - glog.V(LWARNING).Infof("[udp] %s -> %s : %s", node.srcAddr, node.dstAddr, err) - node.err = err - return - } - node.conn = lconn - } else { - tc, err := node.getUDPTunnel() - if err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s -> %s : %s", node.srcAddr, node.dstAddr, err) - node.err = err - return - } - node.conn = tc - } - - defer node.conn.Close() - - timer := time.NewTimer(node.ttl) - errChan := make(chan error, 2) - - go func() { - for { - switch c := node.conn.(type) { - case *net.UDPConn: - b := make([]byte, MediumBufferSize) - n, addr, err := c.ReadFromUDP(b) - if err != nil { - glog.V(LWARNING).Infof("[udp] %s <- %s : %s", node.srcAddr, node.dstAddr, err) - node.err = err - errChan <- err - return - } - - timer.Reset(node.ttl) - glog.V(LDEBUG).Infof("[udp] %s <<< %s : length %d", node.srcAddr, addr, n) - - select { - // swap srcAddr with dstAddr - case node.rChan <- &packet{srcAddr: addr.String(), dstAddr: node.srcAddr, data: b[:n]}: - case <-time.After(time.Second * 3): - glog.V(LWARNING).Infof("[udp] %s <- %s : %s", node.srcAddr, node.dstAddr, "recv queue is full, discard") - } - - default: - dgram, err := gosocks5.ReadUDPDatagram(c) - if err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s <- %s : %s", node.srcAddr, node.dstAddr, err) - node.err = err - errChan <- err - return - } - - timer.Reset(node.ttl) - glog.V(LDEBUG).Infof("[udp-tun] %s <<< %s : length %d", node.srcAddr, dgram.Header.Addr.String(), len(dgram.Data)) - - select { - // swap srcAddr with dstAddr - case node.rChan <- &packet{srcAddr: dgram.Header.Addr.String(), dstAddr: node.srcAddr, data: dgram.Data}: - case <-time.After(time.Second * 3): - glog.V(LWARNING).Infof("[udp-tun] %s <- %s : %s", node.srcAddr, node.dstAddr, "recv queue is full, discard") - } - } - } - }() - - go func() { - for pkt := range node.wChan { - timer.Reset(node.ttl) - - dstAddr, err := net.ResolveUDPAddr("udp", pkt.dstAddr) - if err != nil { - glog.V(LWARNING).Infof("[udp] %s -> %s : %s", pkt.srcAddr, pkt.dstAddr, err) - continue - } - - switch c := node.conn.(type) { - case *net.UDPConn: - if _, err := c.WriteToUDP(pkt.data, dstAddr); err != nil { - glog.V(LWARNING).Infof("[udp] %s -> %s : %s", pkt.srcAddr, pkt.dstAddr, err) - node.err = err - errChan <- err - return - } - glog.V(LDEBUG).Infof("[udp] %s >>> %s : length %d", pkt.srcAddr, pkt.dstAddr, len(pkt.data)) - - default: - dgram := gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(uint16(len(pkt.data)), 0, ToSocksAddr(dstAddr)), pkt.data) - if err := dgram.Write(c); err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s -> %s : %s", pkt.srcAddr, pkt.dstAddr, err) - node.err = err - errChan <- err - return - } - glog.V(LDEBUG).Infof("[udp-tun] %s >>> %s : length %d", pkt.srcAddr, pkt.dstAddr, len(pkt.data)) - } - } - }() - - select { - case <-errChan: - case <-timer.C: - } -} - -type UdpForwardServer struct { - Base *ProxyServer - TTL int -} - -func NewUdpForwardServer(base *ProxyServer, ttl int) *UdpForwardServer { - return &UdpForwardServer{Base: base, TTL: ttl} -} - -func (s *UdpForwardServer) ListenAndServe() error { - laddr, err := net.ResolveUDPAddr("udp", s.Base.Node.Addr) - if err != nil { - return err - } - - raddr, err := net.ResolveUDPAddr("udp", s.Base.Node.Remote) - if err != nil { - return err - } - - conn, err := net.ListenUDP("udp", laddr) - if err != nil { - glog.V(LWARNING).Infof("[udp] %s -> %s : %s", laddr, raddr, err) - return err - } - defer conn.Close() - - rChan, wChan := make(chan *packet, 128), make(chan *packet, 128) - // start send queue - go func(ch chan<- *packet) { - for { - b := make([]byte, MediumBufferSize) - n, addr, err := conn.ReadFromUDP(b) - if err != nil { - glog.V(LWARNING).Infof("[udp] %s -> %s : %s", laddr, raddr, err) - continue - } - - select { - case ch <- &packet{srcAddr: addr.String(), dstAddr: raddr.String(), data: b[:n]}: - case <-time.After(time.Second * 3): - glog.V(LWARNING).Infof("[udp] %s -> %s : %s", addr, raddr, "send queue is full, discard") - } - } - }(wChan) - // start recv queue - go func(ch <-chan *packet) { - for pkt := range ch { - dstAddr, err := net.ResolveUDPAddr("udp", pkt.dstAddr) - if err != nil { - glog.V(LWARNING).Infof("[udp] %s <- %s : %s", pkt.dstAddr, pkt.srcAddr, err) - continue - } - if _, err := conn.WriteToUDP(pkt.data, dstAddr); err != nil { - glog.V(LWARNING).Infof("[udp] %s <- %s : %s", pkt.dstAddr, pkt.srcAddr, err) - return - } - } - }(rChan) - - // mapping client to node - m := make(map[string]*cnode) - - // start dispatcher - for pkt := range wChan { - // clear obsolete nodes - for k, node := range m { - if node != nil && node.err != nil { - close(node.wChan) - delete(m, k) - glog.V(LINFO).Infof("[udp] clear node %s", k) - } - } - - node, ok := m[pkt.srcAddr] - if !ok { - node = &cnode{ - chain: s.Base.Chain, - srcAddr: pkt.srcAddr, - dstAddr: pkt.dstAddr, - rChan: rChan, - wChan: make(chan *packet, 32), - ttl: time.Duration(s.TTL) * time.Second, - } - m[pkt.srcAddr] = node - go node.run() - glog.V(LINFO).Infof("[udp] %s -> %s : new client (%d)", pkt.srcAddr, pkt.dstAddr, len(m)) - } - - select { - case node.wChan <- pkt: - case <-time.After(time.Second * 3): - glog.V(LWARNING).Infof("[udp] %s -> %s : %s", pkt.srcAddr, pkt.dstAddr, "node send queue is full, discard") - } - } - - return nil -} - -type RTcpForwardServer struct { - Base *ProxyServer -} - -func NewRTcpForwardServer(base *ProxyServer) *RTcpForwardServer { - return &RTcpForwardServer{Base: base} -} - -func (s *RTcpForwardServer) Serve() error { - if len(s.Base.Chain.nodes) == 0 { - return errors.New("rtcp: at least one -F must be assigned") - } - - laddr, err := net.ResolveTCPAddr("tcp", s.Base.Node.Addr) - if err != nil { - return err - } - raddr, err := net.ResolveTCPAddr("tcp", s.Base.Node.Remote) - if err != nil { - return err - } - - retry := 0 - for { - conn, err := s.Base.Chain.GetConn() - if err != nil { - glog.V(LWARNING).Infof("[rtcp] %s - %s : %s", laddr, raddr, err) - time.Sleep((1 << uint(retry)) * time.Second) - if retry < 5 { - retry++ - } - continue - } - retry = 0 - - glog.V(LINFO).Infof("[rtcp] %s - %s", laddr, raddr) - - lastNode := s.Base.Chain.lastNode - if lastNode != nil && lastNode.Transport == "ssh" { - s.connectRTcpForwardSSH(conn, lastNode, laddr, raddr) - } else { - if err := s.connectRTcpForward(conn, laddr, raddr); err != nil { - conn.Close() - } - } - time.Sleep(3 * time.Second) - } -} - -func (s *RTcpForwardServer) connectRTcpForwardSSH(conn net.Conn, sshNode *ProxyNode, laddr, raddr net.Addr) error { - defer conn.Close() - - var user, password string - if len(sshNode.Users) > 0 { - user = sshNode.Users[0].Username() - password, _ = sshNode.Users[0].Password() - } - config := ssh.ClientConfig{ - User: user, - Auth: []ssh.AuthMethod{ - ssh.Password(password), - }, - } - c, chans, reqs, err := ssh.NewClientConn(conn, sshNode.Addr, &config) - if err != nil { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : %s", laddr, raddr, err) - return err - } - client := ssh.NewClient(c, chans, reqs) - - quit := make(chan interface{}) - defer close(quit) - - go func() { - defer client.Close() - - var c <-chan time.Time - - ping, _ := strconv.Atoi(sshNode.Get("ping")) - if ping > 0 { - d := time.Second * time.Duration(ping) - glog.V(LINFO).Infoln("[rtcp] ping is enabled:", d) - t := time.NewTicker(d) - defer t.Stop() - c = t.C - } - - for { - select { - case <-c: - _, _, err := client.SendRequest("ping", true, nil) - if err != nil { - glog.V(LWARNING).Infoln("[rtcp] ping", err) - return - } - glog.V(LDEBUG).Infoln("[rtcp] heartbeat OK") - - case <-quit: - glog.V(LWARNING).Infoln("[rtcp] ssh connection closed") - return - } - } - }() - - ln, err := client.Listen("tcp", laddr.String()) - if err != nil { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : %s", laddr, raddr, err) - return err - } - defer ln.Close() - - for { - rc, err := ln.Accept() - if err != nil { - return err - } - - go func(c net.Conn) { - defer c.Close() - - tc, err := net.DialTimeout("tcp", raddr.String(), time.Second*30) - if err != nil { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : %s", laddr, raddr, err) - return - } - defer tc.Close() - - glog.V(LINFO).Infof("[rtcp] %s <-> %s", c.RemoteAddr(), c.LocalAddr()) - Transport(c, tc) - glog.V(LINFO).Infof("[rtcp] %s >-< %s", c.RemoteAddr(), c.LocalAddr()) - }(rc) - } -} - -func (s *RTcpForwardServer) connectRTcpForward(conn net.Conn, laddr, raddr net.Addr) error { - req := gosocks5.NewRequest(gosocks5.CmdBind, ToSocksAddr(laddr)) - if err := req.Write(conn); err != nil { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : %s", laddr, raddr, err) - return err - } - - // first reply, bind status - conn.SetReadDeadline(time.Now().Add(ReadTimeout)) - rep, err := gosocks5.ReadReply(conn) - if err != nil { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : %s", laddr, raddr, err) - return err - } - conn.SetReadDeadline(time.Time{}) - if rep.Rep != gosocks5.Succeeded { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : bind on %s failure", laddr, raddr, laddr) - return errors.New("Bind on " + laddr.String() + " failure") - } - glog.V(LINFO).Infof("[rtcp] %s - %s BIND ON %s OK", laddr, raddr, rep.Addr) - - // second reply, peer connection - rep, err = gosocks5.ReadReply(conn) - if err != nil { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : %s", laddr, raddr, err) - return err - } - if rep.Rep != gosocks5.Succeeded { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : peer connect failure", laddr, raddr) - return errors.New("peer connect failure") - } - - glog.V(LINFO).Infof("[rtcp] %s -> %s PEER %s CONNECTED", laddr, raddr, rep.Addr) - - go func() { - defer conn.Close() - - lconn, err := net.DialTimeout("tcp", raddr.String(), time.Second*30) - if err != nil { - glog.V(LWARNING).Infof("[rtcp] %s -> %s : %s", rep.Addr, raddr, err) - return - } - defer lconn.Close() - - glog.V(LINFO).Infof("[rtcp] %s <-> %s", rep.Addr, lconn.RemoteAddr()) - s.Base.transport(lconn, conn) - glog.V(LINFO).Infof("[rtcp] %s >-< %s", rep.Addr, lconn.RemoteAddr()) - }() - - return nil -} - -type RUdpForwardServer struct { - Base *ProxyServer -} - -func NewRUdpForwardServer(base *ProxyServer) *RUdpForwardServer { - return &RUdpForwardServer{Base: base} -} - -func (s *RUdpForwardServer) Serve() error { - if len(s.Base.Chain.nodes) == 0 { - return errors.New("rudp: at least one -F must be assigned") - } - - laddr, err := net.ResolveUDPAddr("udp", s.Base.Node.Addr) - if err != nil { - return err - } - raddr, err := net.ResolveUDPAddr("udp", s.Base.Node.Remote) - if err != nil { - return err - } - - retry := 0 - for { - conn, err := s.Base.Chain.GetConn() - if err != nil { - glog.V(LWARNING).Infof("[rudp] %s - %s : %s", laddr, raddr, err) - time.Sleep((1 << uint(retry)) * time.Second) - if retry < 5 { - retry++ - } - continue - } - retry = 0 - - if err := s.connectRUdpForward(conn, laddr, raddr); err != nil { - conn.Close() - time.Sleep(6 * time.Second) - } - } -} - -func (s *RUdpForwardServer) connectRUdpForward(conn net.Conn, laddr, raddr *net.UDPAddr) error { - glog.V(LINFO).Infof("[rudp] %s - %s", laddr, raddr) - - req := gosocks5.NewRequest(CmdUdpTun, ToSocksAddr(laddr)) - conn.SetWriteDeadline(time.Now().Add(WriteTimeout)) - if err := req.Write(conn); err != nil { - glog.V(LWARNING).Infof("[rudp] %s -> %s : %s", laddr, raddr, err) - return err - } - conn.SetWriteDeadline(time.Time{}) - - conn.SetReadDeadline(time.Now().Add(ReadTimeout)) - rep, err := gosocks5.ReadReply(conn) - if err != nil { - glog.V(LWARNING).Infof("[rudp] %s <- %s : %s", laddr, raddr, err) - return err - } - conn.SetReadDeadline(time.Time{}) - - if rep.Rep != gosocks5.Succeeded { - glog.V(LWARNING).Infof("[rudp] %s <- %s : bind on %s failure", laddr, raddr, laddr) - return errors.New(fmt.Sprintf("bind on %s failure", laddr)) - } - - glog.V(LINFO).Infof("[rudp] %s - %s BIND ON %s OK", laddr, raddr, rep.Addr) - - for { - dgram, err := gosocks5.ReadUDPDatagram(conn) - if err != nil { - glog.V(LWARNING).Infof("[rudp] %s <- %s : %s", laddr, raddr, err) - return err - } - - go func() { - b := make([]byte, MediumBufferSize) - - relay, err := net.DialUDP("udp", nil, raddr) - if err != nil { - glog.V(LWARNING).Infof("[rudp] %s -> %s : %s", laddr, raddr, err) - return - } - defer relay.Close() - - if _, err := relay.Write(dgram.Data); err != nil { - glog.V(LWARNING).Infof("[rudp] %s -> %s : %s", laddr, raddr, err) - return - } - glog.V(LDEBUG).Infof("[rudp] %s >>> %s length: %d", laddr, raddr, len(dgram.Data)) - - relay.SetReadDeadline(time.Now().Add(ReadTimeout)) - n, err := relay.Read(b) - if err != nil { - glog.V(LWARNING).Infof("[rudp] %s <- %s : %s", laddr, raddr, err) - return - } - relay.SetReadDeadline(time.Time{}) - - glog.V(LDEBUG).Infof("[rudp] %s <<< %s length: %d", laddr, raddr, n) - - conn.SetWriteDeadline(time.Now().Add(WriteTimeout)) - if err := gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(uint16(n), 0, dgram.Header.Addr), b[:n]).Write(conn); err != nil { - glog.V(LWARNING).Infof("[rudp] %s <- %s : %s", laddr, raddr, err) - return - } - conn.SetWriteDeadline(time.Time{}) - }() - } -} diff --git a/vendor/github.com/ginuerzh/gost/gost.go b/vendor/github.com/ginuerzh/gost/gost.go deleted file mode 100644 index 50f4085..0000000 --- a/vendor/github.com/ginuerzh/gost/gost.go +++ /dev/null @@ -1,162 +0,0 @@ -package gost - -import ( - "crypto/tls" - "encoding/base64" - "errors" - "github.com/golang/glog" - "io" - "net" - "strings" - "time" -) - -const ( - Version = "2.4-dev20170303" -) - -// Log level for glog -const ( - LFATAL = iota - LERROR - LWARNING - LINFO - LDEBUG -) - -var ( - KeepAliveTime = 180 * time.Second - DialTimeout = 30 * time.Second - ReadTimeout = 90 * time.Second - WriteTimeout = 90 * time.Second - - DefaultTTL = 60 // default udp node TTL in second for udp port forwarding -) - -var ( - SmallBufferSize = 1 * 1024 // 1KB small buffer - MediumBufferSize = 8 * 1024 // 8KB medium buffer - LargeBufferSize = 32 * 1024 // 32KB large buffer -) - -var ( - DefaultCertFile = "cert.pem" - DefaultKeyFile = "key.pem" - - // This is the default cert and key data for convenience, providing your own cert is recommended. - defaultRawCert = []byte(`-----BEGIN CERTIFICATE----- -MIIC5jCCAdCgAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD -bzAeFw0xNDAzMTcwNjIwNTFaFw0xNTAzMTcwNjIwNTFaMBIxEDAOBgNVBAoTB0Fj -bWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDccNO1xmd4lWSf -d/0/QS3E93cYIWHw831i/IKxigdRD/XMZonLdEHywW6lOiXazaP8e6CqPGSmnl0x -5k/3dvGCMj2JCVxM6+z7NpL+AiwvXmvkj/TOciCgwqssCwYS2CiVwjfazRjx1ZUJ -VDC5qiyRsfktQ2fVHrpnJGVSRagmiQgwGWBilVG9B8QvRtpQKN/GQGq17oIQm8aK -kOdPt93g93ojMIg7YJpgDgOirvVz/hDn7YD4ryrtPos9CMafFkJprymKpRHyvz7P -8a3+OkuPjFjPnwOHQ5u1U3+8vC44vfb1ExWzDLoT8Xp8Gndx39k0f7MVOol3GnYu -MN/dvNUdAgMBAAGjSzBJMA4GA1UdDwEB/wQEAwIAoDATBgNVHSUEDDAKBggrBgEF -BQcDATAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDALBgkqhkiG -9w0BAQUDggEBAIG8CJqvTIgJnNOK+i5/IUc/3yF/mSCWuG8qP+Fmo2t6T0PVOtc0 -8wiWH5iWtCAhjn0MRY9l/hIjWm6gUZGHCGuEgsOPpJDYGoNLjH9Xwokm4y3LFNRK -UBrrrDbKRNibApBHCapPf6gC5sXcjOwx7P2/kiHDgY7YH47jfcRhtAPNsM4gjsEO -RmwENY+hRUFHIRfQTyalqND+x6PWhRo3K6hpHs4DQEYPq4P2kFPqUqSBymH+Ny5/ -BcQ3wdMNmC6Bm/oiL1QV0M+/InOsAgQk/EDd0kmoU1ZT2lYHQduGmP099bOlHNpS -uqO3vXF3q8SPPr/A9TqSs7BKkBQbe0+cdsA= ------END CERTIFICATE-----`) - defaultRawKey = []byte(`-----BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEA3HDTtcZneJVkn3f9P0EtxPd3GCFh8PN9YvyCsYoHUQ/1zGaJ -y3RB8sFupTol2s2j/Hugqjxkpp5dMeZP93bxgjI9iQlcTOvs+zaS/gIsL15r5I/0 -znIgoMKrLAsGEtgolcI32s0Y8dWVCVQwuaoskbH5LUNn1R66ZyRlUkWoJokIMBlg -YpVRvQfEL0baUCjfxkBqte6CEJvGipDnT7fd4Pd6IzCIO2CaYA4Doq71c/4Q5+2A -+K8q7T6LPQjGnxZCaa8piqUR8r8+z/Gt/jpLj4xYz58Dh0ObtVN/vLwuOL329RMV -swy6E/F6fBp3cd/ZNH+zFTqJdxp2LjDf3bzVHQIDAQABAoIBAHal26147nQ+pHwY -jxwers3XDCjWvup7g79lfcqlKi79UiUEA6KYHm7UogMYewt7p4nb2KwH+XycvDiB -aAUf5flXpTs+6IkWauUDiLZi4PlV7uiEexUq5FjirlL0U/6MjbudX4bK4WQ4uxDc -WaV07Kw2iJFOOHLDKT0en9JaX5jtJNc4ZnE9efFoQ5jfypPWtRw65G1rULEg6nvc -GDh+1ce+4foCkpLRC9c24xAwJONZG6x3UqrSS9qfAsb73nWRQrTfUcO3nhoN8VvL -kL9skn1+S06NyUN0KoEtyRBp+RcpXSsBWAo6qZmo/WqhB/gjzWrxVwn20+yJSm35 -ZsMc6QECgYEA8GS+Mp9xfB2szWHz6YTOO1Uu4lHM1ccZMwS1G+dL0KO3uGAiPdvp -woVot6v6w88t7onXsLo5pgz7SYug0CpkF3K/MRd1Ar4lH7PK7IBQ6rFr9ppVxDbx -AEWRswUoPbKCr7W6HU8LbQHDavsDlEIwc6+DiwnL4BzlKjb7RpgQEz0CgYEA6sB5 -uHvx3Y5FDcGk1n73leQSAcq14l3ZLNpjrs8msoREDil/j5WmuSN58/7PGMiMgHEi -1vLm3H796JmvGr9OBvspOjHyk07ui2/We/j9Hoxm1VWhyi8HkLNDj70HKalTTFMz -RHO4O+0xCva+h9mKZrRMVktXr2jjdFn/0MYIZ2ECgYAIIsC1IeRLWQ3CHbCNlKsO -IwHlMvOFwKk/qsceXKOaOhA7szU1dr3gkXdL0Aw6mEZrrkqYdpUA46uVf54/rU+Z -445I8QxKvXiwK/uQKX+TkdGflPWWIG3jnnch4ejMvb/ihnn4B/bRB6A/fKNQXzUY -lTYUfI5j1VaEKTwz1W2l2QKBgByFCcSp+jZqhGUpc3dDsZyaOr3Q/Mvlju7uEVI5 -hIAHpaT60a6GBd1UPAqymEJwivFHzW3D0NxU6VAK68UaHMaoWNfjHY9b9YsnKS2i -kE3XzN56Ks+/avHfdYPO+UHMenw5V28nh+hv5pdoZrlmanQTz3pkaOC8o3WNQZEB -nh/BAoGBAMY5z2f1pmMhrvtPDSlEVjgjELbaInxFaxPLR4Pdyzn83gtIIU14+R8X -2LPs6PPwrNjWnIgrUSVXncIFL3pa45B+Mx1pYCpOAB1+nCZjIBQmpeo4Y0dwA/XH -85EthKPvoszm+OPbyI16OcePV5ocX7lupRYuAo0pek7bomhmHWHz ------END RSA PRIVATE KEY-----`) -) - -var ( - ErrEmptyChain = errors.New("empty chain") -) - -func setKeepAlive(conn net.Conn, d time.Duration) error { - c, ok := conn.(*net.TCPConn) - if !ok { - return errors.New("Not a TCP connection") - } - if err := c.SetKeepAlive(true); err != nil { - return err - } - if err := c.SetKeepAlivePeriod(d); err != nil { - return err - } - return nil -} - -// Load the certificate from cert and key files, will use the default certificate if the provided info are invalid. -func LoadCertificate(certFile, keyFile string) (tls.Certificate, error) { - tlsCert, err := tls.LoadX509KeyPair(certFile, keyFile) - if err == nil { - return tlsCert, nil - } - glog.V(LWARNING).Infoln(err) - return tls.X509KeyPair(defaultRawCert, defaultRawKey) -} - -// Replace the default certificate by your own -func SetDefaultCertificate(rawCert, rawKey []byte) { - defaultRawCert = rawCert - defaultRawKey = rawKey -} - -func basicProxyAuth(proxyAuth string) (username, password string, ok bool) { - if proxyAuth == "" { - return - } - - if !strings.HasPrefix(proxyAuth, "Basic ") { - return - } - c, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(proxyAuth, "Basic ")) - if err != nil { - return - } - cs := string(c) - s := strings.IndexByte(cs, ':') - if s < 0 { - return - } - - return cs[:s], cs[s+1:], true -} - -func Transport(rw1, rw2 io.ReadWriter) error { - errc := make(chan error, 1) - go func() { - _, err := io.Copy(rw1, rw2) - errc <- err - }() - - go func() { - _, err := io.Copy(rw2, rw1) - errc <- err - }() - - return <-errc -} diff --git a/vendor/github.com/ginuerzh/gost/http.go b/vendor/github.com/ginuerzh/gost/http.go deleted file mode 100644 index c0ef87f..0000000 --- a/vendor/github.com/ginuerzh/gost/http.go +++ /dev/null @@ -1,410 +0,0 @@ -package gost - -import ( - "bufio" - "crypto/tls" - "encoding/base64" - "errors" - "github.com/ginuerzh/pht" - "github.com/golang/glog" - "golang.org/x/net/http2" - "io" - "net" - "net/http" - "net/http/httputil" - "time" -) - -type HttpServer struct { - conn net.Conn - Base *ProxyServer -} - -func NewHttpServer(conn net.Conn, base *ProxyServer) *HttpServer { - return &HttpServer{ - conn: conn, - Base: base, - } -} - -// Default HTTP server handler -func (s *HttpServer) HandleRequest(req *http.Request) { - glog.V(LINFO).Infof("[http] %s %s - %s %s", req.Method, s.conn.RemoteAddr(), req.Host, req.Proto) - - if glog.V(LDEBUG) { - dump, _ := httputil.DumpRequest(req, false) - glog.Infoln(string(dump)) - } - - if req.Method == "PRI" && req.ProtoMajor == 2 { - glog.V(LWARNING).Infof("[http] %s <- %s : Not an HTTP2 server", s.conn.RemoteAddr(), req.Host) - resp := "HTTP/1.1 400 Bad Request\r\n" + - "Proxy-Agent: gost/" + Version + "\r\n\r\n" - s.conn.Write([]byte(resp)) - return - } - - valid := false - u, p, _ := basicProxyAuth(req.Header.Get("Proxy-Authorization")) - for _, user := range s.Base.Node.Users { - username := user.Username() - password, _ := user.Password() - if (u == username && p == password) || - (u == username && password == "") || - (username == "" && p == password) { - valid = true - break - } - } - - if len(s.Base.Node.Users) > 0 && !valid { - glog.V(LWARNING).Infof("[http] %s <- %s : proxy authentication required", s.conn.RemoteAddr(), req.Host) - resp := "HTTP/1.1 407 Proxy Authentication Required\r\n" + - "Proxy-Authenticate: Basic realm=\"gost\"\r\n" + - "Proxy-Agent: gost/" + Version + "\r\n\r\n" - s.conn.Write([]byte(resp)) - return - } - - req.Header.Del("Proxy-Authorization") - - // forward http request - lastNode := s.Base.Chain.lastNode - if lastNode != nil && lastNode.Transport == "" && (lastNode.Protocol == "http" || lastNode.Protocol == "") { - s.forwardRequest(req) - return - } - - c, err := s.Base.Chain.Dial(req.Host) - if err != nil { - glog.V(LWARNING).Infof("[http] %s -> %s : %s", s.conn.RemoteAddr(), req.Host, err) - - b := []byte("HTTP/1.1 503 Service unavailable\r\n" + - "Proxy-Agent: gost/" + Version + "\r\n\r\n") - glog.V(LDEBUG).Infof("[http] %s <- %s\n%s", s.conn.RemoteAddr(), req.Host, string(b)) - s.conn.Write(b) - return - } - defer c.Close() - - if req.Method == http.MethodConnect { - b := []byte("HTTP/1.1 200 Connection established\r\n" + - "Proxy-Agent: gost/" + Version + "\r\n\r\n") - glog.V(LDEBUG).Infof("[http] %s <- %s\n%s", s.conn.RemoteAddr(), req.Host, string(b)) - s.conn.Write(b) - } else { - req.Header.Del("Proxy-Connection") - req.Header.Set("Connection", "Keep-Alive") - - if err = req.Write(c); err != nil { - glog.V(LWARNING).Infof("[http] %s -> %s : %s", s.conn.RemoteAddr(), req.Host, err) - return - } - } - - glog.V(LINFO).Infof("[http] %s <-> %s", s.conn.RemoteAddr(), req.Host) - s.Base.transport(s.conn, c) - glog.V(LINFO).Infof("[http] %s >-< %s", s.conn.RemoteAddr(), req.Host) -} - -func (s *HttpServer) forwardRequest(req *http.Request) { - last := s.Base.Chain.lastNode - if last == nil { - return - } - cc, err := s.Base.Chain.GetConn() - if err != nil { - glog.V(LWARNING).Infof("[http] %s -> %s : %s", s.conn.RemoteAddr(), last.Addr, err) - - b := []byte("HTTP/1.1 503 Service unavailable\r\n" + - "Proxy-Agent: gost/" + Version + "\r\n\r\n") - glog.V(LDEBUG).Infof("[http] %s <- %s\n%s", s.conn.RemoteAddr(), last.Addr, string(b)) - s.conn.Write(b) - return - } - defer cc.Close() - - if len(last.Users) > 0 { - user := last.Users[0] - s := user.String() - if _, set := user.Password(); !set { - s += ":" - } - req.Header.Set("Proxy-Authorization", - "Basic "+base64.StdEncoding.EncodeToString([]byte(s))) - } - - cc.SetWriteDeadline(time.Now().Add(WriteTimeout)) - if err = req.WriteProxy(cc); err != nil { - glog.V(LWARNING).Infof("[http] %s -> %s : %s", s.conn.RemoteAddr(), req.Host, err) - return - } - cc.SetWriteDeadline(time.Time{}) - - glog.V(LINFO).Infof("[http] %s <-> %s", s.conn.RemoteAddr(), req.Host) - s.Base.transport(s.conn, cc) - glog.V(LINFO).Infof("[http] %s >-< %s", s.conn.RemoteAddr(), req.Host) - return -} - -type Http2Server struct { - Base *ProxyServer - Handler http.Handler - TLSConfig *tls.Config -} - -func NewHttp2Server(base *ProxyServer) *Http2Server { - return &Http2Server{Base: base} -} - -func (s *Http2Server) ListenAndServeTLS(config *tls.Config) error { - srv := http.Server{ - Addr: s.Base.Node.Addr, - Handler: s.Handler, - TLSConfig: config, - } - if srv.Handler == nil { - srv.Handler = http.HandlerFunc(s.HandleRequest) - } - http2.ConfigureServer(&srv, nil) - return srv.ListenAndServeTLS("", "") -} - -// Default HTTP2 server handler -func (s *Http2Server) HandleRequest(w http.ResponseWriter, req *http.Request) { - target := req.Header.Get("Gost-Target") - if target == "" { - target = req.Host - } - glog.V(LINFO).Infof("[http2] %s %s - %s %s", req.Method, req.RemoteAddr, target, req.Proto) - if glog.V(LDEBUG) { - dump, _ := httputil.DumpRequest(req, false) - glog.Infoln(string(dump)) - } - - w.Header().Set("Proxy-Agent", "gost/"+Version) - - // HTTP2 as transport - if req.Header.Get("Proxy-Switch") == "gost" { - conn, err := s.Upgrade(w, req) - if err != nil { - glog.V(LINFO).Infof("[http2] %s -> %s : %s", req.RemoteAddr, target, err) - return - } - glog.V(LINFO).Infof("[http2] %s - %s : switch to HTTP2 transport mode OK", req.RemoteAddr, target) - s.Base.handleConn(conn) - return - } - - valid := false - u, p, _ := basicProxyAuth(req.Header.Get("Proxy-Authorization")) - for _, user := range s.Base.Node.Users { - username := user.Username() - password, _ := user.Password() - if (u == username && p == password) || - (u == username && password == "") || - (username == "" && p == password) { - valid = true - break - } - } - if len(s.Base.Node.Users) > 0 && !valid { - glog.V(LWARNING).Infof("[http2] %s <- %s : proxy authentication required", req.RemoteAddr, target) - w.WriteHeader(http.StatusProxyAuthRequired) - return - } - - req.Header.Del("Proxy-Authorization") - req.Header.Del("Proxy-Connection") - - c, err := s.Base.Chain.Dial(target) - if err != nil { - glog.V(LWARNING).Infof("[http2] %s -> %s : %s", req.RemoteAddr, target, err) - w.WriteHeader(http.StatusServiceUnavailable) - return - } - defer c.Close() - - glog.V(LINFO).Infof("[http2] %s <-> %s", req.RemoteAddr, target) - - if req.Method == http.MethodConnect { - w.WriteHeader(http.StatusOK) - if fw, ok := w.(http.Flusher); ok { - fw.Flush() - } - - // compatible with HTTP1.x - if hj, ok := w.(http.Hijacker); ok && req.ProtoMajor == 1 { - // we take over the underly connection - conn, _, err := hj.Hijack() - if err != nil { - glog.V(LWARNING).Infof("[http2] %s -> %s : %s", req.RemoteAddr, target, err) - w.WriteHeader(http.StatusInternalServerError) - return - } - defer conn.Close() - glog.V(LINFO).Infof("[http2] %s -> %s : downgrade to HTTP/1.1", req.RemoteAddr, target) - s.Base.transport(conn, c) - return - } - - errc := make(chan error, 2) - go func() { - _, err := io.Copy(c, req.Body) - errc <- err - }() - go func() { - _, err := io.Copy(flushWriter{w}, c) - errc <- err - }() - - select { - case <-errc: - // glog.V(LWARNING).Infoln("exit", err) - } - glog.V(LINFO).Infof("[http2] %s >-< %s", req.RemoteAddr, target) - return - } - - req.Header.Set("Connection", "Keep-Alive") - if err = req.Write(c); err != nil { - glog.V(LWARNING).Infof("[http2] %s -> %s : %s", req.RemoteAddr, target, err) - return - } - - resp, err := http.ReadResponse(bufio.NewReader(c), req) - if err != nil { - glog.V(LWARNING).Infoln("[http2] %s -> %s : %s", req.RemoteAddr, target, err) - return - } - defer resp.Body.Close() - - for k, v := range resp.Header { - for _, vv := range v { - w.Header().Add(k, vv) - } - } - w.WriteHeader(resp.StatusCode) - if _, err := io.Copy(flushWriter{w}, resp.Body); err != nil { - glog.V(LWARNING).Infof("[http2] %s <- %s : %s", req.RemoteAddr, target, err) - } - glog.V(LINFO).Infof("[http2] %s >-< %s", req.RemoteAddr, target) -} - -// Upgrade upgrade an HTTP2 request to a bidirectional connection that preparing for tunneling other protocol, just like a websocket connection. -func (s *Http2Server) Upgrade(w http.ResponseWriter, r *http.Request) (net.Conn, error) { - if r.Method != http.MethodConnect { - w.WriteHeader(http.StatusMethodNotAllowed) - return nil, errors.New("Method not allowed") - } - - w.WriteHeader(http.StatusOK) - - if fw, ok := w.(http.Flusher); ok { - fw.Flush() - } - - conn := &http2Conn{r: r.Body, w: flushWriter{w}} - conn.remoteAddr, _ = net.ResolveTCPAddr("tcp", r.RemoteAddr) - conn.localAddr, _ = net.ResolveTCPAddr("tcp", r.Host) - return conn, nil -} - -// HTTP2 client connection, wrapped up just like a net.Conn -type http2Conn struct { - r io.Reader - w io.Writer - remoteAddr net.Addr - localAddr net.Addr -} - -func (c *http2Conn) Read(b []byte) (n int, err error) { - return c.r.Read(b) -} - -func (c *http2Conn) Write(b []byte) (n int, err error) { - return c.w.Write(b) -} - -func (c *http2Conn) Close() (err error) { - if rc, ok := c.r.(io.Closer); ok { - err = rc.Close() - } - if w, ok := c.w.(io.Closer); ok { - err = w.Close() - } - return -} - -func (c *http2Conn) LocalAddr() net.Addr { - return c.localAddr -} - -func (c *http2Conn) RemoteAddr() net.Addr { - return c.remoteAddr -} - -func (c *http2Conn) SetDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "http2", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} - -func (c *http2Conn) SetReadDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "http2", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} - -func (c *http2Conn) SetWriteDeadline(t time.Time) error { - return &net.OpError{Op: "set", Net: "http2", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} -} - -type flushWriter struct { - w io.Writer -} - -func (fw flushWriter) Write(p []byte) (n int, err error) { - defer func() { - if r := recover(); r != nil { - if s, ok := r.(string); ok { - err = errors.New(s) - return - } - err = r.(error) - } - }() - - n, err = fw.w.Write(p) - if err != nil { - // glog.V(LWARNING).Infoln("flush writer:", err) - return - } - if f, ok := fw.w.(http.Flusher); ok { - f.Flush() - } - return -} - -type PureHttpServer struct { - Base *ProxyServer - Handler func(net.Conn) -} - -func NewPureHttpServer(base *ProxyServer) *PureHttpServer { - return &PureHttpServer{ - Base: base, - } -} - -func (s *PureHttpServer) ListenAndServe() error { - server := pht.Server{ - Addr: s.Base.Node.Addr, - Key: s.Base.Node.Get("key"), - } - if server.Handler == nil { - server.Handler = s.handleConn - } - return server.ListenAndServe() -} - -func (s *PureHttpServer) handleConn(conn net.Conn) { - glog.V(LINFO).Infof("[pht] %s - %s", conn.RemoteAddr(), conn.LocalAddr()) - s.Base.handleConn(conn) -} diff --git a/vendor/github.com/ginuerzh/gost/kcp.go b/vendor/github.com/ginuerzh/gost/kcp.go deleted file mode 100644 index 1980942..0000000 --- a/vendor/github.com/ginuerzh/gost/kcp.go +++ /dev/null @@ -1,408 +0,0 @@ -// KCP feature is based on https://github.com/xtaci/kcptun - -package gost - -import ( - "crypto/sha1" - "encoding/csv" - "encoding/json" - "fmt" - "github.com/golang/glog" - "github.com/klauspost/compress/snappy" - "golang.org/x/crypto/pbkdf2" - "gopkg.in/xtaci/kcp-go.v2" - "gopkg.in/xtaci/smux.v1" - "net" - "os" - "time" -) - -const ( - DefaultKCPConfigFile = "kcp.json" -) - -var ( - SALT = "kcp-go" -) - -type KCPConfig struct { - Key string `json:"key"` - Crypt string `json:"crypt"` - Mode string `json:"mode"` - MTU int `json:"mtu"` - SndWnd int `json:"sndwnd"` - RcvWnd int `json:"rcvwnd"` - DataShard int `json:"datashard"` - ParityShard int `json:"parityshard"` - DSCP int `json:"dscp"` - NoComp bool `json:"nocomp"` - AckNodelay bool `json:"acknodelay"` - NoDelay int `json:"nodelay"` - Interval int `json:"interval"` - Resend int `json:"resend"` - NoCongestion int `json:"nc"` - SockBuf int `json:"sockbuf"` - KeepAlive int `json:"keepalive"` - SnmpLog string `json:"snmplog"` - SnmpPeriod int `json:"snmpperiod"` -} - -func ParseKCPConfig(configFile string) (*KCPConfig, error) { - if configFile == "" { - configFile = DefaultKCPConfigFile - } - file, err := os.Open(configFile) - if err != nil { - return nil, err - } - defer file.Close() - - config := &KCPConfig{} - if err = json.NewDecoder(file).Decode(config); err != nil { - return nil, err - } - return config, nil -} - -func (c *KCPConfig) Init() { - switch c.Mode { - case "normal": - c.NoDelay, c.Interval, c.Resend, c.NoCongestion = 0, 50, 2, 1 - case "fast2": - c.NoDelay, c.Interval, c.Resend, c.NoCongestion = 1, 30, 2, 1 - case "fast3": - c.NoDelay, c.Interval, c.Resend, c.NoCongestion = 1, 20, 2, 1 - case "fast": - fallthrough - default: - c.NoDelay, c.Interval, c.Resend, c.NoCongestion = 0, 40, 2, 1 - } -} - -var ( - DefaultKCPConfig = &KCPConfig{ - Key: "it's a secrect", - Crypt: "aes", - Mode: "fast", - MTU: 1350, - SndWnd: 1024, - RcvWnd: 1024, - DataShard: 10, - ParityShard: 3, - DSCP: 0, - NoComp: false, - AckNodelay: false, - NoDelay: 0, - Interval: 50, - Resend: 0, - NoCongestion: 0, - SockBuf: 4194304, - KeepAlive: 10, - SnmpLog: "", - SnmpPeriod: 60, - } -) - -type KCPServer struct { - Base *ProxyServer - Config *KCPConfig -} - -func NewKCPServer(base *ProxyServer, config *KCPConfig) *KCPServer { - return &KCPServer{Base: base, Config: config} -} - -func (s *KCPServer) ListenAndServe() (err error) { - if s.Config == nil { - s.Config = DefaultKCPConfig - } - s.Config.Init() - - ln, err := kcp.ListenWithOptions(s.Base.Node.Addr, - blockCrypt(s.Config.Key, s.Config.Crypt, SALT), s.Config.DataShard, s.Config.ParityShard) - if err != nil { - return err - } - if err = ln.SetDSCP(s.Config.DSCP); err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - if err = ln.SetReadBuffer(s.Config.SockBuf); err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - if err = ln.SetWriteBuffer(s.Config.SockBuf); err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - - go snmpLogger(s.Config.SnmpLog, s.Config.SnmpPeriod) - go kcpSigHandler() - for { - conn, err := ln.AcceptKCP() - if err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - continue - } - - conn.SetStreamMode(true) - conn.SetNoDelay(s.Config.NoDelay, s.Config.Interval, s.Config.Resend, s.Config.NoCongestion) - conn.SetMtu(s.Config.MTU) - conn.SetWindowSize(s.Config.SndWnd, s.Config.RcvWnd) - conn.SetACKNoDelay(s.Config.AckNodelay) - conn.SetKeepAlive(s.Config.KeepAlive) - - go s.handleMux(conn) - } -} - -func (s *KCPServer) handleMux(conn net.Conn) { - smuxConfig := smux.DefaultConfig() - smuxConfig.MaxReceiveBuffer = s.Config.SockBuf - - glog.V(LINFO).Infof("[kcp] %s - %s", conn.RemoteAddr(), s.Base.Node.Addr) - - if !s.Config.NoComp { - conn = newCompStreamConn(conn) - } - - mux, err := smux.Server(conn, smuxConfig) - if err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - return - } - defer mux.Close() - - glog.V(LINFO).Infof("[kcp] %s <-> %s", conn.RemoteAddr(), s.Base.Node.Addr) - defer glog.V(LINFO).Infof("[kcp] %s >-< %s", conn.RemoteAddr(), s.Base.Node.Addr) - - for { - stream, err := mux.AcceptStream() - if err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - return - } - go s.Base.handleConn(NewKCPConn(conn, stream)) - } -} - -func blockCrypt(key, crypt, salt string) (block kcp.BlockCrypt) { - pass := pbkdf2.Key([]byte(key), []byte(salt), 4096, 32, sha1.New) - - switch crypt { - case "tea": - block, _ = kcp.NewTEABlockCrypt(pass[:16]) - case "xor": - block, _ = kcp.NewSimpleXORBlockCrypt(pass) - case "none": - block, _ = kcp.NewNoneBlockCrypt(pass) - case "aes-128": - block, _ = kcp.NewAESBlockCrypt(pass[:16]) - case "aes-192": - block, _ = kcp.NewAESBlockCrypt(pass[:24]) - case "blowfish": - block, _ = kcp.NewBlowfishBlockCrypt(pass) - case "twofish": - block, _ = kcp.NewTwofishBlockCrypt(pass) - case "cast5": - block, _ = kcp.NewCast5BlockCrypt(pass[:16]) - case "3des": - block, _ = kcp.NewTripleDESBlockCrypt(pass[:24]) - case "xtea": - block, _ = kcp.NewXTEABlockCrypt(pass[:16]) - case "salsa20": - block, _ = kcp.NewSalsa20BlockCrypt(pass) - case "aes": - fallthrough - default: // aes - block, _ = kcp.NewAESBlockCrypt(pass) - } - return -} - -func snmpLogger(path string, interval int) { - if path == "" || interval == 0 { - return - } - ticker := time.NewTicker(time.Duration(interval) * time.Second) - defer ticker.Stop() - for { - select { - case <-ticker.C: - f, err := os.OpenFile(time.Now().Format(path), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) - if err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - return - } - w := csv.NewWriter(f) - // write header in empty file - if stat, err := f.Stat(); err == nil && stat.Size() == 0 { - if err := w.Write(append([]string{"Unix"}, kcp.DefaultSnmp.Header()...)); err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - } - if err := w.Write(append([]string{fmt.Sprint(time.Now().Unix())}, kcp.DefaultSnmp.ToSlice()...)); err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - kcp.DefaultSnmp.Reset() - w.Flush() - f.Close() - } - } -} - -type KCPSession struct { - conn net.Conn - session *smux.Session -} - -func DialKCP(addr string, config *KCPConfig) (*KCPSession, error) { - if config == nil { - config = DefaultKCPConfig - } - config.Init() - - kcpconn, err := kcp.DialWithOptions(addr, - blockCrypt(config.Key, config.Crypt, SALT), config.DataShard, config.ParityShard) - if err != nil { - return nil, err - } - - kcpconn.SetStreamMode(true) - kcpconn.SetNoDelay(config.NoDelay, config.Interval, config.Resend, config.NoCongestion) - kcpconn.SetWindowSize(config.SndWnd, config.RcvWnd) - kcpconn.SetMtu(config.MTU) - kcpconn.SetACKNoDelay(config.AckNodelay) - kcpconn.SetKeepAlive(config.KeepAlive) - - if err := kcpconn.SetDSCP(config.DSCP); err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - if err := kcpconn.SetReadBuffer(config.SockBuf); err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - if err := kcpconn.SetWriteBuffer(config.SockBuf); err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - - // stream multiplex - smuxConfig := smux.DefaultConfig() - smuxConfig.MaxReceiveBuffer = config.SockBuf - var conn net.Conn = kcpconn - if !config.NoComp { - conn = newCompStreamConn(kcpconn) - } - session, err := smux.Client(conn, smuxConfig) - if err != nil { - conn.Close() - return nil, err - } - return &KCPSession{conn: conn, session: session}, nil -} - -func (session *KCPSession) GetConn() (*KCPConn, error) { - stream, err := session.session.OpenStream() - if err != nil { - session.Close() - return nil, err - } - return NewKCPConn(session.conn, stream), nil -} - -func (session *KCPSession) Close() error { - return session.session.Close() -} - -func (session *KCPSession) IsClosed() bool { - return session.session.IsClosed() -} - -func (session *KCPSession) NumStreams() int { - return session.session.NumStreams() -} - -type KCPConn struct { - conn net.Conn - stream *smux.Stream -} - -func NewKCPConn(conn net.Conn, stream *smux.Stream) *KCPConn { - return &KCPConn{conn: conn, stream: stream} -} - -func (c *KCPConn) Read(b []byte) (n int, err error) { - return c.stream.Read(b) -} - -func (c *KCPConn) Write(b []byte) (n int, err error) { - return c.stream.Write(b) -} - -func (c *KCPConn) Close() error { - return c.stream.Close() -} - -func (c *KCPConn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -func (c *KCPConn) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -func (c *KCPConn) SetDeadline(t time.Time) error { - return c.conn.SetDeadline(t) -} - -func (c *KCPConn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -func (c *KCPConn) SetWriteDeadline(t time.Time) error { - return c.conn.SetWriteDeadline(t) -} - -type compStreamConn struct { - conn net.Conn - w *snappy.Writer - r *snappy.Reader -} - -func newCompStreamConn(conn net.Conn) *compStreamConn { - c := new(compStreamConn) - c.conn = conn - c.w = snappy.NewBufferedWriter(conn) - c.r = snappy.NewReader(conn) - return c -} - -func (c *compStreamConn) Read(b []byte) (n int, err error) { - return c.r.Read(b) -} - -func (c *compStreamConn) Write(b []byte) (n int, err error) { - n, err = c.w.Write(b) - err = c.w.Flush() - return n, err -} - -func (c *compStreamConn) Close() error { - return c.conn.Close() -} - -func (c *compStreamConn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -func (c *compStreamConn) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -func (c *compStreamConn) SetDeadline(t time.Time) error { - return c.conn.SetDeadline(t) -} - -func (c *compStreamConn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -func (c *compStreamConn) SetWriteDeadline(t time.Time) error { - return c.conn.SetWriteDeadline(t) -} diff --git a/vendor/github.com/ginuerzh/gost/node.go b/vendor/github.com/ginuerzh/gost/node.go deleted file mode 100644 index f9398f5..0000000 --- a/vendor/github.com/ginuerzh/gost/node.go +++ /dev/null @@ -1,161 +0,0 @@ -package gost - -import ( - "bufio" - "fmt" - "github.com/golang/glog" - "net" - "net/url" - "os" - "strconv" - "strings" -) - -// Proxy node represent a proxy -type ProxyNode struct { - Addr string // [host]:port - Protocol string // protocol: http/socks5/ss - Transport string // transport: ws/wss/tls/http2/tcp/udp/rtcp/rudp - Remote string // remote address, used by tcp/udp port forwarding - Users []*url.Userinfo // authentication for proxy - values url.Values - serverName string - conn net.Conn -} - -// The proxy node string pattern is [scheme://][user:pass@host]:port. -// -// Scheme can be devided into two parts by character '+', such as: http+tls. -func ParseProxyNode(s string) (node ProxyNode, err error) { - if !strings.Contains(s, "://") { - s = "gost://" + s - } - u, err := url.Parse(s) - if err != nil { - return - } - - node = ProxyNode{ - Addr: u.Host, - values: u.Query(), - serverName: u.Host, - } - - if u.User != nil { - node.Users = append(node.Users, u.User) - } - - users, er := parseUsers(node.Get("secrets")) - if users != nil { - node.Users = append(node.Users, users...) - } - if er != nil { - glog.V(LWARNING).Infoln("secrets:", er) - } - - if strings.Contains(u.Host, ":") { - node.serverName, _, _ = net.SplitHostPort(u.Host) - if node.serverName == "" { - node.serverName = "localhost" // default server name - } - } - - schemes := strings.Split(u.Scheme, "+") - if len(schemes) == 1 { - node.Protocol = schemes[0] - node.Transport = schemes[0] - } - if len(schemes) == 2 { - node.Protocol = schemes[0] - node.Transport = schemes[1] - } - - switch node.Transport { - case "ws", "wss", "tls", "http2", "quic", "kcp", "redirect", "ssu", "pht", "ssh": - case "https": - node.Protocol = "http" - node.Transport = "tls" - case "tcp", "udp": // started from v2.1, tcp and udp are for local port forwarding - node.Remote = strings.Trim(u.EscapedPath(), "/") - case "rtcp", "rudp": // started from v2.1, rtcp and rudp are for remote port forwarding - node.Remote = strings.Trim(u.EscapedPath(), "/") - default: - node.Transport = "" - } - - switch node.Protocol { - case "http", "http2", "socks", "socks4", "socks4a", "socks5", "ss": - default: - node.Protocol = "" - } - - return -} - -func parseUsers(authFile string) (users []*url.Userinfo, err error) { - if authFile == "" { - return - } - - file, err := os.Open(authFile) - if err != nil { - return - } - scanner := bufio.NewScanner(file) - for scanner.Scan() { - line := strings.TrimSpace(scanner.Text()) - if line == "" || strings.HasPrefix(line, "#") { - continue - } - - s := strings.SplitN(line, " ", 2) - if len(s) == 1 { - users = append(users, url.User(strings.TrimSpace(s[0]))) - } else if len(s) == 2 { - users = append(users, url.UserPassword(strings.TrimSpace(s[0]), strings.TrimSpace(s[1]))) - } - } - - err = scanner.Err() - return -} - -// Get get node parameter by key -func (node *ProxyNode) Get(key string) string { - return node.values.Get(key) -} - -func (node *ProxyNode) getBool(key string) bool { - s := node.Get(key) - if b, _ := strconv.ParseBool(s); b { - return b - } - n, _ := strconv.Atoi(s) - return n > 0 -} - -func (node *ProxyNode) Set(key, value string) { - node.values.Set(key, value) -} - -func (node *ProxyNode) insecureSkipVerify() bool { - return !node.getBool("secure") -} - -func (node *ProxyNode) certFile() string { - if cert := node.Get("cert"); cert != "" { - return cert - } - return DefaultCertFile -} - -func (node *ProxyNode) keyFile() string { - if key := node.Get("key"); key != "" { - return key - } - return DefaultKeyFile -} - -func (node ProxyNode) String() string { - return fmt.Sprintf("transport: %s, protocol: %s, addr: %s", node.Transport, node.Protocol, node.Addr) -} diff --git a/vendor/github.com/ginuerzh/gost/quic.go b/vendor/github.com/ginuerzh/gost/quic.go deleted file mode 100644 index 446acf2..0000000 --- a/vendor/github.com/ginuerzh/gost/quic.go +++ /dev/null @@ -1,81 +0,0 @@ -package gost - -import ( - "bufio" - "crypto/tls" - "github.com/golang/glog" - "github.com/lucas-clemente/quic-go/h2quic" - "io" - "net/http" - "net/http/httputil" -) - -type QuicServer struct { - Base *ProxyServer - Handler http.Handler - TLSConfig *tls.Config -} - -func NewQuicServer(base *ProxyServer) *QuicServer { - return &QuicServer{Base: base} -} - -func (s *QuicServer) ListenAndServeTLS(config *tls.Config) error { - server := &h2quic.Server{ - Server: &http.Server{ - Addr: s.Base.Node.Addr, - Handler: s.Handler, - TLSConfig: config, - }, - } - if server.Handler == nil { - // server.Handler = http.HandlerFunc(s.HandleRequest) - server.Handler = http.HandlerFunc(NewHttp2Server(s.Base).HandleRequest) - } - return server.ListenAndServe() -} - -func (s *QuicServer) HandleRequest(w http.ResponseWriter, req *http.Request) { - target := req.Host - glog.V(LINFO).Infof("[quic] %s %s - %s %s", req.Method, req.RemoteAddr, target, req.Proto) - - if glog.V(LDEBUG) { - dump, _ := httputil.DumpRequest(req, false) - glog.Infoln(string(dump)) - } - - c, err := s.Base.Chain.Dial(target) - if err != nil { - glog.V(LWARNING).Infof("[quic] %s -> %s : %s", req.RemoteAddr, target, err) - w.WriteHeader(http.StatusServiceUnavailable) - return - } - defer c.Close() - - glog.V(LINFO).Infof("[quic] %s <-> %s", req.RemoteAddr, target) - - req.Header.Set("Connection", "Keep-Alive") - if err = req.Write(c); err != nil { - glog.V(LWARNING).Infof("[quic] %s -> %s : %s", req.RemoteAddr, target, err) - return - } - - resp, err := http.ReadResponse(bufio.NewReader(c), req) - if err != nil { - glog.V(LWARNING).Infoln(err) - return - } - defer resp.Body.Close() - - for k, v := range resp.Header { - for _, vv := range v { - w.Header().Add(k, vv) - } - } - w.WriteHeader(resp.StatusCode) - if _, err := io.Copy(flushWriter{w}, resp.Body); err != nil { - glog.V(LWARNING).Infof("[quic] %s <- %s : %s", req.RemoteAddr, target, err) - } - - glog.V(LINFO).Infof("[quic] %s >-< %s", req.RemoteAddr, target) -} diff --git a/vendor/github.com/ginuerzh/gost/redirect.go b/vendor/github.com/ginuerzh/gost/redirect.go deleted file mode 100644 index 7524418..0000000 --- a/vendor/github.com/ginuerzh/gost/redirect.go +++ /dev/null @@ -1,103 +0,0 @@ -// +build !windows - -package gost - -import ( - "errors" - "fmt" - "github.com/golang/glog" - "net" - "syscall" -) - -const ( - SO_ORIGINAL_DST = 80 -) - -type RedsocksTCPServer struct { - Base *ProxyServer -} - -func NewRedsocksTCPServer(base *ProxyServer) *RedsocksTCPServer { - return &RedsocksTCPServer{ - Base: base, - } -} - -func (s *RedsocksTCPServer) ListenAndServe() error { - laddr, err := net.ResolveTCPAddr("tcp", s.Base.Node.Addr) - if err != nil { - return err - } - ln, err := net.ListenTCP("tcp", laddr) - if err != nil { - return err - } - - defer ln.Close() - for { - conn, err := ln.AcceptTCP() - if err != nil { - glog.V(LWARNING).Infoln(err) - continue - } - go s.handleRedirectTCP(conn) - } -} - -func (s *RedsocksTCPServer) handleRedirectTCP(conn *net.TCPConn) { - srcAddr := conn.RemoteAddr() - dstAddr, conn, err := getOriginalDstAddr(conn) - if err != nil { - glog.V(LWARNING).Infof("[red-tcp] %s -> %s : %s", srcAddr, dstAddr, err) - return - } - defer conn.Close() - - glog.V(LINFO).Infof("[red-tcp] %s -> %s", srcAddr, dstAddr) - - cc, err := s.Base.Chain.Dial(dstAddr.String()) - if err != nil { - glog.V(LWARNING).Infof("[red-tcp] %s -> %s : %s", srcAddr, dstAddr, err) - return - } - defer cc.Close() - - glog.V(LINFO).Infof("[red-tcp] %s <-> %s", srcAddr, dstAddr) - s.Base.transport(conn, cc) - glog.V(LINFO).Infof("[red-tcp] %s >-< %s", srcAddr, dstAddr) -} - -func getOriginalDstAddr(conn *net.TCPConn) (addr net.Addr, c *net.TCPConn, err error) { - defer conn.Close() - - fc, err := conn.File() - if err != nil { - return - } - defer fc.Close() - - mreq, err := syscall.GetsockoptIPv6Mreq(int(fc.Fd()), syscall.IPPROTO_IP, SO_ORIGINAL_DST) - if err != nil { - return - } - - // only ipv4 support - ip := net.IPv4(mreq.Multiaddr[4], mreq.Multiaddr[5], mreq.Multiaddr[6], mreq.Multiaddr[7]) - port := uint16(mreq.Multiaddr[2])<<8 + uint16(mreq.Multiaddr[3]) - addr, err = net.ResolveTCPAddr("tcp4", fmt.Sprintf("%s:%d", ip.String(), port)) - if err != nil { - return - } - - cc, err := net.FileConn(fc) - if err != nil { - return - } - - c, ok := cc.(*net.TCPConn) - if !ok { - err = errors.New("not a TCP connection") - } - return -} diff --git a/vendor/github.com/ginuerzh/gost/redirect_win.go b/vendor/github.com/ginuerzh/gost/redirect_win.go deleted file mode 100644 index 116bdd8..0000000 --- a/vendor/github.com/ginuerzh/gost/redirect_win.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build windows - -package gost - -import ( - "errors" -) - -type RedsocksTCPServer struct{} - -func NewRedsocksTCPServer(base *ProxyServer) *RedsocksTCPServer { - return &RedsocksTCPServer{} -} - -func (s *RedsocksTCPServer) ListenAndServe() error { - return errors.New("Not supported") -} diff --git a/vendor/github.com/ginuerzh/gost/server.go b/vendor/github.com/ginuerzh/gost/server.go deleted file mode 100644 index 5e1f0e8..0000000 --- a/vendor/github.com/ginuerzh/gost/server.go +++ /dev/null @@ -1,284 +0,0 @@ -package gost - -import ( - "bufio" - "crypto/tls" - "github.com/ginuerzh/gosocks4" - "github.com/ginuerzh/gosocks5" - "github.com/golang/glog" - ss "github.com/shadowsocks/shadowsocks-go/shadowsocks" - "golang.org/x/crypto/ssh" - "io" - "io/ioutil" - "net" - "net/http" - "strconv" - "strings" -) - -type ProxyServer struct { - Node ProxyNode - Chain *ProxyChain - TLSConfig *tls.Config - selector *serverSelector - cipher *ss.Cipher - ota bool -} - -func NewProxyServer(node ProxyNode, chain *ProxyChain, config *tls.Config) *ProxyServer { - if chain == nil { - chain = NewProxyChain() - } - if config == nil { - config = &tls.Config{} - } - - var cipher *ss.Cipher - var ota bool - if node.Protocol == "ss" || node.Transport == "ssu" { - var err error - var method, password string - - if len(node.Users) > 0 { - method = node.Users[0].Username() - password, _ = node.Users[0].Password() - } - ota = node.getBool("ota") - if strings.HasSuffix(method, "-auth") { - ota = true - method = strings.TrimSuffix(method, "-auth") - } - cipher, err = ss.NewCipher(method, password) - if err != nil { - glog.Fatal(err) - } - } - return &ProxyServer{ - Node: node, - Chain: chain, - TLSConfig: config, - selector: &serverSelector{ // socks5 server selector - // methods that socks5 server supported - methods: []uint8{ - gosocks5.MethodNoAuth, - gosocks5.MethodUserPass, - MethodTLS, - MethodTLSAuth, - }, - users: node.Users, - tlsConfig: config, - }, - cipher: cipher, - ota: ota, - } -} - -func (s *ProxyServer) Serve() error { - var ln net.Listener - var err error - node := s.Node - - switch node.Transport { - case "ws": // websocket connection - return NewWebsocketServer(s).ListenAndServe() - case "wss": // websocket security connection - return NewWebsocketServer(s).ListenAndServeTLS(s.TLSConfig) - case "tls": // tls connection - ln, err = tls.Listen("tcp", node.Addr, s.TLSConfig) - case "http2": // Standard HTTP2 proxy server, compatible with HTTP1.x. - server := NewHttp2Server(s) - server.Handler = http.HandlerFunc(server.HandleRequest) - return server.ListenAndServeTLS(s.TLSConfig) - case "tcp": // Local TCP port forwarding - return NewTcpForwardServer(s).ListenAndServe() - case "udp": // Local UDP port forwarding - ttl, _ := strconv.Atoi(s.Node.Get("ttl")) - if ttl <= 0 { - ttl = DefaultTTL - } - return NewUdpForwardServer(s, ttl).ListenAndServe() - case "rtcp": // Remote TCP port forwarding - return NewRTcpForwardServer(s).Serve() - case "rudp": // Remote UDP port forwarding - return NewRUdpForwardServer(s).Serve() - case "quic": - return NewQuicServer(s).ListenAndServeTLS(s.TLSConfig) - case "kcp": - config, err := ParseKCPConfig(s.Node.Get("c")) - if err != nil { - glog.V(LWARNING).Infoln("[kcp]", err) - } - if config == nil { - config = DefaultKCPConfig - } - // override crypt and key if specified explicitly - if s.Node.Users != nil { - config.Crypt = s.Node.Users[0].Username() - config.Key, _ = s.Node.Users[0].Password() - } - return NewKCPServer(s, config).ListenAndServe() - case "redirect": - return NewRedsocksTCPServer(s).ListenAndServe() - case "ssu": // shadowsocks udp relay - ttl, _ := strconv.Atoi(s.Node.Get("ttl")) - if ttl <= 0 { - ttl = DefaultTTL - } - return NewShadowUdpServer(s, ttl).ListenAndServe() - case "pht": // pure http tunnel - return NewPureHttpServer(s).ListenAndServe() - case "ssh": // SSH tunnel - key := s.Node.Get("key") - privateBytes, err := ioutil.ReadFile(key) - if err != nil { - glog.V(LWARNING).Infoln("[ssh]", err) - privateBytes = defaultRawKey - } - private, err := ssh.ParsePrivateKey(privateBytes) - if err != nil { - return err - } - config := ssh.ServerConfig{ - PasswordCallback: DefaultPasswordCallback(s.Node.Users), - } - if len(s.Node.Users) == 0 { - config.NoClientAuth = true - } - - config.AddHostKey(private) - s := &SSHServer{ - Addr: node.Addr, - Base: s, - Config: &config, - } - return s.ListenAndServe() - default: - ln, err = net.Listen("tcp", node.Addr) - } - - if err != nil { - return err - } - - defer ln.Close() - - for { - conn, err := ln.Accept() - if err != nil { - glog.V(LWARNING).Infoln(err) - continue - } - - setKeepAlive(conn, KeepAliveTime) - - go s.handleConn(conn) - } -} - -func (s *ProxyServer) handleConn(conn net.Conn) { - defer conn.Close() - - switch s.Node.Protocol { - case "ss": // shadowsocks - server := NewShadowServer(ss.NewConn(conn, s.cipher.Copy()), s) - server.OTA = s.ota - server.Serve() - return - case "http": - req, err := http.ReadRequest(bufio.NewReader(conn)) - if err != nil { - glog.V(LWARNING).Infoln("[http]", err) - return - } - NewHttpServer(conn, s).HandleRequest(req) - return - case "socks", "socks5": - conn = gosocks5.ServerConn(conn, s.selector) - req, err := gosocks5.ReadRequest(conn) - if err != nil { - glog.V(LWARNING).Infoln("[socks5]", err) - return - } - NewSocks5Server(conn, s).HandleRequest(req) - return - case "socks4", "socks4a": - req, err := gosocks4.ReadRequest(conn) - if err != nil { - glog.V(LWARNING).Infoln("[socks4]", err) - return - } - NewSocks4Server(conn, s).HandleRequest(req) - return - } - - br := bufio.NewReader(conn) - b, err := br.Peek(1) - if err != nil { - glog.V(LWARNING).Infoln(err) - return - } - - switch b[0] { - case gosocks4.Ver4: - req, err := gosocks4.ReadRequest(br) - if err != nil { - glog.V(LWARNING).Infoln("[socks4]", err) - return - } - NewSocks4Server(conn, s).HandleRequest(req) - - case gosocks5.Ver5: - methods, err := gosocks5.ReadMethods(br) - if err != nil { - glog.V(LWARNING).Infoln("[socks5]", err) - return - } - method := s.selector.Select(methods...) - if _, err := conn.Write([]byte{gosocks5.Ver5, method}); err != nil { - glog.V(LWARNING).Infoln("[socks5] select:", err) - return - } - c, err := s.selector.OnSelected(method, conn) - if err != nil { - glog.V(LWARNING).Infoln("[socks5] onselected:", err) - return - } - conn = c - - req, err := gosocks5.ReadRequest(conn) - if err != nil { - glog.V(LWARNING).Infoln("[socks5] request:", err) - return - } - NewSocks5Server(conn, s).HandleRequest(req) - - default: // http - req, err := http.ReadRequest(br) - if err != nil { - glog.V(LWARNING).Infoln("[http]", err) - return - } - NewHttpServer(conn, s).HandleRequest(req) - } -} - -func (_ *ProxyServer) transport(conn1, conn2 net.Conn) (err error) { - errc := make(chan error, 2) - - go func() { - _, err := io.Copy(conn1, conn2) - errc <- err - }() - - go func() { - _, err := io.Copy(conn2, conn1) - errc <- err - }() - - select { - case err = <-errc: - // glog.V(LWARNING).Infoln("transport exit", err) - } - - return -} diff --git a/vendor/github.com/ginuerzh/gost/signal.go b/vendor/github.com/ginuerzh/gost/signal.go deleted file mode 100644 index f12e902..0000000 --- a/vendor/github.com/ginuerzh/gost/signal.go +++ /dev/null @@ -1,5 +0,0 @@ -// +build windows - -package gost - -func kcpSigHandler() {} diff --git a/vendor/github.com/ginuerzh/gost/signal_unix.go b/vendor/github.com/ginuerzh/gost/signal_unix.go deleted file mode 100644 index f46b394..0000000 --- a/vendor/github.com/ginuerzh/gost/signal_unix.go +++ /dev/null @@ -1,23 +0,0 @@ -// +build !windows - -package gost - -import ( - "github.com/golang/glog" - "gopkg.in/xtaci/kcp-go.v2" - "os" - "os/signal" - "syscall" -) - -func kcpSigHandler() { - ch := make(chan os.Signal, 1) - signal.Notify(ch, syscall.SIGUSR1) - - for { - switch <-ch { - case syscall.SIGUSR1: - glog.V(LINFO).Infof("[kcp] SNMP: %+v", kcp.DefaultSnmp.Copy()) - } - } -} diff --git a/vendor/github.com/ginuerzh/gost/socks.go b/vendor/github.com/ginuerzh/gost/socks.go deleted file mode 100644 index 7727286..0000000 --- a/vendor/github.com/ginuerzh/gost/socks.go +++ /dev/null @@ -1,746 +0,0 @@ -package gost - -import ( - "bytes" - "crypto/tls" - "github.com/ginuerzh/gosocks4" - "github.com/ginuerzh/gosocks5" - "github.com/golang/glog" - "net" - "net/url" - "strconv" - "time" -) - -const ( - MethodTLS uint8 = 0x80 // extended method for tls - MethodTLSAuth uint8 = 0x82 // extended method for tls+auth -) - -const ( - CmdUdpTun uint8 = 0xF3 // extended method for udp over tcp -) - -type clientSelector struct { - methods []uint8 - user *url.Userinfo - tlsConfig *tls.Config -} - -func (selector *clientSelector) Methods() []uint8 { - return selector.methods -} - -func (selector *clientSelector) Select(methods ...uint8) (method uint8) { - return -} - -func (selector *clientSelector) OnSelected(method uint8, conn net.Conn) (net.Conn, error) { - switch method { - case MethodTLS: - conn = tls.Client(conn, selector.tlsConfig) - - case gosocks5.MethodUserPass, MethodTLSAuth: - if method == MethodTLSAuth { - conn = tls.Client(conn, selector.tlsConfig) - } - - var username, password string - if selector.user != nil { - username = selector.user.Username() - password, _ = selector.user.Password() - } - - req := gosocks5.NewUserPassRequest(gosocks5.UserPassVer, username, password) - if err := req.Write(conn); err != nil { - glog.V(LWARNING).Infoln("socks5 auth:", err) - return nil, err - } - glog.V(LDEBUG).Infoln(req) - - resp, err := gosocks5.ReadUserPassResponse(conn) - if err != nil { - glog.V(LWARNING).Infoln("socks5 auth:", err) - return nil, err - } - glog.V(LDEBUG).Infoln(resp) - - if resp.Status != gosocks5.Succeeded { - return nil, gosocks5.ErrAuthFailure - } - case gosocks5.MethodNoAcceptable: - return nil, gosocks5.ErrBadMethod - } - - return conn, nil -} - -type serverSelector struct { - methods []uint8 - users []*url.Userinfo - tlsConfig *tls.Config -} - -func (selector *serverSelector) Methods() []uint8 { - return selector.methods -} - -func (selector *serverSelector) Select(methods ...uint8) (method uint8) { - glog.V(LDEBUG).Infof("%d %d %v", gosocks5.Ver5, len(methods), methods) - - method = gosocks5.MethodNoAuth - for _, m := range methods { - if m == MethodTLS { - method = m - break - } - } - - // when user/pass is set, auth is mandatory - if selector.users != nil { - if method == gosocks5.MethodNoAuth { - method = gosocks5.MethodUserPass - } - if method == MethodTLS { - method = MethodTLSAuth - } - } - - return -} - -func (selector *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Conn, error) { - glog.V(LDEBUG).Infof("%d %d", gosocks5.Ver5, method) - - switch method { - case MethodTLS: - conn = tls.Server(conn, selector.tlsConfig) - - case gosocks5.MethodUserPass, MethodTLSAuth: - if method == MethodTLSAuth { - conn = tls.Server(conn, selector.tlsConfig) - } - - req, err := gosocks5.ReadUserPassRequest(conn) - if err != nil { - glog.V(LWARNING).Infoln("[socks5-auth]", err) - return nil, err - } - glog.V(LDEBUG).Infoln("[socks5]", req.String()) - - valid := false - for _, user := range selector.users { - username := user.Username() - password, _ := user.Password() - if (req.Username == username && req.Password == password) || - (req.Username == username && password == "") || - (username == "" && req.Password == password) { - valid = true - break - } - } - if len(selector.users) > 0 && !valid { - resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Failure) - if err := resp.Write(conn); err != nil { - glog.V(LWARNING).Infoln("[socks5-auth]", err) - return nil, err - } - glog.V(LDEBUG).Infoln("[socks5]", resp) - glog.V(LWARNING).Infoln("[socks5-auth] proxy authentication required") - - return nil, gosocks5.ErrAuthFailure - } - - resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Succeeded) - if err := resp.Write(conn); err != nil { - glog.V(LWARNING).Infoln("[socks5-auth]", err) - return nil, err - } - glog.V(LDEBUG).Infoln(resp) - - case gosocks5.MethodNoAcceptable: - return nil, gosocks5.ErrBadMethod - } - - return conn, nil -} - -type Socks5Server struct { - conn net.Conn - Base *ProxyServer -} - -func NewSocks5Server(conn net.Conn, base *ProxyServer) *Socks5Server { - return &Socks5Server{conn: conn, Base: base} -} - -func (s *Socks5Server) HandleRequest(req *gosocks5.Request) { - glog.V(LDEBUG).Infof("[socks5] %s -> %s\n%s", s.conn.RemoteAddr(), req.Addr, req) - - switch req.Cmd { - case gosocks5.CmdConnect: - glog.V(LINFO).Infof("[socks5-connect] %s -> %s", s.conn.RemoteAddr(), req.Addr) - s.handleConnect(req) - - case gosocks5.CmdBind: - glog.V(LINFO).Infof("[socks5-bind] %s - %s", s.conn.RemoteAddr(), req.Addr) - s.handleBind(req) - - case gosocks5.CmdUdp: - glog.V(LINFO).Infof("[socks5-udp] %s - %s", s.conn.RemoteAddr(), req.Addr) - s.handleUDPRelay(req) - - case CmdUdpTun: - glog.V(LINFO).Infof("[socks5-udp] %s - %s", s.conn.RemoteAddr(), req.Addr) - s.handleUDPTunnel(req) - - default: - glog.V(LWARNING).Infoln("[socks5] Unrecognized request:", req.Cmd) - } -} - -func (s *Socks5Server) handleConnect(req *gosocks5.Request) { - cc, err := s.Base.Chain.Dial(req.Addr.String()) - if err != nil { - glog.V(LWARNING).Infof("[socks5-connect] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err) - rep := gosocks5.NewReply(gosocks5.HostUnreachable, nil) - rep.Write(s.conn) - glog.V(LDEBUG).Infof("[socks5-connect] %s <- %s\n%s", s.conn.RemoteAddr(), req.Addr, rep) - return - } - defer cc.Close() - - rep := gosocks5.NewReply(gosocks5.Succeeded, nil) - if err := rep.Write(s.conn); err != nil { - glog.V(LWARNING).Infof("[socks5-connect] %s <- %s : %s", s.conn.RemoteAddr(), req.Addr, err) - return - } - glog.V(LDEBUG).Infof("[socks5-connect] %s <- %s\n%s", s.conn.RemoteAddr(), req.Addr, rep) - - glog.V(LINFO).Infof("[socks5-connect] %s <-> %s", s.conn.RemoteAddr(), req.Addr) - //Transport(conn, cc) - s.Base.transport(s.conn, cc) - glog.V(LINFO).Infof("[socks5-connect] %s >-< %s", s.conn.RemoteAddr(), req.Addr) -} - -func (s *Socks5Server) handleBind(req *gosocks5.Request) { - cc, err := s.Base.Chain.GetConn() - - // connection error - if err != nil && err != ErrEmptyChain { - glog.V(LWARNING).Infof("[socks5-bind] %s <- %s : %s", s.conn.RemoteAddr(), req.Addr, err) - reply := gosocks5.NewReply(gosocks5.Failure, nil) - reply.Write(s.conn) - glog.V(LDEBUG).Infof("[socks5-bind] %s <- %s\n%s", s.conn.RemoteAddr(), req.Addr, reply) - return - } - // serve socks5 bind - if err == ErrEmptyChain { - s.bindOn(req.Addr.String()) - return - } - - defer cc.Close() - // forward request - req.Write(cc) - - glog.V(LINFO).Infof("[socks5-bind] %s <-> %s", s.conn.RemoteAddr(), cc.RemoteAddr()) - s.Base.transport(s.conn, cc) - glog.V(LINFO).Infof("[socks5-bind] %s >-< %s", s.conn.RemoteAddr(), cc.RemoteAddr()) -} - -func (s *Socks5Server) handleUDPRelay(req *gosocks5.Request) { - bindAddr, _ := net.ResolveUDPAddr("udp", req.Addr.String()) - relay, err := net.ListenUDP("udp", bindAddr) // udp associate, strict mode: if the port already in use, it will return error - if err != nil { - glog.V(LWARNING).Infof("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err) - reply := gosocks5.NewReply(gosocks5.Failure, nil) - reply.Write(s.conn) - glog.V(LDEBUG).Infof("[socks5-udp] %s <- %s\n%s", s.conn.RemoteAddr(), req.Addr, reply) - return - } - defer relay.Close() - - socksAddr := ToSocksAddr(relay.LocalAddr()) - socksAddr.Host, _, _ = net.SplitHostPort(s.conn.LocalAddr().String()) - reply := gosocks5.NewReply(gosocks5.Succeeded, socksAddr) - if err := reply.Write(s.conn); err != nil { - glog.V(LWARNING).Infof("[socks5-udp] %s <- %s : %s", s.conn.RemoteAddr(), req.Addr, err) - return - } - glog.V(LDEBUG).Infof("[socks5-udp] %s <- %s\n%s", s.conn.RemoteAddr(), reply.Addr, reply) - glog.V(LINFO).Infof("[socks5-udp] %s - %s BIND ON %s OK", s.conn.RemoteAddr(), req.Addr, socksAddr) - - cc, err := s.Base.Chain.GetConn() - // connection error - if err != nil && err != ErrEmptyChain { - glog.V(LWARNING).Infof("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), socksAddr, err) - return - } - - // serve as standard socks5 udp relay local <-> remote - if err == ErrEmptyChain { - peer, er := net.ListenUDP("udp", nil) - if er != nil { - glog.V(LWARNING).Infof("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), socksAddr, er) - return - } - defer peer.Close() - - go s.transportUDP(relay, peer) - } - - // forward udp local <-> tunnel - if err == nil { - defer cc.Close() - - cc.SetWriteDeadline(time.Now().Add(WriteTimeout)) - req := gosocks5.NewRequest(CmdUdpTun, nil) - if err := req.Write(cc); err != nil { - glog.V(LWARNING).Infoln("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), cc.RemoteAddr(), err) - return - } - cc.SetWriteDeadline(time.Time{}) - glog.V(LDEBUG).Infof("[socks5-udp] %s -> %s\n%s", s.conn.RemoteAddr(), cc.RemoteAddr(), req) - - cc.SetReadDeadline(time.Now().Add(ReadTimeout)) - reply, err = gosocks5.ReadReply(cc) - if err != nil { - glog.V(LWARNING).Infoln("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), cc.RemoteAddr(), err) - return - } - glog.V(LDEBUG).Infof("[socks5-udp] %s <- %s\n%s", s.conn.RemoteAddr(), cc.RemoteAddr(), reply) - - if reply.Rep != gosocks5.Succeeded { - glog.V(LWARNING).Infoln("[socks5-udp] %s <- %s : udp associate failed", s.conn.RemoteAddr(), cc.RemoteAddr()) - return - } - cc.SetReadDeadline(time.Time{}) - glog.V(LINFO).Infof("[socks5-udp] %s <-> %s [tun: %s]", s.conn.RemoteAddr(), socksAddr, reply.Addr) - - go s.tunnelClientUDP(relay, cc) - } - - glog.V(LINFO).Infof("[socks5-udp] %s <-> %s", s.conn.RemoteAddr(), socksAddr) - b := make([]byte, SmallBufferSize) - for { - _, err := s.conn.Read(b) // discard any data from tcp connection - if err != nil { - glog.V(LWARNING).Infof("[socks5-udp] %s - %s : %s", s.conn.RemoteAddr(), socksAddr, err) - break // client disconnected - } - } - glog.V(LINFO).Infof("[socks5-udp] %s >-< %s", s.conn.RemoteAddr(), socksAddr) -} - -func (s *Socks5Server) handleUDPTunnel(req *gosocks5.Request) { - cc, err := s.Base.Chain.GetConn() - - // connection error - if err != nil && err != ErrEmptyChain { - glog.V(LWARNING).Infof("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err) - reply := gosocks5.NewReply(gosocks5.Failure, nil) - reply.Write(s.conn) - glog.V(LDEBUG).Infof("[socks5-udp] %s -> %s\n%s", s.conn.RemoteAddr(), req.Addr, reply) - return - } - - // serve tunnel udp, tunnel <-> remote, handle tunnel udp request - if err == ErrEmptyChain { - bindAddr, _ := net.ResolveUDPAddr("udp", req.Addr.String()) - uc, err := net.ListenUDP("udp", bindAddr) - if err != nil { - glog.V(LWARNING).Infof("[socks5-udp] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err) - return - } - defer uc.Close() - - socksAddr := ToSocksAddr(uc.LocalAddr()) - socksAddr.Host, _, _ = net.SplitHostPort(s.conn.LocalAddr().String()) - reply := gosocks5.NewReply(gosocks5.Succeeded, socksAddr) - if err := reply.Write(s.conn); err != nil { - glog.V(LWARNING).Infof("[socks5-udp] %s <- %s : %s", s.conn.RemoteAddr(), socksAddr, err) - return - } - glog.V(LDEBUG).Infof("[socks5-udp] %s <- %s\n%s", s.conn.RemoteAddr(), socksAddr, reply) - - glog.V(LINFO).Infof("[socks5-udp] %s <-> %s", s.conn.RemoteAddr(), socksAddr) - s.tunnelServerUDP(s.conn, uc) - glog.V(LINFO).Infof("[socks5-udp] %s >-< %s", s.conn.RemoteAddr(), socksAddr) - return - } - - defer cc.Close() - - // tunnel <-> tunnel, direct forwarding - req.Write(cc) - - glog.V(LINFO).Infof("[socks5-udp] %s <-> %s [tun]", s.conn.RemoteAddr(), cc.RemoteAddr()) - s.Base.transport(s.conn, cc) - glog.V(LINFO).Infof("[socks5-udp] %s >-< %s [tun]", s.conn.RemoteAddr(), cc.RemoteAddr()) -} - -func (s *Socks5Server) bindOn(addr string) { - bindAddr, _ := net.ResolveTCPAddr("tcp", addr) - ln, err := net.ListenTCP("tcp", bindAddr) // strict mode: if the port already in use, it will return error - if err != nil { - glog.V(LWARNING).Infof("[socks5-bind] %s -> %s : %s", s.conn.RemoteAddr(), addr, err) - gosocks5.NewReply(gosocks5.Failure, nil).Write(s.conn) - return - } - - socksAddr := ToSocksAddr(ln.Addr()) - // Issue: may not reachable when host has multi-interface - socksAddr.Host, _, _ = net.SplitHostPort(s.conn.LocalAddr().String()) - reply := gosocks5.NewReply(gosocks5.Succeeded, socksAddr) - if err := reply.Write(s.conn); err != nil { - glog.V(LWARNING).Infof("[socks5-bind] %s <- %s : %s", s.conn.RemoteAddr(), addr, err) - ln.Close() - return - } - glog.V(LDEBUG).Infof("[socks5-bind] %s <- %s\n%s", s.conn.RemoteAddr(), addr, reply) - glog.V(LINFO).Infof("[socks5-bind] %s - %s BIND ON %s OK", s.conn.RemoteAddr(), addr, socksAddr) - - var pconn net.Conn - accept := func() <-chan error { - errc := make(chan error, 1) - - go func() { - defer close(errc) - defer ln.Close() - - c, err := ln.AcceptTCP() - if err != nil { - errc <- err - return - } - pconn = c - }() - - return errc - } - - pc1, pc2 := net.Pipe() - pipe := func() <-chan error { - errc := make(chan error, 1) - - go func() { - defer close(errc) - defer pc1.Close() - - errc <- s.Base.transport(s.conn, pc1) - }() - - return errc - } - - defer pc2.Close() - - for { - select { - case err := <-accept(): - if err != nil || pconn == nil { - glog.V(LWARNING).Infof("[socks5-bind] %s <- %s : %s", s.conn.RemoteAddr(), addr, err) - return - } - defer pconn.Close() - - reply := gosocks5.NewReply(gosocks5.Succeeded, ToSocksAddr(pconn.RemoteAddr())) - if err := reply.Write(pc2); err != nil { - glog.V(LWARNING).Infof("[socks5-bind] %s <- %s : %s", s.conn.RemoteAddr(), addr, err) - } - glog.V(LDEBUG).Infof("[socks5-bind] %s <- %s\n%s", s.conn.RemoteAddr(), addr, reply) - glog.V(LINFO).Infof("[socks5-bind] %s <- %s PEER %s ACCEPTED", s.conn.RemoteAddr(), socksAddr, pconn.RemoteAddr()) - - glog.V(LINFO).Infof("[socks5-bind] %s <-> %s", s.conn.RemoteAddr(), pconn.RemoteAddr()) - if err = s.Base.transport(pc2, pconn); err != nil { - glog.V(LWARNING).Infoln(err) - } - glog.V(LINFO).Infof("[socks5-bind] %s >-< %s", s.conn.RemoteAddr(), pconn.RemoteAddr()) - return - case err := <-pipe(): - glog.V(LWARNING).Infof("[socks5-bind] %s -> %s : %v", s.conn.RemoteAddr(), addr, err) - ln.Close() - return - } - } -} - -func (s *Socks5Server) transportUDP(relay, peer *net.UDPConn) (err error) { - errc := make(chan error, 2) - - var clientAddr *net.UDPAddr - - go func() { - b := make([]byte, LargeBufferSize) - - for { - n, laddr, err := relay.ReadFromUDP(b) - if err != nil { - errc <- err - return - } - if clientAddr == nil { - clientAddr = laddr - } - dgram, err := gosocks5.ReadUDPDatagram(bytes.NewReader(b[:n])) - if err != nil { - errc <- err - return - } - - raddr, err := net.ResolveUDPAddr("udp", dgram.Header.Addr.String()) - if err != nil { - continue // drop silently - } - if _, err := peer.WriteToUDP(dgram.Data, raddr); err != nil { - errc <- err - return - } - glog.V(LDEBUG).Infof("[socks5-udp] %s >>> %s length: %d", relay.LocalAddr(), raddr, len(dgram.Data)) - } - }() - - go func() { - b := make([]byte, LargeBufferSize) - - for { - n, raddr, err := peer.ReadFromUDP(b) - if err != nil { - errc <- err - return - } - if clientAddr == nil { - continue - } - buf := bytes.Buffer{} - dgram := gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(0, 0, ToSocksAddr(raddr)), b[:n]) - dgram.Write(&buf) - if _, err := relay.WriteToUDP(buf.Bytes(), clientAddr); err != nil { - errc <- err - return - } - glog.V(LDEBUG).Infof("[socks5-udp] %s <<< %s length: %d", relay.LocalAddr(), raddr, len(dgram.Data)) - } - }() - - select { - case err = <-errc: - //log.Println("w exit", err) - } - - return -} - -func (s *Socks5Server) tunnelClientUDP(uc *net.UDPConn, cc net.Conn) (err error) { - errc := make(chan error, 2) - - var clientAddr *net.UDPAddr - - go func() { - b := make([]byte, LargeBufferSize) - - for { - n, addr, err := uc.ReadFromUDP(b) - if err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s <- %s : %s", cc.RemoteAddr(), addr, err) - errc <- err - return - } - - // glog.V(LDEBUG).Infof("read udp %d, % #x", n, b[:n]) - // pipe from relay to tunnel - dgram, err := gosocks5.ReadUDPDatagram(bytes.NewReader(b[:n])) - if err != nil { - errc <- err - return - } - if clientAddr == nil { - clientAddr = addr - } - dgram.Header.Rsv = uint16(len(dgram.Data)) - if err := dgram.Write(cc); err != nil { - errc <- err - return - } - glog.V(LDEBUG).Infof("[udp-tun] %s >>> %s length: %d", uc.LocalAddr(), dgram.Header.Addr, len(dgram.Data)) - } - }() - - go func() { - for { - dgram, err := gosocks5.ReadUDPDatagram(cc) - if err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s -> 0 : %s", cc.RemoteAddr(), err) - errc <- err - return - } - - // pipe from tunnel to relay - if clientAddr == nil { - continue - } - dgram.Header.Rsv = 0 - - buf := bytes.Buffer{} - dgram.Write(&buf) - if _, err := uc.WriteToUDP(buf.Bytes(), clientAddr); err != nil { - errc <- err - return - } - glog.V(LDEBUG).Infof("[udp-tun] %s <<< %s length: %d", uc.LocalAddr(), dgram.Header.Addr, len(dgram.Data)) - } - }() - - select { - case err = <-errc: - } - - return -} - -func (s *Socks5Server) tunnelServerUDP(cc net.Conn, uc *net.UDPConn) (err error) { - errc := make(chan error, 2) - - go func() { - b := make([]byte, LargeBufferSize) - - for { - n, addr, err := uc.ReadFromUDP(b) - if err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s <- %s : %s", cc.RemoteAddr(), addr, err) - errc <- err - return - } - - // pipe from peer to tunnel - dgram := gosocks5.NewUDPDatagram( - gosocks5.NewUDPHeader(uint16(n), 0, ToSocksAddr(addr)), b[:n]) - if err := dgram.Write(cc); err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s <- %s : %s", cc.RemoteAddr(), dgram.Header.Addr, err) - errc <- err - return - } - glog.V(LDEBUG).Infof("[udp-tun] %s <<< %s length: %d", cc.RemoteAddr(), dgram.Header.Addr, len(dgram.Data)) - } - }() - - go func() { - for { - dgram, err := gosocks5.ReadUDPDatagram(cc) - if err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s -> 0 : %s", cc.RemoteAddr(), err) - errc <- err - return - } - - // pipe from tunnel to peer - addr, err := net.ResolveUDPAddr("udp", dgram.Header.Addr.String()) - if err != nil { - continue // drop silently - } - if _, err := uc.WriteToUDP(dgram.Data, addr); err != nil { - glog.V(LWARNING).Infof("[udp-tun] %s -> %s : %s", cc.RemoteAddr(), addr, err) - errc <- err - return - } - glog.V(LDEBUG).Infof("[udp-tun] %s >>> %s length: %d", cc.RemoteAddr(), addr, len(dgram.Data)) - } - }() - - select { - case err = <-errc: - } - - return -} - -func ToSocksAddr(addr net.Addr) *gosocks5.Addr { - host := "0.0.0.0" - port := 0 - if addr != nil { - h, p, _ := net.SplitHostPort(addr.String()) - host = h - port, _ = strconv.Atoi(p) - } - return &gosocks5.Addr{ - Type: gosocks5.AddrIPv4, - Host: host, - Port: uint16(port), - } -} - -type Socks4Server struct { - conn net.Conn - Base *ProxyServer -} - -func NewSocks4Server(conn net.Conn, base *ProxyServer) *Socks4Server { - return &Socks4Server{conn: conn, Base: base} -} - -func (s *Socks4Server) HandleRequest(req *gosocks4.Request) { - glog.V(LDEBUG).Infof("[socks4] %s -> %s\n%s", s.conn.RemoteAddr(), req.Addr, req) - - switch req.Cmd { - case gosocks4.CmdConnect: - glog.V(LINFO).Infof("[socks4-connect] %s -> %s", s.conn.RemoteAddr(), req.Addr) - s.handleConnect(req) - - case gosocks4.CmdBind: - glog.V(LINFO).Infof("[socks4-bind] %s - %s", s.conn.RemoteAddr(), req.Addr) - s.handleBind(req) - - default: - glog.V(LWARNING).Infoln("[socks4] Unrecognized request:", req.Cmd) - } -} - -func (s *Socks4Server) handleConnect(req *gosocks4.Request) { - cc, err := s.Base.Chain.Dial(req.Addr.String()) - if err != nil { - glog.V(LWARNING).Infof("[socks4-connect] %s -> %s : %s", s.conn.RemoteAddr(), req.Addr, err) - rep := gosocks4.NewReply(gosocks4.Failed, nil) - rep.Write(s.conn) - glog.V(LDEBUG).Infof("[socks4-connect] %s <- %s\n%s", s.conn.RemoteAddr(), req.Addr, rep) - return - } - defer cc.Close() - - rep := gosocks4.NewReply(gosocks4.Granted, nil) - if err := rep.Write(s.conn); err != nil { - glog.V(LWARNING).Infof("[socks4-connect] %s <- %s : %s", s.conn.RemoteAddr(), req.Addr, err) - return - } - glog.V(LDEBUG).Infof("[socks4-connect] %s <- %s\n%s", s.conn.RemoteAddr(), req.Addr, rep) - - glog.V(LINFO).Infof("[socks4-connect] %s <-> %s", s.conn.RemoteAddr(), req.Addr) - s.Base.transport(s.conn, cc) - glog.V(LINFO).Infof("[socks4-connect] %s >-< %s", s.conn.RemoteAddr(), req.Addr) -} - -func (s *Socks4Server) handleBind(req *gosocks4.Request) { - cc, err := s.Base.Chain.GetConn() - - // connection error - if err != nil && err != ErrEmptyChain { - glog.V(LWARNING).Infof("[socks4-bind] %s <- %s : %s", s.conn.RemoteAddr(), req.Addr, err) - reply := gosocks4.NewReply(gosocks4.Failed, nil) - reply.Write(s.conn) - glog.V(LDEBUG).Infof("[socks4-bind] %s <- %s\n%s", s.conn.RemoteAddr(), req.Addr, reply) - return - } - // TODO: serve socks4 bind - if err == ErrEmptyChain { - //s.bindOn(req.Addr.String()) - return - } - - defer cc.Close() - // forward request - req.Write(cc) - - glog.V(LINFO).Infof("[socks4-bind] %s <-> %s", s.conn.RemoteAddr(), cc.RemoteAddr()) - s.Base.transport(s.conn, cc) - glog.V(LINFO).Infof("[socks4-bind] %s >-< %s", s.conn.RemoteAddr(), cc.RemoteAddr()) -} diff --git a/vendor/github.com/ginuerzh/gost/ss.go b/vendor/github.com/ginuerzh/gost/ss.go deleted file mode 100644 index cf5eb47..0000000 --- a/vendor/github.com/ginuerzh/gost/ss.go +++ /dev/null @@ -1,353 +0,0 @@ -package gost - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "github.com/ginuerzh/gosocks5" - "github.com/golang/glog" - ss "github.com/shadowsocks/shadowsocks-go/shadowsocks" - "io" - "net" - "strconv" - "time" -) - -const ( - idType = 0 // address type index - idIP0 = 1 // ip addres start index - idDmLen = 1 // domain address length index - idDm0 = 2 // domain address start index - - typeIPv4 = 1 // type is ipv4 address - typeDm = 3 // type is domain address - typeIPv6 = 4 // type is ipv6 address - - lenIPv4 = net.IPv4len + 2 // ipv4 + 2port - lenIPv6 = net.IPv6len + 2 // ipv6 + 2port - lenDmBase = 2 // 1addrLen + 2port, plus addrLen - lenHmacSha1 = 10 -) - -type ShadowServer struct { - conn *ss.Conn - Base *ProxyServer - OTA bool // one time auth -} - -func NewShadowServer(conn *ss.Conn, base *ProxyServer) *ShadowServer { - return &ShadowServer{conn: conn, Base: base} -} - -func (s *ShadowServer) Serve() { - glog.V(LINFO).Infof("[ss] %s - %s", s.conn.RemoteAddr(), s.conn.LocalAddr()) - - addr, ota, err := s.getRequest() - if err != nil { - glog.V(LWARNING).Infof("[ss] %s - %s : %s", s.conn.RemoteAddr(), s.conn.LocalAddr(), err) - return - } - glog.V(LINFO).Infof("[ss] %s -> %s, ota: %v", s.conn.RemoteAddr(), addr, ota) - - cc, err := s.Base.Chain.Dial(addr) - if err != nil { - glog.V(LWARNING).Infof("[ss] %s -> %s : %s", s.conn.RemoteAddr(), addr, err) - return - } - defer cc.Close() - - glog.V(LINFO).Infof("[ss] %s <-> %s", s.conn.RemoteAddr(), addr) - if ota { - s.transportOTA(s.conn, cc) - } else { - s.Base.transport(&shadowConn{conn: s.conn}, cc) - } - glog.V(LINFO).Infof("[ss] %s >-< %s", s.conn.RemoteAddr(), addr) -} - -// This function is copied from shadowsocks library with some modification. -func (s *ShadowServer) getRequest() (host string, ota bool, err error) { - // buf size should at least have the same size with the largest possible - // request size (when addrType is 3, domain name has at most 256 bytes) - // 1(addrType) + 1(lenByte) + 256(max length address) + 2(port) - buf := make([]byte, SmallBufferSize) - - // read till we get possible domain length field - s.conn.SetReadDeadline(time.Now().Add(ReadTimeout)) - if _, err = io.ReadFull(s.conn, buf[:idType+1]); err != nil { - return - } - - var reqStart, reqEnd int - addrType := buf[idType] - switch addrType & ss.AddrMask { - case typeIPv4: - reqStart, reqEnd = idIP0, idIP0+lenIPv4 - case typeIPv6: - reqStart, reqEnd = idIP0, idIP0+lenIPv6 - case typeDm: - if _, err = io.ReadFull(s.conn, buf[idType+1:idDmLen+1]); err != nil { - return - } - reqStart, reqEnd = idDm0, int(idDm0+buf[idDmLen]+lenDmBase) - default: - err = fmt.Errorf("addr type %d not supported", addrType&ss.AddrMask) - return - } - - if _, err = io.ReadFull(s.conn, buf[reqStart:reqEnd]); err != nil { - return - } - - // Return string for typeIP is not most efficient, but browsers (Chrome, - // Safari, Firefox) all seems using typeDm exclusively. So this is not a - // big problem. - switch addrType & ss.AddrMask { - case typeIPv4: - host = net.IP(buf[idIP0 : idIP0+net.IPv4len]).String() - case typeIPv6: - host = net.IP(buf[idIP0 : idIP0+net.IPv6len]).String() - case typeDm: - host = string(buf[idDm0 : idDm0+buf[idDmLen]]) - } - // parse port - port := binary.BigEndian.Uint16(buf[reqEnd-2 : reqEnd]) - host = net.JoinHostPort(host, strconv.Itoa(int(port))) - // if specified one time auth enabled, we should verify this - if s.OTA || addrType&ss.OneTimeAuthMask > 0 { - ota = true - if _, err = io.ReadFull(s.conn, buf[reqEnd:reqEnd+lenHmacSha1]); err != nil { - return - } - iv := s.conn.GetIv() - key := s.conn.GetKey() - actualHmacSha1Buf := ss.HmacSha1(append(iv, key...), buf[:reqEnd]) - if !bytes.Equal(buf[reqEnd:reqEnd+lenHmacSha1], actualHmacSha1Buf) { - err = fmt.Errorf("verify one time auth failed, iv=%v key=%v data=%v", iv, key, buf[:reqEnd]) - return - } - } - return -} - -const ( - dataLenLen = 2 - hmacSha1Len = 10 - idxData0 = dataLenLen + hmacSha1Len -) - -// copyOta copies data from src to dst with ota verification. -// -// This function is copied from shadowsocks library with some modification. -func (s *ShadowServer) copyOta(dst net.Conn, src *ss.Conn) (int64, error) { - // sometimes it have to fill large block - buf := make([]byte, LargeBufferSize) - for { - src.SetReadDeadline(time.Now().Add(ReadTimeout)) - if n, err := io.ReadFull(src, buf[:dataLenLen+hmacSha1Len]); err != nil { - return int64(n), err - } - src.SetReadDeadline(time.Time{}) - - dataLen := binary.BigEndian.Uint16(buf[:dataLenLen]) - expectedHmacSha1 := buf[dataLenLen:idxData0] - - var dataBuf []byte - if len(buf) < int(idxData0+dataLen) { - dataBuf = make([]byte, dataLen) - } else { - dataBuf = buf[idxData0 : idxData0+dataLen] - } - if n, err := io.ReadFull(src, dataBuf); err != nil { - return int64(n), err - } - chunkIdBytes := make([]byte, 4) - chunkId := src.GetAndIncrChunkId() - binary.BigEndian.PutUint32(chunkIdBytes, chunkId) - actualHmacSha1 := ss.HmacSha1(append(src.GetIv(), chunkIdBytes...), dataBuf) - if !bytes.Equal(expectedHmacSha1, actualHmacSha1) { - return 0, errors.New("ota error: mismatch") - } - - if n, err := dst.Write(dataBuf); err != nil { - return int64(n), err - } - } -} - -func (s *ShadowServer) transportOTA(sc *ss.Conn, cc net.Conn) (err error) { - errc := make(chan error, 2) - - go func() { - _, err := io.Copy(&shadowConn{conn: sc}, cc) - errc <- err - }() - - go func() { - _, err := s.copyOta(cc, sc) - errc <- err - }() - - select { - case err = <-errc: - //glog.V(LWARNING).Infoln("transport exit", err) - } - - return -} - -// Due to in/out byte length is inconsistent of the shadowsocks.Conn.Write, -// we wrap around it to make io.Copy happy -type shadowConn struct { - conn *ss.Conn -} - -func (c *shadowConn) Read(b []byte) (n int, err error) { - return c.conn.Read(b) -} - -func (c *shadowConn) Write(b []byte) (n int, err error) { - n = len(b) // force byte length consistent - _, err = c.conn.Write(b) - return -} - -func (c *shadowConn) Close() error { - return c.conn.Close() -} - -func (c *shadowConn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -func (c *shadowConn) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -func (c *shadowConn) SetDeadline(t time.Time) error { - return c.conn.SetDeadline(t) -} - -func (c *shadowConn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -func (c *shadowConn) SetWriteDeadline(t time.Time) error { - return c.conn.SetWriteDeadline(t) -} - -type ShadowUdpServer struct { - Base *ProxyServer - TTL int -} - -func NewShadowUdpServer(base *ProxyServer, ttl int) *ShadowUdpServer { - return &ShadowUdpServer{Base: base, TTL: ttl} -} - -func (s *ShadowUdpServer) ListenAndServe() error { - laddr, err := net.ResolveUDPAddr("udp", s.Base.Node.Addr) - if err != nil { - return err - } - lconn, err := net.ListenUDP("udp", laddr) - if err != nil { - return err - } - defer lconn.Close() - - conn := ss.NewSecurePacketConn(lconn, s.Base.cipher.Copy(), true) // force OTA on - - rChan, wChan := make(chan *packet, 128), make(chan *packet, 128) - // start send queue - go func(ch chan<- *packet) { - for { - b := make([]byte, MediumBufferSize) - n, addr, err := conn.ReadFrom(b[3:]) // add rsv and frag fields to make it the standard SOCKS5 UDP datagram - if err != nil { - glog.V(LWARNING).Infof("[ssu] %s -> %s : %s", addr, laddr, err) - continue - } - - b[3] &= ss.AddrMask // remove OTA flag - dgram, err := gosocks5.ReadUDPDatagram(bytes.NewReader(b[:n+3])) - if err != nil { - glog.V(LWARNING).Infof("[ssu] %s -> %s : %s", addr, laddr, err) - continue - } - - select { - case ch <- &packet{srcAddr: addr.String(), dstAddr: dgram.Header.Addr.String(), data: dgram.Data}: - case <-time.After(time.Second * 3): - glog.V(LWARNING).Infof("[ssu] %s -> %s : %s", addr, dgram.Header.Addr.String(), "send queue is full, discard") - } - } - }(wChan) - // start recv queue - go func(ch <-chan *packet) { - for pkt := range ch { - srcAddr, err := net.ResolveUDPAddr("udp", pkt.srcAddr) - if err != nil { - glog.V(LWARNING).Infof("[ssu] %s <- %s : %s", pkt.dstAddr, pkt.srcAddr, err) - continue - } - dstAddr, err := net.ResolveUDPAddr("udp", pkt.dstAddr) - if err != nil { - glog.V(LWARNING).Infof("[ssu] %s <- %s : %s", pkt.dstAddr, pkt.srcAddr, err) - continue - } - - dgram := gosocks5.NewUDPDatagram(gosocks5.NewUDPHeader(0, 0, ToSocksAddr(srcAddr)), pkt.data) - b := bytes.Buffer{} - dgram.Write(&b) - if b.Len() < 10 { - glog.V(LWARNING).Infof("[ssu] %s <- %s : invalid udp datagram", pkt.dstAddr, pkt.srcAddr) - continue - } - - if _, err := conn.WriteTo(b.Bytes()[3:], dstAddr); err != nil { // remove rsv and frag fields to make it standard shadowsocks UDP datagram - glog.V(LWARNING).Infof("[ssu] %s <- %s : %s", pkt.dstAddr, pkt.srcAddr, err) - return - } - } - }(rChan) - - // mapping client to node - m := make(map[string]*cnode) - - // start dispatcher - for pkt := range wChan { - // clear obsolete nodes - for k, node := range m { - if node != nil && node.err != nil { - close(node.wChan) - delete(m, k) - glog.V(LINFO).Infof("[ssu] clear node %s", k) - } - } - - node, ok := m[pkt.srcAddr] - if !ok { - node = &cnode{ - chain: s.Base.Chain, - srcAddr: pkt.srcAddr, - dstAddr: pkt.dstAddr, - rChan: rChan, - wChan: make(chan *packet, 32), - ttl: time.Duration(s.TTL) * time.Second, - } - m[pkt.srcAddr] = node - go node.run() - glog.V(LINFO).Infof("[ssu] %s -> %s : new client (%d)", pkt.srcAddr, pkt.dstAddr, len(m)) - } - - select { - case node.wChan <- pkt: - case <-time.After(time.Second * 3): - glog.V(LWARNING).Infof("[ssu] %s -> %s : %s", pkt.srcAddr, pkt.dstAddr, "node send queue is full, discard") - } - } - - return nil -} diff --git a/vendor/github.com/ginuerzh/gost/ssh.go b/vendor/github.com/ginuerzh/gost/ssh.go deleted file mode 100644 index 4a838ef..0000000 --- a/vendor/github.com/ginuerzh/gost/ssh.go +++ /dev/null @@ -1,236 +0,0 @@ -// The ssh tunnel is inspired by easyssh(https://dev.justinjudd.org/justin/easyssh) - -package gost - -import ( - "encoding/binary" - "fmt" - "github.com/golang/glog" - "golang.org/x/crypto/ssh" - "net" - "net/url" - "strconv" -) - -// Applicaple SSH Request types for Port Forwarding - RFC 4254 7.X -const ( - DirectForwardRequest = "direct-tcpip" // RFC 4254 7.2 - RemoteForwardRequest = "tcpip-forward" // RFC 4254 7.1 - ForwardedTCPReturnRequest = "forwarded-tcpip" // RFC 4254 7.2 - CancelRemoteForwardRequest = "cancel-tcpip-forward" // RFC 4254 7.1 -) - -type SSHServer struct { - Addr string - Base *ProxyServer - Config *ssh.ServerConfig - Handler func(ssh.Conn, <-chan ssh.NewChannel, <-chan *ssh.Request) -} - -func (s *SSHServer) ListenAndServe() error { - ln, err := net.Listen("tcp", s.Addr) - if err != nil { - glog.V(LWARNING).Infoln("[ssh] Listen:", err) - return err - } - defer ln.Close() - - for { - conn, err := ln.Accept() - if err != nil { - glog.V(LWARNING).Infoln("[ssh] Accept:", err) - return err - } - - go func(conn net.Conn) { - sshConn, chans, reqs, err := ssh.NewServerConn(conn, s.Config) - if err != nil { - glog.V(LWARNING).Infof("[ssh] %s -> %s : %s", conn.RemoteAddr(), s.Addr, err) - return - } - defer sshConn.Close() - - if s.Handler == nil { - s.Handler = s.handleSSHConn - } - - glog.V(LINFO).Infof("[ssh] %s <-> %s", conn.RemoteAddr(), s.Addr) - s.Handler(sshConn, chans, reqs) - glog.V(LINFO).Infof("[ssh] %s >-< %s", conn.RemoteAddr(), s.Addr) - }(conn) - } -} - -func (s *SSHServer) handleSSHConn(conn ssh.Conn, chans <-chan ssh.NewChannel, reqs <-chan *ssh.Request) { - quit := make(chan interface{}) - go func() { - for req := range reqs { - switch req.Type { - case RemoteForwardRequest: - go s.tcpipForwardRequest(conn, req, quit) - default: - // glog.V(LWARNING).Infoln("unknown channel type:", req.Type) - if req.WantReply { - req.Reply(false, nil) - } - } - } - }() - - go func() { - for newChannel := range chans { - // Check the type of channel - t := newChannel.ChannelType() - switch t { - case DirectForwardRequest: - channel, requests, err := newChannel.Accept() - if err != nil { - glog.V(LINFO).Infoln("[ssh] Could not accept channel:", err) - continue - } - p := directForward{} - ssh.Unmarshal(newChannel.ExtraData(), &p) - - go ssh.DiscardRequests(requests) - go s.directPortForwardChannel(channel, fmt.Sprintf("%s:%d", p.Host1, p.Port1)) - default: - glog.V(LWARNING).Infoln("[ssh] Unknown channel type:", t) - newChannel.Reject(ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %s", t)) - } - } - }() - - conn.Wait() - close(quit) -} - -// directForward is structure for RFC 4254 7.2 - can be used for "forwarded-tcpip" and "direct-tcpip" -type directForward struct { - Host1 string - Port1 uint32 - Host2 string - Port2 uint32 -} - -func (p directForward) String() string { - return fmt.Sprintf("%s:%d -> %s:%d", p.Host2, p.Port2, p.Host1, p.Port1) -} - -func (s *SSHServer) directPortForwardChannel(channel ssh.Channel, raddr string) { - defer channel.Close() - - glog.V(LINFO).Infof("[ssh-tcp] %s - %s", s.Addr, raddr) - - conn, err := s.Base.Chain.Dial(raddr) - if err != nil { - glog.V(LINFO).Infof("[ssh-tcp] %s - %s : %s", s.Addr, raddr, err) - return - } - defer conn.Close() - - glog.V(LINFO).Infof("[ssh-tcp] %s <-> %s", s.Addr, raddr) - Transport(conn, channel) - glog.V(LINFO).Infof("[ssh-tcp] %s >-< %s", s.Addr, raddr) -} - -// tcpipForward is structure for RFC 4254 7.1 "tcpip-forward" request -type tcpipForward struct { - Host string - Port uint32 -} - -func (s *SSHServer) tcpipForwardRequest(sshConn ssh.Conn, req *ssh.Request, quit <-chan interface{}) { - t := tcpipForward{} - ssh.Unmarshal(req.Payload, &t) - addr := fmt.Sprintf("%s:%d", t.Host, t.Port) - glog.V(LINFO).Infoln("[ssh-rtcp] listening tcp", addr) - ln, err := net.Listen("tcp", addr) //tie to the client connection - if err != nil { - glog.V(LWARNING).Infoln("[ssh-rtcp]", err) - req.Reply(false, nil) - return - } - defer ln.Close() - - replyFunc := func() error { - if t.Port == 0 && req.WantReply { // Client sent port 0. let them know which port is actually being used - _, port, err := getHostPortFromAddr(ln.Addr()) - if err != nil { - return err - } - var b [4]byte - binary.BigEndian.PutUint32(b[:], uint32(port)) - t.Port = uint32(port) - return req.Reply(true, b[:]) - } - return req.Reply(true, nil) - } - if err := replyFunc(); err != nil { - glog.V(LWARNING).Infoln("[ssh-rtcp]", err) - return - } - - go func() { - for { - conn, err := ln.Accept() - if err != nil { // Unable to accept new connection - listener likely closed - return - } - - go func(conn net.Conn) { - defer conn.Close() - - p := directForward{} - var err error - - var portnum int - p.Host1 = t.Host - p.Port1 = t.Port - p.Host2, portnum, err = getHostPortFromAddr(conn.RemoteAddr()) - if err != nil { - return - } - - p.Port2 = uint32(portnum) - ch, reqs, err := sshConn.OpenChannel(ForwardedTCPReturnRequest, ssh.Marshal(p)) - if err != nil { - glog.V(1).Infoln("[ssh-rtcp] open forwarded channel:", err) - return - } - defer ch.Close() - go ssh.DiscardRequests(reqs) - - glog.V(LINFO).Infof("[ssh-rtcp] %s <-> %s", conn.RemoteAddr(), conn.LocalAddr()) - Transport(ch, conn) - glog.V(LINFO).Infof("[ssh-rtcp] %s >-< %s", conn.RemoteAddr(), conn.LocalAddr()) - }(conn) - } - }() - - <-quit -} - -func getHostPortFromAddr(addr net.Addr) (host string, port int, err error) { - host, portString, err := net.SplitHostPort(addr.String()) - if err != nil { - return - } - port, err = strconv.Atoi(portString) - return -} - -type PasswordCallbackFunc func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) - -func DefaultPasswordCallback(users []*url.Userinfo) PasswordCallbackFunc { - return func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { - for _, user := range users { - u := user.Username() - p, _ := user.Password() - if u == conn.User() && p == string(password) { - return nil, nil - } - } - glog.V(LINFO).Infof("[ssh] %s -> %s : password rejected for %s", conn.RemoteAddr(), conn.LocalAddr(), conn.User()) - return nil, fmt.Errorf("password rejected for %s", conn.User()) - } -} diff --git a/vendor/github.com/ginuerzh/gost/ws.go b/vendor/github.com/ginuerzh/gost/ws.go deleted file mode 100644 index da902e6..0000000 --- a/vendor/github.com/ginuerzh/gost/ws.go +++ /dev/null @@ -1,142 +0,0 @@ -package gost - -import ( - "crypto/tls" - "github.com/golang/glog" - "gopkg.in/gorilla/websocket.v1" - "net" - "net/http" - "net/http/httputil" - "time" -) - -type WebsocketServer struct { - Addr string - Base *ProxyServer - Handler http.Handler - upgrader websocket.Upgrader -} - -func NewWebsocketServer(base *ProxyServer) *WebsocketServer { - return &WebsocketServer{ - Addr: base.Node.Addr, - Base: base, - upgrader: websocket.Upgrader{ - ReadBufferSize: 1024, - WriteBufferSize: 1024, - CheckOrigin: func(r *http.Request) bool { return true }, - EnableCompression: true, - }, - } -} - -// Default websocket server handler -func (s *WebsocketServer) HandleRequest(w http.ResponseWriter, r *http.Request) { - glog.V(LINFO).Infof("[ws] %s - %s", r.RemoteAddr, s.Addr) - if glog.V(LDEBUG) { - dump, _ := httputil.DumpRequest(r, false) - glog.V(LDEBUG).Infof("[ws] %s - %s\n%s", r.RemoteAddr, s.Addr, string(dump)) - } - conn, err := s.upgrader.Upgrade(w, r, nil) - if err != nil { - glog.V(LERROR).Infof("[ws] %s - %s : %s", r.RemoteAddr, s.Addr, err) - return - } - s.Base.handleConn(WebsocketServerConn(conn)) -} - -func (s *WebsocketServer) ListenAndServe() error { - mux := http.NewServeMux() - if s.Handler == nil { - s.Handler = http.HandlerFunc(s.HandleRequest) - } - mux.Handle("/ws", s.Handler) - return http.ListenAndServe(s.Addr, mux) -} - -func (s *WebsocketServer) ListenAndServeTLS(config *tls.Config) error { - mux := http.NewServeMux() - if s.Handler == nil { - s.Handler = http.HandlerFunc(s.HandleRequest) - } - mux.Handle("/ws", s.Handler) - server := &http.Server{ - Addr: s.Addr, - Handler: mux, - TLSConfig: config, - } - return server.ListenAndServeTLS("", "") -} - -type WebsocketConn struct { - conn *websocket.Conn - rb []byte -} - -func WebsocketClientConn(url string, conn net.Conn, config *tls.Config) (*WebsocketConn, error) { - dialer := websocket.Dialer{ - ReadBufferSize: 1024, - WriteBufferSize: 1024, - TLSClientConfig: config, - HandshakeTimeout: DialTimeout, - EnableCompression: true, - NetDial: func(net, addr string) (net.Conn, error) { - return conn, nil - }, - } - - c, resp, err := dialer.Dial(url, nil) - if err != nil { - return nil, err - } - resp.Body.Close() - return &WebsocketConn{conn: c}, nil -} - -func WebsocketServerConn(conn *websocket.Conn) *WebsocketConn { - conn.EnableWriteCompression(true) - return &WebsocketConn{ - conn: conn, - } -} - -func (c *WebsocketConn) Read(b []byte) (n int, err error) { - if len(c.rb) == 0 { - _, c.rb, err = c.conn.ReadMessage() - } - n = copy(b, c.rb) - c.rb = c.rb[n:] - return -} - -func (c *WebsocketConn) Write(b []byte) (n int, err error) { - err = c.conn.WriteMessage(websocket.BinaryMessage, b) - n = len(b) - return -} - -func (c *WebsocketConn) Close() error { - return c.conn.Close() -} - -func (c *WebsocketConn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -func (c *WebsocketConn) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -func (conn *WebsocketConn) SetDeadline(t time.Time) error { - if err := conn.SetReadDeadline(t); err != nil { - return err - } - return conn.SetWriteDeadline(t) -} -func (c *WebsocketConn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -func (c *WebsocketConn) SetWriteDeadline(t time.Time) error { - return c.conn.SetWriteDeadline(t) -} diff --git a/vendor/vendor.json b/vendor/vendor.json index 0c00d25..953c78a 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -20,12 +20,6 @@ "revision": "0f737bddba2abd1496dc03c8b39b817cc5f33fa7", "revisionTime": "2017-01-19T05:34:58Z" }, - { - "checksumSHA1": "90Nj9KD5KzY15ZBn95Coz7G85+0=", - "path": "github.com/ginuerzh/gost", - "revision": "26f4e49f0538177eb5ec33c84a280afe2ae16042", - "revisionTime": "2017-03-03T13:33:05Z" - }, { "checksumSHA1": "+XIOnTW0rv8Kr/amkXgMraNeUr4=", "path": "github.com/ginuerzh/pht",