1NAME
2
3 POE::Component::Server::DNS - A non-blocking, concurrent DNS server POE
4 component
5
6VERSION
7
8 version 0.32
9
10SYNOPSIS
11
12 use strict;
13 use Net::DNS::RR;
14 use POE qw(Component::Server::DNS);
15
16 my $dns_server = POE::Component::Server::DNS->spawn( alias => 'dns_server' );
17
18 POE::Session->create(
19 package_states => [ 'main' => [ qw(_start handler log) ], ],
20 );
21
22 $poe_kernel->run();
23 exit 0;
24
25 sub _start {
26 my ($kernel,$heap) = @_[KERNEL,HEAP];
27
28 # Tell the component that we want log events to go to 'log'
29 $kernel->post( 'dns_server', 'log_event', 'log' );
30
31 # register a handler for any foobar.com suffixed domains
32 $kernel->post( 'dns_server', 'add_handler',
33 {
34 event => 'handler',
35 label => 'foobar',
36 match => 'foobar\.com$',
37 }
38 );
39 undef;
40 }
41
42 sub handler {
43 my ($qname,$qclass,$qtype,$callback) = @_[ARG0..ARG3];
44 my ($rcode, @ans, @auth, @add);
45
46 if ($qtype eq "A") {
47 my ($ttl, $rdata) = (3600, "10.1.2.3");
48 push @ans, Net::DNS::RR->new("$qname $ttl $qclass $qtype $rdata");
49 $rcode = "NOERROR";
50 } else {
51 $rcode = "NXDOMAIN";
52 }
53
54 $callback->($rcode, \@ans, \@auth, \@add, { aa => 1 });
55 undef;
56 }
57
58 sub log {
59 my ($ip_port,$net_dns_packet) = @_[ARG0..ARG1];
60 $net_dns_packet->print();
61 undef;
62 }
63
64DESCRIPTION
65
66 POE::Component::Server::DNS is a POE component that implements a DNS
67 server.
68
69 It uses POE::Component::Client::DNS to handle resolving when configured
70 as 'forward_only' and Net::DNS::Resolver::Recurse wrapped by
71 POE::Component::Generic to perform recursion.
72
73 One may add handlers to massage and manipulate responses to particular
74 queries which is vaguely modelled after Net::DNS::Nameserver.
75
76CONSTRUCTOR
77
78 spawn
79
80 Starts a POE::Component::Server::DNS component session and returns an
81 object. Takes a number of optional arguments:
82
83 "alias", an alias to address the component by;
84 "port", which udp port to listen on. Default is 53, which requires 'root' privilege on UN*X type systems;
85 "address", which local IP address to listen on. Default is INADDR_ANY;
86 "resolver_opts", a set of options to pass to the POE::Component::Client::DNS constructor;
87 "forward_only", be a forwarding only DNS server. Default is 0, be recursive.
88 "no_clients", do not spawn client code (See following notes);
89
90 "no_clients" disables the spawning of client code (PoCo::Client::DNS,
91 Net::DNS::Resolver::Recursive), and doesn't attempt to forward or
92 recurse inbound requests. Any request not handled by one of your
93 handlers will be REFUSED. Saves some resources when you intend your
94 server to be authoritative only (as opposed to a general resolver for
95 DNS client software to point at directly). Additionally, this
96 argument changes the default "Recursion Available" flag in responses
97 to off instead of on.
98
99METHODS
100
101 These are methods that may be used with the object returned by spawn().
102
103 session_id
104
105 Returns the POE::Session ID of the component's session.
106
107 resolver
108
109 Returns a reference to the POE::Component::Client::DNS object.
110
111 shutdown
112
113 Terminates the component and associated resolver.
114
115 sockport
116
117 Returns the port of the socket that the component is listening on.
118
119INPUT EVENTS
120
121 These are states that the component will accept:
122
123 add_handler
124
125 Accepts a hashref as an argument with the following keys:
126
127 "event", the event the component will post to, mandatory;
128 "label", a unique name for this handler, mandatory;
129 "match", a regex expression ( without // ) to match against the host part of queries, mandatory;
130 "session", the session where this handler event should be sent to, defaults to SENDER;
131
132 See OUTPUT EVENTS for details of what happens when a handler is
133 triggered.
134
135 del_handler
136
137 Accepts a handler label to remove.
138
139 log_event
140
141 Tells the component that a session wishes to receive or stop
142 receiving DNS log events. Specify the event you wish to receive log
143 events as the first argument. If no event is specified you stop
144 receiving log events.
145
146 shutdown
147
148 Terminates the component and associated resolver.
149
150HANDLER EVENTS
151
152 These events are triggered by a DNS query matching a handler. The
153 applicable event is fired in the requested session with the following
154 paramters:
155
156 ARG0, query name
157 ARG1, query class
158 ARG2, query type
159 ARG3, a callback coderef
160 ARG4, the IP address and port of the requestor, 'IPaddr:port'
161
162 Do your manipulating then use the callback to fire the response back to
163 the component, returning a response code and references to the answer,
164 authority, and additional sections of the response. For advanced usage
165 there is an optional argument containing an hashref with the settings
166 for the aa, ra, and ad header bits. The argument is of the form { ad =>
167 1, aa => 0, ra => 1 }.
168
169 $callback->( $rcode, \@ans, \@auth, \@add, { aa => 1 } );
170
171LOG EVENTS
172
173 These events are triggered whenever a DNS response is sent to a client.
174
175 ARG0, the IP address and port of the requestor, 'IPaddr:port';
176 ARG1, the Net::DNS::Packet object;
177
178 See Net::DNS::Packet for details.
179
180HISTORY
181
182 The component's genesis was inspired by Jan-Pieter's 'Fun with POE'
183 talk at YAPC::EU 2006, which lay much of the ground-work code such as
184 the POE::Driver and POE::Filter used internally. BinGOs wrapped it all
185 up in a component, added the tests ( borrowed shamelessly from
186 POE::Component::Client::DNS's testsuite ) and documentation.
187
188 Other suggestions as to the API were provided by Ben 'integral' Smith.
189
190 Rocco Caputo brought POE::Component::Client::DNS to the party.
191
192SEE ALSO
193
194 POE::Component::Client::DNS
195
196 POE::Component::Generic
197
198 Net::DNS
199
200 Net::DNS::Packet
201
202AUTHORS
203
204 * Chris Williams <chris@bingosnet.co.uk>
205
206 * Jan-Pieter Cornet <johnpc@xs4all.nl>
207
208 * Brandon Black <blblack@gmail.com>
209
210 * Richard Harman <richard@richardharman.com>
211
212 * Stephan Jauernick <stephan@stejau.de>
213
214COPYRIGHT AND LICENSE
215
216 This software is copyright (c) 2015 by Chris Williams, Jan-Pieter
217 Cornet, Brandon Black, Richard Harman and Stephan Jauernick.
218
219 This is free software; you can redistribute it and/or modify it under
220 the same terms as the Perl 5 programming language system itself.
221
222