Win32 Server Port

Jeremie Miller

The Jabber.org Project

jer@jabber.org

02/20/2001


Intro

For quite some time now there has been a lack of a Jabber server option for Windows. Although development is progressing at jabber.com and winjabber.com, they are not yet available and focused on a commercial server release.

I'm going to do two things here, outline a method for porting the jabber.org server codebase to a native win32 services, and make my ignorance of win32 programming painfully obvious. If my blasphemy becomes too painful at any point, please send me a message and I'll happily take corrections and additions to this document :)

What I'd like to become of this, is attract *SOMEONE* with Microsoft development tools to review and take a stab at implementation. As soon as someone steps up to the plate I'll update this document, and if we get more than one offering to help we can set up cvs and a discussion area.


Overview

Here's the base components in the server (get latest from "cvs -d :pserver:anoncvs@jabber.org:/home/cvs co jabber2"):

	dnsrv
	jsm            
	pthsock  
	xdb_file
	dialback
	jabberd
The codebase is pretty straight-forward ANSI C. The jabberd peice is the mastermind, which contains all of the symbols for the utilities (xml parsing/handling, strings, hashes, etc). The rest of the components are just symbols that are statically called or dynamically loaded into jabberd and run based on the configuration file. The threading model is based on the non-preemptive portable threading library pth (http://www.gnu.org/software/pth/).

In general, I think the plan is going to be to replace 'jabberd' with a native win32 version, and it would have the intelligence on how to handle the components properly. So as to get a win32 version out ASAP, the focus shouldn't be on completly replicating the functionality of the existing jabberd. But in time, it could very well grow to support many of the win32 capabilities at a component level (COM, ODBC, etc).


Jabberd and Threading

The threading model is unfortunately non-preemptive, so most of the components and functions aren't thread-safe in win32 threads. This might work out alright though... if the win32 jabberd, well, let's just call it jabbers (jabber 'service' instead of 'daemon'). If jabbers uses a single win32 thread for each component, then that component shouldn't pose any threading problems.

The most important thing that jabbers has to do is handle calls to deliver() and route them to the right component. When each component calls deliver(), it could use some internal logic (based on configuration like jabberd) that would locate the right component and put it in a packet-queue on that thread. When that component/thread then has cpu time, it could process it's queue. The thread could wake up intermittently and fire any heartbeats if that component needs cpu for checking it's hashes to timeout things.

The next most important thing jabbers has to do is MIO, the Managed IO api. The MIO api is fairly simple, and the complex parts of it probably don't need to be supported in the initial port. I'm not familiar with win32 socket handling, but I shouldn't think it would be too difficult to re-implement native MIO support.

The rest of what jabbers needs is just the utility symbols, xmlnodes, jpackets, jids, etc... Expat is the parser and already common in win32 apps, and the rest of the files are pretty straight C, shouldn't pose any problems.


Required Components

pthsock (client sockets)

If MIO is ported, then pthsock should work fine... it doesn't do anything but some simple logic for processing the data on the sockets and feeding them into the server.


jsm

This one could be a booger, since it uses 'mtq' which is just a fancy way of guaranteeing that each session's packets are processed in order. The only thing that ever blocks any of these session-threads is xdb calls, so the easiest way, although ugly, would be to just spawn a thread whenever a session has data to process and hack the xdb calls to do proper blocking on those threads (and unblock when the parent jsm thread gets the result). The even *easier* way would be to just have a single thread and block on every xdb call, which isn't going to perform very well but it would at least be functional.

The rest of the things that jsm does is just packet manipulation, should port easily. The session and xdb threading is going to be the difficult part here.


xdb_file

Simply loads xml from a file and returns it when asked. Nothing platform specific here except the file IO, but that's easy to do in win32 as well. One tactic in the porting which might simplify things, would be to make the xdb_* calls something that happen in the thread they are called from and not something that is done through a deliver(). This might make the porting of jsm significantly simpler since xdb_* calls are all that block the session threads.


dnsrv

This depends on libresolv, I don't know how dns resolution is done on win32, but libresolv would block the entire process so dnsrv forks a copy and communicates with it over sockets to actually perform the resolutions. I'd home that the functionality dnsrv provides would or could be easily rewritten, and maybe just included as part of the dialback since that's their primary use.


dialback

Nothing particularly difficult here either, as long as MIO works then dialback should be fine as well.