mirror of
https://gitverse.ru/kpa39l/xmpp-server-prosody.git
synced 2026-09-29 09:45:02 +00:00
Initial commit: Hermes skill xmpp-server-prosody
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
# Slidge invite flood, roster loss and group-join "unavailable" — diagnosis playbook
|
||||
|
||||
Symptom cluster (seen 2026-08-29 on nixg.ru, estorozhenko@ account):
|
||||
1. After a server restart the Telegram contacts are GONE from the client roster
|
||||
and even `telegram.nixg.ru` no longer shows.
|
||||
2. Client (Pidgin) got "миллион запросов на подключение к чату" (a flood of
|
||||
group-join invitations), each join failing with «Получатель недоступен» /
|
||||
recipient-unavailable.
|
||||
3. Joining `group-<id>@telegram.nixg.ru/<nick>` errors.
|
||||
|
||||
Root cause chain (verified in logs + slidge 0.4.2 source):
|
||||
|
||||
## Layer 1 — roster is NOT lost on the server
|
||||
|
||||
Before assuming data loss, query the roster from a fresh slixmpp client:
|
||||
|
||||
```python
|
||||
import asyncio, slixmpp
|
||||
async def main():
|
||||
bot = slixmpp.ClientXMPP('user@dom','pass')
|
||||
import ssl; ctx=ssl.create_default_context(); ctx.check_hostname=False; ctx.verify_mode=ssl.CERT_NONE
|
||||
bot.ssl_context=ctx
|
||||
await bot.connect(('localhost',5222))
|
||||
iq = bot.make_iq_get(); iq['id']='roster3'
|
||||
# NOTE: roster get must have NO 'to' attribute — sending to the server domain
|
||||
# (to=nixg.ru) returns service-unavailable!
|
||||
iq.xml.append(iq.xml.makeelement('{jabber:iq:roster}query',{}))
|
||||
# ... await result, count items with 'telegram.nixg.ru' in jid
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
Pitfall: `make_iq_get()` + roster query sent WITH `to=<server domain>` →
|
||||
`service-unavailable` (false negative, made me suspect mod_roster was broken).
|
||||
Without `to` it works and returned 1602 telegram contacts. Conclusion: server
|
||||
side is intact; the CLIENT had dropped the roster view after reconnect. Fix:
|
||||
disable/re-enable the account in the client (Pidgin) or restart it — client
|
||||
re-downloads the roster on login.
|
||||
|
||||
## Layer 2 — mod_privilege (XEP-0356) is 0.12-only API; crashes on 0.11
|
||||
|
||||
`prosody/logs/prosody.err` showed:
|
||||
`mod_privilege.lua: ... attempt to call method 'send_iq' (a nil value)`.
|
||||
The prosody-modules `mod_privilege.lua` is written against Prosody **0.12**
|
||||
(`module:send_iq(wrapped_iq, newsession):next(...)`). On 0.11.9 there is no
|
||||
`module:send_iq`, so every privileged IQ from the bridge crashes the handler.
|
||||
|
||||
Effect on slidge: it uses `xep_0356.send_privileged_iq()` to write the user's
|
||||
PEP **bookmarks**. With mod_privilege broken the write times out →
|
||||
`room.add_to_bookmarks()` hits its failure branch and calls
|
||||
`send_gateway_invite()` for EVERY group (because the bookmark could not be set
|
||||
automatically). That is the "million join invites" — each invite is
|
||||
`group-<id>@telegram.nixg.ru`, and trying to join it while the bookmark write
|
||||
never completed gives recipient-unavailable.
|
||||
|
||||
## Layer 3 — slidge first-run sync floods the Telegram API
|
||||
|
||||
First login after registering a large account: slidge syncs hundreds of
|
||||
chats/contacts via MTProto and hits `Flood in get_chat/get_users/
|
||||
get_chat_member ... sleep for 11-22 seconds` (slidgram `handle_flood`).
|
||||
This slows joins to ~20+ s and contributes to join timeouts. It is transient —
|
||||
after the cache fills, floods stop. Not a bug; do not restart the bridge to
|
||||
"fix" it (each restart re-runs part of the sync and can re-trigger floods, plus
|
||||
`Client is already terminated` noise on stop).
|
||||
|
||||
## Layer 4 — user preference toggle: always_invite_when_adding_bookmarks
|
||||
|
||||
`user_account.preferences` in slidge.sqlite had:
|
||||
`{"sync_avatar": true, "always_invite_when_adding_bookmarks": true, ...}`.
|
||||
With bookmarks broken (Layer 2) every add triggers an invite because of this
|
||||
flag. Turning it off stops the invite spam even while mod_privilege is broken:
|
||||
|
||||
```python
|
||||
import sqlite3; con=sqlite3.connect('/var/lib/slidge/slidge.sqlite')
|
||||
con.execute("UPDATE user_account SET preferences=... " ) # drop the flag; restart icq-slidgram
|
||||
```
|
||||
|
||||
BUT the real fix is Layer 2/0.12 upgrade — the bookmark write then succeeds and
|
||||
no fallback invites are sent at all.
|
||||
|
||||
## Diagnosing orders (do these FIRST)
|
||||
|
||||
1. `docker logs icq-slidgram | grep -iE 'Group|MDS|flood|privilege'` — look for
|
||||
`Flood in get_chat` and `Error while trying to subscribe to the MDS node`.
|
||||
2. `grep -iE 'mod_privilege|send_iq|attempt to' /opt/icq/logs/prosody.err` —
|
||||
the 0.12-API crash.
|
||||
3. Roster reality check via slixmpp (Layer 1) — proves server data intact.
|
||||
4. `sqlite3` room table: `SELECT * FROM room WHERE legacy_id LIKE '%<id>%'`
|
||||
— confirmed group-1001698123474 = "Денис Сорокин (channel)", muc_type=CHANNEL,
|
||||
jid_localpart=group-1001698123474. Room known to the bridge; join failure was
|
||||
purely the bookmark/privilege chain above.
|
||||
|
||||
## Permanent fixes (in priority order)
|
||||
|
||||
- **Upgrade Prosody to 0.12** (built-in mod_privilege) — see
|
||||
`prosody-012-upgrade-path.md`.
|
||||
- Do NOT hand-patch community mod_privilege to fake `send_iq` on 0.11:
|
||||
a stub that ACKs without forwarding still leaves bookmarks unwritten
|
||||
(slidge waits for the forwarded result) → invite flood persists. A stub was
|
||||
tried and still produced `Error while trying to subscribe to the MDS node`.
|
||||
- Alternative: give the bridge roster access via older XEP-0356-free methods
|
||||
(roster push through regular roster set works — slidge `RosterBackend`), so
|
||||
contacts DO appear; only bookmarks/auto-invites stay broken until 0.12.
|
||||
Reference in New Issue
Block a user