64 lines
2.1 KiB
Racket
64 lines
2.1 KiB
Racket
#lang racket/base
|
|
;; DNS drivers using os2.rkt and os2-udp.rkt.
|
|
|
|
(require racket/set)
|
|
(require racket/match)
|
|
(require "codec.rkt")
|
|
(require "../racket-matrix/os2.rkt")
|
|
(require "../racket-matrix/os2-udp.rkt")
|
|
|
|
(provide (struct-out bad-dns-packet)
|
|
(struct-out dns-request)
|
|
(struct-out dns-reply)
|
|
dns-read-driver
|
|
dns-write-driver
|
|
dns-spy)
|
|
|
|
(struct bad-dns-packet (detail source sink reason) #:prefab)
|
|
(struct dns-request (message source sink) #:prefab)
|
|
(struct dns-reply (message source sink) #:prefab)
|
|
|
|
(define (dns-read-driver s)
|
|
(transition 'no-state
|
|
(at-meta-level
|
|
(role (topic-subscriber (udp-packet (wild) s (wild)))
|
|
[(udp-packet source (== s) #"")
|
|
(log-info "Debug dump packet received")
|
|
(send-message `(debug-dump))]
|
|
[(udp-packet source (== s) body)
|
|
(send-message
|
|
(with-handlers ((exn:fail? (lambda (e) (bad-dns-packet body source s 'unparseable))))
|
|
(define message (packet->dns-message body))
|
|
(case (dns-message-direction message)
|
|
((request) (dns-request message source s))
|
|
((response) (dns-reply message source s)))))]))))
|
|
|
|
(define (dns-write-driver s)
|
|
(define (translate message sink)
|
|
(with-handlers ((exn:fail? (lambda (e)
|
|
(send-message (bad-dns-packet message s sink 'unencodable)))))
|
|
(at-meta-level
|
|
(send-message (udp-packet s sink (dns-message->packet message))))))
|
|
(transition 'no-state
|
|
(role (set (topic-subscriber (dns-request (wild) s (wild)))
|
|
(topic-subscriber (dns-reply (wild) s (wild))))
|
|
[(dns-request message (== s) sink) (translate message sink)]
|
|
[(dns-reply message (== s) sink) (translate message sink)])))
|
|
|
|
(define dns-spy
|
|
(transition 'none
|
|
(role (topic-subscriber (wild) #:monitor? #t)
|
|
[(dns-request message source sink)
|
|
(log-info (format "DNS: ~v asks ~v ~v~n : ~v"
|
|
source sink (dns-message-id message)
|
|
(dns-message-questions message)))
|
|
(void)]
|
|
[(dns-reply message source sink)
|
|
(log-info (format "DNS: ~v answers ~v~n : ~v"
|
|
source sink
|
|
message))
|
|
(void)]
|
|
[x
|
|
(log-info (format "DNS: ~v" x))
|
|
(void)])))
|