Barev - XMPP flavoured p2p protocol

barev uses Yggdrasil network underneath, which takes care of routing and end to end encryption.
Currently it has two implementations: a purple plugin (we use it with Pidgin) and a set of libraries written in Pascal and a test cli program.
It supports messages, presence, statuses, typing notifications, avatars, file transfers.

More info in the links, and I’ll try to write more in comment.
:star: Repository

2 Likes

I did not want to invent something new. I like to stick with existing standards.

So some history:

In the beginning the idea was to try using Bonjour, because it is standardized and serverless, over the Yggdrasil network.

For that I wrote a small utility. I would add my peer to a config file, and it would poke that IP’s bonjour port from time to time. I know, very ugly. If the port responded, it would force Avahi (local MDNS server) to believe there’s such contact and it has such IP address. Then Bonjour would sort of work over Yggdrasil.

But that was a very bad solution. We could not set statuses (away, for example), we could not exchange files, because Bonjour shares them by using local IPs. Overall it was a dirty hack and we realized Bonjour relies on MDNS too much for us to be useful over a mesh network.

So this idea was put aside.

Then I “forked” Bonjour plugin. Well, it does not build outside of Pidgin tree, so first I had to make it to build.
Then gradually I was taking whatever XMPP standars are there for streams, messaging, avatars, notifications, status updates (we also have “do not disturb”, which Bonjour lacks), file transfers, and make it all work but without servers.

It took some time, and I am very thankful for support, inspiration and testing to folks in Yggdrasil muc.

So we have a purple plugin now which works.

Since when using Yggdrasil you are exposed to whole Yggdrasil network, people tend to use firewalls. Users could whitelist one port for Barev, but file transfers in Bonjour implementation would choose random ports. So I have adapted it to use a dedicated port range, that could be unlisted.

2 Likes

How to use:
Basically, you build the plugin, and copy it to ~/.purple/plugins or install systemwide.
Then in Pidgin you add an account, and choose a nick. You can also choose custom port, by default it is 1337. Better leave it as is for now.
Then you add buddies.

You add buddies as nick@ipv6 where ipv6 is their yggdrasil IP.

Barev plugin will allow connections only from those nicks and ips and ports that are known. So random people can’t contact you. The connection will be dropped as early as possible. For example from unknown IP.

It is only possible to communicate if you explicitly added each other as nick@ipv6.

If you remove a contact from the roster, it will not be able to interact with you.

It is not possible to impersonate a contact, because Yggdrasil takes care of this. It also takes care of end to end encryption.

If there’s a route it will find a route and it will encrypt the traffic.

1 Like

here is a link to the pascal library

1 Like

It’s a bit unclear to me how much of XEP-0174 is being used here. If you get rid of the discovery and know the exact IP to connect to and do a direct TCP over ygg I guess it ends up being very similar to the XMPP core s2s protocol. Are you doing anything at the moment to verify who the sender is?

Barev is inspired by XEP-0174’s serverless model, but it does not implement DNS-SD/mDNS discovery part of XEP-0174. Peer discovery/addressing is manual (nick@iggIPv6[:port]) and connections are allowlisted.

Once discovery is removed, what remains is basically XMPP-style jabber:client streams + message stanzas over a direct TCP socket, with both peers acting as client + listener. So it looks more like c2s semantics but without server, than s2s.

Sender verification today is:
Firstly, Yggdrasil’s cryptographic identitiy behind the peer’s Yggdrasil IPv6 address, plus an application allowlist check for configured nick + ip + port of the contact in the roster.

We don’t find peers, we add them by nick@yggIPv6. Firstly we check if the connection comes from the known IP address. If it’s not then it is dropped.
Then we check stream for the nick + ip + port. Unknown nick from a known IP will be rejected. However Yggdrasil IP only is already strong identity signal.

Then we filled the gaps by using XMPP stanzas for the rest: chat texts, online/away/dnd/offline and status text, for pings and file transfer negotiations.

For pings we use XEP-0199, for typing notifications stanzas from XEP-0085, for avatars we use XEP-0153, for file transfers XEP-0095 and XEP-0096.

But of course without servers. The stanzas are sent from peer to peer.

Yggdrasil network is responsible in part for identity (IP) and for direct TCP connections and it takes care of end to end encryption.

I was solving my own problem with Barev. When my homelab has no electricity for hours, I loose connection with my contacts. Since I only use XMPP and nothing else, I have no phone, then I am in trouble in case of power outage in my home lab. With Yggdrasil, it doesn’t matter which servers/nodes will route the message. If one has an outage, other will route.

So negotiation is XMPP stanzas, data path is direct TCP over Yggdrasil.

You can have your isolated Yggdrasil network for a community, or connect to a global one.

Is there any reason to keep using jabber:client namespace instead of s2s namespace in this case? It seems basically like the s2s protocol is what’s being implemented here.

Ah right, it makes sense that if the sender uses only IP not hostname you can trust that, especially in ygg

I came to this idea (of behaving like s2s) when, inspired of Barev, folks from Yggdrasil community started experimenting with configuring XMPP servers on Yggdrasil network, by using or not even using the domain names, but only [ipv6] addresses as domains. The latter proved to be very difficult. I think nobody was able to configure a server that uses IP instead of domain and communicate to clearnet XMPP server that also has a Yggdrasil IP successfully, because today clearnet XMPP servers expect correct certificates.

After that I had this thought that perhaps it was better to behave like an XMPP server, and started to dive deeper what would it require. But it would require dialback or PKIX verification, server to server error semantics, multiplexing many users over one connection, handling unknown users, and it would introduce many many difficulties.

Also when seeing that folks who experimented with Yggdrasil XMPP servers ended up using domains, not just IP addresses, I though that it makes sense to keep Barev as is, conceptual descendant of Bonjour (also a fork of that plugin), which was designed for serverless peer to peer communication.

So Barev explicitly does the opposite: only allowlisted peers, one identity per process, no routing, no multi-user authority. And jabber:server would suggest behavior that simple does not exist.

And XEP-0174 from which we started uses client semantics jabber:client, so initially it also felt right.

By the way, the name Barev is also a consequence of the fork.
Barev in Armenian is what Bonjour is in French. So I just used first word that came to mind.

1 Like

I don’t think any of this should be required? dialback or PKIX are certainly common on the current public network, but you’re not aiming to be directly compatible with that anyway, especially to start right? So using your own ygg verification instead serves the same purpose here.

And you only have one user (since you’re also a client) so nothing really to multiplex? Unless I’m missing what you meant here.

By the way, the name Barev is also a consequence of the fork.
Barev in Armenian is what Bonjour is in French. So I just used first word that came to mind.

This would be a good addition to your readme :slight_smile:

1 Like

singpolyma, thank you for your comments! (:

As I tried to express, I agree that it could be done differently. At some point I might want to experiment with a plugin or service that behaves more like an XMPP server on Yggdrasil. I had such an incentive when folks were experimenting with XMPP server on Yggdrasil, but since it proved difficult without using domain names to communicate with clearnet servers, that motivation decreased.

I realized that Barev is what it is, a descendant of the Bonjour plugin. For that model jabber:client felt like the most honest description of what it actually does.

If I ever go the other path, I think it would naturally become a separate project with different assumptions.

For now, Barev solves my needs, and some people already use it, so I’d rather focus on improving what works than redesigning it entirely.

1 Like

so nothing really to multiplex?

I meant that for Barev, each remote user is a separate connection. Even if the remote IP is the same.
So remote identities are handled as separate peer connections, not multiplexed over a single stream.

1 Like