Priority support

Nikolas Coukouma atrus at atrus.org
Tue Jul 11 08:32:40 UTC 2006


-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

This is a fairly quick hack and my first time playing with the internals
of djabberd. Some quick tests suggest that it works as I think it
should, but I'd appreciate a sanity check.

Pertinent section of the spec:
http://www.xmpp.org/specs/rfc3921.html#rules-inbound

Cheers,
- -Nikolas
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (Darwin)

iD8DBQFEs2Ins2zR4YuWmeERA1f4AJ0fiCi1iUUtXhgSTwUHlZJvuq3ZtgCgirv3
XPC7Q80xU0Lsvu7xzfDDBPw=
=JvmA
-----END PGP SIGNATURE-----
-------------- next part --------------
Index: doc/TODO
===================================================================
--- doc/TODO	(revision 594)
+++ doc/TODO	(working copy)
@@ -50,8 +50,6 @@
        4 < <iq id='SgSeu-6' type='get'><query xmlns='jabber:iq:anything'/></iq> INFO  DJabberd.Connection.XML.ClientIn         <iq  to='user0 at jabber.bradfitz.com/Smack' type='error' id='SgSeu-6'></iq> WARN  DJabberd.IQ                              Unknown IQ packet: get-{jabber:iq:anything}query
 
 
--- presence priority
-
 -- allow a fast path when bulk sending tons of messages (like hundreds of unavailable stanzas
    on disconnect):  allow a means to, given a set of full/bare (at least bare) JIDs, filter out
    the ones to be known not available.  (for instance, local/cluster
Index: lib/DJabberd/Presence.pm
===================================================================
--- lib/DJabberd/Presence.pm	(revision 594)
+++ lib/DJabberd/Presence.pm	(working copy)
@@ -430,6 +430,16 @@
     DJabberd::Presence->set_local_presence($jid, $self->clone);
 
     $conn->set_available(1);
+    
+    my $pri = 0;
+    foreach my $elm ($self->children_elements) {
+        if ($elm->namespace eq "jabber:client" && $elm->element_name eq "priority") {
+            
+            $pri = $elm->first_child+0 if $elm->first_child && !(ref $elm->first_child);
+        }
+    }
+    $conn->set_priority($pri);
+    DJabberd::Log->get_logger()->info("Recieved priority $pri");
 
     if ($conn->is_initial_presence) {
         $conn->on_initial_presence;
Index: lib/DJabberd/Delivery/Local.pm
===================================================================
--- lib/DJabberd/Delivery/Local.pm	(revision 594)
+++ lib/DJabberd/Delivery/Local.pm	(working copy)
@@ -11,7 +11,17 @@
 
     my @dconns;
     my $find_bares = sub {
-        @dconns = grep { $_->is_available || $stanza->deliver_when_unavailable } $vhost->find_conns_of_bare($to)
+        @dconns = grep { $_->is_available || $stanza->deliver_when_unavailable } $vhost->find_conns_of_bare($to);
+        
+        if ($stanza->isa("DJabberd::Message")) {
+            my $max_pri = -1;
+            foreach my $p (@dconns) { $max_pri = $p->priority if $p->priority > $max_pri }
+            if ($max_pri < 0) {
+                @dconns = undef;
+            } else {
+                @dconns = grep { $_->priority == $max_pri } @dconns;
+            }
+        }
     };
 
     if ($to->is_bare) {
@@ -29,6 +39,8 @@
 
     $DJabberd::Stats::counter{deliver_local}++;
 
+    # FIXME: should we deliver to all resources with highest priority,
+    #   or just pick one? If picking one, then how?
     foreach my $c (@dconns) {
         $c->send_stanza($stanza);
     }
Index: lib/DJabberd/Connection/ClientIn.pm
===================================================================
--- lib/DJabberd/Connection/ClientIn.pm	(revision 594)
+++ lib/DJabberd/Connection/ClientIn.pm	(working copy)
@@ -10,6 +10,7 @@
             'is_available',          # bool: is an "available resource"
             'directed_presence',     # the jids we have sent directed presence too
             'pend_in_subscriptions', # undef or arrayref of presence type='subscribe' packets to be redelivered when we become available
+            'priority',              # int: the priority of this resource
             );
 
 sub note_pend_in_subscription {
@@ -58,6 +59,17 @@
     return $self->{is_available};
 }
 
+sub set_priority {
+    my ($self, $val) = @_;
+    $self->{priority} = $val;
+}
+
+sub priority {
+    my $self = shift;
+    return $self->{priority};
+}
+
+
 # called when a presence broadcast is received.  on first time,
 # returns tru.
 sub is_initial_presence {


More information about the Djabberd mailing list