add conn limiter
This commit is contained in:
43
limiter/conn/wrapper/conn.go
Normal file
43
limiter/conn/wrapper/conn.go
Normal file
@ -0,0 +1,43 @@
|
||||
package wrapper
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"syscall"
|
||||
|
||||
limiter "github.com/go-gost/core/limiter/conn"
|
||||
)
|
||||
|
||||
var (
|
||||
errUnsupport = errors.New("unsupported operation")
|
||||
)
|
||||
|
||||
// serverConn is a server side Conn with metrics supported.
|
||||
type serverConn struct {
|
||||
net.Conn
|
||||
limiter limiter.Limiter
|
||||
}
|
||||
|
||||
func WrapConn(limiter limiter.Limiter, c net.Conn) net.Conn {
|
||||
if limiter == nil {
|
||||
return c
|
||||
}
|
||||
return &serverConn{
|
||||
Conn: c,
|
||||
limiter: limiter,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *serverConn) SyscallConn() (rc syscall.RawConn, err error) {
|
||||
if sc, ok := c.Conn.(syscall.Conn); ok {
|
||||
rc, err = sc.SyscallConn()
|
||||
return
|
||||
}
|
||||
err = errUnsupport
|
||||
return
|
||||
}
|
||||
|
||||
func (c *serverConn) Close() error {
|
||||
c.limiter.Allow(-1)
|
||||
return c.Conn.Close()
|
||||
}
|
40
limiter/conn/wrapper/listener.go
Normal file
40
limiter/conn/wrapper/listener.go
Normal file
@ -0,0 +1,40 @@
|
||||
package wrapper
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
limiter "github.com/go-gost/core/limiter/conn"
|
||||
)
|
||||
|
||||
type listener struct {
|
||||
net.Listener
|
||||
limiter limiter.ConnLimiter
|
||||
}
|
||||
|
||||
func WrapListener(limiter limiter.ConnLimiter, ln net.Listener) net.Listener {
|
||||
if limiter == nil {
|
||||
return ln
|
||||
}
|
||||
|
||||
return &listener{
|
||||
limiter: limiter,
|
||||
Listener: ln,
|
||||
}
|
||||
}
|
||||
|
||||
func (ln *listener) Accept() (net.Conn, error) {
|
||||
c, err := ln.Listener.Accept()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
host, _, _ := net.SplitHostPort(c.RemoteAddr().String())
|
||||
if lim := ln.limiter.Limiter(host); lim != nil {
|
||||
if lim.Allow(1) {
|
||||
return WrapConn(lim, c), nil
|
||||
}
|
||||
c.Close()
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
Reference in New Issue
Block a user