Compare commits

...
3 Commits
Author SHA1 Message Date
null 542030ca71 chore 2026-10-08 19:30:46 +08:00
Fangliding 0d83d099ac make client unavailable if instance stopped 2026-10-08 19:03:48 +08:00
Fangliding d06cf79243 Hysteria: Remove closed instance conn 2026-10-08 15:35:39 +08:00
2 changed files with 31 additions and 15 deletions
+3 -1
View File
@@ -92,6 +92,8 @@ type Instance struct {
// Instance state
func (server *Instance) IsRunning() bool {
server.statusLock.Lock()
defer server.statusLock.Unlock()
return server.running
}
@@ -320,7 +322,7 @@ func (s *Instance) RequireFeatures(callback interface{}, optional bool) error {
// AddFeature registers a feature into current Instance.
func (s *Instance) AddFeature(feature features.Feature) error {
if s.running {
if s.IsRunning() {
if err := feature.Start(); err != nil {
errors.LogInfoInner(s.ctx, err, "failed to start feature")
}
+28 -14
View File
@@ -17,6 +17,7 @@ import (
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/net/cnc"
"github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/transport/internet"
"github.com/xtls/xray-core/transport/internet/finalmask"
"github.com/xtls/xray-core/transport/internet/hysteria/congestion"
@@ -28,6 +29,7 @@ import (
type client struct {
sync.Mutex
instance *core.Instance
dest net.Destination
config *Config
tlsConfig *gotls.Config
@@ -49,7 +51,10 @@ func (c *client) status() status {
case <-c.conn.Context().Done():
return StatusInactive
default:
return StatusActive
if c.instance == nil || c.instance.IsRunning() {
return StatusActive
}
return StatusInactive
}
}
@@ -64,11 +69,14 @@ func (c *client) close() {
}
func (c *client) dial(ctx context.Context) error {
status := c.status()
if status == StatusActive {
return nil
if c.instance != nil && !c.instance.IsRunning() {
return errors.New("client is closed")
}
if status == StatusInactive {
switch c.status() {
case StatusActive:
return nil
case StatusInactive:
c.close()
}
@@ -256,12 +264,13 @@ func (c *client) udp(ctx context.Context) (stat.Connection, error) {
return c.udpSM.udp()
}
func (c *client) clean() {
func (c *client) clean() bool {
c.Lock()
defer c.Unlock()
if c.status() == StatusInactive {
c.close()
}
c.Unlock()
return c.status() == StatusNull
}
type dialerConf struct {
@@ -277,11 +286,13 @@ type clientManager struct {
func (m *clientManager) clean() {
ticker := time.NewTicker(idleCleanupInterval)
for range ticker.C {
m.RLock()
for _, c := range m.m {
c.clean()
m.Lock()
for k, c := range m.m {
if c.clean() {
delete(m.m, k)
}
}
m.RUnlock()
m.Unlock()
}
}
@@ -306,15 +317,18 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
go manager.clean()
})
dialerConfKey := dialerConf{dest, streamSettings}
manager.RLock()
c := manager.m[dialerConf{dest, streamSettings}]
c := manager.m[dialerConfKey]
manager.RUnlock()
if c == nil {
manager.Lock()
c = manager.m[dialerConf{dest, streamSettings}]
c = manager.m[dialerConfKey]
if c == nil {
c = &client{
instance: core.FromContext(ctx),
dest: dest,
config: streamSettings.ProtocolSettings.(*Config),
tlsConfig: tlsConfig.GetTLSConfig(tls.WithDestination(dest)),
@@ -322,7 +336,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
finalMask: streamSettings.FinalMask,
quicParams: streamSettings.QuicParams,
}
manager.m[dialerConf{dest, streamSettings}] = c
manager.m[dialerConfKey] = c
}
manager.Unlock()
}