ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Net-XMPP2/lib/Net/XMPP2/Connection.pm
Revision: 1.29
Committed: Sun Jul 8 08:37:21 2007 UTC (19 years, 3 months ago) by elmex
Branch: MAIN
Changes since 1.28: +12 -3 lines
Log Message:
fixed some bugs in the error handling

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