chore: support skip the same config Listeners' Close and Listen

This commit is contained in:
gVisor bot 2022-12-04 17:20:24 +08:00
parent 1bcd6cac83
commit e01cfc5627
9 changed files with 94 additions and 32 deletions

View file

@ -20,4 +20,5 @@ type NewListener interface {
Close() error Close() error
Address() string Address() string
RawAddress() string RawAddress() string
Config() string
} }

View file

@ -138,13 +138,25 @@ func GetGeneral() *config.General {
func updateListeners(listeners map[string]C.NewListener) { func updateListeners(listeners map[string]C.NewListener) {
tcpIn := tunnel.TCPIn() tcpIn := tunnel.TCPIn()
udpIn := tunnel.UDPIn() udpIn := tunnel.UDPIn()
for _, listener := range tunnel.Listeners() {
_ = listener.Close() skipNames := map[string]struct{}{}
for name, oldListener := range tunnel.Listeners() {
if newListener, ok := listeners[name]; ok {
if newListener.Config() == oldListener.Config() {
listeners[name] = oldListener
skipNames[name] = struct{}{}
continue
}
}
_ = oldListener.Close()
} }
for _, listener := range listeners { for name, newListener := range listeners {
if err := listener.Listen(tcpIn, udpIn); err != nil { if _, ok := skipNames[name]; ok {
log.Errorln("Listener %s listen err: %s", listener.Name(), err.Error()) continue
}
if err := newListener.Listen(tcpIn, udpIn); err != nil {
log.Errorln("Listener %s listen err: %s", newListener.Name(), err.Error())
} }
} }
tunnel.UpdateListeners(listeners) tunnel.UpdateListeners(listeners)

View file

@ -1,6 +1,7 @@
package inbound package inbound
import ( import (
"encoding/json"
"net" "net"
"net/netip" "net/netip"
"strconv" "strconv"
@ -9,6 +10,7 @@ import (
) )
type Base struct { type Base struct {
config *BaseOption
name string name string
preferRulesName string preferRulesName string
listenAddr netip.Addr listenAddr netip.Addr
@ -28,9 +30,15 @@ func NewBase(options *BaseOption) (*Base, error) {
listenAddr: addr, listenAddr: addr,
preferRulesName: options.PreferRulesName, preferRulesName: options.PreferRulesName,
port: options.Port, port: options.Port,
config: options,
}, nil }, nil
} }
// Config implements constant.NewListener
func (b *Base) Config() string {
return optionToString(b.config)
}
// Address implements constant.NewListener // Address implements constant.NewListener
func (b *Base) Address() string { func (b *Base) Address() string {
return b.RawAddress() return b.RawAddress()
@ -51,7 +59,7 @@ func (b *Base) RawAddress() string {
return net.JoinHostPort(b.listenAddr.String(), strconv.Itoa(int(b.port))) return net.JoinHostPort(b.listenAddr.String(), strconv.Itoa(int(b.port)))
} }
// ReCreate implements constant.NewListener // Listen implements constant.NewListener
func (*Base) Listen(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error { func (*Base) Listen(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error {
return nil return nil
} }
@ -64,3 +72,8 @@ type BaseOption struct {
} }
var _ C.NewListener = (*Base)(nil) var _ C.NewListener = (*Base)(nil)
func optionToString(option any) string {
str, _ := json.Marshal(option)
return string(str)
}

View file

@ -11,7 +11,8 @@ type HTTPOption struct {
} }
type HTTP struct { type HTTP struct {
*Base *Base
l *http.Listener config *HTTPOption
l *http.Listener
} }
func NewHTTP(options *HTTPOption) (*HTTP, error) { func NewHTTP(options *HTTPOption) (*HTTP, error) {
@ -20,16 +21,22 @@ func NewHTTP(options *HTTPOption) (*HTTP, error) {
return nil, err return nil, err
} }
return &HTTP{ return &HTTP{
Base: base, Base: base,
config: options,
}, nil }, nil
} }
// Config implements constant.NewListener
func (h *HTTP) Config() string {
return optionToString(h.config)
}
// Address implements constant.NewListener // Address implements constant.NewListener
func (h *HTTP) Address() string { func (h *HTTP) Address() string {
return h.l.Address() return h.l.Address()
} }
// ReCreate implements constant.NewListener // Listen implements constant.NewListener
func (h *HTTP) Listen(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error { func (h *HTTP) Listen(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error {
var err error var err error
h.l, err = http.NewWithInfos(h.RawAddress(), h.name, h.preferRulesName, tcpIn) h.l, err = http.NewWithInfos(h.RawAddress(), h.name, h.preferRulesName, tcpIn)

View file

@ -17,9 +17,10 @@ type MixedOption struct {
type Mixed struct { type Mixed struct {
*Base *Base
l *mixed.Listener config *MixedOption
lUDP *socks.UDPListener l *mixed.Listener
udp bool lUDP *socks.UDPListener
udp bool
} }
func NewMixed(options *MixedOption) (*Mixed, error) { func NewMixed(options *MixedOption) (*Mixed, error) {
@ -28,17 +29,23 @@ func NewMixed(options *MixedOption) (*Mixed, error) {
return nil, err return nil, err
} }
return &Mixed{ return &Mixed{
Base: base, Base: base,
udp: options.UDP == nil || *options.UDP, config: options,
udp: options.UDP == nil || *options.UDP,
}, nil }, nil
} }
// Config implements constant.NewListener
func (m *Mixed) Config() string {
return optionToString(m.config)
}
// Address implements constant.NewListener // Address implements constant.NewListener
func (m *Mixed) Address() string { func (m *Mixed) Address() string {
return m.l.Address() return m.l.Address()
} }
// ReCreate implements constant.NewListener // Listen implements constant.NewListener
func (m *Mixed) Listen(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error { func (m *Mixed) Listen(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error {
var err error var err error
m.l, err = mixed.NewWithInfos(m.RawAddress(), m.name, m.preferRulesName, tcpIn) m.l, err = mixed.NewWithInfos(m.RawAddress(), m.name, m.preferRulesName, tcpIn)

View file

@ -12,7 +12,8 @@ type RedirOption struct {
type Redir struct { type Redir struct {
*Base *Base
l *redir.Listener config *RedirOption
l *redir.Listener
} }
func NewRedir(options *RedirOption) (*Redir, error) { func NewRedir(options *RedirOption) (*Redir, error) {
@ -21,16 +22,22 @@ func NewRedir(options *RedirOption) (*Redir, error) {
return nil, err return nil, err
} }
return &Redir{ return &Redir{
Base: base, Base: base,
config: options,
}, nil }, nil
} }
// Config implements constant.NewListener
func (r *Redir) Config() string {
return optionToString(r.config)
}
// Address implements constant.NewListener // Address implements constant.NewListener
func (r *Redir) Address() string { func (r *Redir) Address() string {
return r.l.Address() return r.l.Address()
} }
// ReCreate implements constant.NewListener // Listen implements constant.NewListener
func (r *Redir) Listen(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error { func (r *Redir) Listen(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error {
var err error var err error
r.l, err = redir.NewWithInfos(r.Address(), r.name, r.preferRulesName, tcpIn) r.l, err = redir.NewWithInfos(r.Address(), r.name, r.preferRulesName, tcpIn)

View file

@ -14,9 +14,10 @@ type SocksOption struct {
type Socks struct { type Socks struct {
*Base *Base
udp bool config *SocksOption
stl *socks.Listener udp bool
sul *socks.UDPListener stl *socks.Listener
sul *socks.UDPListener
} }
func NewSocks(options *SocksOption) (*Socks, error) { func NewSocks(options *SocksOption) (*Socks, error) {
@ -25,11 +26,17 @@ func NewSocks(options *SocksOption) (*Socks, error) {
return nil, err return nil, err
} }
return &Socks{ return &Socks{
Base: base, Base: base,
udp: options.UDP == nil || *options.UDP, config: options,
udp: options.UDP == nil || *options.UDP,
}, nil }, nil
} }
// Config implements constant.NewListener
func (s *Socks) Config() string {
return optionToString(s.config)
}
// Close implements constant.NewListener // Close implements constant.NewListener
func (s *Socks) Close() error { func (s *Socks) Close() error {
var err error var err error
@ -56,7 +63,7 @@ func (s *Socks) Address() string {
return s.stl.Address() return s.stl.Address()
} }
// ReCreate implements constant.NewListener // Listen implements constant.NewListener
func (s *Socks) Listen(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error { func (s *Socks) Listen(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error {
var err error var err error
if s.stl, err = socks.NewWithInfos(s.RawAddress(), s.name, s.preferRulesName, tcpIn); err != nil { if s.stl, err = socks.NewWithInfos(s.RawAddress(), s.name, s.preferRulesName, tcpIn); err != nil {

View file

@ -15,9 +15,10 @@ type TProxyOption struct {
type TProxy struct { type TProxy struct {
*Base *Base
lUDP *tproxy.UDPListener config *TProxyOption
lTCP *tproxy.Listener lUDP *tproxy.UDPListener
udp bool lTCP *tproxy.Listener
udp bool
} }
func NewTProxy(options *TProxyOption) (*TProxy, error) { func NewTProxy(options *TProxyOption) (*TProxy, error) {
@ -26,18 +27,24 @@ func NewTProxy(options *TProxyOption) (*TProxy, error) {
return nil, err return nil, err
} }
return &TProxy{ return &TProxy{
Base: base, Base: base,
udp: options.UDP == nil || *options.UDP, config: options,
udp: options.UDP == nil || *options.UDP,
}, nil }, nil
} }
// Config implements constant.NewListener
func (t *TProxy) Config() string {
return optionToString(t.config)
}
// Address implements constant.NewListener // Address implements constant.NewListener
func (t *TProxy) Address() string { func (t *TProxy) Address() string {
return t.lTCP.Address() return t.lTCP.Address()
} }
// ReCreate implements constant.NewListener // Listen implements constant.NewListener
func (t *TProxy) Listen(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error { func (t *TProxy) Listen(tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapter) error {
var err error var err error
t.lTCP, err = tproxy.NewWithInfos(t.RawAddress(), t.name, t.preferRulesName, tcpIn) t.lTCP, err = tproxy.NewWithInfos(t.RawAddress(), t.name, t.preferRulesName, tcpIn)

View file

@ -87,9 +87,10 @@ func Rules() []C.Rule {
return rules return rules
} }
func Listeners()map[string]C.NewListener{ func Listeners() map[string]C.NewListener {
return listeners return listeners
} }
// UpdateRules handle update rules // UpdateRules handle update rules
func UpdateRules(newRules []C.Rule, newSubRule map[string][]C.Rule, rp map[string]provider.RuleProvider) { func UpdateRules(newRules []C.Rule, newSubRule map[string][]C.Rule, rp map[string]provider.RuleProvider) {
configMux.Lock() configMux.Lock()
@ -125,7 +126,7 @@ func UpdateProxies(newProxies map[string]C.Proxy, newProviders map[string]provid
func UpdateListeners(newListeners map[string]C.NewListener) { func UpdateListeners(newListeners map[string]C.NewListener) {
configMux.Lock() configMux.Lock()
defer configMux.Unlock() defer configMux.Unlock()
listeners=newListeners listeners = newListeners
} }
func UpdateSniffer(dispatcher *sniffer.SnifferDispatcher) { func UpdateSniffer(dispatcher *sniffer.SnifferDispatcher) {