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:
- Both services need to have the same 'id'.
- One service has a <connect/> element, and the other has a <accept/> element in the configuration. The process containing the <connect/> element will establish the connection to the other process containing the <accept/> element.
- If both processes are running on the same host, you probably want to connect using the localhost address 127.0.0.1. This gives you additional security, no other host is able to connect to this address on your server. But if you run the two processes on different hosts, you can configure the connection using other IP addresses of the host running the router as well.
- You can choose any port for the connection, that is free. If you have different accept-services in your configuration file you even have to take care, that all of them use different ports.
- You can choose any password you want for the connection, but you have to configure the same password for both ends of the connection.
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.