ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Net-XMPP2/lib/Net/XMPP2/Connection.pm
Revision: 1.25
Committed: Fri Jul 6 09:40:15 2007 UTC (19 years, 3 months ago) by elmex
Branch: MAIN
Changes since 1.24: +1 -1 lines
Log Message:
added simxml() function for simpler xml writing
and made writing of data segmented.

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