ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Net-XMPP2/lib/Net/XMPP2/Connection.pm
Revision: 1.26
Committed: Fri Jul 6 15:19:52 2007 UTC (19 years, 3 months ago) by elmex
Branch: MAIN
Changes since 1.25: +1 -2 lines
Log Message:
fixed some bugs in max write length and limit searcher

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 $cb->($node);
456 }
457
458 } elsif ($type eq 'error') {
459 if (my $cb = delete $self->{iqs}->{$id}) {
460
461 my $error = Net::XMPP2::Error::IQ->new (node => $node);
462 $cb->(($error->type eq 'continue' ? $node : undef), $error);
463 }
464
465 } else {
466 my $handled = 0;
467 $self->event ("iq_${type}_request_xml" => $node, \$handled);
468
469 my @from;
470 push @from, (to => $node->attr ('from')) if $node->attr ('from');
471
472 unless ($handled) {
473 $self->reply_iq_error ($node, undef, 'service-unavailable', @from);
474 }
475 }
476 }
477
478 sub send_sasl_auth {
479 my ($self, @mechs) = @_;
480 $self->{writer}->send_sasl_auth (
481 (join ' ', map { $_->text } @mechs),
482 $self->{username}, $self->{domain}, $self->{password}
483 );
484 }
485
486 =item B<request_inband_register_form ($finish_cb)>
487
488 This method starts a in-band-registration attempt. When finished C<$finish_cb>
489 will be called with the first argument being a L<Net::XMPP2::Ext::RegisterForm>
490 object (will be undef if an error occured) and the second an optional error
491 object of type L<Net::XMPP2::Error::Register> if an error occured.
492
493 =cut
494
495 sub request_inband_register_form {
496 my ($self, $finish_cb) = @_;
497
498 $self->send_iq (
499 get =>
500 sub {
501 my ($w) = @_;
502 $w->addPrefix (xmpp_ns ('register'), '');
503 $w->emptyTag ([xmpp_ns ('register'), 'query']);
504 },
505 sub {
506 my ($node, $error) = @_;
507 my $form;
508 $form = Net::XMPP2::Ext::RegisterForm (node => $node, connection => $self)
509 unless $error;
510 $finish_cb->($form, $error);
511 }
512 );
513 }
514
515 sub do_auto_register {
516 my ($self, $mechs) = @_;
517
518 $self->request_inband_register_form (sub {
519 my ($form, $error) = @_;
520
521 if ($error) {
522 $self->event (in_band_register_error => $error);
523
524 } else {
525 if ($self->{register} ne 'manual') {
526 # of course this blows up if the form was more complicated
527 # any ideas?
528 $form->auto_submit (
529 username => $self->{username},
530 password => $self->{password},
531 cb => sub {
532 my ($form, $error) = @_;
533 if ($error) {
534 $self->event (auto_in_band_register_error => $error);
535 } else {
536 $self->event ('auto_in_band_register_ok');
537 $self->send_sasl_auth (@$mechs) if @$mechs;
538 }
539 }
540 );
541
542 } else {
543 $self->event (
544 in_band_register_form =>
545 $form,
546 sub { $self->send_sasl_auth (@$mechs) if @$mechs }
547 )
548 }
549 }
550 });
551
552 }
553
554 sub handle_stream_features {
555 my ($self, $node) = @_;
556 my @mechs = $node->find_all ([qw/sasl mechanisms/], [qw/sasl mechanism/]);
557 my @bind = $node->find_all ([qw/bind bind/]);
558 my @tls = $node->find_all ([qw/tls starttls/]);
559 my @iqa = $node->find_all ([qw/iqauth auth/]);
560
561 # and yet another weird thingie: in XEP-0077 it's said that
562 # the register feature MAY be advertised by the server. That means:
563 # it MAY not be advertised even if it is available... so we don't
564 # care about it...
565 # my @reg = $node->find_all ([qw/register register/]);
566
567 if (not ($self->{disable_ssl}) && not ($self->{ssl_enabled}) && @tls) {
568 $self->{writer}->send_starttls;
569
570 } elsif (not $self->{authenticated}) {
571 if ($self->{register}) {
572 $self->do_auto_register (\@mechs);
573 } elsif (@mechs) {
574 $self->send_sasl_auth (@mechs)
575 } elsif (@iqa) {
576 $self->do_iq_auth;
577 }
578
579 } elsif (@bind) {
580 $self->do_rebind ($self->{resource});
581 }
582 }
583
584 sub handle_sasl_challenge {
585 my ($self, $node) = @_;
586 $self->{writer}->send_sasl_response ($node->text);
587 }
588
589 sub handle_sasl_success {
590 my ($self, $node) = @_;
591 $self->{authenticated} = 1;
592 $self->{parser}->init;
593 $self->{writer}->init;
594 $self->{writer}->send_init_stream ($self->{language}, $self->{domain});
595 }
596
597 sub handle_error {
598 my ($self, $node) = @_;
599 my $error = Net::XMPP2::Error::Stream->new (node => $node);
600
601 $self->event (stream_error => $error);
602 $self->{writer}->send_end_of_stream;
603 }
604
605 sub do_iq_auth {
606 my ($self) = @_;
607 # TODO
608 }
609
610 =item B<send_presence ($type, $create_cb, %attrs)>
611
612 This method sends a presence stanza, for the meanings
613 of C<$type>, C<$create_cb> and C<%attrs> please take a look
614 at the documentation for C<send_presence> method of L<Net::XMPP2::Writer>.
615
616 This methods does attach an id attribute to the message stanza and
617 will return the id that was used (so you can react on possible replies).
618
619 =cut
620
621 sub send_presence {
622 my ($self, $type, $create_cb, %attrs) = @_;
623 my $id = $self->{iq_id}++;
624 $self->{writer}->send_presence ($id, $type, $create_cb, %attrs);
625 $id
626 }
627
628 =item B<send_message ($to, $type, $create_cb, %attrs)>
629
630 This method sends a presence stanza, for the meanings
631 of C<$to>, C<$type>, C<$create_cb> and C<%attrs> please take a look
632 at the documentation for C<send_message> method of L<Net::XMPP2::Writer>.
633
634 This methods does attach an id attribute to the message stanza and
635 will return the id that was used (so you can react on possible replies).
636
637 =cut
638
639 sub send_message {
640 my ($self, $to, $type, $create_cb, %attrs) = @_;
641 my $id = $self->{iq_id}++;
642 $self->{writer}->send_message ($id, $to, $type, $create_cb, %attrs);
643 $id
644 }
645
646 =item B<do_rebind ($resource)>
647
648 In case you got a C<bind_error> event and want to retry
649 binding you can call this function to set a new C<$resource>
650 and retry binding.
651
652 If it fails again you can call this again. Becareful not to
653 end up in a loop!
654
655 If binding was successful the C<stream_ready> event will be generated.
656
657 =cut
658
659 sub do_rebind {
660 my ($self, $resource) = @_;
661 $self->{resource} = $resource;
662 $self->send_iq (
663 set =>
664 sub {
665 my ($w) = @_;
666 if ($self->{resource}) {
667 $w->startTag ([xmpp_ns ('bind'), 'bind']);
668 $w->startTag ([xmpp_ns ('bind'), 'resource']);
669 $w->characters ($self->{resource});
670 $w->endTag;
671 $w->endTag;
672 } else {
673 $w->emptyTag ([xmpp_ns ('bind'), 'bind'])
674 }
675 },
676 sub {
677 my ($ret_iq, $error) = @_;
678
679 if ($error) {
680 my ($res) = $error->xml_node ()->find_all ([qw/bind bind/], [qw/bind resource/]);
681 $self->event (bind_error => $error, ($res ? $res : $self->{resource}));
682
683 } else {
684 my @jid = $ret_iq->find_all ([qw/bind bind/], [qw/bind jid/]);
685 my $jid = $jid[0]->text;
686 unless ($jid) { die "Got empty JID tag from server!\n" }
687 $self->{jid} = $jid;
688
689 $self->event (stream_ready => $jid);
690 }
691 }
692 );
693 }
694
695 =item B<jid>
696
697 After the stream has been bound to a resource the JID can be retrieved via this
698 method.
699
700 =cut
701
702 sub jid { $_[0]->{jid} }
703
704 =item B<features>
705
706 Returns the last received <features> tag in form of an L<Net::XMPP2::Node> object.
707
708 =cut
709
710 sub features { $_[0]->{features} }
711
712 =back
713
714 =head1 EVENTS
715
716 These events can be registered on with C<reg_cb>:
717
718 =over 4
719
720 =item stream_features => $node
721
722 This event is sent when a stream feature (<features>) tag is received. C<$node> is the
723 L<Net::XMPP2::Node> object that represents the <features> tag.
724
725 =item stream_ready => $jid
726
727 This event is sent if the XML stream has been established (and
728 resources have been bound) and is ready for transmitting regular stanzas.
729
730 C<$jid> is the bound jabber id.
731
732 =item stream_error => $error
733
734 This event is sent if a XML stream error occured. C<$error>
735 is a L<Net::XMPP2::Error::Stream> object.
736
737 =item tls_error
738
739 This event is emitted when a TLS error occured on TLS negotiation.
740 After this the connection will be disconnected.
741
742 =item sasl_error => $error
743
744 This event is emitted on SASL authentication error.
745
746 =item bind_error => $error, $resource
747
748 This event is generated when the stream was unable to bind to
749 any or the in C<new> specified resource. C<$error> is a L<Net::XMPP2::Error::IQ>
750 object. C<$resource> is the errornous resource string or undef if none
751 was received.
752
753 The C<condition> of the C<$error> might be one of: 'bad-request',
754 'not-allowed' or 'conflict'.
755
756 Node: this is untested, I couldn't get the server to send a bind error
757 to test this.
758
759 =item connect => $host, $port
760
761 This event is generated when a successful connect was performed to
762 the domain passed to C<new>.
763
764 Note: C<$host> and C<$port> might be different from the domain you passed to
765 C<new> if C<connect> performed a SRV RR lookup.
766
767 If this connection is lost a C<disconnect> will be generated with the same
768 C<$host> and C<$port>.
769
770 =item disconnect => $host, $port, $message
771
772 This event is generated when the connection was lost or another error
773 occured while writing or reading from it.
774
775 C<$message> is a humand readable error message for the failure.
776 C<$host> and C<$port> were the host and port we were connected to.
777
778 Note: C<$host> and C<$port> might be different from the domain you passed to
779 C<new> if C<connect> performed a SRV RR lookup.
780
781 =item presence_xml => $node
782
783 This event is sent when a presence stanza is received. C<$node> is the
784 L<Net::XMPP2::Node> object that represents the <presence> tag.
785
786 =item message_xml => $node
787
788 This event is sent when a message stanza is received. C<$node> is the
789 L<Net::XMPP2::Node> object that represents the <message> tag.
790
791 =item iq_set_request_xml => $node, $handled_ref
792
793 =item iq_get_request_xml => $node, $handled_ref
794
795 These events are sent when an iq request stanza of type 'get' or 'set' is received.
796 C<$type> will either be 'get' or 'set' and C<$node> will be the L<Net::XMPP2::Node>
797 object of the iq tag.
798
799 If C<$$handled_ref> is true an event handler should not handle this message anymore.
800
801 If one of the event handlers handled this message the scalar pointed at by
802 the reference in C<$handled_ref> should be set to 1 true value. If C<$$handled_ref>
803 is still false after all event handlers were executed an error iq will be generated.
804
805 =back
806
807 =head1 AUTHOR
808
809 Robin Redeker, C<< <elmex at ta-sa.org> >>, JID: C<< <elmex at jabber.org> >>
810
811 =head1 COPYRIGHT & LICENSE
812
813 Copyright 2007 Robin Redeker, all rights reserved.
814
815 This program is free software; you can redistribute it and/or modify it
816 under the same terms as Perl itself.
817
818 =cut
819
820 1; # End of Net::XMPP2