75
73
my @localaddresses = @{$self{"LocalAddr"}};
79
75
my @sock_tcp; # All the TCP sockets we will listen to.
80
76
my @sock_udp; # All the UDP sockets we will listen to.
78
# while we are here, print incomplete lines as they come along.
79
local $| = 1 if $self{"Verbose"};
82
81
foreach my $localaddress (@localaddresses){
83
print "Dealing with $localaddress...\n" if $self{"Verbose"};
83
$port = $self{"LocalPort"} || $DEFAULT_PORT;
89
86
$addr = $localaddress;
90
$port = $self{"LocalPort"} || $DEFAULT_PORT;
93
#--------------------------------------------------------------------------
94
# Create the IPv4/IPv6 ONLY TCP socket.
95
#--------------------------------------------------------------------------
88
$addr = $localaddress || inet_ntoa($DEFAULT_ADDR[0]);
91
# If not, it will do DNS lookups trying to resolve it as a hostname
92
# We could also just set it to undef?
94
$addr = inet_ntoa($addr) unless (ip_is_ipv4($addr) || ip_is_ipv6($addr));
96
# Pretty IP-addresses, if they are otherwise binary.
98
$addrname = inet_ntoa($addrname) unless $addrname =~ /^[\w\.:\-]+$/;
100
print "Setting up listening sockets for $addrname...\n" if $self{"Verbose"};
102
print "Creating TCP socket for $addrname - " if $self{"Verbose"};
104
#--------------------------------------------------------------------------
105
# Create the TCP socket.
106
#--------------------------------------------------------------------------
97
print "creating TCP socket for $localaddress" if $self{"Verbose"};
99
$sock_tcp = IO::Socket::INET6->new(
108
my $sock_tcp = inet_new(
100
109
LocalAddr => $addr,
101
110
LocalPort => $port,
110
cluck "couldn't create TCP socket: $!";
113
push @sock_tcp, $sock_tcp;
114
print "done.\n" if $self{"Verbose"};
118
$addr = $localaddress || inet_ntoa($DEFAULT_ADDR[0]);
119
$port = $self{"LocalPort"} || $DEFAULT_PORT;
122
#--------------------------------------------------------------------------
123
# Create the IPv4 ONLY TCP socket.
124
#--------------------------------------------------------------------------
126
print "creating TCP socket for $localaddress" if $self{"Verbose"};
129
$sock_tcp = IO::Socket::INET->new(
139
cluck "couldn't create TCP socket: $!";
142
push @sock_tcp, $sock_tcp;
143
print "done.\n" if $self{"Verbose"};
116
cluck "Couldn't create TCP socket: $!";
119
push @sock_tcp, $sock_tcp;
120
print "done.\n" if $self{"Verbose"};
151
122
#--------------------------------------------------------------------------
152
123
# Create the UDP Socket.
153
124
#--------------------------------------------------------------------------
155
print "creating UDP socket..." if $self{"Verbose"};
126
print "Creating UDP socket for $addrname - " if $self{"Verbose"};
159
$sock_udp = IO::Socket::INET6->new(
128
my $sock_udp = inet_new(
160
129
LocalAddr => $addr,
161
130
LocalPort => $port,
166
$sock_udp = IO::Socket::INET->new(
172
134
if (!$sock_udp) {
173
cluck "couldn't create UDP socket: $!";
135
cluck "Couldn't create UDP socket: $!";
178
print "done.\n" if $self{"Verbose"};
179
138
push @sock_udp, $sock_udp;
139
print "done.\n" if $self{"Verbose"};
182
142
#--------------------------------------------------------------------------
287
259
#------------------------------------------------------------------------------
260
# readfromtcp - read from a TCP client
261
#------------------------------------------------------------------------------
264
my ($self, $sock) = @_;
265
return -1 unless defined $self->{"_tcp"}{$sock};
266
my $peer = $self->{"_tcp"}{$sock}{"peer"};
267
my $charsread = $sock->sysread(
268
$self->{"_tcp"}{$sock}{"inbuffer"},
270
$self->{"_tcp"}{$sock}{"timeout"} = time()+120; # Reset idle timer
271
print "Received $charsread octets from $peer\n" if $self->{"Verbose"};
272
if ($charsread == 0) { # 0 octets means socket has closed
273
print "Connection to $peer closed or lost.\n" if $self->{"Verbose"};
274
$self->{"select"}->remove($sock);
276
delete $self->{"_tcp"}{$sock};
282
#------------------------------------------------------------------------------
288
283
# tcp_connection - Handle a TCP connection.
289
284
#------------------------------------------------------------------------------
291
286
sub tcp_connection {
292
287
my ($self, $sock) = @_;
293
my $peerhost = $sock->peerhost;
295
print "TCP connection from ", $sock->peerhost, ":", $sock->peerport, "\n"
296
if $self->{"Verbose"};
300
print "reading message length..." if $self->{"Verbose"};
301
$sock->read($buf, 2) or last;
302
print "done\n" if $self->{"Verbose"};
304
my ($msglen) = unpack("n", $buf);
305
print "expecting $msglen bytes..." if $self->{"Verbose"};
306
$sock->read($buf, $msglen);
307
print "got ", length($buf), " bytes\n" if $self->{"Verbose"};
309
my $query = Net::DNS::Packet->new(\$buf);
311
my $reply = $self->make_reply($query, $peerhost) || last;
312
my $reply_data = $reply->data;
314
print "writing response..." if $self->{"Verbose"};
315
$sock->write(pack("n", length($reply_data)) . $reply_data);
316
print "done\n" if $self->{"Verbose"};
289
if (not $self->{"_tcp"}{$sock}) {
290
# We go here if we are called with a listener socket.
291
my $client = $sock->accept;
292
if (not defined $client) {
293
print "TCP connection closed by peer before we could accept it.\n" if $self->{"Verbose"};
296
my $peerport= $client->peerport;
297
my $peerhost = $client->peerhost;
299
print "TCP connection from $peerhost:$peerport\n" if $self->{"Verbose"};
300
$client->blocking(0);
301
$self->{"_tcp"}{$client}{"peer"} = "tcp:".$peerhost.":".$peerport;
302
$self->{"_tcp"}{$client}{"state"} = STATE_ACCEPTED;
303
$self->{"_tcp"}{$client}{"socket"} = $client;
304
$self->{"_tcp"}{$client}{"timeout"} = time()+120;
305
$self->{"select"}->add($client);
306
# After we accepted we will look at the socket again
307
# to see if there is any data there. ---Olaf
310
# We go here if we are called with a client socket
311
my $peer = $self->{"_tcp"}{$sock}{"peer"};
313
if ($self->{"_tcp"}{$sock}{"state"} == STATE_ACCEPTED) {
314
if (not $self->{"_tcp"}{$sock}{"inbuffer"} =~ s/^(..)//s) {
315
return; # Still not 2 octets ready
317
my $msglen = unpack("n", $1);
318
print "Removed 2 octets from the input buffer from $peer.\n".
319
"$peer said his query contains $msglen octets.\n"
320
if $self->{"Verbose"};
321
$self->{"_tcp"}{$sock}{"state"} = STATE_GOT_LENGTH;
322
$self->{"_tcp"}{$sock}{"querylength"} = $msglen;
324
# Not elsif, because we might already have all the data
325
if ($self->{"_tcp"}{$sock}{"state"} == STATE_GOT_LENGTH) {
326
# return if not all data has been received yet.
327
return if $self->{"_tcp"}{$sock}{"querylength"} > length $self->{"_tcp"}{$sock}{"inbuffer"};
329
my $qbuf = substr($self->{"_tcp"}{$sock}{"inbuffer"}, 0, $self->{"_tcp"}{$sock}{"querylength"});
330
substr($self->{"_tcp"}{$sock}{"inbuffer"}, 0, $self->{"_tcp"}{$sock}{"querylength"}) = "";
331
my $query = Net::DNS::Packet->new(\$qbuf);
332
my $reply = $self->make_reply($query, $sock->peerhost);
333
if (not defined $reply) {
334
print "I couldn't create a reply for $peer. Closing socket.\n"
335
if $self->{"Verbose"};
336
$self->{"select"}->remove($sock);
338
delete $self->{"_tcp"}{$sock};
341
my $reply_data = $reply->data;
342
my $len = length $reply_data;
343
$self->{"_tcp"}{$sock}{"outbuffer"} = pack("n", $len) . $reply_data;
345
length $self->{"_tcp"}{$sock}{"outbuffer"},
347
if $self->{"Verbose"};
349
$self->{"_tcp"}{$sock}{"state"} = STATE_SENDING;
319
print "closing connection..." if $self->{"Verbose"};
321
print "done\n" if $self->{"Verbose"};
324
354
#------------------------------------------------------------------------------
333
my ($peerhost,$peerport);
335
363
$sock->recv($buf, &Net::DNS::PACKETSZ);
364
my ($peerhost,$peerport) = ($sock->peerhost, $sock->peerport);
337
print "UDP connection from ", $sock->peerhost, ":", $sock->peerport, "\n"
338
if $self->{"Verbose"};
340
print "UDP connection from $peerhost:$peerport\n" if $self->{"Verbose"};
366
print "UDP connection from $peerhost:$peerport\n" if $self->{"Verbose"};
342
368
my $query = Net::DNS::Packet->new(\$buf);
344
370
my $reply = $self->make_reply($query, $peerhost) || return;
345
371
my $reply_data = $reply->data;
347
print "writing response..." if $self->{"Verbose"};
373
local $| = 1 if $self->{"Verbose"};
374
print "Writing response - " if $self->{"Verbose"};
375
# die() ?!?? I think we need something better. --robert
348
376
$sock->send($reply_data) or die "send: $!";
349
377
print "done\n" if $self->{"Verbose"};
383
return keys %{$self->{"_tcp"}};
387
#------------------------------------------------------------------------------
388
# loop_once - Just check "once" on sockets already set up
389
#------------------------------------------------------------------------------
391
# This function might not actually return immediately. If an AXFR request is
392
# coming in which will generate a huge reply, we will not relinquish control
393
# until our outbuffers are empty.
396
# NB this method may be subject to change and is therefore left 'undocumented'
400
my ($self, $timeout) = @_;
401
$timeout=0 unless defined($timeout);
402
print ";loop_once called with $timeout \n" if $self->{"Verbose"} >4;
403
foreach my $sock (keys %{$self->{"_tcp"}}) {
404
$timeout = 0.1 if $self->{"_tcp"}{$sock}{"outbuffer"};
406
my @ready = $self->{"select"}->can_read($timeout);
408
foreach my $sock (@ready) {
409
my $protonum = $sock->protocol;
410
# This is a weird and nasty hack. Although not incorrect,
411
# I just don't know why ->protocol won't tell me the protocol
412
# on a connected socket. --robert
413
$protonum = getprotobyname('tcp') if not defined $protonum and $self->{"_tcp"}{$sock};
415
my $proto = getprotobynumber($protonum);
417
print "ERROR: connection with unknown protocol\n"
418
if $self->{"Verbose"};
419
} elsif (lc($proto) eq "tcp") {
421
$self->readfromtcp($sock) &&
422
$self->tcp_connection($sock);
423
} elsif (lc($proto) eq "udp") {
424
$self->udp_connection($sock);
426
print "ERROR: connection with unsupported protocol $proto\n"
427
if $self->{"Verbose"};
431
# Lets check if any of our TCP clients has pending actions.
432
# (outbuffer, timeout)
433
foreach my $s (keys %{$self->{"_tcp"}}) {
434
my $sock = $self->{"_tcp"}{$s}{"socket"};
435
if ($self->{"_tcp"}{$s}{"outbuffer"}) {
436
# If we have buffered output, then send as much as the OS will accept
437
# and wait with the rest
438
my $len = length $self->{"_tcp"}{$s}{"outbuffer"};
439
my $charssent = $sock->syswrite($self->{"_tcp"}{$s}{"outbuffer"});
440
print "Sent $charssent of $len octets to ",$self->{"_tcp"}{$s}{"peer"},".\n"
441
if $self->{"Verbose"};
442
substr($self->{"_tcp"}{$s}{"outbuffer"}, 0, $charssent) = "";
443
if (length $self->{"_tcp"}{$s}{"outbuffer"} == 0) {
444
delete $self->{"_tcp"}{$s}{"outbuffer"};
445
$self->{"_tcp"}{$s}{"state"} = STATE_ACCEPTED;
446
if (length $self->{"_tcp"}{$s}{"inbuffer"} >= 2) {
447
# See if the client has send us enough data to process the
449
# We do this here, because we only want to process (and buffer!!)
450
# a single query at a time, per client. If we allowed a STATE_SENDING
451
# client to have new requests processed. We could be easilier
452
# victims of DoS (client sending lots of queries and never reading
454
# Note that this does not disable serialisation on part of the
455
# client. The split second it should take for us to lookip the
456
# next query, is likely faster than the time it takes to
457
# send the response... well, unless it's a lot of tiny queries,
458
# in which case we will be generating an entire TCP packet per
460
$self->tcp_connection($self->{"_tcp"}{"socket"});
463
$self->{"_tcp"}{$s}{"timeout"} = time()+120;
465
# Get rid of idle clients.
466
my $timeout = $self->{"_tcp"}{$s}{"timeout"};
467
if ($timeout - $now < 0) {
468
print $self->{"_tcp"}{$s}{"peer"}," has been idle for too long and will be disconnected.\n"
469
if $self->{"Verbose"};
470
$self->{"select"}->remove($sock);
472
delete $self->{"_tcp"}{$s};
352
478
#------------------------------------------------------------------------------
353
479
# main_loop - Main nameserver loop.
354
480
#------------------------------------------------------------------------------
362
print "waiting for connections..." if $self->{"Verbose"};
363
my @ready = $self->{"select"}->can_read;
365
foreach my $sock (@ready) {
366
my $proto = getprotobynumber($sock->protocol);
369
print "ERROR: connection with unknown protocol\n"
370
if $self->{"Verbose"};
371
} elsif (lc($proto) eq "tcp") {
372
my $client = $sock->accept;
373
$self->tcp_connection($client);
374
} elsif (lc($proto) eq "udp") {
375
$self->udp_connection($sock);
377
print "ERROR: connection with unsupported protocol $proto\n"
378
if $self->{"Verbose"};
486
print "Waiting for connections...\n" if $self->{"Verbose"};
487
# You really need an argument otherwise you'll be burning
489
$self->loop_once(10);
477
Start accepting queries.
586
Start accepting queries. Calling main_loop never returns.
592
# The functionality might change. Left "undocumented" for now.
596
$ns->loop_once( [TIMEOUT_IN_SECONDS] );
598
Start accepting queries, but returns. If called without a parameter,
599
the call will not return until a request has been received (and
600
replied to). If called with a number, that number specifies how many
601
seconds (even fractional) to maximum wait before returning. If called
602
with 0 it will return immediately unless there's something to do.
604
Handling a request and replying obviously depends on the speed of
605
ReplyHandler. Assuming ReplyHandler is super fast, loop_once should spend
606
just a fraction of a second, if called with a timeout value of 0 seconds.
607
One exception is when an AXFR has requested a huge amount of data that
608
the OS is not ready to receive in full. In that case, it will keep
609
running through a loop (while servicing new requests) until the reply
612
In case loop_once accepted a TCP connection it will immediatly check
613
if there is data to be read from the socket. If not it will return and
614
you will have to call loop_once() again to check if there is any data
615
waiting on the socket to be processed. In most cases you will have to
616
count on calling "loop_once" twice.
618
A code fragment like:
620
while( $ns->get_open_tcp() ){
624
Would wait for 10 seconds for the initial connection and would then
625
process all TCP sockets until none is left.
629
In scalar context returns the number of TCP connections for which state
630
is maintained. In array context it returns IO::Socket objects, these could
631
be useful for troubleshooting but be careful using them.
511
668
ReplyHandler => \&reply_handler,
513
670
) || die "couldn't create nameserver object\n";
519
Net::DNS::Nameserver objects can handle only one query at a time.
521
676
Limitations in perl 5.8.6 makes it impossible to guarantee that
522
677
replies to UDP queries from Net::DNS::Nameserver are sent from the
523
678
IP-address they were received on. This is a problem for machines with
524
679
multiple IP-addresses and causes violation of RFC2181 section 4.
680
Thus a UDP socket created listening to INADDR_ANY (all available
681
IP-addresses) will reply not necessarily with the source address being
682
the one to which the request was sent, but rather with the address that
683
the operating system choses. This is also often called "the closest
684
address". This should really only be a problem on a server which has
685
more than one IP-address (besides localhost - any experience with IPv6
686
complications here, would be nice). If this is a problem for you, a
687
work-around would be to not listen to INADDR_ANY but to specify each
688
address that you want this module to listen on. A seperate set of
689
sockets will then be created for each IP-address.