1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283(*
* Copyright (c) 2005-2012 Anil Madhavapeddy <anil@recoil.org>
* Copyright (c) 2013 David Sheets <sheets@alum.mit.edu>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)openLwt.InfixmoduleDR=Dns.RRmoduleDP=Dns.PacketmoduleDQ=Dns.Querytypeip_endpoint=Ipaddr.t*inttype'aprocess=src:ip_endpoint->dst:ip_endpoint->'a->Dns.Query.answeroptionLwt.tmoduletypePROCESSOR=sigincludeDns.Protocol.SERVERvalprocess:contextprocessendtype'aprocessor=(modulePROCESSORwithtypecontext='a)letcomposeprocessbackup~src~dstpacket=process~src~dstpacket>>=funresult->matchresultwith|Somea->letopenDQin(matcha.rcodewith|DP.NoError->Lwt.returnresult|_->backup~src~dstpacket)|None->backup~src~dstpacketletprocess_query?allocbuflensrcdstprocessor=letmoduleProcessor=(valprocessor:PROCESSOR)inmatchProcessor.parse(Cstruct.subbuf0len)with|None->Lwt.return_none|Somectxt->Processor.process~src~dstctxt>|=function|None->None|Someanswer->letquery=Processor.query_of_contextctxtinletresponse=Dns.Query.response_of_answerqueryanswerinProcessor.marshal?allocctxtresponseletprocessor_of_processprocess:Dns.Packet.tprocessor=letmoduleP=structincludeDns.Protocol.Serverletprocess=processendin(moduleP)letprocess_of_zonebufszonebufs=letdb=List.fold_left(fundb->Dns.Zone.load~db[])(Dns.Loader.new_db())zonebufsinletdnstrie=db.Dns.Loader.trieinletget_answerqnameqtype_id=Dns.Query.answer~dnssec:trueqnameqtypednstrieinfun~src:_~dst:_d->letopenDPin(* TODO: FIXME so that 0 question queries don't crash the server *)letq=List.hdd.questionsinletr=Dns.Protocol.contain_exc"answer"(fun()->get_answerq.q_nameq.q_typed.id)inLwt.returnrletprocess_of_zonebufzonebuf=process_of_zonebufs[zonebuf]