pike.git
/
lib
/
modules
/
Protocols.pmod
/
DNS.pmod
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/lib/modules/Protocols.pmod/DNS.pmod:599:
sscanf(s[next[0]..next[0]+3],"%2c%2c",m->qd[i]->type, m->qd[i]->cl); next[0]+=4; } m->an=decode_entries(s,m->ancount,next); m->ns=decode_entries(s,m->nscount,next); m->ar=decode_entries(s,m->arcount,next); return m; } };
-
//!
Implements
a Domain Name Service (DNS) server.
+
//!
Base
class for implementing
a Domain Name Service (DNS) server.
+
//!
+
//! This class is typically used by inheriting it,
+
//! and overloading @[reply_query()] and @[handle_response()].
class server { //! inherit protocol; //inherit Stdio.UDP : udp; array(Stdio.UDP) ports = ({}); protected void send_reply(mapping r, mapping q, mapping m, Stdio.UDP udp)
pike.git/lib/modules/Protocols.pmod/DNS.pmod:638:
//! @param udp_data //! Raw UDP data. //! //! @param cb //! Callback you can call with the result instead of returning it. //! In that case, return @expr{0@} (zero). //! //! //! Overload this function to implement the proper lookup. //!
+
//! @note
+
//! To indicate the default failure @[cb] must be called with an
+
//! argument of @expr{0@} (zero), and @expr{0@} (zero) be returned.
+
//!
//! @returns
-
//! Returns @expr{0@} (zero)
on
failure
, or a result mapping
on
success
:
+
//! Returns @expr{0@} (zero)
when
the @[cb] callback will be used
,
+
//!
or a result mapping
if
not
:
//! @mapping //! @member int "rcode" //! @member array(mapping(string:string|int))|void "an" //! @array //! @elem mapping(string:string|int) entry //! @mapping //! @member string|array(string) "name" //! @member int "type" //! @member int "cl" //! @endmapping
pike.git/lib/modules/Protocols.pmod/DNS.pmod:666:
function(mapping:void) cb) { // Override this function. // // Return mapping may contain: // aa, ra, {ad, cd,} rcode, an, ns, ar return 0; }
+
//! Handle a query.
+
//!
+
//! This function calls @[reply_query()],
+
//! and dispatches the result to @[send_reply()].
protected void handle_query(mapping q, mapping m, Stdio.UDP udp) { int(0..1) result_available = 0; void _cb(mapping r) { if(result_available) error("DNS: you can either use the callback OR return the reply, not both.\n"); result_available = 1; send_reply(r, q, m, udp); }; mapping r = reply_query(q, m, _cb); if(r && result_available) error("DNS: you can either use the callback OR return the reply, not both.\n"); if(r) { result_available = 1; send_reply(r, q, m, udp); } }
-
+
//! Handle a query response (stub).
+
//!
+
//! Overload this function to handle responses to possible recursive queries.
protected void handle_response(mapping r, mapping m, Stdio.UDP udp) { // This is a stub intended to simplify servers which allow recursion }
-
+
//! Low-level DNS-data receiver.
+
//!
+
//! This function receives the raw DNS-data from the @[Stdio.UDP] socket
+
//! @[udp], decodes it, and dispatches the decoded DNS request to
+
//! @[handle_query()] and @[handle_response()].
protected private void rec_data(mapping m, Stdio.UDP udp) { mixed err; mapping q; if (err = catch { q=decode_res(m->data); }) { werror("DNS: Failed to read UDP packet.\n%s\n", describe_backtrace(err)); if(m && m->data && sizeof(m->data)>=2) send_reply((["rcode":1]), mkmapping(({"id"}), array_sscanf(m->data, "%2c")), m, udp); } else if(q->qr) handle_response(q, m, udp); else handle_query(q, m, udp); }
-
void create(int|string|void arg1, string|int ... args)
+
//! @decl
void create(
)
+
//! @decl void create(
int
port)
+
//! @decl void create(string ip)
+
//! @decl void create(string ip, int port)
+
//! @decl void create(string ip, int port, string
|
int ... more)
+
//!
+
//! Open one or more new DNS server ports.
+
//!
+
//! @param ip
+
//! The IP to bind to. Defaults to @expr{0@} (ie ANY).
+
//!
+
//! @param port
+
//! The port number to bind to. Defaults to @expr{53@}.
+
//!
+
//! @param more
+
//! Optional further DNS server ports to open.
+
//! Must be a set of @[ip], @[port] argument pairs.
+
protected void create(int|
string|void arg1, string|int ... args)
{ if(!arg1 && !sizeof(args)) arg1 = 53; if(!sizeof(args)) { if(stringp(arg1)) args = ({ arg1, 53 }); else args = ({ 0, arg1 }); }
pike.git/lib/modules/Protocols.pmod/DNS.pmod:741:
if(!udp->bind(args[i+1])) error("DNS: failed to bind port %d.\n", args[i+1]); } udp->set_read_callback(rec_data, udp); // port objects are stored for destruction when the server object is destroyed. ports += ({udp}); } }
-
static
void destory()
+
protected
void destory()
{ if(sizeof(ports)) { foreach(ports;; Stdio.UDP port) destruct(port); } } }
pike.git/lib/modules/Protocols.pmod/DNS.pmod:997:
nameservers = ({ server }); if(arrayp(domain)) domains = domain; else if(stringp(domain)) domains = ({ domain }); } }
-
//!
perform
a syncronous query
+
//!
Perform
a syncronous
DNS
query
.
//! //! @param s
-
//!
result
of @[Protocols.DNS.protocol.mkquery]
+
//!
Result
of @[Protocols.DNS.protocol.mkquery]
//! @returns //! mapping containing query result or 0 on failure/timeout //! //! @example
-
//! //
perform
a hostname lookup, results stored in r->an
-
//! object d=Protocols.DNS.client();
-
//! mapping r=d->do_sync_query(d->mkquery("pike.ida.liu.se", C_IN, T_A));
+
//!
@code
+
//
!
// Perform
a hostname lookup, results stored in r->an
+
//!
object d=Protocols.DNS.client();
+
//!
mapping r=d->do_sync_query(d->mkquery("pike.ida.liu.se", C_IN, T_A));
+
//! @endcode
mapping do_sync_query(string s) { int i; object udp = Stdio.UDP(); // Attempt to randomize the source port. for (i = 0; i < RETRIES; i++) { if (!catch { udp->bind(1024 + random(65536-1024)); }) continue; } if (i >= RETRIES) udp->bind(0); #if 0