File Coverage

blib/lib/Net/Server/Proto/UDP.pm
Criterion Covered Total %
statement 51 60 85.0
branch 22 36 61.1
condition 3 9 33.3
subroutine 9 9 100.0
pod 2 6 33.3
total 87 120 72.5


line stmt bran cond sub pod time code
1             # -*- perl -*-
2             #
3             # Net::Server::Proto::UDP - Net::Server Protocol module
4             #
5             # Copyright (C) 2001-2022
6             #
7             # Paul Seamons
8             #
9             # Modified 2005 by Timothy Watt
10             # Added ability to deal with broadcast packets.
11             #
12             # This package may be distributed under the terms of either the
13             # GNU General Public License
14             # or the
15             # Perl Artistic License
16             #
17             # All rights reserved.
18             #
19             ################################################################
20              
21             package Net::Server::Proto::UDP;
22              
23 2     2   15 use strict;
  2         4  
  2         142  
24 2     2   15 use base qw(Net::Server::Proto::TCP);
  2         5  
  2         328  
25 2     2   14 use Net::Server::Proto qw(AF_INET AF_INET6 AF_UNSPEC);
  2         4  
  2         15  
26              
27             my @udp_args = qw(
28             udp_recv_len
29             udp_recv_flags
30             udp_broadcast
31             );
32              
33 16     16 0 192 sub NS_proto { 'UDP' }
34 14 100   14 0 34 sub NS_recv_len { my $sock = shift; ${*$sock}{'NS_recv_len'} = shift if @_; return ${*$sock}{'NS_recv_len'} }
  14         36  
  11         33  
  14         20  
  14         37  
35 14 100   14 0 27 sub NS_recv_flags { my $sock = shift; ${*$sock}{'NS_recv_flags'} = shift if @_; return ${*$sock}{'NS_recv_flags'} }
  14         32  
  11         32  
  14         20  
  14         44  
36 14 100   14 0 23 sub NS_broadcast { my $sock = shift; ${*$sock}{'NS_broadcast'} = shift if @_; return ${*$sock}{'NS_broadcast'} }
  14         39  
  11         58  
  14         23  
  14         42  
37              
38             sub object {
39 11     11 1 33 my ($class, $info, $server) = @_;
40              
41 11   33     52 my $udp = $server->{'server'}->{'udp_args'} ||= do {
42 11         26 my %temp = map {$_ => undef} @udp_args;
  33         102  
43 11         31 $server->configure({map {$_ => \$temp{$_}} @udp_args});
  33         128  
44 11         56 \%temp;
45             };
46              
47             my $len = defined($info->{'udp_recv_len'}) ? $info->{'udp_recv_len'}
48 11 100       41 : defined($udp->{'udp_recv_len'}) ? $udp->{'udp_recv_len'}
    50          
49             : 4096;
50 11 50       89 $len = ($len =~ /^(\d+)$/) ? $1 : 4096;
51              
52             my $flg = defined($info->{'udp_recv_flags'}) ? $info->{'udp_recv_flags'}
53 11 50       36 : defined($udp->{'udp_recv_flags'}) ? $udp->{'udp_recv_flags'}
    50          
54             : 0;
55 11 50       46 $flg = ($flg =~ /^(\d+)$/) ? $1 : 0;
56              
57 11         83 my $sock = $class->new;
58 11         1135 $sock->NS_host($info->{'host'});
59 11         44 $sock->NS_port($info->{'port'});
60 11         49 $sock->NS_ipv( $info->{'ipv'} );
61 11         85 $sock->NS_recv_len($len);
62 11         30 $sock->NS_recv_flags($flg);
63 11 50       80 $sock->NS_broadcast(exists($info->{'udp_broadcast'}) ? $info->{'udp_broadcast'} : $udp->{'upd_broadcast'});
64 11 50       44 ${*$sock}{'NS_orig_port'} = $info->{'orig_port'} if defined $info->{'orig_port'};
  0         0  
65 11         71 return $sock;
66             }
67              
68             sub connect {
69 1     1 1 1 my ($sock, $server) = @_;
70 1         2 my $host = $sock->NS_host;
71 1         16 my $port = $sock->NS_port;
72 1         8 my $ipv = $sock->NS_ipv;
73              
74 1 50       5 $sock->configure({
    50          
    50          
    50          
    50          
75             LocalPort => $port,
76             Proto => 'udp',
77             ReuseAddr => 1,
78             Reuse => 1, # XXX: Is this needed on UDP?
79             LocalAddr => ($host eq '*' ? undef : $host), # undef means on all interfaces
80             Family => ($ipv eq '6' ? AF_INET6 : $ipv eq '4' ? AF_INET : AF_UNSPEC),
81             ($sock->NS_broadcast ? (Broadcast => 1) : ()),
82             }) or $server->fatal("Cannot bind to UDP port $port on $host [$!]");
83              
84 1 50 33     79 if ($port eq 0 and $port = $sock->sockport) {
    50 33        
85 0           $server->log(2, " Bound to auto-assigned port $port");
86 0           ${*$sock}{'NS_orig_port'} = $sock->NS_port;
  0            
87 0           $sock->NS_port($port);
88             } elsif ($port =~ /\D/ and $port = $sock->sockport) {
89 0           $server->log(2, " Bound to service port ".$sock->NS_port()."($port)");
90 0           ${*$sock}{'NS_orig_port'} = $sock->NS_port;
  0            
91 0           $sock->NS_port($port);
92             }
93             }
94              
95             1;
96              
97             __END__