?

Log in

No account? Create an account
Modular Jabber Server: DJabberd - brad's life [entries|archive|friends|userinfo]
Brad Fitzpatrick

[ website | bradfitz.com ]
[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

Modular Jabber Server: DJabberd [Mar. 2nd, 2006|11:42 pm]
Brad Fitzpatrick
[Tags|, , , ]

UPDATE 2006-04-12: This ancient post is still the top Google hit, so go here for new information DJabberd website.
I've been hacking on a Jabber server lately and getting other people at the company also hacking on it with me. Tonight Artur and I did SSL support and fixed a ton of bugs and missing features. Started to work on s2s/dialback, now that we have SSL, but got tired, and I have jury duty in the morning.

The idea of the server is that it's a dummy shell / base class that you either subclass and/or instantiate a bunch of hook handlers for. (in the spirit of mod_perl, qpsmtpd, etc...)

It'll be usable for:
-- my personal jabber server, on "fitzpat.com" (maybe), but for other dorks
-- our company-internal jabber server, using LDAP auth (an auth plugin)
-- LiveJournal (lots of machines in one logical domain)

The main pluggable phases now are auth and roster management, and you can subclass to handle new stanzas, or to change message routing behavior, etc.

So far we have plugins for:
-- DJabberd::Roster::LiveJournal
-- DJabberd::Auth::StaticPassword
-- DJabberd::Auth::AllowedUsers
-- DJabberd::Auth::LiveJournal

So it's flexible.

Here's the main executable:

my $server = DJabberd->new(
           daemonize => $daemonize,
           s2s       => 1,
           auth_hooks => [
                DJabberd::Auth::AllowedUsers->new(policy => "deny",
         allowed => [qw(brad crucially bradfitz bob test)]),
                DJabberd::Auth::StaticPassword->new(password => "password"),
               #DJabberd::Auth::LiveJournal->new(server => "livejournal.com"),
             ],
            roster_hooks => [ DJabberd::Roster::LiveJournal->new(
                       server => "livejournal.com")
             ],
     );
$server->run;

Also, all the hook chains are processed async, so you have as much time in your handlers as you want, and you can call the callbacks with your response whenever, without stalling the event loop. Or you can be lazy and synchronous for small sites.

Before I started working on it, Artur and I looked into ejabberd, jabberd2, and some other things. They're just not extensible enough. We started to add pluggable roster management to them, but it was getting painful.

One day Artur comes in and says, "Dude, why don't we write our own?" I started to reply that it'd be hard, but I stopped myself and was like, "oh, right... just an event loop that feeds incoming data to a SAX parser..."

Turns out CPAN is full of bad XML code, bad Jabber code, and really bad SSL code. So it wasn't quite as easy as it should've been, but it wasn't that bad. To be fair, a lot of CPAN is good, but crap always outnumbers quality.

Don't go looking at the code yet. It's horrid at the moment, while we rearrange/tinker/etc. But I'll be posting more about it as it mature.
LinkReply

Comments:
[User Picture]From: mart
2006-03-03 08:07 am (UTC)

For ages now I've had on my to-do list “make XML stuff on CPAN not suck”, but unfortunately other projects that are more fun keep beating it. What I really want to do is make all of the XML modules operate on a common DOM so that you can chuck documents/nodes from one to another freely. Currently each library seems to implement its own DOM-like datastructures that aren't interchangable.

My canonical example is that you can parse a document with LibXML and get back a DOM, then give the DOM to the XPath library to extract a bunch of Atom entry elements and then give those element nodes to the Atom parser library and have it parse them. The Atom library would then return an Entry object which is a subclass of a DOM Element so you can still do XPath/DOM on it to extract funny extension elements that the Atom library doesn't know about.

If only there were more hours in a day…

(Reply) (Thread)
From: dan_erat
2006-03-03 08:08 am (UTC)
Don't go looking at the code yet. It's horrid at the moment

So is it up on CPAN yet?

(Reply) (Thread)
[User Picture]From: brad
2006-03-03 04:11 pm (UTC)
Nope.

I don't put stuff on CPAN until I'm really happy with it. I don't use it like my ~/test/ directory like so many others.
(Reply) (Parent) (Thread)
From: dan_erat
2006-03-03 09:41 pm (UTC)
Sarcasm on the Internet: Just say no!

(I probably should've quoted your second-to-last paragraph too.)
(Reply) (Parent) (Thread)
[User Picture]From: brad
2006-03-04 12:06 am (UTC)
I actually recognized it as sarcasm but lately I've been having this knee-jerk reaction where I reply to all sarcasm as if it's real.
(Reply) (Parent) (Thread)
[User Picture]From: daveman692
2006-03-06 12:17 am (UTC)
You have?

Sorry, couldn't pass that one up. :P
(Reply) (Parent) (Thread)
[User Picture]From: jwz
2006-03-03 09:20 am (UTC)
Nobody's ever been able to answer this question with an answer that I was able to retain: "I have an AIM account and so does everyone I know. Why should I give a shit about Jabber?"
(Reply) (Thread)
(Deleted comment)
[User Picture]From: fanf
2006-03-03 04:42 pm (UTC)
Google did that last year.
(Reply) (Parent) (Thread)
From: (Anonymous)
2006-03-03 02:31 pm (UTC)
Two good reasons:
* You want to deploy a cheap instant messaging solution for your LUG, company, organisation, family, and so forth.
* You want to get in touch with people that do not have AIM.
(Reply) (Parent) (Thread)
[User Picture]From: brad
2006-03-03 04:03 pm (UTC)
Reasons:

1. Protocols go open. Jabber servers talk to each other, like SMTP. I'm sure you remember the days before SMTP, where BBS mail systems were closed, and you had an account on each. Or networks before IP.

2. Bots. AOL charges $1M/year (min) to run a bot on their network. You can do so without paying, of course, but once it gets popular, AOL shuts you down.

3. Integration. Want a company- or LiveJournal- integrated chat server? Either for security purposes, or for, say roster integration purposes?

But that's all just wanking until a big provider starts running one and shipping clients:

-- Apple includes iChat, with Jabber support
-- Google ships GTalk client, which is just Jabber. And the voice stuff is open as well.
-- Google runs its GTalk Jabber network, which federates with others.

So it's happening.

Also, Google's recent $1B deal with AOL included something about opening a gateway between AOL and GTalk... whether that includes all Jabber is another question, but I don't think would be far off. So at some point AIM users would be able to send a message to "post@services.livejournal.com" or whatever (from AIM!) and have it post to LiveJournal. Or open a VoIP session from GTalk client to same and leave an audio recording on LiveJournal.

etc, etc.

So it's all about open protocols and freedom to tinker.
(Reply) (Parent) (Thread)
[User Picture]From: midendian
2006-03-03 05:17 pm (UTC)
Heh, you can tinker on AIM, it just takes a lot more work.
(Reply) (Parent) (Thread)
[User Picture]From: pne
2006-03-03 01:34 pm (UTC)

POE?

Does that use POE inside for the "event loop" bit?
(Reply) (Thread)
[User Picture]From: crucially
2006-03-03 04:00 pm (UTC)

Re: POE?

Nope, it uses Danga::Socket.

Though I am fairly sure someone could easily write a Danga::Socket::POE subclass or a Loop::Danga::Socket if the interest was there.

(Reply) (Parent) (Thread)
[User Picture]From: brad
2006-03-03 04:04 pm (UTC)

Re: POE?

Yeah, me too.
(Reply) (Parent) (Thread)
From: (Anonymous)
2006-03-03 02:45 pm (UTC)
I'm feeling incredibly lucky these days... first xmppd, then this. People are finally giving Jabber the clean, low-barrier-to-entry, low-dependencies implementations it deserves.

See http://dekstop.de/weblog/2006/03/jabber_server_space_starts_boiling/ for a longer comment.

Looking forward to your progress,
Martin Dittus/dekstop.de
(Reply) (Thread)
From: evan
2006-03-03 03:24 pm (UTC)
How hard has it been to implement? I've also seen the "it's just incoming data to a SAX parser" but then I look at the spec and the incoming XML data looks hairy.
(Reply) (Thread)
[User Picture]From: crucially
2006-03-03 04:00 pm (UTC)
And even better, the clients suck at parsing it.

I am sure Brad will rant a bit about this later :)
(Reply) (Parent) (Thread)
[User Picture]From: brad
2006-03-03 04:07 pm (UTC)
At least it's well-formed. If not, you disconnect the client with a stream error.

Great thing is often you have to send clients just the right XML, or they barf. If you send semantically identical XML but not how other clients produce ... boom. Makes me question if they're actually using XML parsers or being lazy and using sscanf.

Also, most server code out there ignores XML namespaces.... so sad.

But once I did a bunch of XML helper stuff, it's been easy.
(Reply) (Parent) (Thread)
[User Picture]From: mart
2006-03-04 12:40 am (UTC)

It upsets me that people manage to get XML so wrong. However, it doesn't surprise me in the least.

(Reply) (Parent) (Thread)
From: (Anonymous)
2006-03-05 01:03 am (UTC)
Out of curiosity, did you look at Wildfire aka Jive Messenger at all?

Sure it's java, but it's really fully featured with pretty good plugin support.

But there's that whole having to write your plugins in java, thing. Built-in LDAP support, though, which is why we went with it for our internal jabber server.
(Reply) (Thread)
[User Picture]From: brad
2006-03-05 08:43 am (UTC)
No, I hadn't heard of it. The admin screenshots look awesome, though! I'll have to do some HTTP interface like that.

I might go read its source to see how its design/plugins work. Thanks!
(Reply) (Parent) (Thread)