Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
G
gost
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
gost
Commits
2dd7ace3
Commit
2dd7ace3
authored
Jan 19, 2017
by
rui.zheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
#69 KCP client now supports proxy chain
parent
c1d79272
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
66 additions
and
110 deletions
+66
-110
README.md
README.md
+10
-11
README_en.md
README_en.md
+1
-2
chain.go
chain.go
+26
-47
cmd/gost/vendor/github.com/ginuerzh/gost/chain.go
cmd/gost/vendor/github.com/ginuerzh/gost/chain.go
+25
-46
cmd/gost/vendor/vendor.json
cmd/gost/vendor/vendor.json
+3
-3
gost.go
gost.go
+1
-1
No files found.
README.md
View file @
2dd7ace3
...
@@ -38,25 +38,25 @@ scheme分为两部分: protocol+transport
...
@@ -38,25 +38,25 @@ scheme分为两部分: protocol+transport
protocol: 代理协议类型(http, socks5, shadowsocks), transport: 数据传输方式(ws, wss, tls, http2, quic, kcp), 二者可以任意组合,或单独使用:
protocol: 代理协议类型(http, socks5, shadowsocks), transport: 数据传输方式(ws, wss, tls, http2, quic, kcp), 二者可以任意组合,或单独使用:
> http -
作为
HTTP代理: http://:8080
> http - HTTP代理: http://:8080
> http+tls -
作为HTTPS代理(可能需要提供受信任的证书): http+tl
s://:443
> http+tls -
HTTPS代理(可能需要提供受信任的证书): http+tls://:443或http
s://:443
> http2 -
作为
HTTP2代理并向下兼容HTTPS代理: http2://:443
> http2 - HTTP2代理并向下兼容HTTPS代理: http2://:443
> socks -
作为
标准SOCKS5代理(支持tls协商加密): socks://:1080
> socks - 标准SOCKS5代理(支持tls协商加密): socks://:1080
> socks+wss -
作为
SOCKS5代理,使用websocket传输数据: socks+wss://:1080
> socks+wss - SOCKS5代理,使用websocket传输数据: socks+wss://:1080
> tls -
作为
HTTPS/SOCKS5代理,使用tls传输数据: tls://:443
> tls - HTTPS/SOCKS5代理,使用tls传输数据: tls://:443
> ss -
作为Shadowsocks服务
,ss://aes-256-cfb:123456@:8338
> ss -
Shadowsocks代理
,ss://aes-256-cfb:123456@:8338
> quic -
作为
QUIC代理,quic://:6121
> quic - QUIC代理,quic://:6121
> kcp -
作为
KCP代理,kcp://:8388或kcp://aes:123456@:8388
> kcp - KCP代理,kcp://:8388或kcp://aes:123456@:8388
> redirect -
作为
透明代理,redirect://:12345
> redirect - 透明代理,redirect://:12345
#### 端口转发
#### 端口转发
...
@@ -251,7 +251,6 @@ gost -L=kcp://:8388?c=/path/to/conf/file
...
@@ -251,7 +251,6 @@ gost -L=kcp://:8388?c=/path/to/conf/file
```
```
**注:**
客户端若要开启KCP转发,当且仅当代理链不为空且首个代理节点(第一个-F参数)为kcp类型。
**注:**
客户端若要开启KCP转发,当且仅当代理链不为空且首个代理节点(第一个-F参数)为kcp类型。
当KCP转发开启,代理链中的其他代理节点将被忽略。
#### 透明代理
#### 透明代理
基于iptables的透明代理。
基于iptables的透明代理。
...
...
README_en.md
View file @
2dd7ace3
...
@@ -40,7 +40,7 @@ transport: data transmission mode (ws, wss, tls, http2, quic, kcp), may be used
...
@@ -40,7 +40,7 @@ transport: data transmission mode (ws, wss, tls, http2, quic, kcp), may be used
> http - standard HTTP proxy: http://:8080
> http - standard HTTP proxy: http://:8080
> http+tls - standard HTTPS proxy (may need to provide a trusted certificate): http+tls://:443
> 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
> http2 - HTTP2 proxy and backwards-compatible with HTTPS proxy: http2://:443
...
@@ -253,7 +253,6 @@ gost -L=kcp://:8388?c=/path/to/conf/file
...
@@ -253,7 +253,6 @@ 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.
**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.
When KCP is enabled, other proxy nodes are ignored.
#### Transparent proxy
#### Transparent proxy
Iptables-based transparent proxy
Iptables-based transparent proxy
...
...
chain.go
View file @
2dd7ace3
...
@@ -69,7 +69,7 @@ func (c *ProxyChain) SetNode(index int, node ProxyNode) {
...
@@ -69,7 +69,7 @@ func (c *ProxyChain) SetNode(index int, node ProxyNode) {
}
}
// Init initialize the proxy chain.
// Init initialize the proxy chain.
// KCP will be enabled if the first proxy node is KCP proxy (transport == kcp)
, the remaining nodes are ignored
.
// 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.
// 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.
// NOTE: Should be called immediately when proxy nodes are ready.
...
@@ -81,6 +81,26 @@ func (c *ProxyChain) Init() {
...
@@ -81,6 +81,26 @@ func (c *ProxyChain) Init() {
c
.
lastNode
=
&
c
.
nodes
[
length
-
1
]
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"
&&
i
>
0
{
glog
.
Fatal
(
"KCP must be the first node in the proxy chain"
)
}
}
if
c
.
nodes
[
0
]
.
Transport
==
"kcp"
{
if
c
.
nodes
[
0
]
.
Transport
==
"kcp"
{
glog
.
V
(
LINFO
)
.
Infoln
(
"KCP is enabled"
)
glog
.
V
(
LINFO
)
.
Infoln
(
"KCP is enabled"
)
c
.
kcpEnabled
=
true
c
.
kcpEnabled
=
true
...
@@ -98,20 +118,6 @@ func (c *ProxyChain) Init() {
...
@@ -98,20 +118,6 @@ func (c *ProxyChain) Init() {
c
.
kcpConfig
=
config
c
.
kcpConfig
=
config
return
return
}
}
// 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
}
}
}
}
func
(
c
*
ProxyChain
)
KCPEnabled
()
bool
{
func
(
c
*
ProxyChain
)
KCPEnabled
()
bool
{
...
@@ -198,19 +204,6 @@ func (c *ProxyChain) GetConn() (net.Conn, error) {
...
@@ -198,19 +204,6 @@ func (c *ProxyChain) GetConn() (net.Conn, error) {
return
nil
,
ErrEmptyChain
return
nil
,
ErrEmptyChain
}
}
if
c
.
KCPEnabled
()
{
kcpConn
,
err
:=
c
.
getKCPConn
()
if
err
!=
nil
{
return
nil
,
err
}
pc
:=
NewProxyConn
(
kcpConn
,
c
.
nodes
[
0
])
if
err
:=
pc
.
Handshake
();
err
!=
nil
{
pc
.
Close
()
return
nil
,
err
}
return
pc
,
nil
}
if
c
.
Http2Enabled
()
{
if
c
.
Http2Enabled
()
{
nodes
=
nodes
[
c
.
http2NodeIndex
+
1
:
]
nodes
=
nodes
[
c
.
http2NodeIndex
+
1
:
]
if
len
(
nodes
)
==
0
{
if
len
(
nodes
)
==
0
{
...
@@ -243,23 +236,6 @@ func (c *ProxyChain) dialWithNodes(withHttp2 bool, addr string, nodes ...ProxyNo
...
@@ -243,23 +236,6 @@ func (c *ProxyChain) dialWithNodes(withHttp2 bool, addr string, nodes ...ProxyNo
return
net
.
DialTimeout
(
"tcp"
,
addr
,
DialTimeout
)
return
net
.
DialTimeout
(
"tcp"
,
addr
,
DialTimeout
)
}
}
if
c
.
KCPEnabled
()
{
kcpConn
,
err
:=
c
.
getKCPConn
()
if
err
!=
nil
{
return
nil
,
err
}
pc
:=
NewProxyConn
(
kcpConn
,
nodes
[
0
])
if
err
:=
pc
.
Handshake
();
err
!=
nil
{
pc
.
Close
()
return
nil
,
err
}
if
err
:=
pc
.
Connect
(
addr
);
err
!=
nil
{
pc
.
Close
()
return
nil
,
err
}
return
pc
,
nil
}
if
withHttp2
&&
c
.
Http2Enabled
()
{
if
withHttp2
&&
c
.
Http2Enabled
()
{
nodes
=
nodes
[
c
.
http2NodeIndex
+
1
:
]
nodes
=
nodes
[
c
.
http2NodeIndex
+
1
:
]
if
len
(
nodes
)
==
0
{
if
len
(
nodes
)
==
0
{
...
@@ -291,6 +267,8 @@ func (c *ProxyChain) travelNodes(withHttp2 bool, nodes ...ProxyNode) (conn *Prox
...
@@ -291,6 +267,8 @@ func (c *ProxyChain) travelNodes(withHttp2 bool, nodes ...ProxyNode) (conn *Prox
if
withHttp2
&&
c
.
Http2Enabled
()
{
if
withHttp2
&&
c
.
Http2Enabled
()
{
cc
,
err
=
c
.
http2Connect
(
node
.
Addr
)
cc
,
err
=
c
.
http2Connect
(
node
.
Addr
)
}
else
if
node
.
Transport
==
"kcp"
{
cc
,
err
=
c
.
getKCPConn
()
}
else
{
}
else
{
cc
,
err
=
net
.
DialTimeout
(
"tcp"
,
node
.
Addr
,
DialTimeout
)
cc
,
err
=
net
.
DialTimeout
(
"tcp"
,
node
.
Addr
,
DialTimeout
)
}
}
...
@@ -300,19 +278,20 @@ func (c *ProxyChain) travelNodes(withHttp2 bool, nodes ...ProxyNode) (conn *Prox
...
@@ -300,19 +278,20 @@ func (c *ProxyChain) travelNodes(withHttp2 bool, nodes ...ProxyNode) (conn *Prox
setKeepAlive
(
cc
,
KeepAliveTime
)
setKeepAlive
(
cc
,
KeepAliveTime
)
pc
:=
NewProxyConn
(
cc
,
node
)
pc
:=
NewProxyConn
(
cc
,
node
)
conn
=
pc
if
err
=
pc
.
Handshake
();
err
!=
nil
{
if
err
=
pc
.
Handshake
();
err
!=
nil
{
return
return
}
}
conn
=
pc
for
_
,
node
:=
range
nodes
[
1
:
]
{
for
_
,
node
:=
range
nodes
[
1
:
]
{
if
err
=
conn
.
Connect
(
node
.
Addr
);
err
!=
nil
{
if
err
=
conn
.
Connect
(
node
.
Addr
);
err
!=
nil
{
return
return
}
}
pc
:=
NewProxyConn
(
conn
,
node
)
pc
:=
NewProxyConn
(
conn
,
node
)
conn
=
pc
if
err
=
pc
.
Handshake
();
err
!=
nil
{
if
err
=
pc
.
Handshake
();
err
!=
nil
{
return
return
}
}
conn
=
pc
}
}
return
return
}
}
...
...
cmd/gost/vendor/github.com/ginuerzh/gost/chain.go
View file @
2dd7ace3
...
@@ -81,6 +81,26 @@ func (c *ProxyChain) Init() {
...
@@ -81,6 +81,26 @@ func (c *ProxyChain) Init() {
c
.
lastNode
=
&
c
.
nodes
[
length
-
1
]
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"
&&
i
>
0
{
glog
.
Fatal
(
"KCP must be the first node in the proxy chain"
)
}
}
if
c
.
nodes
[
0
]
.
Transport
==
"kcp"
{
if
c
.
nodes
[
0
]
.
Transport
==
"kcp"
{
glog
.
V
(
LINFO
)
.
Infoln
(
"KCP is enabled"
)
glog
.
V
(
LINFO
)
.
Infoln
(
"KCP is enabled"
)
c
.
kcpEnabled
=
true
c
.
kcpEnabled
=
true
...
@@ -98,20 +118,6 @@ func (c *ProxyChain) Init() {
...
@@ -98,20 +118,6 @@ func (c *ProxyChain) Init() {
c
.
kcpConfig
=
config
c
.
kcpConfig
=
config
return
return
}
}
// 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
}
}
}
}
func
(
c
*
ProxyChain
)
KCPEnabled
()
bool
{
func
(
c
*
ProxyChain
)
KCPEnabled
()
bool
{
...
@@ -198,19 +204,6 @@ func (c *ProxyChain) GetConn() (net.Conn, error) {
...
@@ -198,19 +204,6 @@ func (c *ProxyChain) GetConn() (net.Conn, error) {
return
nil
,
ErrEmptyChain
return
nil
,
ErrEmptyChain
}
}
if
c
.
KCPEnabled
()
{
kcpConn
,
err
:=
c
.
getKCPConn
()
if
err
!=
nil
{
return
nil
,
err
}
pc
:=
NewProxyConn
(
kcpConn
,
c
.
nodes
[
0
])
if
err
:=
pc
.
Handshake
();
err
!=
nil
{
pc
.
Close
()
return
nil
,
err
}
return
pc
,
nil
}
if
c
.
Http2Enabled
()
{
if
c
.
Http2Enabled
()
{
nodes
=
nodes
[
c
.
http2NodeIndex
+
1
:
]
nodes
=
nodes
[
c
.
http2NodeIndex
+
1
:
]
if
len
(
nodes
)
==
0
{
if
len
(
nodes
)
==
0
{
...
@@ -243,23 +236,6 @@ func (c *ProxyChain) dialWithNodes(withHttp2 bool, addr string, nodes ...ProxyNo
...
@@ -243,23 +236,6 @@ func (c *ProxyChain) dialWithNodes(withHttp2 bool, addr string, nodes ...ProxyNo
return
net
.
DialTimeout
(
"tcp"
,
addr
,
DialTimeout
)
return
net
.
DialTimeout
(
"tcp"
,
addr
,
DialTimeout
)
}
}
if
c
.
KCPEnabled
()
{
kcpConn
,
err
:=
c
.
getKCPConn
()
if
err
!=
nil
{
return
nil
,
err
}
pc
:=
NewProxyConn
(
kcpConn
,
nodes
[
0
])
if
err
:=
pc
.
Handshake
();
err
!=
nil
{
pc
.
Close
()
return
nil
,
err
}
if
err
:=
pc
.
Connect
(
addr
);
err
!=
nil
{
pc
.
Close
()
return
nil
,
err
}
return
pc
,
nil
}
if
withHttp2
&&
c
.
Http2Enabled
()
{
if
withHttp2
&&
c
.
Http2Enabled
()
{
nodes
=
nodes
[
c
.
http2NodeIndex
+
1
:
]
nodes
=
nodes
[
c
.
http2NodeIndex
+
1
:
]
if
len
(
nodes
)
==
0
{
if
len
(
nodes
)
==
0
{
...
@@ -291,6 +267,8 @@ func (c *ProxyChain) travelNodes(withHttp2 bool, nodes ...ProxyNode) (conn *Prox
...
@@ -291,6 +267,8 @@ func (c *ProxyChain) travelNodes(withHttp2 bool, nodes ...ProxyNode) (conn *Prox
if
withHttp2
&&
c
.
Http2Enabled
()
{
if
withHttp2
&&
c
.
Http2Enabled
()
{
cc
,
err
=
c
.
http2Connect
(
node
.
Addr
)
cc
,
err
=
c
.
http2Connect
(
node
.
Addr
)
}
else
if
node
.
Transport
==
"kcp"
{
cc
,
err
=
c
.
getKCPConn
()
}
else
{
}
else
{
cc
,
err
=
net
.
DialTimeout
(
"tcp"
,
node
.
Addr
,
DialTimeout
)
cc
,
err
=
net
.
DialTimeout
(
"tcp"
,
node
.
Addr
,
DialTimeout
)
}
}
...
@@ -300,19 +278,20 @@ func (c *ProxyChain) travelNodes(withHttp2 bool, nodes ...ProxyNode) (conn *Prox
...
@@ -300,19 +278,20 @@ func (c *ProxyChain) travelNodes(withHttp2 bool, nodes ...ProxyNode) (conn *Prox
setKeepAlive
(
cc
,
KeepAliveTime
)
setKeepAlive
(
cc
,
KeepAliveTime
)
pc
:=
NewProxyConn
(
cc
,
node
)
pc
:=
NewProxyConn
(
cc
,
node
)
conn
=
pc
if
err
=
pc
.
Handshake
();
err
!=
nil
{
if
err
=
pc
.
Handshake
();
err
!=
nil
{
return
return
}
}
conn
=
pc
for
_
,
node
:=
range
nodes
[
1
:
]
{
for
_
,
node
:=
range
nodes
[
1
:
]
{
if
err
=
conn
.
Connect
(
node
.
Addr
);
err
!=
nil
{
if
err
=
conn
.
Connect
(
node
.
Addr
);
err
!=
nil
{
return
return
}
}
pc
:=
NewProxyConn
(
conn
,
node
)
pc
:=
NewProxyConn
(
conn
,
node
)
conn
=
pc
if
err
=
pc
.
Handshake
();
err
!=
nil
{
if
err
=
pc
.
Handshake
();
err
!=
nil
{
return
return
}
}
conn
=
pc
}
}
return
return
}
}
...
...
cmd/gost/vendor/vendor.json
View file @
2dd7ace3
...
@@ -15,10 +15,10 @@
...
@@ -15,10 +15,10 @@
"revisionTime"
:
"2017-01-19T05:34:58Z"
"revisionTime"
:
"2017-01-19T05:34:58Z"
},
},
{
{
"checksumSHA1"
:
"
g55EnuSESwa92RY7U+shNoPi900
="
,
"checksumSHA1"
:
"
oZV/w2ONwoM0nMDddIJQYDAZOPg
="
,
"path"
:
"github.com/ginuerzh/gost"
,
"path"
:
"github.com/ginuerzh/gost"
,
"revision"
:
"
0585749a819f33404f369650e74716cddf4ed3b7
"
,
"revision"
:
"
c1d79272573ada276e5a4234774ea4c2e2b4e9ef
"
,
"revisionTime"
:
"2017-01-19T05:4
0:53
Z"
"revisionTime"
:
"2017-01-19T05:4
2:02
Z"
},
},
{
{
"checksumSHA1"
:
"URsJa4y/sUUw/STmbeYx9EKqaYE="
,
"checksumSHA1"
:
"URsJa4y/sUUw/STmbeYx9EKqaYE="
,
...
...
gost.go
View file @
2dd7ace3
...
@@ -11,7 +11,7 @@ import (
...
@@ -11,7 +11,7 @@ import (
)
)
const
(
const
(
Version
=
"2.3-rc
2
"
Version
=
"2.3-rc
3
"
)
)
// Log level for glog
// Log level for glog
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment