|
@@ -627,11 +627,13 @@ func (j *CheckClientIpJob) disconnectClientTemporarily(inbound *model.Inbound, c
|
|
|
|
|
|
|
|
// Find the client config
|
|
// Find the client config
|
|
|
var clientConfig map[string]any
|
|
var clientConfig map[string]any
|
|
|
|
|
+ var reverseClient bool
|
|
|
for _, client := range clients {
|
|
for _, client := range clients {
|
|
|
if client.Email == clientEmail {
|
|
if client.Email == clientEmail {
|
|
|
// Convert client to map for API
|
|
// Convert client to map for API
|
|
|
clientBytes, _ := json.Marshal(client)
|
|
clientBytes, _ := json.Marshal(client)
|
|
|
_ = json.Unmarshal(clientBytes, &clientConfig)
|
|
_ = json.Unmarshal(clientBytes, &clientConfig)
|
|
|
|
|
+ reverseClient = client.Reverse != nil
|
|
|
break
|
|
break
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -651,6 +653,13 @@ func (j *CheckClientIpJob) disconnectClientTemporarily(inbound *model.Inbound, c
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // RemoveUser drops a reverse client's outbound handler and the re-add below
|
|
|
|
|
+ // cannot restore it, so its tunnel would stay down until Xray restarts.
|
|
|
|
|
+ if reverseClient {
|
|
|
|
|
+ logger.Warningf("[LIMIT_IP] Not disconnecting %s: its reverse proxy config does not survive a temporary removal", clientEmail)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// For Shadowsocks, ensure the required "cipher" field is present by
|
|
// For Shadowsocks, ensure the required "cipher" field is present by
|
|
|
// reading it from the inbound settings (e.g., settings["method"]).
|
|
// reading it from the inbound settings (e.g., settings["method"]).
|
|
|
if string(inbound.Protocol) == "shadowsocks" {
|
|
if string(inbound.Protocol) == "shadowsocks" {
|
|
@@ -664,8 +673,8 @@ func (j *CheckClientIpJob) disconnectClientTemporarily(inbound *model.Inbound, c
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // The core's RemoveUser clears its validator, so a session already up keeps
|
|
|
|
|
- // running -- except vless, where it also drops a reverse handler.
|
|
|
|
|
|
|
+ // The core's RemoveUser clears its validator: a session already up keeps
|
|
|
|
|
+ // running, except a reverse vless client, which is skipped above.
|
|
|
err = xrayAPI.RemoveUser(inbound.Tag, clientEmail)
|
|
err = xrayAPI.RemoveUser(inbound.Tag, clientEmail)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
logger.Warningf("[LIMIT_IP] Failed to remove user %s: %v", clientEmail, err)
|
|
logger.Warningf("[LIMIT_IP] Failed to remove user %s: %v", clientEmail, err)
|