-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Presence of user's primaryResource broken after unsubscribing and subscribing #108
Comments
I've dug a bit into this. The issue seems that the subscribed presence when the contact approves the request is send from the bare JID and future updates are send from the full JID. Thus the resourceForJID call in updateWithPresence returns nil and a new resource is created instead of updating an existing one. However, as future updates are send from the the full JID, the bare JID resource is never touched again. |
drodriguez
pushed a commit
to drodriguez/XMPPFramework
that referenced
this issue
Jan 2, 2013
…ters an infinite call loop
mperovic
pushed a commit
to mperovic/XMPPFramework
that referenced
this issue
Apr 4, 2014
…ters an infinite call loop
davidchiles
pushed a commit
to davidchiles/XMPPFramework
that referenced
this issue
Jan 26, 2016
…ters an infinite call loop
AndrewMcDrew
pushed a commit
to aurban-iqmessenger/XMPPFramework
that referenced
this issue
Apr 13, 2017
# for free
to join this conversation on GitHub.
Already have an account?
# to comment
Ok, this is probably some edge case scenario and quite a long way to reproduce
TLDRL version
When unsubscribing and subscribing to a contact's presence, a wrong primary resource is calculated so that subsequent presence updates might go unnoticed.
Assuming we have a contact in our roster with a mutual presence subscription. After unsubscribing and subscribing to presence notifications again, presence changes of that contact are not handled correctly probably because a wrong primary resource is calculated. Thus, if a contact is away with his primary resouce, we unsubscribe and subscribe again, the contact is shown as online with his primary resource. All future presence updates until refetching the complete roster are ignored.
Long version
We mutually subscribed to the presence of a user which is online via a single resource. The user has his status set to away.
Unsubscribe from users presence
SEND: <presence type="unsubscribe" to="testuser3@localhost.localdomain"><x xmlns="vcard-temp:x:update"><photo/></x></presence> RECV: <iq xmlns="jabber:client" id="lx170" type="set"><query xmlns="jabber:iq:roster" ver="122"><item jid="testuser3@localhost.localdomain" subscription="from"/></query></iq>
This calls
[XMPPUserCoreDataStorageObjet updateWithItem]
where the subscription is correctly set to "from" The existing away resource is left intact.Subscribe to users presence
SEND: <presence type="subscribe" to="testuser3@localhost.localdomain"><x xmlns="vcard-temp:x:update"><photo/></x></presence> RECV: <iq xmlns="jabber:client" id="lx172" type="set"><query xmlns="jabber:iq:roster" ver="123"><item jid="testuser3@localhost.localdomain" ask="subscribe" subscription="from"/></query></iq> RECV: <presence xmlns="jabber:client" type="unavailable" to="bucks@localhost.localdomain" from="testuser3@localhost.localdomain"/>
In
[XMPPUserCoreDataStorageObjet updateWithPresence:streamBareJidStr]
this callsupdateWithPresence: presence: streamBareJidStr:
In there the following paths are taken:
[self removeResourcesObject:resource];
[[self managedObjectContext] deleteObject:resource];
and finally[XMPPUserCoreDataStorageObjet recalculatePrimaryResource]
is called.In there, sortedResources still contains one object, the away presence that already existed before unsubscribing from the user at the beginning. To verify this, looping sortedResources at the beginning of
recalculatePrimaryResource
results in resources with the following attributes:Resource intShow 2
Resource type available
As this resource is the only one it is set as the new primary resource in the end. The subscription is now requested and pending approval by the user.
User approves presence subscription request
RECV: <presence xmlns="jabber:client" type="subscribed" to="bucks@localhost.localdomain" from="testuser3@localhost.localdomain"/> RECV: <iq xmlns="jabber:client" id="lx191" type="set"><query xmlns="jabber:iq:roster" ver="133"><item jid="testuser3@localhost.localdomain" subscription="both"/></query></iq> RECV: <presence xmlns="jabber:client" to="bucks@localhost.localdomain" from="testuser3@localhost.localdomain/Heisenberg"><show>away</show><status>Away</status><c xmlns="http://jabber.org/protocol/caps" hash="sha-1" ver="DdnydQG7RGhP9E3k9Sf+b+bF0zo=" node="http://pidgin.im/"/><x xmlns="vcard-temp:x:update"><photo/></x></presence>
This calls
[XMPPUserCoreDataStorageObjet updateWithPresence:streamBareJidStr]
for the first received presence. In there, the else branch of the first if is taken, which again takes the else branch in the inner condition to create a new XMPPResourceCoreDataStorageObject and call[self addResourcesObject:newResource]
.Finally
[XMPPUserCoreDataStorageObjet recalculatePrimaryResource]
is called. In there sortedResources now contains contains two objects, the away presence that already existed before unsubscribing from the user at the beginning and the subscribe presence that has just been added. The new one does have an intShow of 3 as this is the default value if a received presence does not include a "show" element.To verify this once again, looping sortedResources at the beginning of recalculatePrimaryResource results in:
Resource intShow 3
Resource type subscribed
Resource intShow 2
Resource type available
The subscribed resource is then set as the primaryResource in the end
For the second presence that contains the actual new presence of the user, the updateWithPresence branch is taken in
[XMPPUserCoreDataStorageObjet updateWithPresence:streamBareJidStr]
and[XMPPUserCoreDataStorageObjet recalculatePrimaryResource]
is called. In there sortedResources still contains two objects, the subscribed one, and an the available, as the updateWithPresence has presumably updated the stale presence that was left from the beginning.Thus, in the end the subscribed resource wins as the primaryResource. From then on, new presence updates get ignored, as the old presence is continuously updated but not assumed to be the primary resource.
The only way to restore order in the presence system is by restarting the app to purge stale resources and start anew.
The text was updated successfully, but these errors were encountered: