Server Configuration

At this stage, we should be fairly comfortable with the notion of a jabberd backbone and a set of components that combine to provide the features needed for a complete messaging system. We've looked at fragments of configuration in the previous section; now it's time to examine the configuration directives in more detail.

It's not uncommon for people installing a Jabber server for the first time to be daunted (I was terrified!) by the contents of the jabber.xml configuration file. But really, for the most part, it's just a collection of component descriptions—what those components are, how they're connected, what packets they are to process, and what their individual configuration is.

Component instances

There's a concept that encompasses Jabber's configuration approach that is taken from the object-oriented (OO) world—the concept of objects (and classes) and instances thereof. In Jabber server configuration, specifically the description of the components that are to make up a particular Jabber server, we talk about instances of components, not components directly.

In other words, a component is something generic that is written to provide a specific service or set of services; when we put that component to use in a Jabber server, we customize the characteristics of that component by specifying detailed configuration pertaining to how that component will actually work. We're creating an "instance" of that component.

A typical component instance description

Each component instance description follows the same approximate pattern:

Of course, for any generalized rule, there's always an exception. The log component type, as mentioned earlier in this chapter, is defined slightly differently —while there is a host filter defined, a component connection definition is not relevant nor present, and the custom configuration is limited— we'll see this later when we take a tour of the jabber.xml.

Let's have a closer look at the Client (to Server) Connections (c2s) component and how an instance of it is specified in the jabber.xml. We're going to use the one which comes delivered in the Jabber 1.4.1 server distribution tarball. Example 4-7 shows how the c2s is defined. The definition includes details of how the component code is connected (using the library load method), and contains some custom configuration covering authentication timeout (the <authtime/> tag), traffic flow control (the <karma/> section), and what port c2s is to listen on (the <ip/> tag). We'll look at these custom configuration tags in detail later.

Example 4-7. The c2s instance configuration in jabber.xml

<service id="c2s">
  <load>
    <pthsock_client>./pthsock/pthsock_client.so</pthsock_client>
  </load>
  <pthcsock xmlns='jabber:config:pth-csock'>
    <authtime/>
    <karma>
      <init>10</init>
      <max>10</max>
      <inc>1</inc>
      <dec>1</dec>
      <penalty>-6</penalty>
      <restore>10</restore>
    </karma>
    <ip port="5222"/>
  </pthcsock>
</service>

Now let's arrange this instance configuration in diagram form. Figure 4-3 highlights the pattern we're expecting to see.

Figure 4-3. A diagram of the c2s instance configuration in jabber.xml


    +-----+                                 
    | c2s |                                
    +-----+-------------------------------------------+
    |                                         service |
    |                                                 |
    |--> host                                         |
    |    (none specified)                             |
    |                                                 |
    |--> connect                                      |
    |    load ./pthsock/pthsock_client.so             |
    |                                                 |
    |--> config                                       |
    |     |                                           |
    |     +--> authtime                               |
    |     |                                           |
    |     +--> karma                                  |
    |     |                                           |
    |     +--> ip                                     |
    |                                                 |
    +-------------------------------------------------+

If we look at the component instance descriptions in this way, it's easy to understand how the configuration is put together, and we can begin to see the pattern emerging. Taking each of the elements of the pattern in turn let's examine what the XML tells us.

Component type

The component type is service. We know that from looking at the outermost tag in the XML:

<service id="c2s">
  ...
</service>

So we know that this component instance will handle <message/>, <presence/>, <iq/> and <route/> packets.

Identification

Each component instance must be uniquely identified within the space of a single Jabber server (configuration). jabberd uses this identification to address the components and deliver packets to the right place. In this case, the identification of this component instance is c2s; it's taken from the id attribute of the component type tag:

<service id="c2s">

Host filter

The diagram shown in Figure 4-3 states "none specified." So what happens now? Well, a host filter is usually one or more <host/> tags containing hostnames to which the component instance will "answer". It's a way of specifying that packets destined for a certain hostname will be received by that component instance.

However, if there are no <host/> tags specified as in this c2s example, then the component instance's identification is taken as the hostname specification. In other words, the <service id="c2s"> declaration in this example, coupled with the lack of any explicit <host/> tag, implies a host filter of "c2s". This component instance wants to receive all packets with addresses that have "c2s" as the hostname. It's the equivalent of this host filter specification:

<host>c2s</host>

The <host/> tag

There is some degree of flexibility in how you specify a hostname in the <host/> tag.

You can specify an absolute hostname like this:

<host>conference.yak</host>

You can specify more than one hostname like this:

<host>conference.yak</host>
<host>talk.yak</host>

For example, if this pair of <host/> tags appeared in an instance specification for the Conferencing component, you could address the component instance using either hostname.

You can use a wildcard character to specify all hostnames within a domain, for example:

<host>*.pipetree.com</host>

will match on all hosts with the domain name pipetree.com.

If you want the component instance to receive packets regardless of the hostname, you can specify an empty tag thus:

<host/>

Component connection method

What is the component? Where do we load it from, or how does it connect to the Jabber backbone? There is a component connection method (see the section called Component Connection Methods earlier in this Chapter) specified in each of the component instance definitions. In our example of the c2s component instance, we see that the library load method is being used to load the ./pthsock/pthsock_client.so shared object library, and that the component registration routine pthsock_client() should be called once loading is complete:

<load>
  <pthsock_client>./pthsock/pthsock_client.so</pthsock_client>
</load>

Custom configuration

Once we've dealt with the (optional or implied) <host/> tag hostname filters, and the component connection method, all that is left is the custom configuration for the component instance itself. This will look different for different components, but there is still a pattern that you can recognize. The configuration always appears in a "wrapper" tag that, like the <host/> and <load/> tags above, appears as an immediate child of the component type tag (that's <service/> in our c2s example):

<service id="c2s">
  ...
  <pthcsock xmlns='jabber:config:pth-csock'>
     ... [configuration here] ...
  </pthcsock>
</service>

There are two things to note here:

  • The tag name (<pthcsock/>)

  • The namespace declaration (xmlns='jabber:config:pth-csock')

To put it bluntly, one is important, the other isn't. The name of the tag enclosing the instance's configuration—"pthcsock" is not important. There must be a name (otherwise it wouldn't be valid XML) but it might as well be "banana" for all the effect it would have. So as it might as well be "banana," it might as well be something meaningful—hence "pthcsock."

The important part of the configuration wrapper tag is the namespace declaration:

xmlns="jabber:config:pth-csock"

because that is what the component actually uses to search for and retrieve the configuration.

As for the actual configuration elements for the c2s component instance that we see here ( <authtime/> and <karma/>), we'll take a look at them in the next section.