Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file dns_block.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100openDnsletsrc=Logs.Src.create"dns_block"~doc:"DNS block"moduleLog=(valLogs.src_logsrc:Logs.LOG)letnameserver=letlh=Domain_name.of_string_exn"localhost"andbl=Domain_name.of_string_exn"blocked"infunns->Domain_name.equalnslh||Domain_name.equalnsblletipv4=letlh=Ipaddr.V4.(Set.singletonlocalhost)andany=Ipaddr.V4.(Set.singletonany)infunipv4s->Ipaddr.V4.Set.equalipv4slh||Ipaddr.V4.Set.equalipv4sanyletipv6=letlh=Ipaddr.V6.(Set.singletonlocalhost)andun=Ipaddr.V6.(Set.singletonunspecified)infunipv6s->Ipaddr.V6.Set.equalipv6slh||Ipaddr.V6.Set.equalipv6sunletlikelyreply=(* HACK! We assume blocked domains have a certain shape. *)letblocked_soaauth=Domain_name.Map.cardinalauth>0&&Domain_name.Map.for_all(fun_domainrr->matchRr_map.findRr_map.Soarrwith|None->false|Somesoa->nameserversoa.nameserver)authinmatchreply.Packet.datawith|`Answer(answ,_auth)->Domain_name.Map.for_all(fun_domainrr->Rr_map.for_all(function|Rr_map.B(Rr_map.A,(_,ips))->ipv4ips|Rr_map.B(Rr_map.Aaaa,(_,ips))->ipv6ips|_->false)rr)answ|`Rcode_error(Rcode.NXDomain,_,Some(_answ,auth))->blocked_soaauth|_->falseletreasonreply=letfind_soa_hostmasterrr=matchRr_map.findRr_map.Soarrwith|None->None|Somesoa->ifnameserversoa.Soa.nameserverthenSome(Domain_name.to_stringsoa.Soa.hostmaster)elseNoneinletfind_soa_hostmaster_in_domain_mapmap=Domain_name.Map.fold(fun_domainrracc->matchacc,find_soa_hostmasterrrwith|None,x->x|Somex,None->Somex|Somex,Somey->ifnot(String.equalxy)thenLog.info(funm->m"finding blocklist resulted in %S and %S, using the first"xy);Somex)mapNoneinletfind_soa_hostmaster_in_replyanswerauthority=matchfind_soa_hostmaster_in_domain_mapanswer,find_soa_hostmaster_in_domain_mapauthoritywith|None,x->x|Somex,None->Somex|Somex,Somey->ifnot(String.equalxy)thenLog.info(funm->m"finding blocklist resulted in %S (answer) and %S (authority), using the first"xy);Somexinletr=matchreply.Packet.datawith|`Answer(answ,auth)->find_soa_hostmaster_in_replyanswauth|`Rcode_error(Rcode.NXDomain,_,Some(answ,auth))->find_soa_hostmaster_in_replyanswauth|_->NoneinOption.map(funreason->"appears in blocklist "^reason)rletednsreply=iflikelyreplythen(* After guessing that a domain is blocked we add [`Filtered] extended error
code and emit a [`Blocked] metrics event. *)letreason=reasonreplyinmatchreply.ednswith|None->Some(Edns.create~extended_error:(`Blocked,reason)())|Some({Edns.extensions=[];extended_rcode;version;dnssec_ok;payload_size})->Some(Edns.create~extended_error:(`Blocked,reason)~extended_rcode~version~dnssec_ok~payload_size())|Someedns->Log.warn(funm->m"don't know how to extend edns to add extended error; not doing anything:@ %a"Edns.ppedns);SomeednselseNone