The Routing Layer of PSYC is syntactically almost the same as PSYC itself.

This once had its own name: Modular Message Protocol aka MMP, but this led to the false assumption that MMP makes sense in itself without its higher layers. The higher layers are in fact needed for signaling of many kinds, so it's better to just call it PSYC's routing layer.

The routing layer has a fundamental builtin notion of context and multicasting. The actual implementation of multicasting albeit is flexible and free for any brilliant mind to improve.

The purpose of separating routing from end-to-end content is to be able to produce rapid router technology (in hardware if necessary) which only parses the routing layer, then operates accordingly, without having to look at anything below (see also framing).

RFC 1324 postulates this distinction as a requirement for a future conferencing protocol in paragraph 5.2.1 Message passing:

A conferencing server should pass on all messages not destined for itself or its users to the destination as quickly and efficiently as possible. To this end, the server should not be required to do extensive parsing of the incoming message, but rather, look at the header and decide from there whether to send it on in the typical gateway/relay fashion or parse it and pass it to one or more of its users.

The historic specification resides at We are working on a new one.

The routing layer in theory was supposed to have a lot of negotiable modules, but in fact that was never really needed, wanted, implemented or anything. See modules for details.



When an entity sends a packet to another entity the destination root entity has to decide where to put the packet next. Either it relays it to a remote entity or delivers it to a local one.

Where packets come from and where they should go to is mainly defined by the three routing variables _source, _target and _context.

Contents of _source, _target and _context

The routing variables can contain any uniform scheme. PSYC nodes SHOULD NOT assume that only psyc: scheme uniforms appear in these variables.

When the uniform scheme matches the psyc: scheme routing is performed as specified in this section.

When the scheme of the uniform in _target is not known the PSYC node MAY choose to forward the packet to a locally connected gateway. When receiving packets from a gateway _source and _context can also contain unknown uniform schemes.

NOTE: The psyc: scheme allows for more fine-grained routing decisions in the PSYC node and the PSYC network in general. This means that PSYC nodes know how to resolve PSYC uniforms to other hostnames and ports and can establish circuits to them to deliver the packet. Other schemes usually only travel between gateways and the PSYC server node they are connected to, no further resolution of the uniforms is done in this case.

Overview of basic routing operations

The basic operations of routing are defined by the presence or absence of the three _source, _context and _target variables. The various multicast strategies build on top of that. So let's first look at the important constellations, then open up a window to future PSYC developments.

Regular Unicast Messages

A regular unicast message uses _source and _target, no _context.

A message with a _source only, is a message to the root entity of the receiving node. (Typically a user requesting the amount of logged in users or similar.)

A message with a _target only, is a message coming from the root entity of the sending node. (Typically a short-lived script or automation like wikinotify, which sends some event notification to a given recipient.)

NOTE: Setting persistent entity variables is invalid for unicast messages in current PSYC. This means you MUST NOT try to apply modifiers (see also Spec:Packet) that modify end-to-end entity variables (eg. with the = operator) in messages without a _context set. Supporting this special case would cause plenty of extra implementation complexity with little advantage, and is therefore reserved for a potential future use. templates MAY still refer to persistent variables of the entity's context, however.

Multicast Messages

This is a message that comes from a context. (for example a chatroom, a user's own presence multicast or some other kind of context) whose recipients are defined by the context subscription mechanism only has the _context routing variable set. The original sender is delivered by _source_relay.

These messages have to be multicast to all members of a context. The general rule is: A multicast message SHOULD travel a physical Spec:Circuit only once.

For this to succeed a PSYC node needs to keep track of who is member of either a local or a remote context. There is a special case with person entities.

NOTE: The term for the manager of context multicasts in psyced is context slave.

Unicast Message for State Signaling

A message with _target and _context is a unicast from the place to a single member. The affected state however is the state of the self-sending _context. This is for example used to bring a new place member's state up to speed with the current conversation.

Future Multipeer Multicasting and Signaling

  • A message with _source and _context is reserved for future use (It will probably be used for peer-to-multicast messages, as defined in a future PSYC version).
  • A message with all three routing variables _source, _context and _target set is also reserved for future use (It will probably be a unicast from _source to _target, which configures the state between _source and _context. In a peer-to-multicast scenario this is a message that each sending participant unicasts to a new member of the group, given he finds his outgoing state important enough to do that. Other solutions to achieve the same result would be to reassign the state with the next posting, or not to use much state at all.)

Routing Variable Table

Same information again in a graphical style.

_context _source _target ... and what to do with it
unicast from root to root
x unicast from root to target
x unicast from source to root
x x unicast from source to target
x multicast from context to members
x x unicast from context to single member
x x invalid: multicast from source to context members
x x x invalid: unicast from source to single member

All invalid configurations are reserved for future use and only invalid in current PSYC version.

To support these routing rules we define some helper terms like logical source in Spec:Glossary.


Some PSYC nodes (usually servers) or entities may provide the ability to relay packets.

Relaying MAY be done by servers which receive packets where the _target variable doesn't address a local entity, then the root entity will relay the packet.

When a packet is relayed it's original _source is moved to the _source_relay variable. The uniform of the relaying entity (either the root entity of a server or some other relaying entity) is then provided in the _source field.

NOTE: Usually PSYC roots limit relaying to trusted entities and sources, like for example Spec:Circuits from localhost.

Routing in a post-federation network

Although the actual encoding may differ (it makes sense to use the native binary encoding of GNUnet), in PSYC2 these concepts of routing are still relevant. In particular the separation between routing and content is obvious since the content is typically encrypted for the final destination.

Questions and Answers

Doctor asks
In IRC the topology is a tree, so loss of communication between two servers causes a net split. Does PSYC have the ability to automatically reroute around a break in a connection?

<lynX> Not unless you explicitly write new extensions to do such a job. Since IRC sends everything along its single tree, you can make the tree wrap around broken links. That was actually useful in the old days, but in today's Internet you shouldn't be unable to communicate between two nodes. The reason why IRC still experiences netsplits is about the distributed presence database of IRC which PSYC does not have, so the problem doesn't really arise in the first place. If two nodes really need to talk to each other so much, they break a connection, then sending things over a proxy will probably not make it better. Still PSYC does have notions of relaying/ proxying, so a configuration which does such a kind of job is feasible.

Also, most information that PSYC delivers is organized in multicast contexts. By definition you could switch to a different point in this particular context's multicast tree to get the information forwarded to you, should the existing constellation fail to deliver. So the answer is mixed: It can be done by design of the protocol, we're not doing this now.

Doctor says
I would like presence information to be somewhat reliable, even if a router fails somewhere in the world.

<lynX> I personally tend to think, if the Internet is so badly damaged that routers fail, then presence isn't exactly the kind of critical application that I want my back-up network connections to be hogged by. Still, presence in PSYC is a multicast context, so the above applies.

So, there is no built in routing protocol in the sense of adaptive routing? i like the idea of latency-and-trust-metric-based linkstate routing. this sounds taxing, but if every circuit link-state change were multicast as server presence information, the map would not be redundant, overlapping heavily with the social network. was reading the wick on Multicast, and GeoIP (or publishing current geolocation coordinates as part of presence) sounds like a good idea. even if it's possible to lie about one's location, you only need a rough estimate, and there's a built in incentive to be honest. so would it be a good idea for geolocation, trust metrics, and network latency to all factor into the metrics used for packet forwarding?

<lynX> All sounds great and like a lot of work. See also pseudo on technologies that already do some of that and just need our trust metrics added to them.

<coyo> does GNUNet optimize for latency? or can we manipulate GNUNet for speed?