[Standards] MIX Addressing

Kevin Smith kevin.smith at isode.com
Fri Jun 1 08:49:03 UTC 2018

> On 1 Jun 2018, at 09:36, Jonas Wielicki <jonas at wielicki.name> wrote:
> On Freitag, 1. Juni 2018 09:21:45 CEST Kevin Smith wrote:
>> On 31 May 2018, at 20:12, Jonas Wielicki <jonas at wielicki.name> wrote:
>>> On Donnerstag, 31. Mai 2018 13:45:06 CEST Kevin Smith wrote:
>>>> We’ve had some discussions recently about whether presence should come
>>>> from
>>>> the channel’s JID, the user’s proxy JID, or be encoded in pubsub.
>>>> Similarly
>>>> whether messages should be coming from the channel’s JID or the user’s
>>>> proxy JID. I think the argument that things should come from the user’s
>>>> in-channel JID rather than the channel’s is reasonable - this is also
>>>> what
>>>> happens already in MUC and is familiar.
>>>> The reason for the proxy JIDs is that we need a stable identifier for the
>>>> user in the channel, and we need it to be addressable per client. In MUC
>>>> we
>>>> don’t have this, we have room at server/nick, which is not stable for the
>>>> user, which makes several things unpleasant, nor is it unique for a
>>>> client
>>>> (no resource), which makes routing (e.g. iq, which has to be to go to a
>>>> unique client) and other issues annoying.
>>>> This means that we want a routable address that encodes up to four pieces
>>>> of information:
>>>> The channel’s domain
>>>> The channel’s identifier (I don’t want to use ‘name’, because that’s
>>>> confusing - I mean the bit that in MUC would be the node of the JID). The
>>>> user’s stable identifier
>>>> A thing representing a resource of the user (Although not necessarily the
>>>> exact resource they’re using)
>>>> I shall call these ‘domain’, ‘channel’, ‘user’, ‘resource’ respectively,
>>>> because I’m tremendously creative.
>>>> The current approach is to have a unique ‘proxy JID’ per user:
>>>> user#channel at domain
>>>> and this in turn can have resources hanging off it as
>>>> user#channel at domain/resource1, etc.
>>>> This is not the most elegant thing in the world (and some people have
>>>> objected to having proxy JIDs at all), and has implications for e.g.
>>>> servers that block messages from anyone that isn’t in your roster or
>>>> receiving directed presence.
>>>> We could alternatively encode it as
>>>> channel at domain/user and channel at domain/user/resource (Note carefully that
>>>> user is *not* nick, so this doesn’t fall into the issues of MUC
>>>> stability,
>>>> and it allows encoding resources, so doesn’t fall into the MUC issues of
>>>> routing).
>>>> Then there are no more proxy JIDs, everything is hanging off
>>>> channel at domain, much like people are familiar with from MUC but without
>>>> (as far as I can see at the moment) those issues of conflating nick with
>>>> both user and client identity.
>>>> I think if we want routability we need to choose one of these two things:
>>>> 1) Stick with proxy JIDs and user%channel at domain[/resource] (or similar),
>>>> with the resource missed off for bare-JID traffic, where
>>>> ‘user%channel at domain’ as the proxy JID is the user’s identifier used
>>>> everywhere. 2) Drop proxy JIDs, use channel at domain/user[/resource] and
>>>> then
>>>> ‘user’ is just a string identifier for the user, of whatever format (as
>>>> long as it doesn’t contain ‘/‘).
>>>> What are people’s thoughts here?Are there any advantages of (1) over (2),
>>>> or vice versa?
>>> I very much prefer the semantics of (1). The reason is that about
>>> everywhere (except MUC) you can assume that equal bare JID implies equal
>>> identity.
>> Ah, but it’s more complicated than that.
>> In most of XMPP you have the concept that identity (of the sender) = routing
>> (of a reply) = context (e.g. the chat window in your client, or the entity
>> you need queries for in your MAM archive). If you receive a normal 1:1 chat
>> message, the from on the stanza (less the resource) shows you the identity
>> of the sender (it’s just them), the routing to reply to them (it’s just
>> them) and the context of the messages (the chat with that person). With MUC
>> or MIX you now have this changed.
>> For MUC currently:
>> Identity of the sender: full JID (although this is broken, as we know, by
>> the conflating of identity/nick etc. in MUC) Routing of a reply (type=gc):
>> bare JID
>> Routing of a reply (type=chat, sent through channel): full JID
>> Context (type=gc): bare JID
>> Context (type=chat, sent through the channel): full JID
>> With option 1 (encode channel and user into node):
>> Identity of the sender: bare JID
>> Routing a reply (type=gc): strip the user out of the localpart and then it’s
>> the remaining bare JID 
>> Routing a reply (type=chat, sent through channel): bare JID
>> Context (type=gc): strip the user out of the localpart and then it’s the
>> remaining bare JID 
>> Context (type=chat, sent through the channel): bare JID
>> With option 2 (encode user and resource into resource):
>> Identity of the sender: full JID
>> Routing a reply (type=gc): bare JID
>> Routing a reply (type=chat, sent through channel): full JID
>> Context (type=gc): bare JID
>> Context (type=chat, sent through the channel): full JID
> This isn’t entirely correct, is it? Routing a 1:1 reply would need to route to 
> the stripped full JID (i.e. only /user suffix, not /user/resource), because we 
> don’t want to do resource locking anymore. Likewise for identity (which is 
> relevant for things like avatars). Eliding the stripping makes this look much 
> more attractive than it is ;-).

Ah, yes and no. There’s no stripping for identity, because the user’s identity in the room is presented as the semi-full JID (/user not /user/resource), and it’s only their presence that has the full-full JID (and the uses for that are mostly limited to sending IQs). For messages, I don’t think there’s any reason the channel should need to send from the full-full JID, it could send from the semi-full JID, and then there’s none of the stripping, and it’s just as attractive as I present ;)

> (Or are you saying (I would’ve missed that somehow) that messages would be 
> coming from the pseudo-bare full JID (channel at service/user instead of 
> channel at service/user/resource)? That won’t work with presence, which carries 
> relevant information for caches (avatars, again), so it’s only partly 
> helpful.)

I’m suggesting that for everything other than presence, yes. And for presence you always have to do stripping - just that in MIX you strip from full-full to semi-full instead of full to bare. I *think* that’s a detail in the implementation that isn’t onerous as you have a different code path for tracking presence in a channel from the one for tracking presence in the roster, and the hierarchical JID means you only need to care at the last minute (once you’re inside the handling for the MIX).

>> So, yes, option 1 gives you that the identity of the sender is the bare JID,
>> and this is desirable. It also loses the idea that the context of the
>> messages for channel messages is the bare JID and this makes client
>> architecture harder and (possibly more importantly, and I hadn’t really
>> thought about this enough before) breaks querying for messages in a channel
>> in personal MAM. Your client comes online, you want to show unread messages
>> so you query your archive for the last messages in the room since the ID
>> and … get nothing.
> To be fair (and this is another rabbit hole, I know), if I wasn’t running a 
> sync-all model, I would probably be querying the MIX anyways, because this is 
> safe against s2s issues.

Yes and no. If you want to be querying “what has new/unread messages”, it has to be your server that answers the query.
(As an aside, this is my model for MAM - you query for unreads on login, so you can show unread status in the roster, and thereafter you query lazily as the user wants to open a chat).

>> The cleanest option in terms of keeping identity, routing and context
>> straight might actually be that messages from the channel (type=gc),
>> presence, etc. all come from option 2, while if you send PMs they come from
>> option 1. That way replying is always ‘right’, you can do a mapping between
>> the two (but don’t need to), and you don’t have the unpleasant issue that
>> archive queries get screwey because you’re overloading what the
>> context/routing is based on message type.
> Uh, having two different JIDs for the same identity in a MIX sounds worse. I’d 
> prefer Option 2 over that, actually. 

It’s another trade-off, certainly. I think there are significant benefits, particularly in terms of archiving, to having messages sent to the channel and messages sent outside the channel having different from addresses. The current status in MUC of both PMs and room messages appearing with the same from is quite a large gotcha and I’m aware of it causing a non-trivial number of issues in the wild. I think the removal of the potential for such issues (which I’ve seen in both clients and servers) might well be worth the (not large) increase in complexity on the client (I think the server code actually gets easier with 4 than 1 or 2, but that’s not my driving motivation).


More information about the Standards mailing list