XMPP

XMPP is almost 20 years old now, and I've been using it (on a private server for the past few years, and additionally a local instance working over Tor for the past month) while looking for ways to get distributed messaging. New protocols and technologies are fun, and I don't quite like XML, but XMPP has good documentation, works, can be used in either federated or distributed fashion (as most of the other federated systems, coupled with Tor or a similar network), and has plenty of software – so now I'm thinking that it may be sufficient, at least for messaging.

Its specifications (see RFC 6120, RFC 6121, RFC 7622, and extensions) are well-written and apparently thought through, a small core with optional extensions is a nice approach, there is usable software, there are users, and even XML is not that bad (perhaps even quite suitable for a protocol like that, especially while not being abused).

Though the situation with software could have been better.

Message handling acknowledgements

Message delivery is pretty unreliable with some of the major clients and servers, since acknowledgements are not always supported – making it worse than email and approximately as IRC, with respect to reliability of delivery. I'd think XEP-0198 should be among the first extensions to implement (actually XEP-0387: XMPP Compliance Suites 2018 includes it, but just for advanced implementations – along with things such as user avatars), and usually assumed that it's there (without bothering to check, since didn't care much about XMPP, and assumed that it'll be dealt with anyway, because the protocol and the software are popular), but among the three XMPP implementations which I use:

Client certificates (and a bit more)

Certificate-based client authentication is not an essential feature, but I wanted to get rid of passwords as I did with email, so investigated that too.

Prosody has a a bunch of useful modules for authentication, including dovecot SASL and client certificate-based authentication (via SASL EXTERNAL authentication mechanism), but client support is rather bad:

Encryption

The primary options are:

All those have drawbacks (with no corresponding XEP being recommended for use by XMPP Standards Foundation), though any one would have been useful if it was implemented consistently and used commonly. But in my experience end-to-end encryption is mostly used by those who use private (somewhat trusted) servers and TLS anyway, while users of public servers rarely bother to enable those even when they are available in their clients.

Summary

Here's a table summarising support of some features in XMPP implementations (libraries, clients, servers; feature support via external plugins is counted; "C API" only applies to libraries):

Implementation SCRAM EXTERNAL XEP-0198 C API Language
Pidgin/libpurple+--+C
Prosody+++Lua
jabberd2+--C
bitlbee+--C
weechat/jabber.py--?C/Python
mcabber/loudmouth---+C
Conversations+++Java
ChatSecure/XMPPFramework+-+Java
Profanity/libstrophe+--+C
Psi???C++
Vacuum-IM---C++
pontarius-xmpp+---Haskell
Gajim/nbxmpp+++-Python
Dino+?+Vala
gloox-++-C++
Swift/Swiften+++-C++
SleekXMPP/slixmpp+++-Python

Improving the software

While patching libpurple's jabber plugin, some minor libpurple-specific issues surfaced (related to both this XEP and XMPP in general), as it often happens with generic interfaces: they rarely fit well. That's one of the reasons why it's more fun to work on new implementations than to improve existing software: the latter is harder, takes more time for the same features (both implementation and organisational chores), and even then the features barely (if at all) fit into existing APIs. But in order to get somewhere, there has to be incremental improvement (which may be long and boring sometimes), and it looks like there's not enough of it.

On the other hand, some features are impossible to cram into libpurple without changing the APIs, and even libpurple, while being reused by multiple clients and for multiple protocols, implements XMPP from scratch instead of reusing a library; though there seem to be just libstrophe and loudmouth out of actually reusable (from any common language via C FFI) ones, but they seem to have more issues than features. So here's that situation once again, in which there's many implementations already, but it feels like the right thing to do may be just to start over, and add one more – because none are perfect.

A compromise may be to try to get at least important and basic things to work first, to get as far as practical with existing software, and only proceed to new implementations and experimentation then.

If one was to start over, apparently the proper way (leading to reusable and portable code, relying on mature and complete libraries which wouldn't introduce unnecessary limitations) would also be a boring one, along the lines of:

Though GHC's foreign export may also be suitable to get a reusable library, and to avoid C.

Slightly related: Software extensibility.