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
bb1afcc4
Commit
bb1afcc4
authored
Dec 26, 2018
by
ginuerzh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add more tests
parent
d3b03e42
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
609 additions
and
46 deletions
+609
-46
Dockerfile.mod
Dockerfile.mod
+21
-0
cmd/gost/route.go
cmd/gost/route.go
+7
-1
http2.go
http2.go
+7
-2
obfs.go
obfs.go
+25
-38
obfs_test.go
obfs_test.go
+371
-0
ssh.go
ssh.go
+8
-5
ssh_test.go
ssh_test.go
+170
-0
No files found.
Dockerfile.mod
0 → 100644
View file @
bb1afcc4
FROM golang:1-alpine as builder
RUN apk add --no-cache musl-dev git gcc
ADD . /data
WORKDIR /data
ENV GO111MODULE=on
RUN cd cmd/gost && go build
FROM alpine:latest
WORKDIR /bin/
COPY --from=builder /data/cmd/gost/gost .
RUN /bin/gost -V
ENTRYPOINT ["/bin/gost"]
\ No newline at end of file
cmd/gost/route.go
View file @
bb1afcc4
...
...
@@ -110,6 +110,8 @@ func parseChainNode(ns string) (nodes []gost.Node, err error) {
wsOpts
.
WriteBufferSize
=
node
.
GetInt
(
"wbuf"
)
wsOpts
.
UserAgent
=
node
.
Get
(
"agent"
)
var
host
string
var
tr
gost
.
Transporter
switch
node
.
Transport
{
case
"tls"
:
...
...
@@ -160,6 +162,7 @@ func parseChainNode(ns string) (nodes []gost.Node, err error) {
case
"obfs4"
:
tr
=
gost
.
Obfs4Transporter
()
case
"ohttp"
:
host
=
node
.
Get
(
"host"
)
tr
=
gost
.
ObfsHTTPTransporter
()
default
:
tr
=
gost
.
TCPTransporter
()
...
...
@@ -197,9 +200,12 @@ func parseChainNode(ns string) (nodes []gost.Node, err error) {
gost
.
TimeoutDialOption
(
time
.
Duration
(
timeout
)
*
time
.
Second
),
)
if
host
==
""
{
host
=
node
.
Host
}
handshakeOptions
:=
[]
gost
.
HandshakeOption
{
gost
.
AddrHandshakeOption
(
node
.
Addr
),
gost
.
HostHandshakeOption
(
node
.
H
ost
),
gost
.
HostHandshakeOption
(
h
ost
),
gost
.
UserHandshakeOption
(
node
.
User
),
gost
.
TLSConfigHandshakeOption
(
tlsCfg
),
gost
.
IntervalHandshakeOption
(
time
.
Duration
(
node
.
GetInt
(
"ping"
))
*
time
.
Second
),
...
...
http2.go
View file @
bb1afcc4
...
...
@@ -34,6 +34,11 @@ func HTTP2Connector(user *url.Userinfo) Connector {
}
func
(
c
*
http2Connector
)
Connect
(
conn
net
.
Conn
,
addr
string
,
options
...
ConnectOption
)
(
net
.
Conn
,
error
)
{
opts
:=
&
ConnectOptions
{}
for
_
,
option
:=
range
options
{
option
(
opts
)
}
cc
,
ok
:=
conn
.
(
*
http2ClientConn
)
if
!
ok
{
return
nil
,
errors
.
New
(
"wrong connection type"
)
...
...
@@ -142,7 +147,7 @@ func (tr *http2Transporter) Dial(addr string, options ...DialOption) (net.Conn,
}
client
=
&
http
.
Client
{
Transport
:
&
transport
,
Timeout
:
timeout
,
//
Timeout: timeout,
}
tr
.
clients
[
addr
]
=
client
}
...
...
@@ -214,7 +219,7 @@ func (tr *h2Transporter) Dial(addr string, options ...DialOption) (net.Conn, err
}
client
=
&
http
.
Client
{
Transport
:
&
transport
,
Timeout
:
timeout
,
//
Timeout: timeout,
}
tr
.
clients
[
addr
]
=
client
}
...
...
obfs.go
View file @
bb1afcc4
...
...
@@ -67,10 +67,7 @@ func (l *obfsHTTPListener) Accept() (net.Conn, error) {
type
obfsHTTPConn
struct
{
net
.
Conn
host
string
request
*
http
.
Request
response
*
http
.
Response
rbuf
[]
byte
wbuf
[]
byte
buf
[]
byte
isServer
bool
handshaked
bool
handshakeMutex
sync
.
Mutex
...
...
@@ -99,19 +96,19 @@ func (c *obfsHTTPConn) Handshake() (err error) {
func
(
c
*
obfsHTTPConn
)
serverHandshake
()
(
err
error
)
{
br
:=
bufio
.
NewReader
(
c
.
Conn
)
c
.
request
,
err
=
http
.
ReadRequest
(
br
)
r
,
err
:
=
http
.
ReadRequest
(
br
)
if
err
!=
nil
{
return
}
if
Debug
{
dump
,
_
:=
httputil
.
DumpRequest
(
c
.
request
,
false
)
dump
,
_
:=
httputil
.
DumpRequest
(
r
,
false
)
log
.
Logf
(
"[ohttp] %s -> %s
\n
%s"
,
c
.
Conn
.
RemoteAddr
(),
c
.
Conn
.
LocalAddr
(),
string
(
dump
))
}
if
br
.
Buffered
()
>
0
{
c
.
rbuf
,
err
=
br
.
Peek
(
br
.
Buffered
()
)
if
r
.
ContentLength
>
0
{
c
.
buf
,
err
=
ioutil
.
ReadAll
(
r
.
Body
)
}
else
{
c
.
rbuf
,
err
=
ioutil
.
ReadAll
(
c
.
request
.
Body
)
c
.
buf
,
err
=
br
.
Peek
(
br
.
Buffered
()
)
}
if
err
!=
nil
{
...
...
@@ -120,13 +117,13 @@ func (c *obfsHTTPConn) serverHandshake() (err error) {
}
b
:=
bytes
.
Buffer
{}
if
c
.
request
.
Header
.
Get
(
"Upgrade"
)
==
"websocket"
{
if
r
.
Header
.
Get
(
"Upgrade"
)
==
"websocket"
{
b
.
WriteString
(
"HTTP/1.1 101 Switching Protocols
\r\n
"
)
b
.
WriteString
(
"Server: nginx/1.10.0
\r\n
"
)
b
.
WriteString
(
"Date: "
+
time
.
Now
()
.
Format
(
time
.
RFC1123
)
+
"
\r\n
"
)
b
.
WriteString
(
"Connection: Upgrade
\r\n
"
)
b
.
WriteString
(
"Upgrade: websocket
\r\n
"
)
b
.
WriteString
(
fmt
.
Sprintf
(
"Sec-WebSocket-Accept: %s
\r\n
"
,
computeAcceptKey
(
c
.
request
.
Header
.
Get
(
"Sec-WebSocket-Key"
))))
b
.
WriteString
(
fmt
.
Sprintf
(
"Sec-WebSocket-Accept: %s
\r\n
"
,
computeAcceptKey
(
r
.
Header
.
Get
(
"Sec-WebSocket-Key"
))))
b
.
WriteString
(
"
\r\n
"
)
}
else
{
b
.
WriteString
(
"HTTP/1.1 200 OK
\r\n
"
)
...
...
@@ -146,24 +143,19 @@ func (c *obfsHTTPConn) serverHandshake() (err error) {
}
func
(
c
*
obfsHTTPConn
)
clientHandshake
()
(
err
error
)
{
r
:=
c
.
request
if
r
==
nil
{
r
=
&
http
.
Request
{
Method
:
http
.
MethodGet
,
ProtoMajor
:
1
,
ProtoMinor
:
1
,
URL
:
&
url
.
URL
{
Scheme
:
"http"
,
Host
:
c
.
host
},
Header
:
make
(
http
.
Header
),
}
r
.
Header
.
Set
(
"Connection"
,
"keep-alive"
)
r
.
Header
.
Set
(
"Upgrade"
,
"websocket"
)
r
.
Header
.
Set
(
"User-Agent"
,
DefaultUserAgent
)
if
len
(
c
.
wbuf
)
>
0
{
log
.
Log
(
"write buf"
,
len
(
c
.
wbuf
))
r
.
Body
=
ioutil
.
NopCloser
(
bytes
.
NewReader
(
c
.
wbuf
))
r
.
ContentLength
=
int64
(
len
(
c
.
wbuf
))
}
}
r
:=
&
http
.
Request
{
Method
:
http
.
MethodGet
,
ProtoMajor
:
1
,
ProtoMinor
:
1
,
URL
:
&
url
.
URL
{
Scheme
:
"http"
,
Host
:
c
.
host
},
Header
:
make
(
http
.
Header
),
}
r
.
Header
.
Set
(
"User-Agent"
,
"curl/7.49.1"
)
r
.
Header
.
Set
(
"Connection"
,
"Upgrade"
)
r
.
Header
.
Set
(
"Upgrade"
,
"websocket"
)
key
,
_
:=
generateChallengeKey
()
r
.
Header
.
Set
(
"Sec-WebSocket-Key"
,
key
)
if
err
=
r
.
Write
(
c
.
Conn
);
err
!=
nil
{
return
}
...
...
@@ -182,6 +174,7 @@ func (c *obfsHTTPConn) clientHandshake() (err error) {
dump
,
_
:=
httputil
.
DumpResponse
(
resp
,
false
)
log
.
Logf
(
"[ohttp] %s <- %s
\n
%s"
,
c
.
Conn
.
LocalAddr
(),
c
.
Conn
.
RemoteAddr
(),
string
(
dump
))
}
return
nil
}
...
...
@@ -189,24 +182,18 @@ func (c *obfsHTTPConn) Read(b []byte) (n int, err error) {
if
err
=
c
.
Handshake
();
err
!=
nil
{
return
}
if
len
(
c
.
r
buf
)
>
0
{
n
=
copy
(
b
,
c
.
r
buf
)
c
.
rbuf
=
c
.
r
buf
[
n
:
]
if
len
(
c
.
buf
)
>
0
{
n
=
copy
(
b
,
c
.
buf
)
c
.
buf
=
c
.
buf
[
n
:
]
return
}
return
c
.
Conn
.
Read
(
b
)
}
func
(
c
*
obfsHTTPConn
)
Write
(
b
[]
byte
)
(
n
int
,
err
error
)
{
handshaked
:=
c
.
handshaked
c
.
wbuf
=
b
if
err
=
c
.
Handshake
();
err
!=
nil
{
return
}
if
!
handshaked
{
n
=
len
(
c
.
wbuf
)
return
}
return
c
.
Conn
.
Write
(
b
)
}
...
...
obfs_test.go
0 → 100644
View file @
bb1afcc4
package
gost
import
(
"crypto/rand"
"fmt"
"net/http/httptest"
"net/url"
"testing"
)
func
httpOverObfsHTTPRoundtrip
(
targetURL
string
,
data
[]
byte
,
clientInfo
*
url
.
Userinfo
,
serverInfo
[]
*
url
.
Userinfo
)
error
{
ln
,
err
:=
ObfsHTTPListener
(
""
)
if
err
!=
nil
{
return
err
}
client
:=
&
Client
{
Connector
:
HTTPConnector
(
clientInfo
),
Transporter
:
ObfsHTTPTransporter
(),
}
server
:=
&
Server
{
Listener
:
ln
,
Handler
:
HTTPHandler
(
UsersHandlerOption
(
serverInfo
...
),
),
}
go
server
.
Run
()
defer
server
.
Close
()
return
proxyRoundtrip
(
client
,
server
,
targetURL
,
data
)
}
func
TestHTTPOverObfsHTTP
(
t
*
testing
.
T
)
{
httpSrv
:=
httptest
.
NewServer
(
httpTestHandler
)
defer
httpSrv
.
Close
()
sendData
:=
make
([]
byte
,
128
)
rand
.
Read
(
sendData
)
for
i
,
tc
:=
range
httpProxyTests
{
tc
:=
tc
t
.
Run
(
fmt
.
Sprintf
(
"#%d"
,
i
),
func
(
t
*
testing
.
T
)
{
err
:=
httpOverObfsHTTPRoundtrip
(
httpSrv
.
URL
,
sendData
,
tc
.
cliUser
,
tc
.
srvUsers
)
if
err
==
nil
{
if
tc
.
errStr
!=
""
{
t
.
Errorf
(
"#%d should failed with error %s"
,
i
,
tc
.
errStr
)
}
}
else
{
if
tc
.
errStr
==
""
{
t
.
Errorf
(
"#%d got error %v"
,
i
,
err
)
}
if
err
.
Error
()
!=
tc
.
errStr
{
t
.
Errorf
(
"#%d got error %v, want %v"
,
i
,
err
,
tc
.
errStr
)
}
}
})
}
}
func
BenchmarkHTTPOverObfsHTTP
(
b
*
testing
.
B
)
{
httpSrv
:=
httptest
.
NewServer
(
httpTestHandler
)
defer
httpSrv
.
Close
()
sendData
:=
make
([]
byte
,
128
)
rand
.
Read
(
sendData
)
ln
,
err
:=
ObfsHTTPListener
(
""
)
if
err
!=
nil
{
b
.
Error
(
err
)
}
// b.Log(ln.Addr())
client
:=
&
Client
{
Connector
:
HTTPConnector
(
url
.
UserPassword
(
"admin"
,
"123456"
)),
Transporter
:
ObfsHTTPTransporter
(),
}
server
:=
&
Server
{
Listener
:
ln
,
Handler
:
HTTPHandler
(
UsersHandlerOption
(
url
.
UserPassword
(
"admin"
,
"123456"
)),
),
}
go
server
.
Run
()
defer
server
.
Close
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
if
err
:=
proxyRoundtrip
(
client
,
server
,
httpSrv
.
URL
,
sendData
);
err
!=
nil
{
b
.
Error
(
err
)
}
}
}
func
BenchmarkHTTPOverObfsHTTPParallel
(
b
*
testing
.
B
)
{
httpSrv
:=
httptest
.
NewServer
(
httpTestHandler
)
defer
httpSrv
.
Close
()
sendData
:=
make
([]
byte
,
128
)
rand
.
Read
(
sendData
)
ln
,
err
:=
ObfsHTTPListener
(
""
)
if
err
!=
nil
{
b
.
Error
(
err
)
}
client
:=
&
Client
{
Connector
:
HTTPConnector
(
url
.
UserPassword
(
"admin"
,
"123456"
)),
Transporter
:
ObfsHTTPTransporter
(),
}
server
:=
&
Server
{
Listener
:
ln
,
Handler
:
HTTPHandler
(
UsersHandlerOption
(
url
.
UserPassword
(
"admin"
,
"123456"
)),
),
}
go
server
.
Run
()
defer
server
.
Close
()
b
.
RunParallel
(
func
(
pb
*
testing
.
PB
)
{
for
pb
.
Next
()
{
if
err
:=
proxyRoundtrip
(
client
,
server
,
httpSrv
.
URL
,
sendData
);
err
!=
nil
{
b
.
Error
(
err
)
}
}
})
}
func
socks5OverObfsHTTPRoundtrip
(
targetURL
string
,
data
[]
byte
,
clientInfo
*
url
.
Userinfo
,
serverInfo
[]
*
url
.
Userinfo
)
error
{
ln
,
err
:=
ObfsHTTPListener
(
""
)
if
err
!=
nil
{
return
err
}
client
:=
&
Client
{
Connector
:
SOCKS5Connector
(
clientInfo
),
Transporter
:
ObfsHTTPTransporter
(),
}
server
:=
&
Server
{
Listener
:
ln
,
Handler
:
SOCKS5Handler
(
UsersHandlerOption
(
serverInfo
...
),
),
}
go
server
.
Run
()
defer
server
.
Close
()
return
proxyRoundtrip
(
client
,
server
,
targetURL
,
data
)
}
func
TestSOCKS5OverObfsHTTP
(
t
*
testing
.
T
)
{
httpSrv
:=
httptest
.
NewServer
(
httpTestHandler
)
defer
httpSrv
.
Close
()
sendData
:=
make
([]
byte
,
128
)
rand
.
Read
(
sendData
)
for
i
,
tc
:=
range
socks5ProxyTests
{
err
:=
socks5OverObfsHTTPRoundtrip
(
httpSrv
.
URL
,
sendData
,
tc
.
cliUser
,
tc
.
srvUsers
,
)
if
err
==
nil
{
if
!
tc
.
pass
{
t
.
Errorf
(
"#%d should failed"
,
i
)
}
}
else
{
// t.Logf("#%d %v", i, err)
if
tc
.
pass
{
t
.
Errorf
(
"#%d got error: %v"
,
i
,
err
)
}
}
}
}
func
socks4OverObfsHTTPRoundtrip
(
targetURL
string
,
data
[]
byte
)
error
{
ln
,
err
:=
ObfsHTTPListener
(
""
)
if
err
!=
nil
{
return
err
}
client
:=
&
Client
{
Connector
:
SOCKS4Connector
(),
Transporter
:
ObfsHTTPTransporter
(),
}
server
:=
&
Server
{
Listener
:
ln
,
Handler
:
SOCKS4Handler
(),
}
go
server
.
Run
()
defer
server
.
Close
()
return
proxyRoundtrip
(
client
,
server
,
targetURL
,
data
)
}
func
TestSOCKS4OverObfsHTTP
(
t
*
testing
.
T
)
{
httpSrv
:=
httptest
.
NewServer
(
httpTestHandler
)
defer
httpSrv
.
Close
()
sendData
:=
make
([]
byte
,
128
)
rand
.
Read
(
sendData
)
err
:=
socks4OverObfsHTTPRoundtrip
(
httpSrv
.
URL
,
sendData
)
// t.Logf("#%d %v", i, err)
if
err
!=
nil
{
t
.
Errorf
(
"got error: %v"
,
err
)
}
}
func
socks4aOverObfsHTTPRoundtrip
(
targetURL
string
,
data
[]
byte
)
error
{
ln
,
err
:=
ObfsHTTPListener
(
""
)
if
err
!=
nil
{
return
err
}
client
:=
&
Client
{
Connector
:
SOCKS4AConnector
(),
Transporter
:
ObfsHTTPTransporter
(),
}
server
:=
&
Server
{
Listener
:
ln
,
Handler
:
SOCKS4Handler
(),
}
go
server
.
Run
()
defer
server
.
Close
()
return
proxyRoundtrip
(
client
,
server
,
targetURL
,
data
)
}
func
TestSOCKS4AOverObfsHTTP
(
t
*
testing
.
T
)
{
httpSrv
:=
httptest
.
NewServer
(
httpTestHandler
)
defer
httpSrv
.
Close
()
sendData
:=
make
([]
byte
,
128
)
rand
.
Read
(
sendData
)
err
:=
socks4aOverObfsHTTPRoundtrip
(
httpSrv
.
URL
,
sendData
)
// t.Logf("#%d %v", i, err)
if
err
!=
nil
{
t
.
Errorf
(
"got error: %v"
,
err
)
}
}
func
ssOverObfsHTTPRoundtrip
(
targetURL
string
,
data
[]
byte
,
clientInfo
,
serverInfo
*
url
.
Userinfo
)
error
{
ln
,
err
:=
ObfsHTTPListener
(
""
)
if
err
!=
nil
{
return
err
}
client
:=
&
Client
{
Connector
:
ShadowConnector
(
clientInfo
),
Transporter
:
ObfsHTTPTransporter
(),
}
server
:=
&
Server
{
Listener
:
ln
,
Handler
:
ShadowHandler
(
UsersHandlerOption
(
serverInfo
),
),
}
go
server
.
Run
()
defer
server
.
Close
()
return
proxyRoundtrip
(
client
,
server
,
targetURL
,
data
)
}
func
TestSSOverObfsHTTP
(
t
*
testing
.
T
)
{
httpSrv
:=
httptest
.
NewServer
(
httpTestHandler
)
defer
httpSrv
.
Close
()
sendData
:=
make
([]
byte
,
128
)
rand
.
Read
(
sendData
)
for
i
,
tc
:=
range
ssProxyTests
{
err
:=
ssOverObfsHTTPRoundtrip
(
httpSrv
.
URL
,
sendData
,
tc
.
clientCipher
,
tc
.
serverCipher
,
)
if
err
==
nil
{
if
!
tc
.
pass
{
t
.
Errorf
(
"#%d should failed"
,
i
)
}
}
else
{
// t.Logf("#%d %v", i, err)
if
tc
.
pass
{
t
.
Errorf
(
"#%d got error: %v"
,
i
,
err
)
}
}
}
}
func
sniOverObfsHTTPRoundtrip
(
targetURL
string
,
data
[]
byte
,
host
string
)
error
{
ln
,
err
:=
ObfsHTTPListener
(
""
)
if
err
!=
nil
{
return
err
}
u
,
err
:=
url
.
Parse
(
targetURL
)
if
err
!=
nil
{
return
err
}
client
:=
&
Client
{
Connector
:
SNIConnector
(
host
),
Transporter
:
ObfsHTTPTransporter
(),
}
server
:=
&
Server
{
Listener
:
ln
,
Handler
:
SNIHandler
(
HostHandlerOption
(
u
.
Host
)),
}
go
server
.
Run
()
defer
server
.
Close
()
return
sniRoundtrip
(
client
,
server
,
targetURL
,
data
)
}
func
TestSNIOverObfsHTTP
(
t
*
testing
.
T
)
{
httpSrv
:=
httptest
.
NewServer
(
httpTestHandler
)
defer
httpSrv
.
Close
()
httpsSrv
:=
httptest
.
NewTLSServer
(
httpTestHandler
)
defer
httpsSrv
.
Close
()
sendData
:=
make
([]
byte
,
128
)
rand
.
Read
(
sendData
)
var
sniProxyTests
=
[]
struct
{
targetURL
string
host
string
pass
bool
}{
{
httpSrv
.
URL
,
""
,
true
},
{
httpSrv
.
URL
,
"example.com"
,
true
},
{
httpsSrv
.
URL
,
""
,
true
},
{
httpsSrv
.
URL
,
"example.com"
,
true
},
}
for
i
,
tc
:=
range
sniProxyTests
{
tc
:=
tc
t
.
Run
(
fmt
.
Sprintf
(
"#%d"
,
i
),
func
(
t
*
testing
.
T
)
{
err
:=
sniOverObfsHTTPRoundtrip
(
tc
.
targetURL
,
sendData
,
tc
.
host
)
if
err
==
nil
{
if
!
tc
.
pass
{
t
.
Errorf
(
"#%d should failed"
,
i
)
}
}
else
{
// t.Logf("#%d %v", i, err)
if
tc
.
pass
{
t
.
Errorf
(
"#%d got error: %v"
,
i
,
err
)
}
}
})
}
}
ssh.go
View file @
bb1afcc4
...
...
@@ -95,13 +95,15 @@ func (c *sshRemoteForwardConnector) Connect(conn net.Conn, addr string, options
if
err
!=
nil
{
return
}
log
.
Log
(
"[ssh-rtcp] listening on"
,
ln
.
Addr
())
for
{
rc
,
err
:=
ln
.
Accept
()
if
err
!=
nil
{
log
.
Logf
(
"[ssh-rtcp] %s <-> %s accpet : %s"
,
ln
.
Addr
(),
addr
,
err
)
return
}
// log.Log("[ssh-rtcp] accept", rc.LocalAddr(), rc.RemoteAddr())
select
{
case
cc
.
session
.
connChan
<-
rc
:
default
:
...
...
@@ -593,7 +595,6 @@ func (h *sshForwardHandler) tcpipForwardRequest(sshConn ssh.Conn, req *ssh.Reque
return
}
log
.
Log
(
"[ssh-rtcp] listening on tcp"
,
addr
)
ln
,
err
:=
net
.
Listen
(
"tcp"
,
addr
)
//tie to the client connection
if
err
!=
nil
{
log
.
Log
(
"[ssh-rtcp]"
,
err
)
...
...
@@ -602,6 +603,8 @@ func (h *sshForwardHandler) tcpipForwardRequest(sshConn ssh.Conn, req *ssh.Reque
}
defer
ln
.
Close
()
log
.
Log
(
"[ssh-rtcp] listening on tcp"
,
ln
.
Addr
())
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
())
...
...
@@ -850,15 +853,15 @@ func (c *sshNopConn) RemoteAddr() net.Addr {
}
func
(
c
*
sshNopConn
)
SetDeadline
(
t
time
.
Time
)
error
{
return
&
net
.
OpError
{
Op
:
"set"
,
Net
:
"
http2
"
,
Source
:
nil
,
Addr
:
nil
,
Err
:
errors
.
New
(
"deadline not supported"
)}
return
&
net
.
OpError
{
Op
:
"set"
,
Net
:
"
ssh
"
,
Source
:
nil
,
Addr
:
nil
,
Err
:
errors
.
New
(
"deadline not supported"
)}
}
func
(
c
*
sshNopConn
)
SetReadDeadline
(
t
time
.
Time
)
error
{
return
&
net
.
OpError
{
Op
:
"set"
,
Net
:
"
http2
"
,
Source
:
nil
,
Addr
:
nil
,
Err
:
errors
.
New
(
"deadline not supported"
)}
return
&
net
.
OpError
{
Op
:
"set"
,
Net
:
"
ssh
"
,
Source
:
nil
,
Addr
:
nil
,
Err
:
errors
.
New
(
"deadline not supported"
)}
}
func
(
c
*
sshNopConn
)
SetWriteDeadline
(
t
time
.
Time
)
error
{
return
&
net
.
OpError
{
Op
:
"set"
,
Net
:
"
http2
"
,
Source
:
nil
,
Addr
:
nil
,
Err
:
errors
.
New
(
"deadline not supported"
)}
return
&
net
.
OpError
{
Op
:
"set"
,
Net
:
"
ssh
"
,
Source
:
nil
,
Addr
:
nil
,
Err
:
errors
.
New
(
"deadline not supported"
)}
}
type
sshConn
struct
{
...
...
ssh_test.go
View file @
bb1afcc4
...
...
@@ -4,11 +4,181 @@ import (
"crypto/rand"
"crypto/tls"
"fmt"
"net"
"net/http/httptest"
"net/url"
"testing"
)
func
sshDirectForwardRoundtrip
(
targetURL
string
,
data
[]
byte
)
error
{
ln
,
err
:=
TCPListener
(
""
)
if
err
!=
nil
{
return
err
}
client
:=
&
Client
{
Connector
:
SSHDirectForwardConnector
(),
Transporter
:
SSHForwardTransporter
(),
}
server
:=
&
Server
{
Listener
:
ln
,
Handler
:
SSHForwardHandler
(),
}
go
server
.
Run
()
defer
server
.
Close
()
return
proxyRoundtrip
(
client
,
server
,
targetURL
,
data
)
}
func
TestSSHDirectForward
(
t
*
testing
.
T
)
{
httpSrv
:=
httptest
.
NewServer
(
httpTestHandler
)
defer
httpSrv
.
Close
()
sendData
:=
make
([]
byte
,
128
)
rand
.
Read
(
sendData
)
err
:=
sshDirectForwardRoundtrip
(
httpSrv
.
URL
,
sendData
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
}
func
BenchmarkSSHDirectForward
(
b
*
testing
.
B
)
{
httpSrv
:=
httptest
.
NewServer
(
httpTestHandler
)
defer
httpSrv
.
Close
()
sendData
:=
make
([]
byte
,
128
)
rand
.
Read
(
sendData
)
ln
,
err
:=
TCPListener
(
""
)
if
err
!=
nil
{
b
.
Error
(
err
)
}
client
:=
&
Client
{
Connector
:
SSHDirectForwardConnector
(),
Transporter
:
SSHForwardTransporter
(),
}
server
:=
&
Server
{
Listener
:
ln
,
Handler
:
SSHForwardHandler
(),
}
go
server
.
Run
()
defer
server
.
Close
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
if
err
:=
proxyRoundtrip
(
client
,
server
,
httpSrv
.
URL
,
sendData
);
err
!=
nil
{
b
.
Error
(
err
)
}
}
}
func
BenchmarkSSHDirectForwardParallel
(
b
*
testing
.
B
)
{
httpSrv
:=
httptest
.
NewServer
(
httpTestHandler
)
defer
httpSrv
.
Close
()
sendData
:=
make
([]
byte
,
128
)
rand
.
Read
(
sendData
)
ln
,
err
:=
TCPListener
(
""
)
if
err
!=
nil
{
b
.
Error
(
err
)
}
client
:=
&
Client
{
Connector
:
SSHDirectForwardConnector
(),
Transporter
:
SSHForwardTransporter
(),
}
server
:=
&
Server
{
Listener
:
ln
,
Handler
:
SSHForwardHandler
(),
}
go
server
.
Run
()
defer
server
.
Close
()
b
.
RunParallel
(
func
(
pb
*
testing
.
PB
)
{
for
pb
.
Next
()
{
if
err
:=
proxyRoundtrip
(
client
,
server
,
httpSrv
.
URL
,
sendData
);
err
!=
nil
{
b
.
Error
(
err
)
}
}
})
}
func
sshRemoteForwardRoundtrip
(
t
*
testing
.
T
,
targetURL
string
,
data
[]
byte
)
(
err
error
)
{
ln
,
err
:=
TCPListener
(
""
)
if
err
!=
nil
{
return
}
client
:=
&
Client
{
Connector
:
SSHRemoteForwardConnector
(),
Transporter
:
SSHForwardTransporter
(),
}
server
:=
&
Server
{
Listener
:
ln
,
Handler
:
SSHForwardHandler
(),
}
go
server
.
Run
()
defer
server
.
Close
()
conn
,
err
:=
proxyConn
(
client
,
server
)
if
err
!=
nil
{
return
}
defer
conn
.
Close
()
go
func
()
{
conn
,
err
=
client
.
Connect
(
conn
,
":0"
)
if
err
!=
nil
{
return
}
}()
c
,
err
:=
net
.
Dial
(
"tcp"
,
conn
.
LocalAddr
()
.
String
())
if
err
!=
nil
{
return
}
defer
c
.
Close
()
u
,
err
:=
url
.
Parse
(
targetURL
)
if
err
!=
nil
{
return
}
cc
,
err
:=
net
.
Dial
(
"tcp"
,
u
.
Host
)
if
err
!=
nil
{
return
}
defer
cc
.
Close
()
go
transport
(
conn
,
cc
)
t
.
Log
(
"httpRoundtrip"
)
return
httpRoundtrip
(
c
,
targetURL
,
data
)
}
func
_TestSSHRemoteForward
(
t
*
testing
.
T
)
{
httpSrv
:=
httptest
.
NewServer
(
httpTestHandler
)
defer
httpSrv
.
Close
()
sendData
:=
make
([]
byte
,
128
)
rand
.
Read
(
sendData
)
err
:=
sshRemoteForwardRoundtrip
(
t
,
httpSrv
.
URL
,
sendData
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
}
func
httpOverSSHTunnelRoundtrip
(
targetURL
string
,
data
[]
byte
,
tlsConfig
*
tls
.
Config
,
clientInfo
*
url
.
Userinfo
,
serverInfo
[]
*
url
.
Userinfo
)
error
{
...
...
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