ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Net-XMPP2/lib/Net/XMPP2/Connection.pm
Revision: 1.27
Committed: Fri Jul 6 22:22:21 2007 UTC (19 years, 3 months ago) by elmex
Branch: MAIN
Changes since 1.26: +9 -1 lines
Log Message:
implemented dataforms - phew! that was a bullet of work

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