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
5efffa7d
Commit
5efffa7d
authored
Feb 10, 2017
by
rui.zheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
#77 add SOCKS4(A) support
parent
333291e9
Changes
21
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
912 additions
and
36 deletions
+912
-36
README.md
README.md
+9
-5
README_en.md
README_en.md
+8
-4
chain.go
chain.go
+83
-3
cmd/gost/vendor/github.com/ginuerzh/gosocks4/LICENSE
cmd/gost/vendor/github.com/ginuerzh/gosocks4/LICENSE
+21
-0
cmd/gost/vendor/github.com/ginuerzh/gosocks4/README.md
cmd/gost/vendor/github.com/ginuerzh/gosocks4/README.md
+2
-0
cmd/gost/vendor/github.com/ginuerzh/gosocks4/socks4.go
cmd/gost/vendor/github.com/ginuerzh/gosocks4/socks4.go
+252
-0
cmd/gost/vendor/github.com/ginuerzh/gosocks4/socks4.protocol.txt
...t/vendor/github.com/ginuerzh/gosocks4/socks4.protocol.txt
+152
-0
cmd/gost/vendor/github.com/ginuerzh/gosocks4/socks4a.protocol.txt
.../vendor/github.com/ginuerzh/gosocks4/socks4a.protocol.txt
+39
-0
cmd/gost/vendor/github.com/ginuerzh/gost/README.md
cmd/gost/vendor/github.com/ginuerzh/gost/README.md
+9
-5
cmd/gost/vendor/github.com/ginuerzh/gost/README_en.md
cmd/gost/vendor/github.com/ginuerzh/gost/README_en.md
+8
-4
cmd/gost/vendor/github.com/ginuerzh/gost/chain.go
cmd/gost/vendor/github.com/ginuerzh/gost/chain.go
+83
-3
cmd/gost/vendor/github.com/ginuerzh/gost/conn.go
cmd/gost/vendor/github.com/ginuerzh/gost/conn.go
+35
-0
cmd/gost/vendor/github.com/ginuerzh/gost/node.go
cmd/gost/vendor/github.com/ginuerzh/gost/node.go
+1
-1
cmd/gost/vendor/github.com/ginuerzh/gost/quic.go
cmd/gost/vendor/github.com/ginuerzh/gost/quic.go
+2
-1
cmd/gost/vendor/github.com/ginuerzh/gost/server.go
cmd/gost/vendor/github.com/ginuerzh/gost/server.go
+9
-0
cmd/gost/vendor/github.com/ginuerzh/gost/socks.go
cmd/gost/vendor/github.com/ginuerzh/gost/socks.go
+76
-4
conn.go
conn.go
+35
-0
node.go
node.go
+1
-1
quic.go
quic.go
+2
-1
server.go
server.go
+9
-0
socks.go
socks.go
+76
-4
No files found.
README.md
View file @
5efffa7d
...
@@ -9,7 +9,7 @@ gost - GO Simple Tunnel
...
@@ -9,7 +9,7 @@ gost - GO Simple Tunnel
------
------
*
可同时监听多端口
*
可同时监听多端口
*
可设置转发代理,支持多级转发(代理链)
*
可设置转发代理,支持多级转发(代理链)
*
支持标准HTTP/HTTPS/SOCKS5代理协议
*
支持标准HTTP/HTTPS/SOCKS
4(A)/SOCKS
5代理协议
*
SOCKS5代理支持TLS协商加密
*
SOCKS5代理支持TLS协商加密
*
Tunnel UDP over TCP
*
Tunnel UDP over TCP
*
支持Shadowsocks协议 (OTA: 2.2+,UDP: 2.4+)
*
支持Shadowsocks协议 (OTA: 2.2+,UDP: 2.4+)
...
@@ -36,7 +36,7 @@ Google讨论组: https://groups.google.com/d/forum/go-gost
...
@@ -36,7 +36,7 @@ Google讨论组: https://groups.google.com/d/forum/go-gost
```
```
scheme分为两部分: protocol+transport
scheme分为两部分: protocol+transport
protocol: 代理协议类型(http, socks
5, shadowsocks), transport: 数据传输方式(ws, wss, tls, http2, quic, kcp
), 二者可以任意组合,或单独使用:
protocol: 代理协议类型(http, socks
4(a), socks5, shadowsocks), transport: 数据传输方式(ws, wss, tls, http2, quic, kcp, pht
), 二者可以任意组合,或单独使用:
> http - HTTP代理: http://:8080
> http - HTTP代理: http://:8080
...
@@ -44,11 +44,13 @@ protocol: 代理协议类型(http, socks5, shadowsocks), transport: 数据传输
...
@@ -44,11 +44,13 @@ protocol: 代理协议类型(http, socks5, shadowsocks), transport: 数据传输
> http2 - HTTP2代理并向下兼容HTTPS代理: http2://:443
> http2 - HTTP2代理并向下兼容HTTPS代理: http2://:443
> socks - 标准SOCKS5代理(支持tls协商加密): socks://:1080
> socks4(a) - 标准SOCKS4(A)代理: socks4://:1080或socks4a://: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://chacha20:123456@:8338
> ss - Shadowsocks代理,ss://chacha20:123456@:8338
...
@@ -56,7 +58,9 @@ protocol: 代理协议类型(http, socks5, shadowsocks), transport: 数据传输
...
@@ -56,7 +58,9 @@ protocol: 代理协议类型(http, socks5, shadowsocks), transport: 数据传输
> quic - QUIC代理,quic://:6121
> quic - QUIC代理,quic://:6121
> kcp - KCP代理,kcp://:8388或kcp://aes:123456@:8388
> kcp - KCP通道,kcp://:8388或kcp://aes:123456@:8388
> pht - 普通HTTP通道,pht://:8080
> redirect - 透明代理,redirect://:12345
> redirect - 透明代理,redirect://:12345
...
...
README_en.md
View file @
5efffa7d
...
@@ -7,7 +7,7 @@ Features
...
@@ -7,7 +7,7 @@ Features
------
------
*
Listening on multiple ports
*
Listening on multiple ports
*
Multi-level forward proxy - proxy chain
*
Multi-level forward proxy - proxy chain
*
Standard HTTP/HTTPS/SOCKS5 proxy protocols support
*
Standard HTTP/HTTPS/SOCKS
4(A)/SOCKS
5 proxy protocols support
*
TLS encryption via negotiation support for SOCKS5 proxy
*
TLS encryption via negotiation support for SOCKS5 proxy
*
Tunnel UDP over TCP
*
Tunnel UDP over TCP
*
Shadowsocks protocol support (OTA: 2.2+, UDP: 2.4+)
*
Shadowsocks protocol support (OTA: 2.2+, UDP: 2.4+)
...
@@ -35,8 +35,8 @@ Effective for the -L and -F parameters
...
@@ -35,8 +35,8 @@ Effective for the -L and -F parameters
```
```
scheme can be divided into two parts: protocol+transport
scheme can be divided into two parts: protocol+transport
protocol: proxy protocol types (http, socks5, shadowsocks),
protocol: proxy protocol types (http, socks
4(a), socks
5, shadowsocks),
transport: data transmission mode (ws, wss, tls, http2, quic, kcp), may be used in any combination or individually:
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 - standard HTTP proxy: http://:8080
...
@@ -44,11 +44,13 @@ transport: data transmission mode (ws, wss, tls, http2, quic, kcp), may be used
...
@@ -44,11 +44,13 @@ transport: data transmission mode (ws, wss, tls, http2, quic, kcp), may be used
> http2 - HTTP2 proxy and backwards-compatible with HTTPS proxy: http2://: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 - standard SOCKS5 proxy: socks://:1080
> socks+wss - SOCKS5 over websocket: socks+wss://:1080
> socks+wss - SOCKS5 over websocket: socks+wss://:1080
> tls - HTTPS/SOCKS5 over
tls
: tls://:443
> tls - HTTPS/SOCKS5 over
TLS
: tls://:443
> ss - standard shadowsocks proxy, ss://chacha20:123456@:8338
> ss - standard shadowsocks proxy, ss://chacha20:123456@:8338
...
@@ -58,6 +60,8 @@ transport: data transmission mode (ws, wss, tls, http2, quic, kcp), may be used
...
@@ -58,6 +60,8 @@ transport: data transmission mode (ws, wss, tls, http2, quic, kcp), may be used
> kcp - standard KCP tunnel,kcp://:8388 or kcp://aes:123456@:8388
> kcp - standard KCP tunnel,kcp://:8388 or kcp://aes:123456@:8388
> pht - plain HTTP tunnel, pht://:8080
> redirect - transparent proxy,redirect://:12345
> redirect - transparent proxy,redirect://:12345
#### Port forwarding
#### Port forwarding
...
...
chain.go
View file @
5efffa7d
...
@@ -7,6 +7,7 @@ import (
...
@@ -7,6 +7,7 @@ import (
"errors"
"errors"
"github.com/ginuerzh/pht"
"github.com/ginuerzh/pht"
"github.com/golang/glog"
"github.com/golang/glog"
"github.com/lucas-clemente/quic-go/h2quic"
"golang.org/x/net/http2"
"golang.org/x/net/http2"
"io"
"io"
"net"
"net"
...
@@ -30,7 +31,8 @@ type ProxyChain struct {
...
@@ -30,7 +31,8 @@ type ProxyChain struct {
kcpConfig
*
KCPConfig
kcpConfig
*
KCPConfig
kcpSession
*
KCPSession
kcpSession
*
KCPSession
kcpMutex
sync
.
Mutex
kcpMutex
sync
.
Mutex
phttpClient
*
pht
.
Client
phtClient
*
pht
.
Client
quicClient
*
http
.
Client
}
}
func
NewProxyChain
(
nodes
...
ProxyNode
)
*
ProxyChain
{
func
NewProxyChain
(
nodes
...
ProxyNode
)
*
ProxyChain
{
...
@@ -121,9 +123,21 @@ func (c *ProxyChain) Init() {
...
@@ -121,9 +123,21 @@ func (c *ProxyChain) Init() {
return
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"
{
if
c
.
nodes
[
0
]
.
Transport
==
"pht"
{
glog
.
V
(
LINFO
)
.
Infoln
(
"Pure HTTP mode is enabled"
)
glog
.
V
(
LINFO
)
.
Infoln
(
"Pure HTTP mode is enabled"
)
c
.
pht
tp
Client
=
pht
.
NewClient
(
c
.
nodes
[
0
]
.
Addr
,
c
.
nodes
[
0
]
.
Get
(
"key"
))
c
.
phtClient
=
pht
.
NewClient
(
c
.
nodes
[
0
]
.
Addr
,
c
.
nodes
[
0
]
.
Get
(
"key"
))
}
}
}
}
...
@@ -249,6 +263,12 @@ func (c *ProxyChain) dialWithNodes(withHttp2 bool, addr string, nodes ...ProxyNo
...
@@ -249,6 +263,12 @@ func (c *ProxyChain) dialWithNodes(withHttp2 bool, addr string, nodes ...ProxyNo
return
c
.
http2Connect
(
addr
)
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
...
)
pc
,
err
:=
c
.
travelNodes
(
withHttp2
,
nodes
...
)
if
err
!=
nil
{
if
err
!=
nil
{
return
return
...
@@ -277,7 +297,7 @@ func (c *ProxyChain) travelNodes(withHttp2 bool, nodes ...ProxyNode) (conn *Prox
...
@@ -277,7 +297,7 @@ func (c *ProxyChain) travelNodes(withHttp2 bool, nodes ...ProxyNode) (conn *Prox
}
else
if
node
.
Transport
==
"kcp"
{
}
else
if
node
.
Transport
==
"kcp"
{
cc
,
err
=
c
.
getKCPConn
()
cc
,
err
=
c
.
getKCPConn
()
}
else
if
node
.
Transport
==
"pht"
{
}
else
if
node
.
Transport
==
"pht"
{
cc
,
err
=
c
.
pht
tp
Client
.
Dial
()
cc
,
err
=
c
.
phtClient
.
Dial
()
}
else
{
}
else
{
cc
,
err
=
net
.
DialTimeout
(
"tcp"
,
node
.
Addr
,
DialTimeout
)
cc
,
err
=
net
.
DialTimeout
(
"tcp"
,
node
.
Addr
,
DialTimeout
)
}
}
...
@@ -388,3 +408,63 @@ func (c *ProxyChain) http2Connect(addr string) (net.Conn, error) {
...
@@ -388,3 +408,63 @@ func (c *ProxyChain) http2Connect(addr string) (net.Conn, error) {
}
}
return
c
.
getHttp2Conn
(
header
)
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
}
cmd/gost/vendor/github.com/ginuerzh/gosocks4/LICENSE
0 → 100644
View file @
5efffa7d
MIT License
Copyright (c) 2017 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.
cmd/gost/vendor/github.com/ginuerzh/gosocks4/README.md
0 → 100644
View file @
5efffa7d
# gosocks4
golang and SOCKS4(a)
cmd/gost/vendor/github.com/ginuerzh/gosocks4/socks4.go
0 → 100644
View file @
5efffa7d
// SOCKS Protocol Version 4(a)
// https://www.openssh.com/txt/socks4.protocol
// https://www.openssh.com/txt/socks4a.protocol
package
gosocks4
import
(
"bufio"
"encoding/binary"
"errors"
"fmt"
"io"
"net"
"strconv"
)
const
(
Ver4
=
4
)
const
(
CmdConnect
uint8
=
1
CmdBind
=
2
)
const
(
AddrIPv4
=
0
AddrDomain
=
1
)
const
(
Granted
=
90
Failed
=
91
Rejected
=
92
RejectedUserid
=
93
)
var
(
ErrBadVersion
=
errors
.
New
(
"Bad version"
)
ErrBadFormat
=
errors
.
New
(
"Bad format"
)
ErrBadAddrType
=
errors
.
New
(
"Bad address type"
)
ErrShortDataLength
=
errors
.
New
(
"Short data length"
)
ErrBadCmd
=
errors
.
New
(
"Bad Command"
)
)
type
Addr
struct
{
Type
int
Host
string
Port
uint16
}
func
(
addr
*
Addr
)
Decode
(
b
[]
byte
)
error
{
if
len
(
b
)
<
6
{
return
ErrShortDataLength
}
addr
.
Port
=
binary
.
BigEndian
.
Uint16
(
b
[
0
:
2
])
addr
.
Host
=
net
.
IP
(
b
[
2
:
2
+
net
.
IPv4len
])
.
String
()
if
b
[
2
]
|
b
[
3
]
|
b
[
4
]
==
0
{
addr
.
Type
=
AddrDomain
}
return
nil
}
func
(
addr
*
Addr
)
Encode
(
b
[]
byte
)
error
{
if
len
(
b
)
<
6
{
return
ErrShortDataLength
}
binary
.
BigEndian
.
PutUint16
(
b
[
0
:
2
],
addr
.
Port
)
switch
addr
.
Type
{
case
AddrIPv4
:
ip4
:=
net
.
ParseIP
(
addr
.
Host
)
.
To4
()
if
ip4
==
nil
{
return
ErrBadAddrType
}
copy
(
b
[
2
:
],
ip4
)
case
AddrDomain
:
ip4
:=
net
.
IPv4
(
0
,
0
,
0
,
1
)
copy
(
b
[
2
:
],
ip4
)
default
:
return
ErrBadAddrType
}
return
nil
}
func
(
addr
*
Addr
)
String
()
string
{
return
net
.
JoinHostPort
(
addr
.
Host
,
strconv
.
Itoa
(
int
(
addr
.
Port
)))
}
/*
+----+----+----+----+----+----+----+----+----+----+....+----+
| VN | CD | DSTPORT | DSTIP | USERID |NULL|
+----+----+----+----+----+----+----+----+----+----+....+----+
1 1 2 4 variable 1
*/
type
Request
struct
{
Cmd
uint8
Addr
*
Addr
Userid
[]
byte
}
func
NewRequest
(
cmd
uint8
,
addr
*
Addr
,
userid
[]
byte
)
*
Request
{
return
&
Request
{
Cmd
:
cmd
,
Addr
:
addr
,
Userid
:
userid
,
}
}
func
ReadRequest
(
r
io
.
Reader
)
(
*
Request
,
error
)
{
br
:=
bufio
.
NewReader
(
r
)
b
,
err
:=
br
.
Peek
(
8
)
if
err
!=
nil
{
return
nil
,
err
}
if
b
[
0
]
!=
Ver4
{
return
nil
,
ErrBadVersion
}
request
:=
&
Request
{
Cmd
:
b
[
1
],
}
addr
:=
&
Addr
{}
if
err
:=
addr
.
Decode
(
b
[
2
:
8
]);
err
!=
nil
{
return
nil
,
err
}
request
.
Addr
=
addr
if
_
,
err
:=
br
.
Discard
(
8
);
err
!=
nil
{
return
nil
,
err
}
b
,
err
=
br
.
ReadBytes
(
0
)
if
err
!=
nil
{
return
nil
,
err
}
request
.
Userid
=
b
[
:
len
(
b
)
-
1
]
if
request
.
Addr
.
Type
==
AddrDomain
{
b
,
err
=
br
.
ReadBytes
(
0
)
if
err
!=
nil
{
return
nil
,
err
}
request
.
Addr
.
Host
=
string
(
b
[
:
len
(
b
)
-
1
])
}
return
request
,
nil
}
func
(
r
*
Request
)
Write
(
w
io
.
Writer
)
(
err
error
)
{
bw
:=
bufio
.
NewWriter
(
w
)
bw
.
Write
([]
byte
{
Ver4
,
r
.
Cmd
})
if
r
.
Addr
==
nil
{
return
ErrBadAddrType
}
var
b
[
6
]
byte
if
err
=
r
.
Addr
.
Encode
(
b
[
:
]);
err
!=
nil
{
return
}
bw
.
Write
(
b
[
:
])
if
len
(
r
.
Userid
)
>
0
{
bw
.
Write
(
r
.
Userid
)
}
bw
.
WriteByte
(
0
)
if
r
.
Addr
.
Type
==
AddrDomain
{
bw
.
WriteString
(
r
.
Addr
.
Host
)
bw
.
WriteByte
(
0
)
}
return
bw
.
Flush
()
}
func
(
r
*
Request
)
String
()
string
{
addr
:=
r
.
Addr
if
addr
==
nil
{
addr
=
&
Addr
{}
}
return
fmt
.
Sprintf
(
"%d %d %s"
,
Ver4
,
r
.
Cmd
,
addr
.
String
())
}
/*
+----+----+----+----+----+----+----+----+
| VN | CD | DSTPORT | DSTIP |
+----+----+----+----+----+----+----+----+
1 1 2 4
*/
type
Reply
struct
{
Code
uint8
Addr
*
Addr
}
func
NewReply
(
code
uint8
,
addr
*
Addr
)
*
Reply
{
return
&
Reply
{
Code
:
code
,
Addr
:
addr
,
}
}
func
ReadReply
(
r
io
.
Reader
)
(
*
Reply
,
error
)
{
var
b
[
8
]
byte
_
,
err
:=
io
.
ReadFull
(
r
,
b
[
:
])
if
err
!=
nil
{
return
nil
,
err
}
if
b
[
0
]
!=
0
{
return
nil
,
ErrBadVersion
}
reply
:=
&
Reply
{
Code
:
b
[
1
],
}
reply
.
Addr
=
&
Addr
{}
if
err
:=
reply
.
Addr
.
Decode
(
b
[
2
:
]);
err
!=
nil
{
return
nil
,
err
}
return
reply
,
nil
}
func
(
r
*
Reply
)
Write
(
w
io
.
Writer
)
(
err
error
)
{
var
b
[
8
]
byte
b
[
1
]
=
r
.
Code
if
r
.
Addr
!=
nil
{
if
err
=
r
.
Addr
.
Encode
(
b
[
2
:
]);
err
!=
nil
{
return
}
}
_
,
err
=
w
.
Write
(
b
[
:
])
return
}
func
(
r
*
Reply
)
String
()
string
{
addr
:=
r
.
Addr
if
addr
==
nil
{
addr
=
&
Addr
{}
}
return
fmt
.
Sprintf
(
"0 %d %s"
,
r
.
Code
,
addr
.
String
())
}
cmd/gost/vendor/github.com/ginuerzh/gosocks4/socks4.protocol.txt
0 → 100644
View file @
5efffa7d
SOCKS: A protocol for TCP proxy across firewalls
Ying-Da Lee
Principal Member Technical Staff
NEC Systems Laboratory, CSTC
ylee@syl.dl.nec.com
SOCKS was originally developed by David Koblas and subsequently modified
and extended by me to its current running version -- version 4. It is a
protocol that relays TCP sessions at a firewall host to allow application
users transparent access across the firewall. Because the protocol is
independent of application protocols, it can be (and has been) used for
many different services, such as telnet, ftp, finger, whois, gopher, WWW,
etc. Access control can be applied at the beginning of each TCP session;
thereafter the server simply relays the data between the client and the
application server, incurring minimum processing overhead. Since SOCKS
never has to know anything about the application protocol, it should also
be easy for it to accommodate applications which use encryption to protect
their traffic from nosey snoopers.
Two operations are defined: CONNECT and BIND.
1) CONNECT
The client connects to the SOCKS server and sends a CONNECT request when
it wants to establish a connection to an application server. The client
includes in the request packet the IP address and the port number of the
destination host, and userid, in the following format.
+----+----+----+----+----+----+----+----+----+----+....+----+
| VN | CD | DSTPORT | DSTIP | USERID |NULL|
+----+----+----+----+----+----+----+----+----+----+....+----+
# of bytes: 1 1 2 4 variable 1
VN is the SOCKS protocol version number and should be 4. CD is the
SOCKS command code and should be 1 for CONNECT request. NULL is a byte
of all zero bits.
The SOCKS server checks to see whether such a request should be granted
based on any combination of source IP address, destination IP address,
destination port number, the userid, and information it may obtain by
consulting IDENT, cf. RFC 1413. If the request is granted, the SOCKS
server makes a connection to the specified port of the destination host.
A reply packet is sent to the client when this connection is established,
or when the request is rejected or the operation fails.
+----+----+----+----+----+----+----+----+
| VN | CD | DSTPORT | DSTIP |
+----+----+----+----+----+----+----+----+
# of bytes: 1 1 2 4
VN is the version of the reply code and should be 0. CD is the result
code with one of the following values:
90: request granted
91: request rejected or failed
92: request rejected becasue SOCKS server cannot connect to
identd on the client
93: request rejected because the client program and identd
report different user-ids
The remaining fields are ignored.
The SOCKS server closes its connection immediately after notifying
the client of a failed or rejected request. For a successful request,
the SOCKS server gets ready to relay traffic on both directions. This
enables the client to do I/O on its connection as if it were directly
connected to the application server.
2) BIND
The client connects to the SOCKS server and sends a BIND request when
it wants to prepare for an inbound connection from an application server.
This should only happen after a primary connection to the application
server has been established with a CONNECT. Typically, this is part of
the sequence of actions:
-bind(): obtain a socket
-getsockname(): get the IP address and port number of the socket
-listen(): ready to accept call from the application server
-use the primary connection to inform the application server of
the IP address and the port number that it should connect to.
-accept(): accept a connection from the application server
The purpose of SOCKS BIND operation is to support such a sequence
but using a socket on the SOCKS server rather than on the client.
The client includes in the request packet the IP address of the
application server, the destination port used in the primary connection,
and the userid.
+----+----+----+----+----+----+----+----+----+----+....+----+
| VN | CD | DSTPORT | DSTIP | USERID |NULL|
+----+----+----+----+----+----+----+----+----+----+....+----+
# of bytes: 1 1 2 4 variable 1
VN is again 4 for the SOCKS protocol version number. CD must be 2 to
indicate BIND request.
The SOCKS server uses the client information to decide whether the
request is to be granted. The reply it sends back to the client has
the same format as the reply for CONNECT request, i.e.,
+----+----+----+----+----+----+----+----+
| VN | CD | DSTPORT | DSTIP |
+----+----+----+----+----+----+----+----+
# of bytes: 1 1 2 4
VN is the version of the reply code and should be 0. CD is the result
code with one of the following values:
90: request granted
91: request rejected or failed
92: request rejected becasue SOCKS server cannot connect to
identd on the client
93: request rejected because the client program and identd
report different user-ids.
However, for a granted request (CD is 90), the DSTPORT and DSTIP fields
are meaningful. In that case, the SOCKS server obtains a socket to wait
for an incoming connection and sends the port number and the IP address
of that socket to the client in DSTPORT and DSTIP, respectively. If the
DSTIP in the reply is 0 (the value of constant INADDR_ANY), then the
client should replace it by the IP address of the SOCKS server to which
the cleint is connected. (This happens if the SOCKS server is not a
multi-homed host.) In the typical scenario, these two numbers are
made available to the application client prgram via the result of the
subsequent getsockname() call. The application protocol must provide a
way for these two pieces of information to be sent from the client to
the application server so that it can initiate the connection, which
connects it to the SOCKS server rather than directly to the application
client as it normally would.
The SOCKS server sends a second reply packet to the client when the
anticipated connection from the application server is established.
The SOCKS server checks the IP address of the originating host against
the value of DSTIP specified in the client's BIND request. If a mismatch
is found, the CD field in the second reply is set to 91 and the SOCKS
server closes both connections. If the two match, CD in the second
reply is set to 90 and the SOCKS server gets ready to relay the traffic
on its two connections. From then on the client does I/O on its connection
to the SOCKS server as if it were directly connected to the application
server.
For both CONNECT and BIND operations, the server sets a time limit
(2 minutes in current CSTC implementation) for the establishment of its
connection with the application server. If the connection is still not
establiched when the time limit expires, the server closes its connection
to the client and gives up.
cmd/gost/vendor/github.com/ginuerzh/gosocks4/socks4a.protocol.txt
0 → 100644
View file @
5efffa7d
SOCKS 4A: A Simple Extension to SOCKS 4 Protocol
Ying-Da Lee
yingda@best.com or yingda@esd.sgi.com
Please read SOCKS4.protocol first for an description of the version 4
protocol. This extension is intended to allow the use of SOCKS on hosts
which are not capable of resolving all domain names.
In version 4, the client sends the following packet to the SOCKS server
to request a CONNECT or a BIND operation:
+----+----+----+----+----+----+----+----+----+----+....+----+
| VN | CD | DSTPORT | DSTIP | USERID |NULL|
+----+----+----+----+----+----+----+----+----+----+....+----+
# of bytes: 1 1 2 4 variable 1
VN is the SOCKS protocol version number and should be 4. CD is the
SOCKS command code and should be 1 for CONNECT or 2 for BIND. NULL
is a byte of all zero bits.
For version 4A, if the client cannot resolve the destination host's
domain name to find its IP address, it should set the first three bytes
of DSTIP to NULL and the last byte to a non-zero value. (This corresponds
to IP address 0.0.0.x, with x nonzero. As decreed by IANA -- The
Internet Assigned Numbers Authority -- such an address is inadmissible
as a destination IP address and thus should never occur if the client
can resolve the domain name.) Following the NULL byte terminating
USERID, the client must sends the destination domain name and termiantes
it with another NULL byte. This is used for both CONNECT and BIND requests.
A server using protocol 4A must check the DSTIP in the request packet.
If it represent address 0.0.0.x with nonzero x, the server must read
in the domain name that the client sends in the packet. The server
should resolve the domain name and make connection to the destination
host if it can.
SOCKSified sockd may pass domain names that it cannot resolve to
the next-hop SOCKS server.
cmd/gost/vendor/github.com/ginuerzh/gost/README.md
View file @
5efffa7d
...
@@ -9,7 +9,7 @@ gost - GO Simple Tunnel
...
@@ -9,7 +9,7 @@ gost - GO Simple Tunnel
------
------
*
可同时监听多端口
*
可同时监听多端口
*
可设置转发代理,支持多级转发(代理链)
*
可设置转发代理,支持多级转发(代理链)
*
支持标准HTTP/HTTPS/SOCKS5代理协议
*
支持标准HTTP/HTTPS/SOCKS
4(A)/SOCKS
5代理协议
*
SOCKS5代理支持TLS协商加密
*
SOCKS5代理支持TLS协商加密
*
Tunnel UDP over TCP
*
Tunnel UDP over TCP
*
支持Shadowsocks协议 (OTA: 2.2+,UDP: 2.4+)
*
支持Shadowsocks协议 (OTA: 2.2+,UDP: 2.4+)
...
@@ -36,7 +36,7 @@ Google讨论组: https://groups.google.com/d/forum/go-gost
...
@@ -36,7 +36,7 @@ Google讨论组: https://groups.google.com/d/forum/go-gost
```
```
scheme分为两部分: protocol+transport
scheme分为两部分: protocol+transport
protocol: 代理协议类型(http, socks
5, shadowsocks), transport: 数据传输方式(ws, wss, tls, http2, quic, kcp
), 二者可以任意组合,或单独使用:
protocol: 代理协议类型(http, socks
4(a), socks5, shadowsocks), transport: 数据传输方式(ws, wss, tls, http2, quic, kcp, pht
), 二者可以任意组合,或单独使用:
> http - HTTP代理: http://:8080
> http - HTTP代理: http://:8080
...
@@ -44,11 +44,13 @@ protocol: 代理协议类型(http, socks5, shadowsocks), transport: 数据传输
...
@@ -44,11 +44,13 @@ protocol: 代理协议类型(http, socks5, shadowsocks), transport: 数据传输
> http2 - HTTP2代理并向下兼容HTTPS代理: http2://:443
> http2 - HTTP2代理并向下兼容HTTPS代理: http2://:443
> socks - 标准SOCKS5代理(支持tls协商加密): socks://:1080
> socks4(a) - 标准SOCKS4(A)代理: socks4://:1080或socks4a://: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://chacha20:123456@:8338
> ss - Shadowsocks代理,ss://chacha20:123456@:8338
...
@@ -56,7 +58,9 @@ protocol: 代理协议类型(http, socks5, shadowsocks), transport: 数据传输
...
@@ -56,7 +58,9 @@ protocol: 代理协议类型(http, socks5, shadowsocks), transport: 数据传输
> quic - QUIC代理,quic://:6121
> quic - QUIC代理,quic://:6121
> kcp - KCP代理,kcp://:8388或kcp://aes:123456@:8388
> kcp - KCP通道,kcp://:8388或kcp://aes:123456@:8388
> pht - 普通HTTP通道,pht://:8080
> redirect - 透明代理,redirect://:12345
> redirect - 透明代理,redirect://:12345
...
...
cmd/gost/vendor/github.com/ginuerzh/gost/README_en.md
View file @
5efffa7d
...
@@ -7,7 +7,7 @@ Features
...
@@ -7,7 +7,7 @@ Features
------
------
*
Listening on multiple ports
*
Listening on multiple ports
*
Multi-level forward proxy - proxy chain
*
Multi-level forward proxy - proxy chain
*
Standard HTTP/HTTPS/SOCKS5 proxy protocols support
*
Standard HTTP/HTTPS/SOCKS
4(A)/SOCKS
5 proxy protocols support
*
TLS encryption via negotiation support for SOCKS5 proxy
*
TLS encryption via negotiation support for SOCKS5 proxy
*
Tunnel UDP over TCP
*
Tunnel UDP over TCP
*
Shadowsocks protocol support (OTA: 2.2+, UDP: 2.4+)
*
Shadowsocks protocol support (OTA: 2.2+, UDP: 2.4+)
...
@@ -35,8 +35,8 @@ Effective for the -L and -F parameters
...
@@ -35,8 +35,8 @@ Effective for the -L and -F parameters
```
```
scheme can be divided into two parts: protocol+transport
scheme can be divided into two parts: protocol+transport
protocol: proxy protocol types (http, socks5, shadowsocks),
protocol: proxy protocol types (http, socks
4(a), socks
5, shadowsocks),
transport: data transmission mode (ws, wss, tls, http2, quic, kcp), may be used in any combination or individually:
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 - standard HTTP proxy: http://:8080
...
@@ -44,11 +44,13 @@ transport: data transmission mode (ws, wss, tls, http2, quic, kcp), may be used
...
@@ -44,11 +44,13 @@ transport: data transmission mode (ws, wss, tls, http2, quic, kcp), may be used
> http2 - HTTP2 proxy and backwards-compatible with HTTPS proxy: http2://: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 - standard SOCKS5 proxy: socks://:1080
> socks+wss - SOCKS5 over websocket: socks+wss://:1080
> socks+wss - SOCKS5 over websocket: socks+wss://:1080
> tls - HTTPS/SOCKS5 over
tls
: tls://:443
> tls - HTTPS/SOCKS5 over
TLS
: tls://:443
> ss - standard shadowsocks proxy, ss://chacha20:123456@:8338
> ss - standard shadowsocks proxy, ss://chacha20:123456@:8338
...
@@ -58,6 +60,8 @@ transport: data transmission mode (ws, wss, tls, http2, quic, kcp), may be used
...
@@ -58,6 +60,8 @@ transport: data transmission mode (ws, wss, tls, http2, quic, kcp), may be used
> kcp - standard KCP tunnel,kcp://:8388 or kcp://aes:123456@:8388
> kcp - standard KCP tunnel,kcp://:8388 or kcp://aes:123456@:8388
> pht - plain HTTP tunnel, pht://:8080
> redirect - transparent proxy,redirect://:12345
> redirect - transparent proxy,redirect://:12345
#### Port forwarding
#### Port forwarding
...
...
cmd/gost/vendor/github.com/ginuerzh/gost/chain.go
View file @
5efffa7d
...
@@ -7,6 +7,7 @@ import (
...
@@ -7,6 +7,7 @@ import (
"errors"
"errors"
"github.com/ginuerzh/pht"
"github.com/ginuerzh/pht"
"github.com/golang/glog"
"github.com/golang/glog"
"github.com/lucas-clemente/quic-go/h2quic"
"golang.org/x/net/http2"
"golang.org/x/net/http2"
"io"
"io"
"net"
"net"
...
@@ -30,7 +31,8 @@ type ProxyChain struct {
...
@@ -30,7 +31,8 @@ type ProxyChain struct {
kcpConfig
*
KCPConfig
kcpConfig
*
KCPConfig
kcpSession
*
KCPSession
kcpSession
*
KCPSession
kcpMutex
sync
.
Mutex
kcpMutex
sync
.
Mutex
phttpClient
*
pht
.
Client
phtClient
*
pht
.
Client
quicClient
*
http
.
Client
}
}
func
NewProxyChain
(
nodes
...
ProxyNode
)
*
ProxyChain
{
func
NewProxyChain
(
nodes
...
ProxyNode
)
*
ProxyChain
{
...
@@ -121,9 +123,21 @@ func (c *ProxyChain) Init() {
...
@@ -121,9 +123,21 @@ func (c *ProxyChain) Init() {
return
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"
{
if
c
.
nodes
[
0
]
.
Transport
==
"pht"
{
glog
.
V
(
LINFO
)
.
Infoln
(
"Pure HTTP mode is enabled"
)
glog
.
V
(
LINFO
)
.
Infoln
(
"Pure HTTP mode is enabled"
)
c
.
pht
tp
Client
=
pht
.
NewClient
(
c
.
nodes
[
0
]
.
Addr
,
c
.
nodes
[
0
]
.
Get
(
"key"
))
c
.
phtClient
=
pht
.
NewClient
(
c
.
nodes
[
0
]
.
Addr
,
c
.
nodes
[
0
]
.
Get
(
"key"
))
}
}
}
}
...
@@ -249,6 +263,12 @@ func (c *ProxyChain) dialWithNodes(withHttp2 bool, addr string, nodes ...ProxyNo
...
@@ -249,6 +263,12 @@ func (c *ProxyChain) dialWithNodes(withHttp2 bool, addr string, nodes ...ProxyNo
return
c
.
http2Connect
(
addr
)
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
...
)
pc
,
err
:=
c
.
travelNodes
(
withHttp2
,
nodes
...
)
if
err
!=
nil
{
if
err
!=
nil
{
return
return
...
@@ -277,7 +297,7 @@ func (c *ProxyChain) travelNodes(withHttp2 bool, nodes ...ProxyNode) (conn *Prox
...
@@ -277,7 +297,7 @@ func (c *ProxyChain) travelNodes(withHttp2 bool, nodes ...ProxyNode) (conn *Prox
}
else
if
node
.
Transport
==
"kcp"
{
}
else
if
node
.
Transport
==
"kcp"
{
cc
,
err
=
c
.
getKCPConn
()
cc
,
err
=
c
.
getKCPConn
()
}
else
if
node
.
Transport
==
"pht"
{
}
else
if
node
.
Transport
==
"pht"
{
cc
,
err
=
c
.
pht
tp
Client
.
Dial
()
cc
,
err
=
c
.
phtClient
.
Dial
()
}
else
{
}
else
{
cc
,
err
=
net
.
DialTimeout
(
"tcp"
,
node
.
Addr
,
DialTimeout
)
cc
,
err
=
net
.
DialTimeout
(
"tcp"
,
node
.
Addr
,
DialTimeout
)
}
}
...
@@ -388,3 +408,63 @@ func (c *ProxyChain) http2Connect(addr string) (net.Conn, error) {
...
@@ -388,3 +408,63 @@ func (c *ProxyChain) http2Connect(addr string) (net.Conn, error) {
}
}
return
c
.
getHttp2Conn
(
header
)
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
}
cmd/gost/vendor/github.com/ginuerzh/gost/conn.go
View file @
5efffa7d
...
@@ -5,6 +5,8 @@ import (
...
@@ -5,6 +5,8 @@ import (
"crypto/tls"
"crypto/tls"
"encoding/base64"
"encoding/base64"
"errors"
"errors"
"fmt"
"github.com/ginuerzh/gosocks4"
"github.com/ginuerzh/gosocks5"
"github.com/ginuerzh/gosocks5"
"github.com/golang/glog"
"github.com/golang/glog"
ss
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
ss
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
...
@@ -179,6 +181,39 @@ func (c *ProxyConn) Connect(addr string) error {
...
@@ -179,6 +181,39 @@ func (c *ProxyConn) Connect(addr string) error {
if
reply
.
Rep
!=
gosocks5
.
Succeeded
{
if
reply
.
Rep
!=
gosocks5
.
Succeeded
{
return
errors
.
New
(
"Service unavailable"
)
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"
:
case
"http"
:
fallthrough
fallthrough
default
:
default
:
...
...
cmd/gost/vendor/github.com/ginuerzh/gost/node.go
View file @
5efffa7d
...
@@ -84,7 +84,7 @@ func ParseProxyNode(s string) (node ProxyNode, err error) {
...
@@ -84,7 +84,7 @@ func ParseProxyNode(s string) (node ProxyNode, err error) {
}
}
switch
node
.
Protocol
{
switch
node
.
Protocol
{
case
"http"
,
"http2"
,
"socks"
,
"socks5"
,
"ss"
:
case
"http"
,
"http2"
,
"socks"
,
"socks
4"
,
"socks4a"
,
"socks
5"
,
"ss"
:
default
:
default
:
node
.
Protocol
=
""
node
.
Protocol
=
""
}
}
...
...
cmd/gost/vendor/github.com/ginuerzh/gost/quic.go
View file @
5efffa7d
...
@@ -29,7 +29,8 @@ func (s *QuicServer) ListenAndServeTLS(config *tls.Config) error {
...
@@ -29,7 +29,8 @@ func (s *QuicServer) ListenAndServeTLS(config *tls.Config) error {
},
},
}
}
if
server
.
Handler
==
nil
{
if
server
.
Handler
==
nil
{
server
.
Handler
=
http
.
HandlerFunc
(
s
.
HandleRequest
)
// server.Handler = http.HandlerFunc(s.HandleRequest)
server
.
Handler
=
http
.
HandlerFunc
(
NewHttp2Server
(
s
.
Base
)
.
HandleRequest
)
}
}
return
server
.
ListenAndServe
()
return
server
.
ListenAndServe
()
}
}
...
...
cmd/gost/vendor/github.com/ginuerzh/gost/server.go
View file @
5efffa7d
...
@@ -3,6 +3,7 @@ package gost
...
@@ -3,6 +3,7 @@ package gost
import
(
import
(
"bufio"
"bufio"
"crypto/tls"
"crypto/tls"
"github.com/ginuerzh/gosocks4"
"github.com/ginuerzh/gosocks5"
"github.com/ginuerzh/gosocks5"
"github.com/golang/glog"
"github.com/golang/glog"
ss
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
ss
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
...
@@ -173,6 +174,14 @@ func (s *ProxyServer) handleConn(conn net.Conn) {
...
@@ -173,6 +174,14 @@ func (s *ProxyServer) handleConn(conn net.Conn) {
}
}
NewSocks5Server
(
conn
,
s
)
.
HandleRequest
(
req
)
NewSocks5Server
(
conn
,
s
)
.
HandleRequest
(
req
)
return
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
}
}
// http or socks5
// http or socks5
...
...
cmd/gost/vendor/github.com/ginuerzh/gost/socks.go
View file @
5efffa7d
...
@@ -3,12 +3,9 @@ package gost
...
@@ -3,12 +3,9 @@ package gost
import
(
import
(
"bytes"
"bytes"
"crypto/tls"
"crypto/tls"
//"errors
"
"github.com/ginuerzh/gosocks4
"
"github.com/ginuerzh/gosocks5"
"github.com/ginuerzh/gosocks5"
"github.com/golang/glog"
"github.com/golang/glog"
//"os/exec"
//"io"
//"io/ioutil"
"net"
"net"
"net/url"
"net/url"
"strconv"
"strconv"
...
@@ -672,3 +669,78 @@ func ToSocksAddr(addr net.Addr) *gosocks5.Addr {
...
@@ -672,3 +669,78 @@ func ToSocksAddr(addr net.Addr) *gosocks5.Addr {
Port
:
uint16
(
port
),
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
())
}
conn.go
View file @
5efffa7d
...
@@ -5,6 +5,8 @@ import (
...
@@ -5,6 +5,8 @@ import (
"crypto/tls"
"crypto/tls"
"encoding/base64"
"encoding/base64"
"errors"
"errors"
"fmt"
"github.com/ginuerzh/gosocks4"
"github.com/ginuerzh/gosocks5"
"github.com/ginuerzh/gosocks5"
"github.com/golang/glog"
"github.com/golang/glog"
ss
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
ss
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
...
@@ -179,6 +181,39 @@ func (c *ProxyConn) Connect(addr string) error {
...
@@ -179,6 +181,39 @@ func (c *ProxyConn) Connect(addr string) error {
if
reply
.
Rep
!=
gosocks5
.
Succeeded
{
if
reply
.
Rep
!=
gosocks5
.
Succeeded
{
return
errors
.
New
(
"Service unavailable"
)
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"
:
case
"http"
:
fallthrough
fallthrough
default
:
default
:
...
...
node.go
View file @
5efffa7d
...
@@ -84,7 +84,7 @@ func ParseProxyNode(s string) (node ProxyNode, err error) {
...
@@ -84,7 +84,7 @@ func ParseProxyNode(s string) (node ProxyNode, err error) {
}
}
switch
node
.
Protocol
{
switch
node
.
Protocol
{
case
"http"
,
"http2"
,
"socks"
,
"socks5"
,
"ss"
:
case
"http"
,
"http2"
,
"socks"
,
"socks
4"
,
"socks4a"
,
"socks
5"
,
"ss"
:
default
:
default
:
node
.
Protocol
=
""
node
.
Protocol
=
""
}
}
...
...
quic.go
View file @
5efffa7d
...
@@ -29,7 +29,8 @@ func (s *QuicServer) ListenAndServeTLS(config *tls.Config) error {
...
@@ -29,7 +29,8 @@ func (s *QuicServer) ListenAndServeTLS(config *tls.Config) error {
},
},
}
}
if
server
.
Handler
==
nil
{
if
server
.
Handler
==
nil
{
server
.
Handler
=
http
.
HandlerFunc
(
s
.
HandleRequest
)
// server.Handler = http.HandlerFunc(s.HandleRequest)
server
.
Handler
=
http
.
HandlerFunc
(
NewHttp2Server
(
s
.
Base
)
.
HandleRequest
)
}
}
return
server
.
ListenAndServe
()
return
server
.
ListenAndServe
()
}
}
...
...
server.go
View file @
5efffa7d
...
@@ -3,6 +3,7 @@ package gost
...
@@ -3,6 +3,7 @@ package gost
import
(
import
(
"bufio"
"bufio"
"crypto/tls"
"crypto/tls"
"github.com/ginuerzh/gosocks4"
"github.com/ginuerzh/gosocks5"
"github.com/ginuerzh/gosocks5"
"github.com/golang/glog"
"github.com/golang/glog"
ss
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
ss
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
...
@@ -173,6 +174,14 @@ func (s *ProxyServer) handleConn(conn net.Conn) {
...
@@ -173,6 +174,14 @@ func (s *ProxyServer) handleConn(conn net.Conn) {
}
}
NewSocks5Server
(
conn
,
s
)
.
HandleRequest
(
req
)
NewSocks5Server
(
conn
,
s
)
.
HandleRequest
(
req
)
return
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
}
}
// http or socks5
// http or socks5
...
...
socks.go
View file @
5efffa7d
...
@@ -3,12 +3,9 @@ package gost
...
@@ -3,12 +3,9 @@ package gost
import
(
import
(
"bytes"
"bytes"
"crypto/tls"
"crypto/tls"
//"errors
"
"github.com/ginuerzh/gosocks4
"
"github.com/ginuerzh/gosocks5"
"github.com/ginuerzh/gosocks5"
"github.com/golang/glog"
"github.com/golang/glog"
//"os/exec"
//"io"
//"io/ioutil"
"net"
"net"
"net/url"
"net/url"
"strconv"
"strconv"
...
@@ -672,3 +669,78 @@ func ToSocksAddr(addr net.Addr) *gosocks5.Addr {
...
@@ -672,3 +669,78 @@ func ToSocksAddr(addr net.Addr) *gosocks5.Addr {
Port
:
uint16
(
port
),
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
())
}
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