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
72d7850c
Commit
72d7850c
authored
Dec 27, 2018
by
ginuerzh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add tests for shadowsocks UDP relay
parent
a7d49f0b
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
197 additions
and
47 deletions
+197
-47
forward.go
forward.go
+3
-3
ss.go
ss.go
+119
-44
ss_test.go
ss_test.go
+74
-0
ssh_test.go
ssh_test.go
+1
-0
No files found.
forward.go
View file @
72d7850c
...
@@ -617,15 +617,15 @@ func (c *udpServerConn) RemoteAddr() net.Addr {
...
@@ -617,15 +617,15 @@ func (c *udpServerConn) RemoteAddr() net.Addr {
}
}
func
(
c
*
udpServerConn
)
SetDeadline
(
t
time
.
Time
)
error
{
func
(
c
*
udpServerConn
)
SetDeadline
(
t
time
.
Time
)
error
{
return
nil
return
c
.
conn
.
SetDeadline
(
t
)
}
}
func
(
c
*
udpServerConn
)
SetReadDeadline
(
t
time
.
Time
)
error
{
func
(
c
*
udpServerConn
)
SetReadDeadline
(
t
time
.
Time
)
error
{
return
nil
return
c
.
conn
.
SetReadDeadline
(
t
)
}
}
func
(
c
*
udpServerConn
)
SetWriteDeadline
(
t
time
.
Time
)
error
{
func
(
c
*
udpServerConn
)
SetWriteDeadline
(
t
time
.
Time
)
error
{
return
nil
return
c
.
conn
.
SetWriteDeadline
(
t
)
}
}
type
tcpRemoteForwardListener
struct
{
type
tcpRemoteForwardListener
struct
{
...
...
ss.go
View file @
72d7850c
...
@@ -16,46 +16,6 @@ import (
...
@@ -16,46 +16,6 @@ import (
ss
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
ss
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
)
)
// 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
net
.
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
shadowConnector
struct
{
type
shadowConnector
struct
{
Cipher
*
url
.
Userinfo
Cipher
*
url
.
Userinfo
}
}
...
@@ -102,7 +62,7 @@ func (c *shadowConnector) Connect(conn net.Conn, addr string, options ...Connect
...
@@ -102,7 +62,7 @@ func (c *shadowConnector) Connect(conn net.Conn, addr string, options ...Connect
if
_
,
err
:=
sc
.
Write
(
rawaddr
);
err
!=
nil
{
if
_
,
err
:=
sc
.
Write
(
rawaddr
);
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
return
&
shadowConn
{
conn
:
sc
},
nil
return
&
shadowConn
{
sc
},
nil
}
}
type
shadowHandler
struct
{
type
shadowHandler
struct
{
...
@@ -142,7 +102,7 @@ func (h *shadowHandler) Handle(conn net.Conn) {
...
@@ -142,7 +102,7 @@ func (h *shadowHandler) Handle(conn net.Conn) {
conn
.
RemoteAddr
(),
conn
.
LocalAddr
(),
err
)
conn
.
RemoteAddr
(),
conn
.
LocalAddr
(),
err
)
return
return
}
}
conn
=
&
shadowConn
{
conn
:
ss
.
NewConn
(
conn
,
cipher
)}
conn
=
&
shadowConn
{
ss
.
NewConn
(
conn
,
cipher
)}
conn
.
SetReadDeadline
(
time
.
Now
()
.
Add
(
ReadTimeout
))
conn
.
SetReadDeadline
(
time
.
Now
()
.
Add
(
ReadTimeout
))
host
,
err
:=
h
.
getRequest
(
conn
)
host
,
err
:=
h
.
getRequest
(
conn
)
...
@@ -284,6 +244,55 @@ func (h *shadowHandler) getRequest(r io.Reader) (host string, err error) {
...
@@ -284,6 +244,55 @@ func (h *shadowHandler) getRequest(r io.Reader) (host string, err error) {
return
return
}
}
type
shadowUDPConnector
struct
{
Cipher
*
url
.
Userinfo
}
// ShadowUDPConnector creates a Connector for shadowsocks UDP client.
// It accepts a cipher info for shadowsocks data encryption/decryption.
// The cipher must not be nil.
func
ShadowUDPConnector
(
cipher
*
url
.
Userinfo
)
Connector
{
return
&
shadowUDPConnector
{
Cipher
:
cipher
}
}
func
(
c
*
shadowUDPConnector
)
Connect
(
conn
net
.
Conn
,
addr
string
,
options
...
ConnectOption
)
(
net
.
Conn
,
error
)
{
opts
:=
&
ConnectOptions
{}
for
_
,
option
:=
range
options
{
option
(
opts
)
}
timeout
:=
opts
.
Timeout
if
timeout
<=
0
{
timeout
=
ConnectTimeout
}
conn
.
SetDeadline
(
time
.
Now
()
.
Add
(
timeout
))
defer
conn
.
SetDeadline
(
time
.
Time
{})
rawaddr
,
err
:=
ss
.
RawAddr
(
addr
)
if
err
!=
nil
{
return
nil
,
err
}
var
method
,
password
string
if
c
.
Cipher
!=
nil
{
method
=
c
.
Cipher
.
Username
()
password
,
_
=
c
.
Cipher
.
Password
()
}
cipher
,
err
:=
ss
.
NewCipher
(
method
,
password
)
if
err
!=
nil
{
return
nil
,
err
}
sc
:=
ss
.
NewSecurePacketConn
(
&
shadowPacketConn
{
conn
},
cipher
,
false
)
return
&
shadowUDPConn
{
PacketConn
:
sc
,
raddr
:
conn
.
RemoteAddr
(),
header
:
rawaddr
,
},
nil
}
type
shadowUDPListener
struct
{
type
shadowUDPListener
struct
{
ln
net
.
PacketConn
ln
net
.
PacketConn
conns
map
[
string
]
*
udpServerConn
conns
map
[
string
]
*
udpServerConn
...
@@ -434,7 +443,9 @@ func (h *shadowUDPdHandler) transportUDP(sc net.Conn, cc net.PacketConn) error {
...
@@ -434,7 +443,9 @@ func (h *shadowUDPdHandler) transportUDP(sc net.Conn, cc net.PacketConn) error {
errc
:=
make
(
chan
error
,
1
)
errc
:=
make
(
chan
error
,
1
)
go
func
()
{
go
func
()
{
for
{
for
{
b
:=
make
([]
byte
,
mediumBufferSize
)
b
:=
mPool
.
Get
()
.
([]
byte
)
defer
mPool
.
Put
(
b
)
n
,
err
:=
sc
.
Read
(
b
[
3
:
])
// add rsv and frag fields to make it the standard SOCKS5 UDP datagram
n
,
err
:=
sc
.
Read
(
b
[
3
:
])
// add rsv and frag fields to make it the standard SOCKS5 UDP datagram
if
err
!=
nil
{
if
err
!=
nil
{
// log.Logf("[ssu] %s - %s : %s", sc.RemoteAddr(), sc.LocalAddr(), err)
// log.Logf("[ssu] %s - %s : %s", sc.RemoteAddr(), sc.LocalAddr(), err)
...
@@ -468,7 +479,9 @@ func (h *shadowUDPdHandler) transportUDP(sc net.Conn, cc net.PacketConn) error {
...
@@ -468,7 +479,9 @@ func (h *shadowUDPdHandler) transportUDP(sc net.Conn, cc net.PacketConn) error {
go
func
()
{
go
func
()
{
for
{
for
{
b
:=
make
([]
byte
,
mediumBufferSize
)
b
:=
mPool
.
Get
()
.
([]
byte
)
defer
mPool
.
Put
(
b
)
n
,
addr
,
err
:=
cc
.
ReadFrom
(
b
)
n
,
addr
,
err
:=
cc
.
ReadFrom
(
b
)
if
err
!=
nil
{
if
err
!=
nil
{
errc
<-
err
errc
<-
err
...
@@ -501,3 +514,65 @@ func (h *shadowUDPdHandler) transportUDP(sc net.Conn, cc net.PacketConn) error {
...
@@ -501,3 +514,65 @@ func (h *shadowUDPdHandler) transportUDP(sc net.Conn, cc net.PacketConn) error {
}
}
return
err
return
err
}
}
// 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
{
net
.
Conn
}
func
(
c
*
shadowConn
)
Write
(
b
[]
byte
)
(
n
int
,
err
error
)
{
n
=
len
(
b
)
// force byte length consistent
_
,
err
=
c
.
Conn
.
Write
(
b
)
return
}
type
shadowUDPConn
struct
{
net
.
PacketConn
raddr
net
.
Addr
header
[]
byte
}
func
(
c
*
shadowUDPConn
)
Write
(
b
[]
byte
)
(
n
int
,
err
error
)
{
n
=
len
(
b
)
// force byte length consistent
if
len
(
c
.
header
)
>
0
{
b
=
append
(
c
.
header
,
b
...
)
}
_
,
err
=
c
.
PacketConn
.
WriteTo
(
b
,
c
.
raddr
)
return
}
func
(
c
*
shadowUDPConn
)
Read
(
b
[]
byte
)
(
n
int
,
err
error
)
{
buf
:=
mPool
.
Get
()
.
([]
byte
)
defer
mPool
.
Put
(
buf
)
n
,
_
,
err
=
c
.
PacketConn
.
ReadFrom
(
buf
[
3
:
])
if
err
!=
nil
{
return
}
dgram
,
err
:=
gosocks5
.
ReadUDPDatagram
(
bytes
.
NewReader
(
buf
[
:
n
+
3
]))
if
err
!=
nil
{
return
}
n
=
copy
(
b
,
dgram
.
Data
)
return
}
func
(
c
*
shadowUDPConn
)
RemoteAddr
()
net
.
Addr
{
return
c
.
raddr
}
type
shadowPacketConn
struct
{
net
.
Conn
}
func
(
c
*
shadowPacketConn
)
ReadFrom
(
b
[]
byte
)
(
n
int
,
addr
net
.
Addr
,
err
error
)
{
n
,
err
=
c
.
Conn
.
Read
(
b
)
addr
=
c
.
Conn
.
RemoteAddr
()
return
}
func
(
c
*
shadowPacketConn
)
WriteTo
(
b
[]
byte
,
addr
net
.
Addr
)
(
n
int
,
err
error
)
{
return
c
.
Conn
.
Write
(
b
)
}
ss_test.go
View file @
72d7850c
...
@@ -5,8 +5,13 @@ import (
...
@@ -5,8 +5,13 @@ import (
"net/http/httptest"
"net/http/httptest"
"net/url"
"net/url"
"testing"
"testing"
"time"
)
)
func
init
()
{
// ss.Debug = true
}
var
ssTests
=
[]
struct
{
var
ssTests
=
[]
struct
{
clientCipher
*
url
.
Userinfo
clientCipher
*
url
.
Userinfo
serverCipher
*
url
.
Userinfo
serverCipher
*
url
.
Userinfo
...
@@ -289,3 +294,72 @@ func BenchmarkSSProxyParallel(b *testing.B) {
...
@@ -289,3 +294,72 @@ func BenchmarkSSProxyParallel(b *testing.B) {
}
}
})
})
}
}
func
shadowUDPRoundtrip
(
t
*
testing
.
T
,
host
string
,
data
[]
byte
)
error
{
ln
,
err
:=
ShadowUDPListener
(
"localhost:0"
,
url
.
UserPassword
(
"chacha20-ietf"
,
"123456"
),
0
)
if
err
!=
nil
{
return
err
}
client
:=
&
Client
{
Connector
:
ShadowUDPConnector
(
url
.
UserPassword
(
"chacha20-ietf"
,
"123456"
)),
Transporter
:
UDPTransporter
(),
}
server
:=
&
Server
{
Handler
:
ShadowUDPdHandler
(),
Listener
:
ln
,
}
go
server
.
Run
()
defer
server
.
Close
()
return
udpRoundtrip
(
client
,
server
,
host
,
data
)
}
func
TestShadowUDP
(
t
*
testing
.
T
)
{
udpSrv
:=
newUDPTestServer
(
udpTestHandler
)
udpSrv
.
Start
()
defer
udpSrv
.
Close
()
sendData
:=
make
([]
byte
,
128
)
rand
.
Read
(
sendData
)
err
:=
shadowUDPRoundtrip
(
t
,
udpSrv
.
Addr
(),
sendData
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
}
// TODO: fix shadowsocks UDP relay benchmark.
func
BenchmarkShadowUDP
(
b
*
testing
.
B
)
{
udpSrv
:=
newUDPTestServer
(
udpTestHandler
)
udpSrv
.
Start
()
defer
udpSrv
.
Close
()
sendData
:=
make
([]
byte
,
128
)
rand
.
Read
(
sendData
)
ln
,
err
:=
ShadowUDPListener
(
"localhost:0"
,
url
.
UserPassword
(
"chacha20-ietf"
,
"123456"
),
1000
*
time
.
Millisecond
)
if
err
!=
nil
{
b
.
Error
(
err
)
}
client
:=
&
Client
{
Connector
:
ShadowUDPConnector
(
url
.
UserPassword
(
"chacha20-ietf"
,
"123456"
)),
Transporter
:
UDPTransporter
(),
}
server
:=
&
Server
{
Handler
:
ShadowUDPdHandler
(),
Listener
:
ln
,
}
go
server
.
Run
()
defer
server
.
Close
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
if
err
:=
udpRoundtrip
(
client
,
server
,
udpSrv
.
Addr
(),
sendData
);
err
!=
nil
{
b
.
Error
(
err
)
}
}
}
ssh_test.go
View file @
72d7850c
...
@@ -166,6 +166,7 @@ func sshRemoteForwardRoundtrip(t *testing.T, targetURL string, data []byte) (err
...
@@ -166,6 +166,7 @@ func sshRemoteForwardRoundtrip(t *testing.T, targetURL string, data []byte) (err
return
httpRoundtrip
(
c
,
targetURL
,
data
)
return
httpRoundtrip
(
c
,
targetURL
,
data
)
}
}
// TODO: fix this test
func
_TestSSHRemoteForward
(
t
*
testing
.
T
)
{
func
_TestSSHRemoteForward
(
t
*
testing
.
T
)
{
httpSrv
:=
httptest
.
NewServer
(
httpTestHandler
)
httpSrv
:=
httptest
.
NewServer
(
httpTestHandler
)
defer
httpSrv
.
Close
()
defer
httpSrv
.
Close
()
...
...
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