add config for udp forward listener
This commit is contained in:
parent
2e428aaba9
commit
56d90dfa70
@ -297,6 +297,11 @@ func (r *route) GenRouters() ([]router, error) {
|
|||||||
wsOpts.WriteBufferSize = node.GetInt("wbuf")
|
wsOpts.WriteBufferSize = node.GetInt("wbuf")
|
||||||
wsOpts.Path = node.Get("path")
|
wsOpts.Path = node.Get("path")
|
||||||
|
|
||||||
|
ttl, err := time.ParseDuration(node.Get("ttl"))
|
||||||
|
if err != nil {
|
||||||
|
ttl = time.Duration(node.GetInt("ttl")) * time.Second
|
||||||
|
}
|
||||||
|
|
||||||
var ln gost.Listener
|
var ln gost.Listener
|
||||||
switch node.Transport {
|
switch node.Transport {
|
||||||
case "tls":
|
case "tls":
|
||||||
@ -361,11 +366,27 @@ func (r *route) GenRouters() ([]router, error) {
|
|||||||
}
|
}
|
||||||
ln, err = gost.TCPRemoteForwardListener(node.Addr, chain)
|
ln, err = gost.TCPRemoteForwardListener(node.Addr, chain)
|
||||||
case "udp":
|
case "udp":
|
||||||
ln, err = gost.UDPDirectForwardListener(node.Addr, time.Duration(node.GetInt("ttl"))*time.Second)
|
ln, err = gost.UDPDirectForwardListener(node.Addr, &gost.UDPForwardListenConfig{
|
||||||
|
TTL: ttl,
|
||||||
|
Backlog: node.GetInt("backlog"),
|
||||||
|
QueueSize: node.GetInt("queue"),
|
||||||
|
})
|
||||||
case "rudp":
|
case "rudp":
|
||||||
ln, err = gost.UDPRemoteForwardListener(node.Addr, chain, time.Duration(node.GetInt("ttl"))*time.Second)
|
ln, err = gost.UDPRemoteForwardListener(node.Addr,
|
||||||
|
chain,
|
||||||
|
&gost.UDPForwardListenConfig{
|
||||||
|
TTL: ttl,
|
||||||
|
Backlog: node.GetInt("backlog"),
|
||||||
|
QueueSize: node.GetInt("queue"),
|
||||||
|
})
|
||||||
case "ssu":
|
case "ssu":
|
||||||
ln, err = gost.ShadowUDPListener(node.Addr, node.User, time.Duration(node.GetInt("ttl"))*time.Second)
|
ln, err = gost.ShadowUDPListener(node.Addr,
|
||||||
|
node.User,
|
||||||
|
&gost.UDPForwardListenConfig{
|
||||||
|
TTL: ttl,
|
||||||
|
Backlog: node.GetInt("backlog"),
|
||||||
|
QueueSize: node.GetInt("queue"),
|
||||||
|
})
|
||||||
case "obfs4":
|
case "obfs4":
|
||||||
if err = gost.Obfs4Init(node, true); err != nil {
|
if err = gost.Obfs4Init(node, true); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
60
forward.go
60
forward.go
@ -372,16 +372,22 @@ func (m *udpConnMap) Size() int64 {
|
|||||||
return atomic.LoadInt64(&m.size)
|
return atomic.LoadInt64(&m.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UDPForwardListenConfig struct {
|
||||||
|
TTL time.Duration
|
||||||
|
Backlog int
|
||||||
|
QueueSize int
|
||||||
|
}
|
||||||
|
|
||||||
type udpDirectForwardListener struct {
|
type udpDirectForwardListener struct {
|
||||||
ln net.PacketConn
|
ln net.PacketConn
|
||||||
connChan chan net.Conn
|
connChan chan net.Conn
|
||||||
errChan chan error
|
errChan chan error
|
||||||
ttl time.Duration
|
|
||||||
connMap udpConnMap
|
connMap udpConnMap
|
||||||
|
config *UDPForwardListenConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// UDPDirectForwardListener creates a Listener for UDP port forwarding server.
|
// UDPDirectForwardListener creates a Listener for UDP port forwarding server.
|
||||||
func UDPDirectForwardListener(addr string, ttl time.Duration) (Listener, error) {
|
func UDPDirectForwardListener(addr string, cfg *UDPForwardListenConfig) (Listener, error) {
|
||||||
laddr, err := net.ResolveUDPAddr("udp", addr)
|
laddr, err := net.ResolveUDPAddr("udp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -390,11 +396,21 @@ func UDPDirectForwardListener(addr string, ttl time.Duration) (Listener, error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg == nil {
|
||||||
|
cfg = &UDPForwardListenConfig{}
|
||||||
|
}
|
||||||
|
|
||||||
|
backlog := cfg.Backlog
|
||||||
|
if backlog <= 0 {
|
||||||
|
backlog = defaultBacklog
|
||||||
|
}
|
||||||
|
|
||||||
l := &udpDirectForwardListener{
|
l := &udpDirectForwardListener{
|
||||||
ln: ln,
|
ln: ln,
|
||||||
connChan: make(chan net.Conn, 128),
|
connChan: make(chan net.Conn, backlog),
|
||||||
errChan: make(chan error, 1),
|
errChan: make(chan error, 1),
|
||||||
ttl: ttl,
|
config: cfg,
|
||||||
}
|
}
|
||||||
go l.listenLoop()
|
go l.listenLoop()
|
||||||
return l, nil
|
return l, nil
|
||||||
@ -414,7 +430,7 @@ func (l *udpDirectForwardListener) listenLoop() {
|
|||||||
|
|
||||||
conn, ok := l.connMap.Get(raddr.String())
|
conn, ok := l.connMap.Get(raddr.String())
|
||||||
if !ok {
|
if !ok {
|
||||||
conn = newUDPServerConn(l.ln, raddr, l.ttl)
|
conn = newUDPServerConn(l.ln, raddr, l.config.TTL, l.config.QueueSize)
|
||||||
conn.onClose = func() {
|
conn.onClose = func() {
|
||||||
l.connMap.Delete(raddr.String())
|
l.connMap.Delete(raddr.String())
|
||||||
log.Logf("[udp] %s closed (%d)", raddr, l.connMap.Size())
|
log.Logf("[udp] %s closed (%d)", raddr, l.connMap.Size())
|
||||||
@ -426,7 +442,7 @@ func (l *udpDirectForwardListener) listenLoop() {
|
|||||||
log.Logf("[udp] %s -> %s (%d)", raddr, l.Addr(), l.connMap.Size())
|
log.Logf("[udp] %s -> %s (%d)", raddr, l.Addr(), l.connMap.Size())
|
||||||
default:
|
default:
|
||||||
conn.Close()
|
conn.Close()
|
||||||
log.Logf("[udp] %s - %s: connection queue is full", raddr, l.Addr())
|
log.Logf("[udp] %s - %s: connection queue is full (%d)", raddr, l.Addr(), cap(l.connChan))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,7 +452,7 @@ func (l *udpDirectForwardListener) listenLoop() {
|
|||||||
log.Logf("[udp] %s >>> %s : length %d", raddr, l.Addr(), n)
|
log.Logf("[udp] %s >>> %s : length %d", raddr, l.Addr(), n)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
log.Logf("[udp] %s -> %s : read queue is full", raddr, l.Addr())
|
log.Logf("[udp] %s -> %s : recv queue is full (%d)", raddr, l.Addr(), cap(conn.rChan))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -478,11 +494,14 @@ type udpServerConn struct {
|
|||||||
onClose func()
|
onClose func()
|
||||||
}
|
}
|
||||||
|
|
||||||
func newUDPServerConn(conn net.PacketConn, raddr net.Addr, ttl time.Duration) *udpServerConn {
|
func newUDPServerConn(conn net.PacketConn, raddr net.Addr, ttl time.Duration, qsize int) *udpServerConn {
|
||||||
|
if qsize <= 0 {
|
||||||
|
qsize = defaultQueueSize
|
||||||
|
}
|
||||||
c := &udpServerConn{
|
c := &udpServerConn{
|
||||||
conn: conn,
|
conn: conn,
|
||||||
raddr: raddr,
|
raddr: raddr,
|
||||||
rChan: make(chan []byte, 128),
|
rChan: make(chan []byte, qsize),
|
||||||
closed: make(chan struct{}),
|
closed: make(chan struct{}),
|
||||||
nopChan: make(chan int),
|
nopChan: make(chan int),
|
||||||
ttl: ttl,
|
ttl: ttl,
|
||||||
@ -853,22 +872,32 @@ type udpRemoteForwardListener struct {
|
|||||||
closed chan struct{}
|
closed chan struct{}
|
||||||
closeMux sync.Mutex
|
closeMux sync.Mutex
|
||||||
once sync.Once
|
once sync.Once
|
||||||
|
config *UDPForwardListenConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// UDPRemoteForwardListener creates a Listener for UDP remote port forwarding server.
|
// UDPRemoteForwardListener creates a Listener for UDP remote port forwarding server.
|
||||||
func UDPRemoteForwardListener(addr string, chain *Chain, ttl time.Duration) (Listener, error) {
|
func UDPRemoteForwardListener(addr string, chain *Chain, cfg *UDPForwardListenConfig) (Listener, error) {
|
||||||
laddr, err := net.ResolveUDPAddr("udp", addr)
|
laddr, err := net.ResolveUDPAddr("udp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg == nil {
|
||||||
|
cfg = &UDPForwardListenConfig{}
|
||||||
|
}
|
||||||
|
|
||||||
|
backlog := cfg.Backlog
|
||||||
|
if backlog <= 0 {
|
||||||
|
backlog = defaultBacklog
|
||||||
|
}
|
||||||
|
|
||||||
ln := &udpRemoteForwardListener{
|
ln := &udpRemoteForwardListener{
|
||||||
addr: laddr,
|
addr: laddr,
|
||||||
chain: chain,
|
chain: chain,
|
||||||
connChan: make(chan net.Conn, 128),
|
connChan: make(chan net.Conn, backlog),
|
||||||
errChan: make(chan error, 1),
|
errChan: make(chan error, 1),
|
||||||
ttl: ttl,
|
|
||||||
closed: make(chan struct{}),
|
closed: make(chan struct{}),
|
||||||
|
config: cfg,
|
||||||
}
|
}
|
||||||
|
|
||||||
go ln.listenLoop()
|
go ln.listenLoop()
|
||||||
@ -904,7 +933,7 @@ func (l *udpRemoteForwardListener) listenLoop() {
|
|||||||
|
|
||||||
uc, ok := l.connMap.Get(raddr.String())
|
uc, ok := l.connMap.Get(raddr.String())
|
||||||
if !ok {
|
if !ok {
|
||||||
uc = newUDPServerConn(conn, raddr, l.ttl)
|
uc = newUDPServerConn(conn, raddr, l.config.TTL, l.config.QueueSize)
|
||||||
uc.onClose = func() {
|
uc.onClose = func() {
|
||||||
l.connMap.Delete(raddr.String())
|
l.connMap.Delete(raddr.String())
|
||||||
log.Logf("[rudp] %s closed (%d)", raddr, l.connMap.Size())
|
log.Logf("[rudp] %s closed (%d)", raddr, l.connMap.Size())
|
||||||
@ -916,7 +945,8 @@ func (l *udpRemoteForwardListener) listenLoop() {
|
|||||||
log.Logf("[rudp] %s -> %s (%d)", raddr, l.Addr(), l.connMap.Size())
|
log.Logf("[rudp] %s -> %s (%d)", raddr, l.Addr(), l.connMap.Size())
|
||||||
default:
|
default:
|
||||||
uc.Close()
|
uc.Close()
|
||||||
log.Logf("[rudp] %s - %s: connection queue is full", raddr, l.Addr())
|
log.Logf("[rudp] %s - %s: connection queue is full (%d)",
|
||||||
|
raddr, l.Addr(), cap(l.connChan))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -926,7 +956,7 @@ func (l *udpRemoteForwardListener) listenLoop() {
|
|||||||
log.Logf("[rudp] %s >>> %s : length %d", raddr, l.Addr(), n)
|
log.Logf("[rudp] %s >>> %s : length %d", raddr, l.Addr(), n)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
log.Logf("[rudp] %s -> %s : write queue is full", raddr, l.Addr())
|
log.Logf("[rudp] %s -> %s : recv queue is full", raddr, l.Addr(), cap(uc.rChan))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
4
gost.go
4
gost.go
@ -68,7 +68,9 @@ var (
|
|||||||
// PingRetries is the reties of ping.
|
// PingRetries is the reties of ping.
|
||||||
PingRetries = 1
|
PingRetries = 1
|
||||||
// default udp node TTL in second for udp port forwarding.
|
// default udp node TTL in second for udp port forwarding.
|
||||||
defaultTTL = 60 * time.Second
|
defaultTTL = 60 * time.Second
|
||||||
|
defaultBacklog = 128
|
||||||
|
defaultQueueSize = 128
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
22
ss.go
22
ss.go
@ -302,10 +302,11 @@ type shadowUDPListener struct {
|
|||||||
errChan chan error
|
errChan chan error
|
||||||
ttl time.Duration
|
ttl time.Duration
|
||||||
connMap udpConnMap
|
connMap udpConnMap
|
||||||
|
config *UDPForwardListenConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShadowUDPListener creates a Listener for shadowsocks UDP relay server.
|
// ShadowUDPListener creates a Listener for shadowsocks UDP relay server.
|
||||||
func ShadowUDPListener(addr string, cipher *url.Userinfo, ttl time.Duration) (Listener, error) {
|
func ShadowUDPListener(addr string, cipher *url.Userinfo, cfg *UDPForwardListenConfig) (Listener, error) {
|
||||||
laddr, err := net.ResolveUDPAddr("udp", addr)
|
laddr, err := net.ResolveUDPAddr("udp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -326,11 +327,20 @@ func ShadowUDPListener(addr string, cipher *url.Userinfo, ttl time.Duration) (Li
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg == nil {
|
||||||
|
cfg = &UDPForwardListenConfig{}
|
||||||
|
}
|
||||||
|
|
||||||
|
backlog := cfg.Backlog
|
||||||
|
if backlog <= 0 {
|
||||||
|
backlog = defaultBacklog
|
||||||
|
}
|
||||||
|
|
||||||
l := &shadowUDPListener{
|
l := &shadowUDPListener{
|
||||||
ln: ss.NewSecurePacketConn(ln, cp, false),
|
ln: ss.NewSecurePacketConn(ln, cp, false),
|
||||||
connChan: make(chan net.Conn, 128),
|
connChan: make(chan net.Conn, backlog),
|
||||||
errChan: make(chan error, 1),
|
errChan: make(chan error, 1),
|
||||||
ttl: ttl,
|
config: cfg,
|
||||||
}
|
}
|
||||||
go l.listenLoop()
|
go l.listenLoop()
|
||||||
return l, nil
|
return l, nil
|
||||||
@ -350,7 +360,7 @@ func (l *shadowUDPListener) listenLoop() {
|
|||||||
|
|
||||||
conn, ok := l.connMap.Get(raddr.String())
|
conn, ok := l.connMap.Get(raddr.String())
|
||||||
if !ok {
|
if !ok {
|
||||||
conn = newUDPServerConn(l.ln, raddr, l.ttl)
|
conn = newUDPServerConn(l.ln, raddr, l.config.TTL, l.config.QueueSize)
|
||||||
conn.onClose = func() {
|
conn.onClose = func() {
|
||||||
l.connMap.Delete(raddr.String())
|
l.connMap.Delete(raddr.String())
|
||||||
log.Logf("[ssu] %s closed (%d)", raddr, l.connMap.Size())
|
log.Logf("[ssu] %s closed (%d)", raddr, l.connMap.Size())
|
||||||
@ -362,7 +372,7 @@ func (l *shadowUDPListener) listenLoop() {
|
|||||||
log.Logf("[ssu] %s -> %s (%d)", raddr, l.Addr(), l.connMap.Size())
|
log.Logf("[ssu] %s -> %s (%d)", raddr, l.Addr(), l.connMap.Size())
|
||||||
default:
|
default:
|
||||||
conn.Close()
|
conn.Close()
|
||||||
log.Logf("[ssu] %s - %s: connection queue is full", raddr, l.Addr())
|
log.Logf("[ssu] %s - %s: connection queue is full (%d)", raddr, l.Addr(), cap(l.connChan))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +382,7 @@ func (l *shadowUDPListener) listenLoop() {
|
|||||||
log.Logf("[ssu] %s >>> %s : length %d", raddr, l.Addr(), n)
|
log.Logf("[ssu] %s >>> %s : length %d", raddr, l.Addr(), n)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
log.Logf("[ssu] %s -> %s : read queue is full", raddr, l.Addr())
|
log.Logf("[ssu] %s -> %s : recv queue is full (%d)", raddr, l.Addr(), cap(conn.rChan))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user