Is QUI DI1 the correct way to mark a client as offline?
Howdy,
I have been crafting a small ADC hub recently, based entirely off of the ADC protocol specification. Recently, I have been testing with DC++-based clients, including DC++ itself.
A curious problem has shown up. I randomly generate SIDs with no reuse, as others do. Occasionally, the list of connected clients will not clear in DC++. This usually happens after a reconnection, but it can also happen after a client has quit. If a client quits and reconnects, they will receive a new SID. DC++ will then *discard* the new information being broadcast for that client, because it still believes the other SID is still valid and ignores the new SID.
The end result is that DC++ now sees a ghost user that no longer exists and that the hub doesn't know about, and also denies the existence of an actual user that is definitely connected to the hub.
I have obtained the DC++ source corresponding to DC++ 0.802, and have been studying dcpp/AdcHub.cpp. I believe that I understand the anatomy of this bug, even if I don't know the correct resolution.
At dcpp/AdcHub.
Now, the hub does appear to have one recourse. When a DC++ client attempts to use an invalid SID, the hub could guess that the client is using a ghost SID which no longer exists. The hub could then send a message which is targeted to trigger putUser(SID, false) which will remove the ghostly SID from the DC++ client. The only such point is in handle(QUI, ...) at dcpp/AdcHub.
This technique works! It has a couple flaws, though. First, this conflicts with the protocol's idea of how QUI works, which is that QUI should *already* notify the client definitively that the given SID is deallocated. In fact, I have tried sending normal QUIs when clients disconnect, and sadly QUI does not remove entries from the client list nor erase the SID-CID mapping for that hub. DI1 is supposed to be for when a client is poisonous and should not be talked to under any circumstances; this is clearly both incorrect and overkill.
Second, the hub cannot always know which CID the DC++ client wanted to reference. Hubs are apparently not required to remember past clients' SIDs, and they can't do it in all circumstances. This bug can be triggered by the hub restarting, so persisting SIDs would take a fair amount of extra effort. It's possible, but no other hubs appear to do it. As a consequence, it's not really possible to know exactly which client's INF needs to be resent to DC++ to tell it about the *real* client that it wanted to connect to.
I'd love to have a better resolution to this problem, since it happens constantly and I can't really know enough about client-side state to be able to fix it every time.
~ C.
Question information
- Language:
- English Edit question
- Status:
- Answered
- For:
- DC++ Edit question
- Assignee:
- No assignee Edit question
- Last query:
- Last reply:
Can you help with this problem?
Provide an answer of your own, or ask Corbin Simpson for more information if necessary.