2 USING: kernel sequences combinators accessors locals random
3 combinators.short-circuit
5 dns dns.util dns.cache.rr dns.cache.nx
10 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12 :: query->rrs ( QUERY -- rrs/f )
13 [let | RRS [ QUERY cache-get ] |
17 [let | NAME [ QUERY name>> ]
19 CLASS [ QUERY class>> ] |
21 [let | RRS/CNAME [ T{ query f NAME CNAME CLASS } cache-get ] |
26 [let | RR/CNAME [ RRS/CNAME first ] |
28 [let | REAL-NAME [ RR/CNAME rdata>> ] |
31 T{ query f REAL-NAME TYPE CLASS } query->rrs
35 [ RRS/CNAME RRS append ]
46 :: answer-from-cache ( MSG -- msg/f )
47 [let | QUERY [ MSG message-query ] |
49 [let | NX [ QUERY name>> non-existent-name? ]
50 RRS [ QUERY query->rrs ] |
53 { [ NX ] [ MSG NAME-ERROR >>rcode ] }
54 { [ RRS ] [ MSG RRS >>answer-section ] }
61 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
63 : message-soa ( message -- rr/soa )
64 authority-section>> [ type>> SOA = ] filter first ;
66 ! :: cache-message ( MSG -- msg )
67 ! MSG rcode>> NAME-ERROR =
69 ! [let | NAME [ MSG message-query name>> ]
70 ! TTL [ MSG message-soa ttl>> ] |
71 ! NAME TTL cache-non-existent-name
75 ! MSG answer-section>> [ cache-add ] each
76 ! MSG authority-section>> [ cache-add ] each
77 ! MSG additional-section>> [ cache-add ] each
80 :: cache-message ( MSG -- msg )
81 MSG rcode>> NAME-ERROR =
85 [ type>> SOA = ] filter
86 dup empty? [ drop f ] [ first ] if ] |
89 [let | NAME [ MSG message-query name>> ]
90 TTL [ MSG message-soa ttl>> ] |
91 NAME TTL cache-non-existent-name
98 MSG answer-section>> [ cache-add ] each
99 MSG authority-section>> [ cache-add ] each
100 MSG additional-section>> [ cache-add ] each
103 ! : answer-from-server ( msg servers -- msg ) random ask-server cache-message ;
105 : answer-from-server ( msg servers -- msg ) ask-servers cache-message ;
107 :: find-answer ( MSG SERVERS -- msg )
108 { [ MSG answer-from-cache ] [ MSG SERVERS answer-from-server ] } 0|| ;
110 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
112 :: start-server ( ADDR-SPEC SERVERS -- )
114 [let | SOCKET [ ADDR-SPEC <datagram> ] |
117 SOCKET receive-packet
118 [ parse-message SERVERS find-answer message->ba ]