The Jabber Server

The incarnation of the Jabber Server at the time of writing is version 1.4, more specifically 1.4.1. Version 1.4 represents a major step towards the 2.0 release and brings stabilisation of the server code and increases in performance and reliability over earlier versions. 1.4.1 is the version of the Jabber Server we will obtain and install here, and this will be used as the server for the recipes in the rest of this book.

Getting It

The Jabber Server package can be obtained from the Jabber project site - http://www.jabber.org; the 1.4.1 version is available in the downloads area:

http://download.jabber.org/dists/1.4/final/jabber-1.4.1.tar.gz

The tarball jabber-1.4.1.tar.gz contains everything that you need to get a Jabber Server up and running. [1] Previous versions of the Jabber server came in multiple packages - it was necessary to separately obtain and install GNU's portable threads library (pth) and the asynchronous DNS package (ADNS), as well as obtaining and installing various Jabber-specific libraries such as libxode, libjabber and libetherx. Now some of these libraries and packages have become obsolete as far as the Jabber Server is concerned (ADNS and libetherx) and others have been combined into the main Jabber Server tarball.

Installing It

Once you have downloaded the Jabber Server tarball, you need to unpack, configure the build environment, and compile it. The general idea is that the Jabber server will be compiled and run from wherever you decide to unpack it; that is, there is no separate 'install' step.

For this reason, and because it's also often useful to be able to install and start up a different version of the Jabber Server for testing and comparisons, create a generic 'jabber' directory somewhere central but local, for example in /usr/local/:

yak:/usr/local# mkdir jabber

The Jabber Server does not and should not be run as root; so create a new user jabber (group jabber) to be used as the Jabber Server administrator and make that user the owner of the generic Jabber Server directory:

yak:/usr/local# groupadd jabber
yak:/usr/local# useradd -g jabber -d /usr/local/jabber jabber
yak:/usr/local# passwd jabber
Changing password for jabber
Enter the new password (minimum of 5, maximum of 127 characters)
Please use a combination of upper and lower case letters and numbers.
New password: ********
Re-enter new password: ********
Password changed.
yak:/usr/local# chown jabber:jabber jabber
yak:/usr/local#

Once you've created the generic Jabber Server directory, switch to the new Jabber Server administration user jabber, unpack the tarball you downloaded and enter the resulting directory:

yak:/usr/local# su - jabber
yak:~$ tar xzf jabber-1.4.1.tar.gz
yak:~$ cd jabber-1.4.1/
yak:~/jabber-1.4.1$ 

configure

Examining the contents of the jabber-1.4.1 directory, we see the following files:

as well as a number of directories that contain the source code.

The first step is to run the configure script:

yak:~/jabber-1.4.1$ ./configure

to determine your platform's compiler settings.

If you want SSL support in the Jabber Server, run the script with the --enable-ssl switch:

yak:~/jabber-1.4.1$ ./configure --enable-ssl

If you specified the --enable-ssl switch, the configure script will look for your SSL installation and add the appropriate compiler flags. If it doesn't find your SSL installation, it will say so and your Jabber Server will be compiled without SSL support.

Next, it will try to determine whether you have pth installed, and if so will use the pth-config command to glean the extra compiler options for building the Jabber Server. pth is required, so if it isn't already installed, it will be set up within your current jabber-1.4.1 directory tree (as pth is included in the jabber-1.4.1.tar.gz tarball) and the appropriate compiler options added.

(If pth is set up during the course of running configure, you may see a message: "Now please type 'make' to compile. Good luck." which comes at the end of the pth configure procedure; you can ignore this because there is only one make step, for the Jabber Server, that must be carried out as we are merely preparing the pth build environment for binding into the Jabber Server build.)

Finally, after extra platform specific compiler settings are determined, a shell script to set the build environment variables is created with the name platform-settings. This is used in the next step.

Example 3-1 shows typical output from the configure script.

Example 3-1. Typical output from configure

Running Jabber Configure
========================

Getting pth settings...         Done.
Setting Build Parameters...     Done.
Generating Settings Script...   Done.

You may now type 'make' to build your new Jabber system.

make

Once the platform settings have been determined by the configure script, we are ready to build the Jabber Server with make.

yak:~/jabber-1.4.1$ make

Example 3-2 shows abbreviated typical output from the make command.

Example 3-2. Typical output from make

Making all in pthsock
make[1]: Entering directory `/usr/local/jabber/jabber-1.4.1/pthsock'
gcc -g -Wall -fPIC -I. -I.. -I/usr/local/include -I../jabberd/   -c client.c -o
client.o
gcc -g -Wall -fPIC -I. -I.. -I/usr/local/include -I../jabberd/ -shared -o pthsoc
k_client.so client.o -L/usr/local/lib -lpth -ldl -lresolv
make[1]: Leaving directory `/usr/local/jabber/jabber-1.4.1/pthsock'
Making all in xdb_file
make[1]: Entering directory `/usr/local/jabber/jabber-1.4.1/xdb_file'
gcc -g -Wall -fPIC -I. -I.. -I/usr/local/include -I../jabberd   -c xdb_file.c -o
 xdb_file.o

...

gcc -g -Wall -fPIC -I. -I.. -I/usr/local/include -DHOME="\"/usr/local/jabber/jab
ber-1.4.1\"" -DCONFIGXML="\"jabber.xml\"" -o jabberd config.o mio.o mio_raw.o mi
o_xml.o mio_ssl.o deliver.o heartbeat.o jabberd.o load.o xdb.o mtq.o static.o lo
g.o lib/expat.o lib/genhash.o lib/hashtable.o lib/jid.o lib/jpacket.o lib/jutil.
o lib/karma.o lib/pool.o lib/pproxy.o lib/rate.o lib/sha.o lib/snprintf.o lib/so
cket.o lib/str.o lib/xmlnode.o lib/xmlparse.o lib/xmlrole.o lib/xmltok.o lib/xst
ream.o lib/xhash.o base/base_connect.o base/base_dynamic.o base/base_exec.o base
/base_stdout.o base/base_accept.o base/base_file.o base/base_format.o base/base_
stderr.o base/base_to.o -Wl,--export-dynamic -L/usr/local/lib -lpth -ldl -lresol
v
make[2]: Leaving directory `/usr/local/jabber/jabber-1.4.1/jabberd'
make[1]: Leaving directory `/usr/local/jabber/jabber-1.4.1/jabberd'
make[1]: Entering directory `/usr/local/jabber/jabber-1.4.1'
make[1]: Nothing to be done for `all-local'.
make[1]: Leaving directory `/usr/local/jabber/jabber-1.4.1'

Configuring The Jabber Server

The nature and behavior of a Jabber Server is controlled by the contents of a configuration file (with a default name of jabber.xml) which you will find in the jabber-1.4.1 directory. As you can probably guess from the filename's extension, the configuration is formatted in XML, and affords a very powerful way of expressing the nature and features of your Jabber Server and associated services and components.

Details on how to navigate, interpret, and edit this configuration file are given in the next chapter; here we will just look at the basic settings that can be modified before you start up the Jabber Server.

For an experimental Jabber Server (such as for the purposes of this book) there isn't actually anything you need to change in the configuration. The out-of-the-box configuration settings are pretty much what we need to experiment with our recipes later in the book; nevertheless, let's look at some of the settings which you may wish to change right now.

You may have noticed that the values for each of these two settings (<host/> and <update/>) were wrapped in another tag:

<jabberd:cmdline flag="h">...</jabberd:cmdline>

This means that you can override the setting with a command-line switch (or 'flag'), in this case -h. So in fact, you don't even need to modify the jabber.xml configuration at all, if you specify your hostname when you start the server up (the welcome message will not be changed, of course).

Starting and Stopping the Jabber Server

At this stage, we have a Jabber server with enough basic configuration to be able to start it up and have it do something useful (like accept client connections). If you're curious about the rest of the configuration you encountered while editing the jabber.xml file, you can jump to Chapter 4. Otherwise, let's start it up!

Starting the Server

The basic invocation looks like this:

yak:~/jabber-1.4.1$ ./jabberd/jabberd

but if you haven't bothered to change localhost anywhere in the configuration (as described earlier) you can use the -h switch to specify the hostname:

yak:~/jabber-1.4.1$ ./jabberd/jabberd -h yak

As it stands, there's a directive in the standard jabber.xml configuration file that specifies that any server error messages are to be written out to STDERR:

<log id='elogger'>
  <host/>
  <logtype/>
  <format>%d: [%t] (%h): %s</format>
  <file>error.log</file>
  <stderr/>
</log>

So either comment the directive out:

<!--
  <stderr/>
-->
Or redirect STDERR to /dev/null:

yak:~/jabber-1.4.1$ ./jabberd/jabberd -h yak 2>/dev/null

You won't lose the error messages - as you can see they're also written to the error.log file.

Assuming you wish to free up the terminal session after starting the server, you can send it to the background:

yak:~/jabber-1.4.1$ ./jabberd/jabberd -h yak 2>/dev/null &

Stopping the Server

To stop the server, just kill the processes, and it will shut down gracefully:

yak:~/jabber-1.4.1$ killall jabberd

or:

yak:~/jabber-1.4.1$ kill `cat jabber.pid`

jabberd Command Line Switches

We've seen the -h switch to specify the host when starting the server up; there are other switches available on the command line too; here is a list:

Table 3-1. Command Line Switches

SwitchRelating toDescription
-cAlternate configurationUse this to specify an alternative configuration file if you don't want to use jabber.xml
-DDebugging infoSpecifying this switch will cause (a large amount of) debugging information to be sent to STDERR.
-hHostnameThe hostname of the Jabber Server
-HHome folderUsed to specify 'home' folder or directory
-sSpool areaThe directory where the Jabber Server stores data via the xdb_file module
-vShow versionReports Jabber Server version and exits
-VShow versionSame as -v
-ZDebugging infoLimit the debugging information to certain 'zones' (comma separated) [a]
Notes:
a. the 'zones' are the filenames that immediately follow the timestamp in the debug log records, for example 'xdb_file' or 'deliver'.

Starting the Jabber Server with any unrecognized switches will cause it to show you a list of valid switches:

[yak: ~/jabber-1.4.1]$ ./jabberd/jabberd -badswitch
Usage:
jabberd &
 Optional Parameters:
 -c             configuration file
 -D             enable debug output
 -H             location of home folder
 -v             server version
 -V             server version

Yes, the list isn't complete. If the common switch -h were present in the list, we could almost consider the unlisted switches as undocumented, but it is isn't present, so we won't.

Monitoring and Troubleshooting

We've already seen a glimpse of the configuration relating to logging of messages in the previous section. As standard, the Jabber Server configuration describes two types of logging record and a recipient file for each type:

Error logging

Error log records are written to error.log in the current directory, as determined thus:

<log id='elogger'>
  <host/>
  <logtype/>
  <format>%d: [%t] (%h): %s</format>
  <file>error.log</file>
  <stderr/>
</log>

Statistical logging

Statistical log records used for tracking purposes are written to record.log in the current directory, as determined thus:

<log id='rlogger'>
  <host/>
  <logtype>record</logtype>
  <format>%d %h %s</format>
  <file>record.log</file>
</log>

Log records of this type are written when a client connects to the server, and when a client disconnects.

Furthermore, we can use the debugging switch (-D) when we start the server and have debugging and trace output written to STDERR.

If your Server Doesn't Start

There are a number of things to check that are likely candidates for preventing your server from starting.

Bad XML configuration

It is not difficult to make errors (typographical or otherwise) in the server configuration. The first line of defense is to be careful when editing your jabber.xml file. After that, the Jabber Server isn't going to be too forthcoming with information if you have broken the well-formedness of the XML:

yak:~/jabber-1.4.1$ ./jabberd/jabberd -h yak
Configuration parsing using jabber.xml failed

Help is at hand in the shape of Perl and the XML::Parser module, which is a wrapper around the XML parser, expat.

Providing you have Perl and the XML::Parser module installed, you can get expat to give you a clue where the XML is broken:

yak:~/jabber-1.4.1$ perl -MXML::Parser -e 'XML::Parser->new->parsefile("jabber.xml", ErrorContext => 3)'

not well-formed (invalid token) at line 47, column 35, byte 1750:
    be on one line, the server doesn't like it otherwise! :)
    -->

    <host><jabberd:cmdline flag="h"yak</jabberd:cmdline></host>
==================================^

    &lt;!--
    This is the custom configuration section for the
 at /usr/local/lib/perl5/site_perl/5.6.0/i586-linux/XML/Parser.pm line 185
yak:~/jabber-1.4.1$

This shows us exactly where our problem is. In this case I inadvertently removed the close-tag symbol ">" when replacing localhost with yak.

Unable to Listen On Port(s)

Taking the standard jabber.xml configuration, the Jabber Server will try to bind to and listen on two ports: 5222 (for incoming client connections) and 5269 (for server to server connections). If other processes are already listening to these ports, then the Jabber Server cannot start and you will see something like this in the error log:

20010407T12:11:06: [alert] (-internal): io_select unable to listen on 5222 [(null)]
20010406T12:11:06: [alert] (-internal): io_select unable to listen on 5269 [(null)]

If this is the case, you can check the status of the ports with the netstat command:

yak:~/jabber-1.4.1$ netstat -an | grep -E '5222|5269'
tcp        0      0 0.0.0.0:5269            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:5222            0.0.0.0:*               LISTEN

If you see entries like this, it means that processes have been bound to these ports on all IP addresses. [4] For example, if 0.0.0.0:5222 is being listened to then you may have another instance of a Jabber Server already running.

On BSD systems, you cannot bind to the 'default' null address; the same error messages will be issued as if the ports were already bound. In the standard jabber.xml configuration file, a bind to the null address is specified for each port as standard; what you must do is change this and specify an explicit IP address for each of the ports in the configuration. That is, instead of:

<ip port="5222"/>

do something like this:

<ip port="5222">127.0.0.1</ip>

Notes

[1]

If you want the Jabber Server to support SSL connections, you will need to have installed an SSL package; see the next chapter for more details.

[2]

A "virtual" business card containing contact information.

[3]

Some Jabber clients such as Jabber Instant Messenger require vCard information to be entered when registering for a new account, which means that an attempt to contact users.jabber.org would be made the first time a user connects.

[4]

This "all" relates to the (null) shown in the "unable to listen" error messages shown earlier.