File Coverage

blib/lib/Megagram/ResolveSRV.pm
Criterion Covered Total %
statement 3 43 6.9
branch 0 8 0.0
condition 0 6 0.0
subroutine 1 3 33.3
pod 0 2 0.0
total 4 62 6.4


line stmt bran cond sub pod time code
1             package Megagram::ResolveSRV;
2              
3             our $VERSION = '0.01';
4              
5             =head1 NAME
6              
7             Megagram::ResolveSRV
8              
9             =head1 SYNOPSIS
10              
11             Tells you the hosts and order to use for services using SRV records (like XMPP, etc).
12              
13             =head1 ABSTRACT
14              
15             use Megagram::ResolveSRV;
16              
17             my $rsrv = Megagram::ResolveSRV->new;
18             my @hosts = $rsrv->resolve('_xmpp-server._tcp.google.com');
19              
20             use Data::Dumper;
21             print Dumper(\@hosts);
22              
23             =head1 BUGS
24              
25             Not really a bug, but the weighting logic is a little crummy.
26             Feel free to send a patch for it. It works well enough for me for the moment.
27              
28             =head1 AUTHOR
29              
30             Dusty Wilson
31             Megagram Managed Technical Services
32             http://www.megagram.com/
33              
34             =head1 LICENSE
35              
36             This module is free software, you can redistribute it and/or modify
37             it under the same terms as Perl itself.
38              
39             =cut
40              
41 1     1   52712 use Net::DNS;
  1         593607  
  1         836  
42              
43             sub new
44             {
45 0     0 0   my $class = shift;
46 0           my %opts = @_;
47 0           my $self = {};
48 0   0       $self->{dnsobj} = $opts{dnsobj} || Net::DNS::Resolver->new;
49 0           return bless($self, $class);
50             }
51              
52             sub resolve
53             {
54 0     0 0   my $self = shift;
55 0           my $domain = shift;
56 0   0       my $dnsobj = shift || $self->{dnsobj};
57              
58 0           my $query = $dnsobj->search($domain, 'SRV');
59 0 0         return undef unless $query;
60              
61 0           my $srv = {};
62 0           foreach my $rr ($query->answer)
63             {
64 0 0         next unless $rr->type eq "SRV";
65 0 0         if ($rr->target eq '.')
66             {
67 0           $srv = {};
68 0           last;
69             }
70 0           $srv->{count}->{substr('000'.$rr->priority, -3, 3)} ++;
71 0           $srv->{weight}->{substr('000'.$rr->priority, -3, 3)} += $rr->weight;
72 0           push(@{$srv->{priority}->{substr('000'.$rr->priority, -3, 3)}}, {priority => $rr->priority, weight => $rr->weight, port => $rr->port, target => $rr->target});
  0            
73             }
74              
75 0           foreach my $priority (sort(keys(%{$srv->{priority}})))
  0            
76             {
77 0           my $weight_total = $srv->{weight}->{$priority};
78 0           my $priority_count = $srv->{count}->{$priority};
79 0           foreach my $record (@{$srv->{priority}->{$priority}})
  0            
80             {
81 0 0         if ($weight_total)
82             {
83 0           $record->{weight} = 100 / $weight_total * $record->{weight};
84             }
85             else
86             { # don't want div-by-0 error
87 0           $record->{weight} = 100 / $priority_count;
88             }
89             }
90 0           foreach my $record (@{$srv->{priority}->{$priority}})
  0            
91             {
92 0           my $order = substr('00000'.int(rand() * $record->{weight} * 100), -5, 5); # flawed logic, but it works for now.
93 0           $srv->{order}->{$priority}->{$order} = $record;
94             }
95             }
96              
97 0           my @hosts;
98 0           foreach my $priority (sort(keys(%{$srv->{order}})))
  0            
99             {
100 0           foreach my $order (sort(keys(%{$srv->{order}->{$priority}})))
  0            
101             {
102 0           push(@hosts, $srv->{order}->{$priority}->{$order});
103             }
104             }
105              
106 0           return @hosts;
107             }
108              
109             1;