ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Net-XMPP2/lib/Net/XMPP2/Connection.pm
Revision: 1.28
Committed: Sat Jul 7 12:39:45 2007 UTC (19 years, 3 months ago) by elmex
Branch: MAIN
Changes since 1.27: +82 -88 lines
Log Message:
fixed some bugs, redesigned disco mechanism, probably added some bugs,
added samples/disco_test example.

File Contents

# Content
1 package Net::XMPP2::Connection;
2 use strict;
3 use AnyEvent;
4 use IO::Socket::INET;
5 use Net::XMPP2::Parser;
6 use Net::XMPP2::Writer;
7 use Net::XMPP2::Util qw/split_jid/;
8 use Net::XMPP2::Event;
9 use Net::XMPP2::SimpleConnection;
10 use Net::XMPP2::Namespaces qw/xmpp_ns/;
11 use Net::XMPP2::Extendable;
12 use Net::XMPP2::Error;
13 use Net::DNS;
14
15 our @ISA = qw/Net::XMPP2::SimpleConnection Net::XMPP2::Event Net::XMPP2::Extendable/;
16
17 =head1 NAME
18
19 Net::XMPP2::Connection - XML stream that implements the XMPP RFC 3920.
20
21 =head1 SYNOPSIS
22
23 use Net::XMPP2::Connection;
24
25 my $con =
26 Net::XMPP2::Connection->new (
27 username => "abc",
28 domain => "jabber.org",
29 resource => "Net::XMPP2"
30 );
31
32 $con->connect or die "Couldn't connect to jabber.org: $!";
33 $con->init;
34 $con->reg_cb (stream_ready => sub { print "XMPP stream ready!\n" });
35
36 =head1 DESCRIPTION
37
38 This module represents a XMPP stream as described in RFC 3920. You can issue the basic
39 XMPP XML stanzas with methods like C<send_iq>, C<send_message> and C<send_presence>.
40
41 And receive events with the C<reg_cb> event framework from the connection.
42
43 If you need instant messaging stuff please take a look at C<Net::XMPP2::IM::Connection>.
44
45 =head1 METHODS
46
47 =over 4
48
49 =item B<new (%args)>
50
51 Following arguments can be passed in C<%args>:
52
53 =over 4
54
55 =item language => $tag
56
57 This should be the language of the human readable contents that
58 will be transmitted over the stream. The default will be 'en'.
59
60 Please look in RFC 3066 how C<$tag> should look like.
61
62 =item jid => $jid
63
64 This can be used to set the settings C<username>, C<domain>
65 (and optionally C<resource>) from a C<$jid>.
66
67 =item resource => $resource
68
69 If this argument is given C<$resource> will be passed as desired
70 resource on resource binding.
71
72 Note: You have to take care that the stringprep profile for
73 resources can be applied at: C<$resource>. Otherwise the server
74 might signal an error. See L<Net::XMPP2::Util> for utility functions
75 to check this.
76
77 =item domain => $domain
78
79 This is the destination host we are going to connect to.
80 As the connection won't be automatically connected use C<connect>
81 to initiate the connect.
82
83 Note: A SRV RR lookup will be performed to discover the real hostname
84 and port to connect to. See also C<connect>.
85
86 =item override_host => $host
87 =item override_port => $port
88
89 This will be used as override to connect to.
90
91 =item port => $port
92
93 This is optional, the default port is 5222.
94
95 Note: A SRV RR lookup will be performed to discover the real hostname
96 and port to connect to. See also C<connect>.
97
98 =item username => $username
99
100 This is your C<$username> (the userpart in the JID);
101
102 Note: You have to take care that the stringprep profile for
103 nodes can be applied at: C<$username>. Otherwise the server
104 might signal an error. See L<Net::XMPP2::Util> for utility functions
105 to check this.
106
107 =item password => $password
108
109 This is the password for the C<username> above.
110
111 =item disable_ssl => $bool
112
113 If C<$bool> is true no SSL will be used.
114
115 =back
116
117 =cut
118
119 sub new {
120 my $this = shift;
121 my $class = ref($this) || $this;
122 my $self = $class->SUPER::new (language => 'en', @_);
123
124 $self->{parser} = new Net::XMPP2::Parser;
125 $self->{writer} = Net::XMPP2::Writer->new (
126 write_cb => sub { $self->write_data ($_[0]) }
127 );
128
129 $self->{parser}->set_stanza_cb (sub {
130 $self->handle_stanza (@_);
131 });
132 $self->{parser}->set_error_cb (sub {
133 my $pe = Net::XMPP2::Error::Parser (exception => $_[0], data => $_[1]);
134 $self->event (xml_parser_error => $pe);
135 $self->disconnect ("xml error: $_[0], $_[1]");
136 });
137
138 $self->{iq_id} = 1;
139 $self->{default_iq_timeout} = 60;
140
141 $self->{disconnect_cb} = sub {
142 my ($host, $port, $message) = @_;
143 delete $self->{authenticated};
144 delete $self->{ssl_enabled};
145 $self->event (disconnect => $host, $port, $message);
146 };
147
148 if ($self->{jid}) {
149 my ($user, $host, $res) = split_jid ($self->{jid});
150 $self->{username} = $user;
151 $self->{domain} = $host;
152 $self->{resource} = $res if defined $res;
153 }
154
155 for (qw/username password domain/) {
156 die "No '$_' argument given to new, but '$_' is required\n"
157 unless $self->{$_};
158 }
159
160 my $proxy_cb = sub {
161 my ($self, $er) = @_;
162 $self->event (error => $er);
163 1
164 };
165
166 $self->reg_cb (
167 xml_parser_error => $proxy_cb,
168 sasl_error => $proxy_cb,
169 stream_error => $proxy_cb,
170 bind_error => $proxy_cb,
171 tls_error => sub {
172 my ($self) = @_;
173 $self->event (error =>
174 Net::XMPP2::Error->new (text => 'tls_error: tls negotiation failed')
175 );
176 1
177 },
178 );
179
180 return $self;
181 }
182
183 =item B<connect ($no_srv_rr)>
184
185 Try to connect to the domain and port passed in C<new>.
186
187 A SRV RR lookup will be performed on the domain to discover
188 the host and port to use. If you don't want this set C<$no_srv_rr>
189 to a true value. C<$no_srv_rr> is false by default.
190
191 As the SRV RR lookup might return multiple host and you fail to
192 connect to one you might just call this function again to try a
193 different host.
194
195 If C<connect> was successful and we connected a true value is returned.
196 If the connect was unsuccessful undef is returned and C<$!> will be set
197 to the error that occured while connecting.
198
199 If you want to know whether further connection attempts might be more
200 successful (as SRV RR lookup may return multiple hosts) call C<may_try_connect>
201 (see also C<may_try_connect>).
202
203 Note that an internal list will be kept of tried hosts. Use
204 C<reset_connect_tries> to reset the internal list of tried hosts.
205
206 =cut
207
208 sub connect {
209 my ($self, $no_srv_rr) = @_;
210
211 my ($host, $port) = ($self->{domain}, $self->{port} || 5222);
212 if ($self->{override_host}) {
213 ($host, $port) = ($self->{override_host}, $self->{override_port} || 5222);
214
215 } else {
216 unless ($no_srv_rr) {
217 my $res = Net::DNS::Resolver->new;
218 my $p = $res->query ('_xmpp-client._tcp.'.$host, 'SRV');
219 if ($p) {
220 my @srvs = grep { $_->type eq 'SRV' } $p->answer;
221 if (@srvs) {
222 @srvs = sort { $a->priority <=> $b->priority } @srvs;
223 @srvs = sort { $b->weight <=> $a->weight } @srvs; # TODO
224 $port = $srvs[0]->port;
225 $host = $srvs[0]->target;
226 }
227 }
228 }
229 }
230
231 if ($self->SUPER::connect ($host, $port)) {
232 $self->event (connect => $host, $port);
233 return 1;
234 } else {
235 return undef;
236 }
237 }
238
239 =item B<may_try_connect>
240
241 Returns the number of left alternatives of hosts to connect to for the
242 domain passed to C<new>.
243
244 An internal list of tried hosts will be managed by C<connect> and those
245 hosts will be ignored by a SRV RR lookup (which will be done if you
246 call this function).
247
248 Use C<reset_connect_tries> to reset the internal list of tried hosts.
249
250 =cut
251
252 sub may_try_connect {
253 # TODO
254 }
255
256 =item B<reset_connect_tries>
257
258 This function resets the internal list of tried hosts for C<connect>.
259 See also C<connect>.
260
261 =cut
262
263 sub reset_connect_tries {
264 # TODO
265 }
266
267 sub handle_data {
268 my ($self, $buf) = @_;
269 $self->event (debug_recv => $$buf);
270 $self->{parser}->feed (substr $$buf, 0, (length $$buf), '');
271 }
272
273 sub debug_wrote_data {
274 my ($self, $data) = @_;
275 $self->event (debug_send => $data);
276 }
277
278 sub write_data {
279 my ($self, $data) = @_;
280 $self->SUPER::write_data ($data);
281 }
282
283 sub handle_stanza {
284 my ($self, $p, $node) = @_;
285
286 if (not defined $node) { # got stream end
287 $self->disconnect ("end of 'XML' stream encountered");
288 return;
289 }
290
291 if ($node->eq (stream => 'features')) {
292 $self->event (stream_features => $node);
293 $self->{features} = $node;
294 $self->handle_stream_features ($node);
295
296 } elsif ($node->eq (tls => 'proceed')) {
297 $self->enable_ssl;
298 $self->{parser}->init;
299 $self->{writer}->init;
300 $self->{writer}->send_init_stream ($self->{language}, $self->{domain});
301
302 } elsif ($node->eq (tls => 'failure')) {
303 $self->event ('tls_error');
304 $self->disconnect ('TLS failure on TLS negotiation.');
305
306 } elsif ($node->eq (sasl => 'challenge')) {
307 $self->handle_sasl_challenge ($node);
308
309 } elsif ($node->eq (sasl => 'success')) {
310 $self->handle_sasl_success ($node);
311
312 } elsif ($node->eq (sasl => 'failure')) {
313 my $error = Net::XMPP2::Error::SASL->new (node => $node);
314 $self->event (sasl_error => $error);
315 $self->disconnect ('SASL authentication failure: ' . $error->string);
316
317 } elsif ($node->eq (client => 'iq')) {
318 $self->handle_iq ($node);
319
320 } elsif ($node->eq (client => 'message')) {
321 $self->event (message_xml => $node);
322
323 } elsif ($node->eq (client => 'presence')) {
324 $self->event (presence_xml => $node);
325
326 } elsif ($node->eq (stream => 'error')) {
327 $self->handle_error ($node);
328
329 } else {
330 warn "Didn't understood stanza: '" . $node->name . "'";
331 }
332 }
333
334 =item B<init ()>
335
336 Initiate the XML stream.
337
338 =cut
339
340 sub init {
341 my ($self) = @_;
342 $self->{writer}->send_init_stream ($self->{language}, $self->{domain});
343 }
344
345 =item B<is_connected ()>
346
347 Returns true if the connection is still connected and stanzas can be
348 sent.
349
350 =cut
351
352 sub is_connected {
353 my ($self) = @_;
354 $self->{authenticated}
355 }
356
357 =item B<set_default_iq_timeout ($seconds)>
358
359 This sets the default timeout for IQ requests. If the timeout runs out
360 the request will be aborted and the callback called with a L<Net::XMPP2::Error::IQ> object
361 where the C<condition> method returns a special value (see also C<condition> method of L<Net::XMPP2::Error::IQ>).
362
363 The default timeout for IQ is 60 seconds.
364
365 =cut
366
367 sub set_default_iq_timeout {
368 my ($self, $sec) = @_;
369 $self->{default_iq_timeout} = $sec;
370 }
371
372 =item B<send_iq ($type, $create_cb, $result_cb, %attrs)>
373
374 This method sends an IQ XMPP request.
375
376 Please take a look at the documentation for C<send_iq> in Net::XMPP2::Writer
377 about the meaning of C<$type>, C<$create_cb> and C<%attrs> (with the exception
378 of the 'timeout' key of C<%attrs>, see below).
379
380 C<$result_cb> will be called when a result was received or the timeout reached.
381 The first argument to C<$result_cb> will be a Net::XMPP2::Node instance
382 containing the IQ result stanza contents.
383
384 If the IQ resulted in a stanza error the second argument to C<$result_cb> will
385 be C<undef> (if the error type was not 'continue') and the third argument will
386 be a L<Net::XMPP2::Error::IQ> object.
387
388 The timeout can be set by C<set_default_iq_timeout> or passed seperatly
389 in the C<%attrs> array as the value for the key C<timeout> (timeout in seconds btw.).
390
391 This method returns the newly generated id for this iq request.
392
393 =cut
394
395 sub send_iq {
396 my ($self, $type, $create_cb, $result_cb, %attrs) = @_;
397 my $id = $self->{iq_id}++;
398 $self->{iqs}->{$id} = $result_cb;
399
400 my $timeout = delete $attrs{timeout} || $self->{default_iq_timeout};
401 if ($timeout) {
402 $self->{iq_timers}->{$id} =
403 AnyEvent->timer (after => $timeout, cb => sub {
404 delete $self->{iq_timers}->{$id};
405 my $cb = delete $self->{iqs}->{$id};
406 $cb->(undef, Net::XMPP2::Error::IQ->new)
407 });
408 }
409
410 $self->{writer}->send_iq ($id, $type, $create_cb, %attrs);
411 $id
412 }
413
414 =item B<reply_iq_result ($req_iq_node, $create_cb, %attrs)>
415
416 This method will generate a result reply to the iq request C<Net::XMPP2::Node>
417 in C<$req_iq_node>.
418
419 Please take a look at the documentation for C<send_iq> in Net::XMPP2::Writer
420 about the meaning C<$create_cb> and C<%attrs>.
421
422 Use C<$create_cb> to create the XML for the result.
423
424 The type for this iq reply is 'result'.
425
426 =cut
427
428 sub reply_iq_result {
429 my ($self, $iqnode, $create_cb, %attrs) = @_;
430 $self->{writer}->send_iq ($iqnode->attr ('id'), 'result', $create_cb, %attrs);
431 }
432
433 =item B<reply_iq_error ($req_iq_node, $error_type, $error, %attrs)>
434
435 This method will generate an error reply to the iq request C<Net::XMPP2::Node>
436 in C<$req_iq_node>.
437
438 C<$error_type> is one of 'cancel', 'continue', 'modify', 'auth' and 'wait'.
439 C<$error> is one of the defined error conditions described in
440 C<write_error_tag> method of L<Net::XMPP2::Writer>.
441
442 Please take a look at the documentation for C<send_iq> in Net::XMPP2::Writer
443 about the meaning of C<%attrs>.
444
445 The type for this iq reply is 'error'.
446
447 =cut
448
449 sub reply_iq_error {
450 my ($self, $iqnode, $errtype, $error, %attrs) = @_;
451
452 $self->{writer}->send_iq (
453 $iqnode->attr ('id'), 'error',
454 sub { $self->{writer}->write_error_tag ($iqnode, $errtype, $error) },
455 %attrs
456 );
457 }
458
459 sub handle_iq {
460 my ($self, $node) = @_;
461
462 my $type = $node->attr ('type');
463
464 my $id = $node->attr ('id');
465 delete $self->{iq_timers}->{$id} if defined $id;
466
467 if ($type eq 'result') {
468 if (my $cb = delete $self->{iqs}->{$id}) {
469 eval {
470 $cb->($node);
471 };
472 if ($@) { $self->event (iq_result_cb_exception => $@) }
473 }
474
475 } elsif ($type eq 'error') {
476 if (my $cb = delete $self->{iqs}->{$id}) {
477
478 my $error = Net::XMPP2::Error::IQ->new (node => $node);
479 $cb->(($error->type eq 'continue' ? $node : undef), $error);
480 }
481
482 } else {
483 my $handled = 0;
484 $self->event ("iq_${type}_request_xml" => $node, \$handled);
485
486 my @from;
487 push @from, (to => $node->attr ('from')) if $node->attr ('from');
488
489 unless ($handled) {
490 $self->reply_iq_error ($node, undef, 'service-unavailable', @from);
491 }
492 }
493 }
494
495 sub send_sasl_auth {
496 my ($self, @mechs) = @_;
497 $self->{writer}->send_sasl_auth (
498 (join ' ', map { $_->text } @mechs),
499 $self->{username}, $self->{domain}, $self->{password}
500 );
501 }
502
503 sub handle_stream_features {
504 my ($self, $node) = @_;
505 my @bind = $node->find_all ([qw/bind bind/]);
506 my @tls = $node->find_all ([qw/tls starttls/]);
507
508 # and yet another weird thingie: in XEP-0077 it's said that
509 # the register feature MAY be advertised by the server. That means:
510 # it MAY not be advertised even if it is available... so we don't
511 # care about it...
512 # my @reg = $node->find_all ([qw/register register/]);
513
514 if (not ($self->{disable_ssl}) && not ($self->{ssl_enabled}) && @tls) {
515 $self->{writer}->send_starttls;
516
517 } elsif (not $self->{authenticated}) {
518 my $continue = 1;
519 $self->event (stream_pre_authentication => \$continue);
520 if ($continue) {
521 $self->authenticate;
522 }
523
524 } elsif (@bind) {
525 $self->do_rebind ($self->{resource});
526 }
527 }
528
529 =item B<authenticate>
530
531 This method should be called after the C<stream_pre_authentication> event
532 was emitted to continue authentication of the stream.
533
534 Usually this method only has to be called when you want to register before
535 you authenticate. See also the documentation of the C<stream_pre_authentication>
536 event below.
537
538 =cut
539
540 sub authenticate {
541 my ($self) = @_;
542 my $node = $self->{features};
543 my @mechs = $node->find_all ([qw/sasl mechanisms/], [qw/sasl mechanism/]);
544 my @iqa = $node->find_all ([qw/iqauth auth/]);
545
546 if (@mechs) {
547 $self->send_sasl_auth (@mechs)
548 } elsif (@iqa) {
549 $self->do_iq_auth;
550 }
551 }
552
553 sub handle_sasl_challenge {
554 my ($self, $node) = @_;
555 $self->{writer}->send_sasl_response ($node->text);
556 }
557
558 sub handle_sasl_success {
559 my ($self, $node) = @_;
560 $self->{authenticated} = 1;
561 $self->{parser}->init;
562 $self->{writer}->init;
563 $self->{writer}->send_init_stream ($self->{language}, $self->{domain});
564 }
565
566 sub handle_error {
567 my ($self, $node) = @_;
568 my $error = Net::XMPP2::Error::Stream->new (node => $node);
569
570 $self->event (stream_error => $error);
571 $self->{writer}->send_end_of_stream;
572 }
573
574 sub do_iq_auth {
575 my ($self) = @_;
576 # TODO
577 }
578
579 =item B<send_presence ($type, $create_cb, %attrs)>
580
581 This method sends a presence stanza, for the meanings
582 of C<$type>, C<$create_cb> and C<%attrs> please take a look
583 at the documentation for C<send_presence> method of L<Net::XMPP2::Writer>.
584
585 This methods does attach an id attribute to the message stanza and
586 will return the id that was used (so you can react on possible replies).
587
588 =cut
589
590 sub send_presence {
591 my ($self, $type, $create_cb, %attrs) = @_;
592 my $id = $self->{iq_id}++;
593 $self->{writer}->send_presence ($id, $type, $create_cb, %attrs);
594 $id
595 }
596
597 =item B<send_message ($to, $type, $create_cb, %attrs)>
598
599 This method sends a presence stanza, for the meanings
600 of C<$to>, C<$type>, C<$create_cb> and C<%attrs> please take a look
601 at the documentation for C<send_message> method of L<Net::XMPP2::Writer>.
602
603 This methods does attach an id attribute to the message stanza and
604 will return the id that was used (so you can react on possible replies).
605
606 =cut
607
608 sub send_message {
609 my ($self, $to, $type, $create_cb, %attrs) = @_;
610 my $id = $self->{iq_id}++;
611 $self->{writer}->send_message ($id, $to, $type, $create_cb, %attrs);
612 $id
613 }
614
615 =item B<do_rebind ($resource)>
616
617 In case you got a C<bind_error> event and want to retry
618 binding you can call this function to set a new C<$resource>
619 and retry binding.
620
621 If it fails again you can call this again. Becareful not to
622 end up in a loop!
623
624 If binding was successful the C<stream_ready> event will be generated.
625
626 =cut
627
628 sub do_rebind {
629 my ($self, $resource) = @_;
630 $self->{resource} = $resource;
631 $self->send_iq (
632 set =>
633 sub {
634 my ($w) = @_;
635 if ($self->{resource}) {
636 $w->startTag ([xmpp_ns ('bind'), 'bind']);
637 $w->startTag ([xmpp_ns ('bind'), 'resource']);
638 $w->characters ($self->{resource});
639 $w->endTag;
640 $w->endTag;
641 } else {
642 $w->emptyTag ([xmpp_ns ('bind'), 'bind'])
643 }
644 },
645 sub {
646 my ($ret_iq, $error) = @_;
647
648 if ($error) {
649 my ($res) = $error->xml_node ()->find_all ([qw/bind bind/], [qw/bind resource/]);
650 # TODO: make bind error into a seperate error class?
651 $self->event (bind_error => $error, ($res ? $res : $self->{resource}));
652
653 } else {
654 my @jid = $ret_iq->find_all ([qw/bind bind/], [qw/bind jid/]);
655 my $jid = $jid[0]->text;
656 unless ($jid) { die "Got empty JID tag from server!\n" }
657 $self->{jid} = $jid;
658
659 $self->event (stream_ready => $jid);
660 }
661 }
662 );
663 }
664
665 =item B<jid>
666
667 After the stream has been bound to a resource the JID can be retrieved via this
668 method.
669
670 =cut
671
672 sub jid { $_[0]->{jid} }
673
674 =item B<features>
675
676 Returns the last received <features> tag in form of an L<Net::XMPP2::Node> object.
677
678 =cut
679
680 sub features { $_[0]->{features} }
681
682 =back
683
684 =head1 EVENTS
685
686 These events can be registered on with C<reg_cb>:
687
688 =over 4
689
690 =item stream_features => $node
691
692 This event is sent when a stream feature (<features>) tag is received. C<$node> is the
693 L<Net::XMPP2::Node> object that represents the <features> tag.
694
695 =item stream_pre_authentication => $rcontinue
696
697 This event is emitted after TLS/SSL was initiated (if enabled) and before any
698 authentication happened. C<$rcontinue> is a reference to a scalar that per default
699 holds a true value. If that scalar is true the authentication will continue
700 after handling this event. If you set C<$$rcontinue> to a false value
701 the authentication will stop and you have to call the C<authenticate>
702 method later.
703
704 This event is usually used when you want to do in-band registration,
705 see also L<Net::XMPP2::Ext::Registration>.
706
707 =item stream_ready => $jid
708
709 This event is sent if the XML stream has been established (and
710 resources have been bound) and is ready for transmitting regular stanzas.
711
712 C<$jid> is the bound jabber id.
713
714 =item error => $error
715
716 This event is generated whenever some error occured.
717 C<$error> is an instance of L<Net::XMPP2::Error>.
718 Trivial error reporting may look like this:
719
720 $con->reg_cb (error => sub { warn "xmpp error: " . $_[1]->string . "\n"; 1 });
721
722 Basically this event is a collect event for all other error events.
723
724 =item stream_error => $error
725
726 This event is sent if a XML stream error occured. C<$error>
727 is a L<Net::XMPP2::Error::Stream> object.
728
729 =item xml_parser_error => $error
730
731 This event is generated whenever the parser trips over XML that it can't
732 read. C<$error> is a L<Net::XMPP2::Error::Parser> object.
733
734 =item tls_error
735
736 This event is emitted when a TLS error occured on TLS negotiation.
737 After this the connection will be disconnected.
738
739 =item sasl_error => $error
740
741 This event is emitted on SASL authentication error.
742
743 =item bind_error => $error, $resource
744
745 This event is generated when the stream was unable to bind to
746 any or the in C<new> specified resource. C<$error> is a L<Net::XMPP2::Error::IQ>
747 object. C<$resource> is the errornous resource string or undef if none
748 was received.
749
750 The C<condition> of the C<$error> might be one of: 'bad-request',
751 'not-allowed' or 'conflict'.
752
753 Node: this is untested, I couldn't get the server to send a bind error
754 to test this.
755
756 =item connect => $host, $port
757
758 This event is generated when a successful connect was performed to
759 the domain passed to C<new>.
760
761 Note: C<$host> and C<$port> might be different from the domain you passed to
762 C<new> if C<connect> performed a SRV RR lookup.
763
764 If this connection is lost a C<disconnect> will be generated with the same
765 C<$host> and C<$port>.
766
767 =item disconnect => $host, $port, $message
768
769 This event is generated when the connection was lost or another error
770 occured while writing or reading from it.
771
772 C<$message> is a humand readable error message for the failure.
773 C<$host> and C<$port> were the host and port we were connected to.
774
775 Note: C<$host> and C<$port> might be different from the domain you passed to
776 C<new> if C<connect> performed a SRV RR lookup.
777
778 =item presence_xml => $node
779
780 This event is sent when a presence stanza is received. C<$node> is the
781 L<Net::XMPP2::Node> object that represents the <presence> tag.
782
783 =item message_xml => $node
784
785 This event is sent when a message stanza is received. C<$node> is the
786 L<Net::XMPP2::Node> object that represents the <message> tag.
787
788 =item iq_set_request_xml => $node, $handled_ref
789
790 =item iq_get_request_xml => $node, $handled_ref
791
792 These events are sent when an iq request stanza of type 'get' or 'set' is received.
793 C<$type> will either be 'get' or 'set' and C<$node> will be the L<Net::XMPP2::Node>
794 object of the iq tag.
795
796 If C<$$handled_ref> is true an event handler should not handle this message anymore.
797
798 If one of the event handlers handled this message the scalar pointed at by
799 the reference in C<$handled_ref> should be set to 1 true value. If C<$$handled_ref>
800 is still false after all event handlers were executed an error iq will be generated.
801
802 =item iq_result_cb_exception => $exception
803
804 If the C<$result_cb> of a C<send_iq> operation somehow threw a exception
805 or failed this event will be generated.
806
807 =back
808
809 =head1 AUTHOR
810
811 Robin Redeker, C<< <elmex at ta-sa.org> >>, JID: C<< <elmex at jabber.org> >>
812
813 =head1 COPYRIGHT & LICENSE
814
815 Copyright 2007 Robin Redeker, all rights reserved.
816
817 This program is free software; you can redistribute it and/or modify it
818 under the same terms as Perl itself.
819
820 =cut
821
822 1; # End of Net::XMPP2