jabberd14 - the original Jabber server implementation

jabberd14 HOWTO: external s2s component

The s2s component is responsible to manage to connections to other Jabber/XMPP servers. Sometimes is might be desirable to run this component in its own process. With an external s2s component you can restart this component, and with that reset all s2s connections, without a complete restart of your server - your users can stay online. As well as an external s2s component is the basis for clustering the s2s component.

There is no special magic in running the s2s component in its own process. It's the same as with running jabberd14-based transports in their own process: You start two instances of jabberd, one that runs all the other components (in the further text I will call this the router), and one that runs the external s2s component (which I will call s2s-process).

These two jabberd14 instances have to be connected to each other. This is done by one jabberd14 connecting to the other jabberd14 using a TCP/IP connection. Typically you will have the s2s-process connect to the router, but it could be done the other way round as well (e.g. if your firewall requires you to do so). To establish this connection, you have to add a new <service/> element to each configuration file of your jabberd14 processes:

In the configuration file of the router add the following service:

<service id='s2s-linker'>
    <!-- here we will add something later -->
    <accept>
        <ip>127.0.0.1</ip>
	<port>5300</port>
	<secret>password</secret>
    </accept>
</service>
    

In the configuration file of the s2s-process add the following service:

<service id='s2s-linker'>
    <!-- here we will add something later -->
    <connect>
        <ip>127.0.0.1</ip>
	<port>5300</port>
	<secret>password</secret>
    </connect>
</service>
    

The important things here are:

Guess what? With just that we already successfully interconnected the two instances of jabberd14!

What is left to do now is to tell the both jabberd14 when to use this connection. This is done by setting up something I call routing. Before looking on how to write down the routing to your configuration files, let's see what we have do:

We have to send all stanzas, that are received inside the s2s-instance (which are the stanzas received from other hosts) to our router. Therefore all stanzas in the s2s-instance have to be sent to the link between the two instances.

In the router we only have to sent those stanzas to the other process, that are for the s2s component inside the s2s-instance. (Note: We do not really have to send the stanzas address to other servers to the s2s component. It is the DNS resolver component, that we have to route these stanzas to and this component stays in our router. It is the task of this DNS resolver to first lookup the destination IP address, tag the stanza with this IP address, and resend the tagged stanza to the s2s component. That is why we configure inside the dnsrv component the name (id value) of the s2s component.) Therefore all we have to route to the connection inside the router are packets addressed to s2s.

We now configure this routing inside the configuration files:

In the configuration file of the router we now have:

<service id='s2s-linker'>
    <host>s2s</host>
    <accept>
        <ip>127.0.0.1</ip>
	<port>5300</port>
	<secret>password</secret>
    </accept>
</service>
    

In the configuration file of the s2s-process add the following service:

<service id='s2s-linker'>
    <uplink/>
    <connect>
        <ip>127.0.0.1</ip>
	<port>5300</port>
	<secret>password</secret>
    </connect>
</service>
    

As you can see, we can add explicit routings by adding <host> elements to a service. This element has to be added as an immediate child element to the <service/> element. You can also add multible <host/> elements to a service if you need, but in this case, there is no such need.

An alternative to adding <host/> elements is to use the <uplink/> element. Only one <service/> element inside the configuration of a jabberd14 instance is allowed to contain an <uplink/> element. jabberd14 will send all stanzas to the <service/> containing the <uplink/> element, that have no other routing defined by a <host/> element. (Note: <host>*</host> would do the same. The difference is, that <host/> would only route stanzas, while <uplink/> also routes internal jabberd14 messages for database access and logging.)

As a last thing, you have to change the filename for the pid-file, that is written on startup of the jabberd process. Or if you do not need pid-files, you can also just remove the <pidfile/> element from the configuration.

Now we are done. Your s2s component will run in its own process. Just make sure, that you now have to start both instances of jabberd14. Therefore you now have to tell jabberd14 when starting which configuration file it has to use. This is done using the -c command line switch.

Example files

To have a look at complete configuration files, I made these changes to the default jabberd14 configuration file (version as of 2006-08-04).

Configuration file for the router.
Configuration file for the s2s-instance.