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
f8702c67
Commit
f8702c67
authored
Aug 01, 2017
by
rui.zheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add shadowsocks UDP relay support
parent
89681dd5
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
268 additions
and
4 deletions
+268
-4
gost/examples/bench/srv.go
gost/examples/bench/srv.go
+11
-0
gost/examples/ssu/ssu.go
gost/examples/ssu/ssu.go
+55
-0
gost/forward.go
gost/forward.go
+3
-4
gost/ss.go
gost/ss.go
+199
-0
No files found.
gost/examples/bench/srv.go
View file @
f8702c67
...
@@ -41,6 +41,7 @@ func main() {
...
@@ -41,6 +41,7 @@ func main() {
go
sshTunnelServer
()
go
sshTunnelServer
()
// go http2Server()
// go http2Server()
go
quicServer
()
go
quicServer
()
go
shadowUDPServer
()
select
{}
select
{}
}
}
...
@@ -238,6 +239,16 @@ func quicServer() {
...
@@ -238,6 +239,16 @@ func quicServer() {
log
.
Fatal
(
s
.
Serve
(
ln
,
h
))
log
.
Fatal
(
s
.
Serve
(
ln
,
h
))
}
}
func
shadowUDPServer
()
{
s
:=
&
gost
.
Server
{}
ln
,
err
:=
gost
.
ShadowUDPListener
(
":18338"
,
url
.
UserPassword
(
"chacha20"
,
"123456"
),
30
*
time
.
Second
)
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
h
:=
gost
.
ShadowUDPdHandler
()
log
.
Fatal
(
s
.
Serve
(
ln
,
h
))
}
var
(
var
(
rawCert
=
[]
byte
(
`-----BEGIN CERTIFICATE-----
rawCert
=
[]
byte
(
`-----BEGIN CERTIFICATE-----
MIIC+jCCAeKgAwIBAgIRAMlREhz8Miu1FQozsxbeqyMwDQYJKoZIhvcNAQELBQAw
MIIC+jCCAeKgAwIBAgIRAMlREhz8Miu1FQozsxbeqyMwDQYJKoZIhvcNAQELBQAw
...
...
gost/examples/ssu/ssu.go
0 → 100644
View file @
f8702c67
package
main
import
(
"bytes"
"log"
"net"
"strconv"
"github.com/ginuerzh/gosocks5"
ss
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
)
func
main
()
{
ssuClient
()
}
func
ssuClient
()
{
addr
,
err
:=
net
.
ResolveUDPAddr
(
"udp"
,
":18338"
)
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
conn
,
err
:=
net
.
ListenUDP
(
"udp"
,
nil
)
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
cp
,
err
:=
ss
.
NewCipher
(
"chacha20"
,
"123456"
)
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
cc
:=
ss
.
NewSecurePacketConn
(
conn
,
cp
,
false
)
raddr
,
_
:=
net
.
ResolveTCPAddr
(
"udp"
,
":8080"
)
msg
:=
[]
byte
(
`abcdefghijklmnopqrstuvwxyz`
)
dgram
:=
gosocks5
.
NewUDPDatagram
(
gosocks5
.
NewUDPHeader
(
0
,
0
,
toSocksAddr
(
raddr
)),
msg
)
buf
:=
bytes
.
Buffer
{}
dgram
.
Write
(
&
buf
)
if
_
,
err
:=
cc
.
WriteTo
(
buf
.
Bytes
()[
3
:
],
addr
);
err
!=
nil
{
log
.
Fatal
(
err
)
}
}
func
toSocksAddr
(
addr
net
.
Addr
)
*
gosocks5
.
Addr
{
host
:=
"0.0.0.0"
port
:=
0
if
addr
!=
nil
{
h
,
p
,
_
:=
net
.
SplitHostPort
(
addr
.
String
())
host
=
h
port
,
_
=
strconv
.
Atoi
(
p
)
}
return
&
gosocks5
.
Addr
{
Type
:
gosocks5
.
AddrIPv4
,
Host
:
host
,
Port
:
uint16
(
port
),
}
}
gost/forward.go
View file @
f8702c67
...
@@ -48,7 +48,6 @@ func (h *tcpDirectForwardHandler) Handle(conn net.Conn) {
...
@@ -48,7 +48,6 @@ func (h *tcpDirectForwardHandler) Handle(conn net.Conn) {
type
udpDirectForwardHandler
struct
{
type
udpDirectForwardHandler
struct
{
raddr
string
raddr
string
ttl
time
.
Duration
options
*
HandlerOptions
options
*
HandlerOptions
}
}
...
@@ -168,7 +167,7 @@ func (h *udpRemoteForwardHandler) Handle(conn net.Conn) {
...
@@ -168,7 +167,7 @@ func (h *udpRemoteForwardHandler) Handle(conn net.Conn) {
}
}
type
udpDirectForwardListener
struct
{
type
udpDirectForwardListener
struct
{
ln
*
net
.
UDP
Conn
ln
net
.
Packet
Conn
conns
map
[
string
]
*
udpServerConn
conns
map
[
string
]
*
udpServerConn
connChan
chan
net
.
Conn
connChan
chan
net
.
Conn
errChan
chan
error
errChan
chan
error
...
@@ -199,7 +198,7 @@ func UDPDirectForwardListener(addr string, ttl time.Duration) (Listener, error)
...
@@ -199,7 +198,7 @@ func UDPDirectForwardListener(addr string, ttl time.Duration) (Listener, error)
func
(
l
*
udpDirectForwardListener
)
listenLoop
()
{
func
(
l
*
udpDirectForwardListener
)
listenLoop
()
{
for
{
for
{
b
:=
make
([]
byte
,
mediumBufferSize
)
b
:=
make
([]
byte
,
mediumBufferSize
)
n
,
raddr
,
err
:=
l
.
ln
.
ReadFrom
UDP
(
b
)
n
,
raddr
,
err
:=
l
.
ln
.
ReadFrom
(
b
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Logf
(
"[udp] peer -> %s : %s"
,
l
.
Addr
(),
err
)
log
.
Logf
(
"[udp] peer -> %s : %s"
,
l
.
Addr
(),
err
)
l
.
ln
.
Close
()
l
.
ln
.
Close
()
...
@@ -226,7 +225,7 @@ func (l *udpDirectForwardListener) listenLoop() {
...
@@ -226,7 +225,7 @@ func (l *udpDirectForwardListener) listenLoop() {
select
{
select
{
case
conn
.
rChan
<-
b
[
:
n
]
:
case
conn
.
rChan
<-
b
[
:
n
]
:
default
:
default
:
log
.
Logf
(
"[udp] %s -> %s :
write
queue is full"
,
raddr
,
l
.
Addr
())
log
.
Logf
(
"[udp] %s -> %s :
read
queue is full"
,
raddr
,
l
.
Addr
())
}
}
}
}
}
}
...
...
gost/ss.go
View file @
f8702c67
package
gost
package
gost
import
(
import
(
"bytes"
"encoding/binary"
"encoding/binary"
"errors"
"fmt"
"fmt"
"io"
"io"
"net"
"net"
...
@@ -9,6 +11,7 @@ import (
...
@@ -9,6 +11,7 @@ import (
"strconv"
"strconv"
"time"
"time"
"github.com/ginuerzh/gosocks5"
"github.com/go-log/log"
"github.com/go-log/log"
ss
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
ss
"github.com/shadowsocks/shadowsocks-go/shadowsocks"
)
)
...
@@ -207,3 +210,199 @@ func (h *shadowHandler) getRequest(conn net.Conn) (host string, err error) {
...
@@ -207,3 +210,199 @@ func (h *shadowHandler) getRequest(conn net.Conn) (host string, err error) {
host
=
net
.
JoinHostPort
(
host
,
strconv
.
Itoa
(
int
(
port
)))
host
=
net
.
JoinHostPort
(
host
,
strconv
.
Itoa
(
int
(
port
)))
return
return
}
}
type
shadowUDPListener
struct
{
ln
net
.
PacketConn
conns
map
[
string
]
*
udpServerConn
connChan
chan
net
.
Conn
errChan
chan
error
ttl
time
.
Duration
}
// ShadowUDPListener creates a Listener for shadowsocks UDP relay server.
func
ShadowUDPListener
(
addr
string
,
cipher
*
url
.
Userinfo
,
ttl
time
.
Duration
)
(
Listener
,
error
)
{
laddr
,
err
:=
net
.
ResolveUDPAddr
(
"udp"
,
addr
)
if
err
!=
nil
{
return
nil
,
err
}
ln
,
err
:=
net
.
ListenUDP
(
"udp"
,
laddr
)
if
err
!=
nil
{
return
nil
,
err
}
var
method
,
password
string
if
cipher
!=
nil
{
method
=
cipher
.
Username
()
password
,
_
=
cipher
.
Password
()
}
cp
,
err
:=
ss
.
NewCipher
(
method
,
password
)
if
err
!=
nil
{
ln
.
Close
()
return
nil
,
err
}
l
:=
&
udpDirectForwardListener
{
ln
:
ss
.
NewSecurePacketConn
(
ln
,
cp
,
false
),
conns
:
make
(
map
[
string
]
*
udpServerConn
),
connChan
:
make
(
chan
net
.
Conn
,
1024
),
errChan
:
make
(
chan
error
,
1
),
ttl
:
ttl
,
}
go
l
.
listenLoop
()
return
l
,
nil
}
func
(
l
*
shadowUDPListener
)
listenLoop
()
{
for
{
b
:=
make
([]
byte
,
mediumBufferSize
)
n
,
raddr
,
err
:=
l
.
ln
.
ReadFrom
(
b
[
3
:
])
// add rsv and frag fields to make it the standard SOCKS5 UDP datagram
if
err
!=
nil
{
log
.
Logf
(
"[ssu] peer -> %s : %s"
,
l
.
Addr
(),
err
)
l
.
ln
.
Close
()
l
.
errChan
<-
err
close
(
l
.
errChan
)
return
}
if
Debug
{
log
.
Logf
(
"[ssu] %s >>> %s : length %d"
,
raddr
,
l
.
Addr
(),
n
)
}
b
[
3
]
&=
ss
.
AddrMask
// remove OTA flag
conn
,
ok
:=
l
.
conns
[
raddr
.
String
()]
if
!
ok
||
conn
.
Closed
()
{
conn
=
newUDPServerConn
(
l
.
ln
,
raddr
,
l
.
ttl
)
l
.
conns
[
raddr
.
String
()]
=
conn
select
{
case
l
.
connChan
<-
conn
:
default
:
conn
.
Close
()
log
.
Logf
(
"[ssu] %s - %s: connection queue is full"
,
raddr
,
l
.
Addr
())
}
}
select
{
case
conn
.
rChan
<-
b
[
:
n
+
3
]
:
// we keep the addr info so that the handler can identify the destination.
default
:
log
.
Logf
(
"[ssu] %s -> %s : read queue is full"
,
raddr
,
l
.
Addr
())
}
}
}
func
(
l
*
shadowUDPListener
)
Accept
()
(
conn
net
.
Conn
,
err
error
)
{
var
ok
bool
select
{
case
conn
=
<-
l
.
connChan
:
case
err
,
ok
=
<-
l
.
errChan
:
if
!
ok
{
err
=
errors
.
New
(
"accpet on closed listener"
)
}
}
return
}
func
(
l
*
shadowUDPListener
)
Addr
()
net
.
Addr
{
return
l
.
ln
.
LocalAddr
()
}
func
(
l
*
shadowUDPListener
)
Close
()
error
{
return
l
.
ln
.
Close
()
}
type
shadowUDPdHandler
struct
{
ttl
time
.
Duration
options
*
HandlerOptions
}
// ShadowUDPdHandler creates a server Handler for shadowsocks UDP relay server.
func
ShadowUDPdHandler
(
opts
...
HandlerOption
)
Handler
{
h
:=
&
udpDirectForwardHandler
{
options
:
&
HandlerOptions
{},
}
for
_
,
opt
:=
range
opts
{
opt
(
h
.
options
)
}
return
h
}
func
(
h
*
shadowUDPdHandler
)
Handle
(
conn
net
.
Conn
)
{
defer
conn
.
Close
()
var
err
error
var
cc
net
.
PacketConn
if
h
.
options
.
Chain
.
IsEmpty
()
{
cc
,
err
=
net
.
ListenUDP
(
"udp"
,
nil
)
if
err
!=
nil
{
log
.
Logf
(
"[udp] %s - : %s"
,
conn
.
LocalAddr
(),
err
)
return
}
}
else
{
var
c
net
.
Conn
c
,
err
=
getSOCKS5UDPTunnel
(
h
.
options
.
Chain
,
nil
)
if
err
!=
nil
{
log
.
Logf
(
"[udp] %s - : %s"
,
conn
.
LocalAddr
(),
err
)
return
}
cc
=
&
udpTunnelConn
{
Conn
:
c
}
}
defer
cc
.
Close
()
log
.
Logf
(
"[udp] %s <-> %s"
,
conn
.
RemoteAddr
(),
conn
.
LocalAddr
())
transportUDP
(
conn
,
cc
)
log
.
Logf
(
"[udp] %s >-< %s"
,
conn
.
RemoteAddr
(),
conn
.
LocalAddr
())
}
func
transportUDP
(
sc
net
.
Conn
,
cc
net
.
PacketConn
)
error
{
errc
:=
make
(
chan
error
,
1
)
go
func
()
{
for
{
dgram
,
err
:=
gosocks5
.
ReadUDPDatagram
(
sc
)
if
err
!=
nil
{
errc
<-
err
return
}
if
Debug
{
log
.
Logf
(
"[ssu] %s >>> %s length: %d"
,
sc
.
RemoteAddr
(),
dgram
.
Header
.
Addr
.
String
(),
len
(
dgram
.
Data
))
}
addr
,
err
:=
net
.
ResolveUDPAddr
(
"udp"
,
dgram
.
Header
.
Addr
.
String
())
if
err
!=
nil
{
errc
<-
err
return
}
if
_
,
err
:=
cc
.
WriteTo
(
dgram
.
Data
,
addr
);
err
!=
nil
{
errc
<-
err
return
}
}
}()
go
func
()
{
for
{
b
:=
make
([]
byte
,
mediumBufferSize
)
n
,
addr
,
err
:=
cc
.
ReadFrom
(
b
)
if
err
!=
nil
{
errc
<-
err
return
}
if
Debug
{
log
.
Logf
(
"[ssu] %s <<< %s length: %d"
,
sc
.
RemoteAddr
(),
addr
,
n
)
}
dgram
:=
gosocks5
.
NewUDPDatagram
(
gosocks5
.
NewUDPHeader
(
0
,
0
,
toSocksAddr
(
addr
)),
b
[
:
n
])
buf
:=
bytes
.
Buffer
{}
dgram
.
Write
(
&
buf
)
if
buf
.
Len
()
<
10
{
log
.
Logf
(
"[ssu] %s <- %s : invalid udp datagram"
,
sc
.
RemoteAddr
(),
addr
)
continue
}
if
_
,
err
:=
sc
.
Write
(
buf
.
Bytes
()[
3
:
]);
err
!=
nil
{
errc
<-
err
return
}
}
}()
err
:=
<-
errc
if
err
!=
nil
&&
err
==
io
.
EOF
{
err
=
nil
}
return
err
}
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