DJabberd

 view release on metacpan or  search on metacpan

doc/rfc3920-notes.txt  view on Meta::CPAN


Copyright Notice

   Copyright (C) The Internet Society (2004).

Abstract

   This memo defines the core features of the Extensible Messaging and
   Presence Protocol (XMPP), a protocol for streaming Extensible Markup
   Language (XML) elements in order to exchange structured information
   in close to real time between any two network endpoints.  While XMPP
   provides a generalized, extensible framework for exchanging XML data,
   it is used mainly for the purpose of building instant messaging and
   presence applications that meet the requirements of RFC 2779.







doc/rfc3920-notes.txt  view on Meta::CPAN


Saint-Andre, Ed.            Standards Track                     [Page 4]

RFC 3920                       XMPP Core                    October 2004


3.  Addressing Scheme

3.1.  Overview

   An entity is anything that can be considered a network endpoint
   (i.e., an ID on the network) and that can communicate using XMPP.
   All such entities are uniquely addressable in a form that is
   consistent with RFC 2396 [URI].  For historical reasons, the address
   of an XMPP entity is called a Jabber Identifier or JID.  A valid JID
   contains a set of ordered elements formed of a domain identifier,
   node identifier, and resource identifier.

   The syntax for a JID is defined below using the Augmented Backus-Naur
   Form as defined in [ABNF].  (The IPv4address and IPv6address rules
   are defined in Appendix B of [IPv6]; the allowable character

doc/rfc3920.txt  view on Meta::CPAN


Copyright Notice

   Copyright (C) The Internet Society (2004).

Abstract

   This memo defines the core features of the Extensible Messaging and
   Presence Protocol (XMPP), a protocol for streaming Extensible Markup
   Language (XML) elements in order to exchange structured information
   in close to real time between any two network endpoints.  While XMPP
   provides a generalized, extensible framework for exchanging XML data,
   it is used mainly for the purpose of building instant messaging and
   presence applications that meet the requirements of RFC 2779.







doc/rfc3920.txt  view on Meta::CPAN


Saint-Andre, Ed.            Standards Track                     [Page 4]

RFC 3920                       XMPP Core                    October 2004


3.  Addressing Scheme

3.1.  Overview

   An entity is anything that can be considered a network endpoint
   (i.e., an ID on the network) and that can communicate using XMPP.
   All such entities are uniquely addressable in a form that is
   consistent with RFC 2396 [URI].  For historical reasons, the address
   of an XMPP entity is called a Jabber Identifier or JID.  A valid JID
   contains a set of ordered elements formed of a domain identifier,
   node identifier, and resource identifier.

   The syntax for a JID is defined below using the Augmented Backus-Naur
   Form as defined in [ABNF].  (The IPv4address and IPv6address rules
   are defined in Appendix B of [IPv6]; the allowable character

lib/DJabberd/Connection/ComponentOut.pm  view on Meta::CPAN

use fields (
    'state',           # Connection state ('disconnected', 'connecting', 'connected')
    'authenticated',   # Whether we have completed the authentication handshake (boolean)
    'secret',          # The secret used in the handshake with the server (a string)
    'connect_handlers',  # array of coderefs to call when this connection is established
);

sub new {
    my ($class, %opts) = @_;
    
    my $endpoint = delete($opts{endpoint}) or $logger->logdie("No endpoint specified");
    my $vhost = delete($opts{vhost}) or $logger->logdie("No vhost specified");
    my $secret = delete($opts{secret}) || ""; # FIXME: The secret can't currently be the number 0 :)
    $logger->logdie("Invalid options ".join(',',keys %opts)) if %opts;
    
    $logger->warning("No shared secret specified for component connection in $vhost") unless $secret;
    
    my $server = $vhost->server;

    $logger->debug("Making a $class connecting to ".$endpoint->addr.":".$endpoint->port);
    
    my $sock;
    socket $sock, PF_INET, SOCK_STREAM, IPPROTO_TCP;
    unless ($sock && defined fileno($sock)) {
        $logger->logdie("Failed to allocate socket");
        return;
    }
    IO::Handle::blocking($sock, 0) or $logger->logdie("Failed to make socket non-blocking");
    connect $sock, Socket::sockaddr_in($endpoint->port, Socket::inet_aton($endpoint->addr));
    
    my $self = $class->SUPER::new($sock, $server);
    $self->watch_write(1);

    $self->set_vhost($vhost);
    $self->{secret} = $secret;
    $self->{authenticated} = 0;
    $self->{state} = 'connecting';
    
    #$self->{cmpnt_handler} = $handler;

lib/DJabberd/Connection/ServerOut.pm  view on Meta::CPAN

            );

use IO::Handle;
use Socket qw(PF_INET IPPROTO_TCP SOCK_STREAM);
use Carp qw(croak);

sub new {
    my ($class, %opts) = @_;

    my $ip    = delete $opts{ip};
    my $endpt = delete $opts{endpoint};
    my $queue = delete $opts{queue} or croak "no queue";
    die "unknown options" if %opts;

    croak "No 'ip' or 'endpoint'\n" unless $ip || $endpt;
    $endpt ||= DJabberd::IPEndpoint->new($ip, 5269);

    my $sock;
    socket $sock, PF_INET, SOCK_STREAM, IPPROTO_TCP;
    unless ($sock && defined fileno($sock)) {
        $queue->on_connection_failed("Cannot alloc socket");
        return;
    }
    IO::Handle::blocking($sock, 0);
    $ip = $endpt->addr;

lib/DJabberd/Delivery/ComponentConnection.pm  view on Meta::CPAN

        $self->_start_listener($self);
    }
}

sub _start_connection {
    my ($self) = @_;
    
    my $vhost = $self->vhost;
    
    my $connection = DJabberd::Connection::ComponentOut->new(
        endpoint => DJabberd::IPEndPoint->new($self->{remoteaddr}, $self->{remoteport}),
        vhost => $vhost,
        secret => $self->{secret},
    );
    $connection->watch_read(1);
    $connection->add_connect_handler(sub {
        $logger->debug("Connection established and channel open.");
        $self->{connection} = $connection;
    });
    $connection->add_disconnect_handler(sub {
        # FIXME: Maybe this delay should get exponentially longer each retry?

lib/DJabberd/Queue.pm  view on Meta::CPAN

use base 'Exporter';

our @EXPORT_OK = qw(NO_CONN RESOLVING CONNECTING CONNECTED);

use DJabberd::Log;

our $logger = DJabberd::Log->get_logger;

use fields (
            'vhost',
            'endpoints',
            'to_deliver',
            'last_connect_fail',
            'state',
            'connection',
            );

use constant NO_CONN    => \ "no connection";
use constant RESOLVING  => \ "resolving";
use constant CONNECTING => \ "connecting";
use constant CONNECTED  => \ "connected";

sub new {
    my $self = shift;
    my %opts = @_;

    $self = fields::new($self) unless ref $self;

    $self->{vhost}      = delete $opts{vhost}  or die "vhost required";
    Carp::croak("Not a vhost: $self->{vhost}") unless $self->vhost->isa("DJabberd::VHost");

    if (my $endpoints = delete $opts{endpoints}) {
        Carp::croak("endpoints must be an arrayref") unless (ref $endpoints eq 'ARRAY');
          $self->{endpoints} = $endpoints;
      } else {
          $self->{endpoints} = [];
      }

    die "too many opts" if %opts;

    $self->{to_deliver} = [];  # DJabberd::QueueItem?
    $self->{last_connect_fail} = 0;  # unixtime of last connection failure

    $self->{state} = NO_CONN;   # see states above

    return $self;
}

sub endpoints {
    my $self = shift;
    my $endpoints = $self->{endpoints};

    if (@_) {
        @$endpoints = @_;
    }
    return @$endpoints;
}

# called by Connection::ServerOut constructor
sub set_connection {
    my ($self, $conn) = @_;
    $logger->debug("Set connection for queue to '$self->{domain}' to connection '$conn->{id}'");
    $self->{connection} = $conn;
}

sub vhost {

lib/DJabberd/Queue.pm  view on Meta::CPAN

    while (my $qi = shift @{ $self->{to_deliver} }) {
        $qi->callback->error("connection failure");
    }
}

sub start_connecting {
    my $self = shift;
    $logger->debug("Starting connection");
    die unless $self->{state} == NO_CONN;

    my $endpoints = $self->{endpoints};

    unless (@$endpoints) {
        $self->failed_to_connect;
        return;
    }

    $self->{state} = CONNECTING;

    my $endpt = $endpoints->[0];
    my $conn = $self->new_connection(endpoint => $endpt, queue => $self);
    $self->set_connection($conn);
    $conn->start_connecting;

}

sub new_connection {
    die "Sorry, this method needs to be overridden in your subclass of " . ref( $_[0] ) . ".";
}

package DJabberd::QueueItem;

lib/DJabberd/Queue/ClusterOut.pm  view on Meta::CPAN

use DJabberd::Queue qw();
use DJabberd::Connection::ClusterOut;

use DJabberd::Log;

our $logger = DJabberd::Log->get_logger;

sub new {
    my ($class, %opts) = @_;
    my $self = bless {}, $class;
    $self->{endpt}    = delete $opts{endpoint} or die "endpoint required";
    $self->{vhost}    = delete $opts{vhost}  or die "vhost required";
    $logger->debug("Creating new server out queue for vhost '" . $self->{vhost}->name . "' to domain '$self->{domain}'.");

    return $self;
}


1;

lib/DJabberd/Queue/ServerOut.pm  view on Meta::CPAN

    # TODO: moratorium/exponential backoff on attempting to deliver to
    # something that's recently failed to connect.  instead, immediately
    # call ->failed_to_connect without even trying.

    $self->{state} = RESOLVING;

    # async DNS lookup
    DJabberd::DNS->srv(service  => "_xmpp-server._tcp",
                       domain   => $self->{domain},
                       callback => sub {
                           $self->endpoints(@_);
                           $logger->debug("Resolver callback for '$self->{domain}': [@_]");
                           $self->{state} = NO_CONN;
                           $self->SUPER::start_connecting;
                       });
}

sub new_connection {
    my $self = shift;
    my %opts = @_;



( run in 0.467 second using v1.01-cache-2.11-cpan-cc502c75498 )