test_dns.py 150 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824
  1. # test-case-name: twisted.names.test.test_dns
  2. # Copyright (c) Twisted Matrix Laboratories.
  3. # See LICENSE for details.
  4. """
  5. Tests for twisted.names.dns.
  6. """
  7. from __future__ import division, absolute_import
  8. from io import BytesIO
  9. import struct
  10. from zope.interface.verify import verifyClass
  11. from twisted.python.failure import Failure
  12. from twisted.python.util import FancyEqMixin, FancyStrMixin
  13. from twisted.internet import address, task
  14. from twisted.internet.error import CannotListenError, ConnectionDone
  15. from twisted.trial import unittest
  16. from twisted.names import dns
  17. from twisted.test import proto_helpers
  18. from twisted.test.testutils import ComparisonTestsMixin
  19. RECORD_TYPES = [
  20. dns.Record_NS, dns.Record_MD, dns.Record_MF, dns.Record_CNAME,
  21. dns.Record_MB, dns.Record_MG, dns.Record_MR, dns.Record_PTR,
  22. dns.Record_DNAME, dns.Record_A, dns.Record_SOA, dns.Record_NULL,
  23. dns.Record_WKS, dns.Record_SRV, dns.Record_AFSDB, dns.Record_RP,
  24. dns.Record_HINFO, dns.Record_MINFO, dns.Record_MX, dns.Record_TXT,
  25. dns.Record_AAAA, dns.Record_A6, dns.Record_NAPTR, dns.UnknownRecord,
  26. ]
  27. class Ord2ByteTests(unittest.TestCase):
  28. """
  29. Tests for L{dns._ord2bytes}.
  30. """
  31. def test_ord2byte(self):
  32. """
  33. L{dns._ord2byte} accepts an integer and returns a byte string of length
  34. one with an ordinal value equal to the given integer.
  35. """
  36. self.assertEqual(b'\x10', dns._ord2bytes(0x10))
  37. class Str2TimeTests(unittest.TestCase):
  38. """
  39. Tests for L{dns.str2name}.
  40. """
  41. def test_nonString(self):
  42. """
  43. When passed a non-string object, L{dns.str2name} returns it unmodified.
  44. """
  45. time = object()
  46. self.assertIs(time, dns.str2time(time))
  47. def test_seconds(self):
  48. """
  49. Passed a string giving a number of seconds, L{dns.str2time} returns the
  50. number of seconds represented. For example, C{"10S"} represents C{10}
  51. seconds.
  52. """
  53. self.assertEqual(10, dns.str2time("10S"))
  54. def test_minutes(self):
  55. """
  56. Like C{test_seconds}, but for the C{"M"} suffix which multiplies the
  57. time value by C{60} (the number of seconds in a minute!).
  58. """
  59. self.assertEqual(2 * 60, dns.str2time("2M"))
  60. def test_hours(self):
  61. """
  62. Like C{test_seconds}, but for the C{"H"} suffix which multiplies the
  63. time value by C{3600}, the number of seconds in an hour.
  64. """
  65. self.assertEqual(3 * 3600, dns.str2time("3H"))
  66. def test_days(self):
  67. """
  68. Like L{test_seconds}, but for the C{"D"} suffix which multiplies the
  69. time value by C{86400}, the number of seconds in a day.
  70. """
  71. self.assertEqual(4 * 86400, dns.str2time("4D"))
  72. def test_weeks(self):
  73. """
  74. Like L{test_seconds}, but for the C{"W"} suffix which multiplies the
  75. time value by C{604800}, the number of seconds in a week.
  76. """
  77. self.assertEqual(5 * 604800, dns.str2time("5W"))
  78. def test_years(self):
  79. """
  80. Like L{test_seconds}, but for the C{"Y"} suffix which multiplies the
  81. time value by C{31536000}, the number of seconds in a year.
  82. """
  83. self.assertEqual(6 * 31536000, dns.str2time("6Y"))
  84. def test_invalidPrefix(self):
  85. """
  86. If a non-integer prefix is given, L{dns.str2time} raises L{ValueError}.
  87. """
  88. self.assertRaises(ValueError, dns.str2time, "fooS")
  89. class NameTests(unittest.TestCase):
  90. """
  91. Tests for L{Name}, the representation of a single domain name with support
  92. for encoding into and decoding from DNS message format.
  93. """
  94. def test_nonStringName(self):
  95. """
  96. When constructed with a name which is neither C{bytes} nor C{str},
  97. L{Name} raises L{TypeError}.
  98. """
  99. self.assertRaises(TypeError, dns.Name, 123)
  100. self.assertRaises(TypeError, dns.Name, object())
  101. self.assertRaises(TypeError, dns.Name, [])
  102. def test_unicodeName(self):
  103. """
  104. L{dns.Name} automatically encodes unicode domain name using C{idna}
  105. encoding.
  106. """
  107. name = dns.Name(u'\u00e9chec.example.org')
  108. self.assertIsInstance(name.name, bytes)
  109. self.assertEqual(b'xn--chec-9oa.example.org', name.name)
  110. def test_decode(self):
  111. """
  112. L{Name.decode} populates the L{Name} instance with name information read
  113. from the file-like object passed to it.
  114. """
  115. n = dns.Name()
  116. n.decode(BytesIO(b"\x07example\x03com\x00"))
  117. self.assertEqual(n.name, b"example.com")
  118. def test_encode(self):
  119. """
  120. L{Name.encode} encodes its name information and writes it to the
  121. file-like object passed to it.
  122. """
  123. name = dns.Name(b"foo.example.com")
  124. stream = BytesIO()
  125. name.encode(stream)
  126. self.assertEqual(stream.getvalue(), b"\x03foo\x07example\x03com\x00")
  127. def test_encodeWithCompression(self):
  128. """
  129. If a compression dictionary is passed to it, L{Name.encode} uses offset
  130. information from it to encode its name with references to existing
  131. labels in the stream instead of including another copy of them in the
  132. output. It also updates the compression dictionary with the location of
  133. the name it writes to the stream.
  134. """
  135. name = dns.Name(b"foo.example.com")
  136. compression = {b"example.com": 0x17}
  137. # Some bytes already encoded into the stream for this message
  138. previous = b"some prefix to change .tell()"
  139. stream = BytesIO()
  140. stream.write(previous)
  141. # The position at which the encoded form of this new name will appear in
  142. # the stream.
  143. expected = len(previous) + dns.Message.headerSize
  144. name.encode(stream, compression)
  145. self.assertEqual(
  146. b"\x03foo\xc0\x17",
  147. stream.getvalue()[len(previous):])
  148. self.assertEqual(
  149. {b"example.com": 0x17, b"foo.example.com": expected},
  150. compression)
  151. def test_unknown(self):
  152. """
  153. A resource record of unknown type and class is parsed into an
  154. L{UnknownRecord} instance with its data preserved, and an
  155. L{UnknownRecord} instance is serialized to a string equal to the one it
  156. was parsed from.
  157. """
  158. wire = (
  159. b'\x01\x00' # Message ID
  160. b'\x00' # answer bit, opCode nibble, auth bit, trunc bit, recursive
  161. # bit
  162. b'\x00' # recursion bit, empty bit, authenticData bit,
  163. # checkingDisabled bit, response code nibble
  164. b'\x00\x01' # number of queries
  165. b'\x00\x01' # number of answers
  166. b'\x00\x00' # number of authorities
  167. b'\x00\x01' # number of additionals
  168. # query
  169. b'\x03foo\x03bar\x00' # foo.bar
  170. b'\xde\xad' # type=0xdead
  171. b'\xbe\xef' # cls=0xbeef
  172. # 1st answer
  173. b'\xc0\x0c' # foo.bar - compressed
  174. b'\xde\xad' # type=0xdead
  175. b'\xbe\xef' # cls=0xbeef
  176. b'\x00\x00\x01\x01' # ttl=257
  177. b'\x00\x08somedata' # some payload data
  178. # 1st additional
  179. b'\x03baz\x03ban\x00' # baz.ban
  180. b'\x00\x01' # type=A
  181. b'\x00\x01' # cls=IN
  182. b'\x00\x00\x01\x01' # ttl=257
  183. b'\x00\x04' # len=4
  184. b'\x01\x02\x03\x04' # 1.2.3.4
  185. )
  186. msg = dns.Message()
  187. msg.fromStr(wire)
  188. self.assertEqual(msg.queries, [
  189. dns.Query(b'foo.bar', type=0xdead, cls=0xbeef),
  190. ])
  191. self.assertEqual(msg.answers, [
  192. dns.RRHeader(b'foo.bar', type=0xdead, cls=0xbeef, ttl=257,
  193. payload=dns.UnknownRecord(b'somedata', ttl=257)),
  194. ])
  195. self.assertEqual(msg.additional, [
  196. dns.RRHeader(b'baz.ban', type=dns.A, cls=dns.IN, ttl=257,
  197. payload=dns.Record_A('1.2.3.4', ttl=257)),
  198. ])
  199. enc = msg.toStr()
  200. self.assertEqual(enc, wire)
  201. def test_decodeWithCompression(self):
  202. """
  203. If the leading byte of an encoded label (in bytes read from a stream
  204. passed to L{Name.decode}) has its two high bits set, the next byte is
  205. treated as a pointer to another label in the stream and that label is
  206. included in the name being decoded.
  207. """
  208. # Slightly modified version of the example from RFC 1035, section 4.1.4.
  209. stream = BytesIO(
  210. b"x" * 20 +
  211. b"\x01f\x03isi\x04arpa\x00"
  212. b"\x03foo\xc0\x14"
  213. b"\x03bar\xc0\x20")
  214. stream.seek(20)
  215. name = dns.Name()
  216. name.decode(stream)
  217. # Verify we found the first name in the stream and that the stream
  218. # position is left at the first byte after the decoded name.
  219. self.assertEqual(b"f.isi.arpa", name.name)
  220. self.assertEqual(32, stream.tell())
  221. # Get the second name from the stream and make the same assertions.
  222. name.decode(stream)
  223. self.assertEqual(name.name, b"foo.f.isi.arpa")
  224. self.assertEqual(38, stream.tell())
  225. # Get the third and final name
  226. name.decode(stream)
  227. self.assertEqual(name.name, b"bar.foo.f.isi.arpa")
  228. self.assertEqual(44, stream.tell())
  229. def test_rejectCompressionLoop(self):
  230. """
  231. L{Name.decode} raises L{ValueError} if the stream passed to it includes
  232. a compression pointer which forms a loop, causing the name to be
  233. undecodable.
  234. """
  235. name = dns.Name()
  236. stream = BytesIO(b"\xc0\x00")
  237. self.assertRaises(ValueError, name.decode, stream)
  238. def test_equality(self):
  239. """
  240. L{Name} instances are equal as long as they have the same value for
  241. L{Name.name}, regardless of the case.
  242. """
  243. name1 = dns.Name(b"foo.bar")
  244. name2 = dns.Name(b"foo.bar")
  245. self.assertEqual(name1, name2)
  246. name3 = dns.Name(b"fOO.bar")
  247. self.assertEqual(name1, name3)
  248. def test_inequality(self):
  249. """
  250. L{Name} instances are not equal as long as they have different
  251. L{Name.name} attributes.
  252. """
  253. name1 = dns.Name(b"foo.bar")
  254. name2 = dns.Name(b"bar.foo")
  255. self.assertNotEqual(name1, name2)
  256. class RoundtripDNSTests(unittest.TestCase):
  257. """
  258. Encoding and then decoding various objects.
  259. """
  260. names = [b"example.org", b"go-away.fish.tv", b"23strikesback.net"]
  261. def test_name(self):
  262. for n in self.names:
  263. # encode the name
  264. f = BytesIO()
  265. dns.Name(n).encode(f)
  266. # decode the name
  267. f.seek(0, 0)
  268. result = dns.Name()
  269. result.decode(f)
  270. self.assertEqual(result.name, n)
  271. def test_query(self):
  272. """
  273. L{dns.Query.encode} returns a byte string representing the fields of the
  274. query which can be decoded into a new L{dns.Query} instance using
  275. L{dns.Query.decode}.
  276. """
  277. for n in self.names:
  278. for dnstype in range(1, 17):
  279. for dnscls in range(1, 5):
  280. # encode the query
  281. f = BytesIO()
  282. dns.Query(n, dnstype, dnscls).encode(f)
  283. # decode the result
  284. f.seek(0, 0)
  285. result = dns.Query()
  286. result.decode(f)
  287. self.assertEqual(result.name, n)
  288. self.assertEqual(result.type, dnstype)
  289. self.assertEqual(result.cls, dnscls)
  290. def test_resourceRecordHeader(self):
  291. """
  292. L{dns.RRHeader.encode} encodes the record header's information and
  293. writes it to the file-like object passed to it and
  294. L{dns.RRHeader.decode} reads from a file-like object to re-construct a
  295. L{dns.RRHeader} instance.
  296. """
  297. # encode the RR
  298. f = BytesIO()
  299. dns.RRHeader(b"test.org", 3, 4, 17).encode(f)
  300. # decode the result
  301. f.seek(0, 0)
  302. result = dns.RRHeader()
  303. result.decode(f)
  304. self.assertEqual(result.name, dns.Name(b"test.org"))
  305. self.assertEqual(result.type, 3)
  306. self.assertEqual(result.cls, 4)
  307. self.assertEqual(result.ttl, 17)
  308. def test_resources(self):
  309. """
  310. L{dns.SimpleRecord.encode} encodes the record's name information and
  311. writes it to the file-like object passed to it and
  312. L{dns.SimpleRecord.decode} reads from a file-like object to re-construct
  313. a L{dns.SimpleRecord} instance.
  314. """
  315. names = (
  316. b"this.are.test.name",
  317. b"will.compress.will.this.will.name.will.hopefully",
  318. b"test.CASE.preSErVatIOn.YeAH",
  319. b"a.s.h.o.r.t.c.a.s.e.t.o.t.e.s.t",
  320. b"singleton"
  321. )
  322. for s in names:
  323. f = BytesIO()
  324. dns.SimpleRecord(s).encode(f)
  325. f.seek(0, 0)
  326. result = dns.SimpleRecord()
  327. result.decode(f)
  328. self.assertEqual(result.name, dns.Name(s))
  329. def test_hashable(self):
  330. """
  331. Instances of all record types are hashable.
  332. """
  333. for k in RECORD_TYPES:
  334. k1, k2 = k(), k()
  335. hk1 = hash(k1)
  336. hk2 = hash(k2)
  337. self.assertEqual(hk1, hk2, "%s != %s (for %s)" % (hk1,hk2,k))
  338. def test_Charstr(self):
  339. """
  340. Test L{dns.Charstr} encode and decode.
  341. """
  342. for n in self.names:
  343. # encode the name
  344. f = BytesIO()
  345. dns.Charstr(n).encode(f)
  346. # decode the name
  347. f.seek(0, 0)
  348. result = dns.Charstr()
  349. result.decode(f)
  350. self.assertEqual(result.string, n)
  351. def _recordRoundtripTest(self, record):
  352. """
  353. Assert that encoding C{record} and then decoding the resulting bytes
  354. creates a record which compares equal to C{record}.
  355. """
  356. stream = BytesIO()
  357. record.encode(stream)
  358. length = stream.tell()
  359. stream.seek(0, 0)
  360. replica = record.__class__()
  361. replica.decode(stream, length)
  362. self.assertEqual(record, replica)
  363. def test_SOA(self):
  364. """
  365. The byte stream written by L{dns.Record_SOA.encode} can be used by
  366. L{dns.Record_SOA.decode} to reconstruct the state of the original
  367. L{dns.Record_SOA} instance.
  368. """
  369. self._recordRoundtripTest(
  370. dns.Record_SOA(
  371. mname=b'foo', rname=b'bar', serial=12, refresh=34,
  372. retry=56, expire=78, minimum=90))
  373. def test_A(self):
  374. """
  375. The byte stream written by L{dns.Record_A.encode} can be used by
  376. L{dns.Record_A.decode} to reconstruct the state of the original
  377. L{dns.Record_A} instance.
  378. """
  379. self._recordRoundtripTest(dns.Record_A('1.2.3.4'))
  380. def test_NULL(self):
  381. """
  382. The byte stream written by L{dns.Record_NULL.encode} can be used by
  383. L{dns.Record_NULL.decode} to reconstruct the state of the original
  384. L{dns.Record_NULL} instance.
  385. """
  386. self._recordRoundtripTest(dns.Record_NULL(b'foo bar'))
  387. def test_WKS(self):
  388. """
  389. The byte stream written by L{dns.Record_WKS.encode} can be used by
  390. L{dns.Record_WKS.decode} to reconstruct the state of the original
  391. L{dns.Record_WKS} instance.
  392. """
  393. self._recordRoundtripTest(dns.Record_WKS('1.2.3.4', 3, b'xyz'))
  394. def test_AAAA(self):
  395. """
  396. The byte stream written by L{dns.Record_AAAA.encode} can be used by
  397. L{dns.Record_AAAA.decode} to reconstruct the state of the original
  398. L{dns.Record_AAAA} instance.
  399. """
  400. self._recordRoundtripTest(dns.Record_AAAA('::1'))
  401. def test_A6(self):
  402. """
  403. The byte stream written by L{dns.Record_A6.encode} can be used by
  404. L{dns.Record_A6.decode} to reconstruct the state of the original
  405. L{dns.Record_A6} instance.
  406. """
  407. self._recordRoundtripTest(dns.Record_A6(8, '::1:2', b'foo'))
  408. def test_SRV(self):
  409. """
  410. The byte stream written by L{dns.Record_SRV.encode} can be used by
  411. L{dns.Record_SRV.decode} to reconstruct the state of the original
  412. L{dns.Record_SRV} instance.
  413. """
  414. self._recordRoundtripTest(dns.Record_SRV(
  415. priority=1, weight=2, port=3, target=b'example.com'))
  416. def test_NAPTR(self):
  417. """
  418. Test L{dns.Record_NAPTR} encode and decode.
  419. """
  420. naptrs = [
  421. (100, 10, b"u", b"sip+E2U",
  422. b"!^.*$!sip:information@domain.tld!", b""),
  423. (100, 50, b"s", b"http+I2L+I2C+I2R",
  424. b"", b"_http._tcp.gatech.edu")]
  425. for (order, preference, flags, service, regexp, replacement) in naptrs:
  426. rin = dns.Record_NAPTR(order, preference, flags, service, regexp,
  427. replacement)
  428. e = BytesIO()
  429. rin.encode(e)
  430. e.seek(0, 0)
  431. rout = dns.Record_NAPTR()
  432. rout.decode(e)
  433. self.assertEqual(rin.order, rout.order)
  434. self.assertEqual(rin.preference, rout.preference)
  435. self.assertEqual(rin.flags, rout.flags)
  436. self.assertEqual(rin.service, rout.service)
  437. self.assertEqual(rin.regexp, rout.regexp)
  438. self.assertEqual(rin.replacement.name, rout.replacement.name)
  439. self.assertEqual(rin.ttl, rout.ttl)
  440. def test_AFSDB(self):
  441. """
  442. The byte stream written by L{dns.Record_AFSDB.encode} can be used by
  443. L{dns.Record_AFSDB.decode} to reconstruct the state of the original
  444. L{dns.Record_AFSDB} instance.
  445. """
  446. self._recordRoundtripTest(dns.Record_AFSDB(
  447. subtype=3, hostname=b'example.com'))
  448. def test_RP(self):
  449. """
  450. The byte stream written by L{dns.Record_RP.encode} can be used by
  451. L{dns.Record_RP.decode} to reconstruct the state of the original
  452. L{dns.Record_RP} instance.
  453. """
  454. self._recordRoundtripTest(dns.Record_RP(
  455. mbox=b'alice.example.com', txt=b'example.com'))
  456. def test_HINFO(self):
  457. """
  458. The byte stream written by L{dns.Record_HINFO.encode} can be used by
  459. L{dns.Record_HINFO.decode} to reconstruct the state of the original
  460. L{dns.Record_HINFO} instance.
  461. """
  462. self._recordRoundtripTest(dns.Record_HINFO(cpu=b'fast', os=b'great'))
  463. def test_MINFO(self):
  464. """
  465. The byte stream written by L{dns.Record_MINFO.encode} can be used by
  466. L{dns.Record_MINFO.decode} to reconstruct the state of the original
  467. L{dns.Record_MINFO} instance.
  468. """
  469. self._recordRoundtripTest(dns.Record_MINFO(
  470. rmailbx=b'foo', emailbx=b'bar'))
  471. def test_MX(self):
  472. """
  473. The byte stream written by L{dns.Record_MX.encode} can be used by
  474. L{dns.Record_MX.decode} to reconstruct the state of the original
  475. L{dns.Record_MX} instance.
  476. """
  477. self._recordRoundtripTest(dns.Record_MX(
  478. preference=1, name=b'example.com'))
  479. def test_TXT(self):
  480. """
  481. The byte stream written by L{dns.Record_TXT.encode} can be used by
  482. L{dns.Record_TXT.decode} to reconstruct the state of the original
  483. L{dns.Record_TXT} instance.
  484. """
  485. self._recordRoundtripTest(dns.Record_TXT(b'foo', b'bar'))
  486. MESSAGE_AUTHENTIC_DATA_BYTES = (
  487. b'\x00\x00' # ID
  488. b'\x00' #
  489. b'\x20' # RA, Z, AD=1, CD, RCODE
  490. b'\x00\x00' # Query count
  491. b'\x00\x00' # Answer count
  492. b'\x00\x00' # Authority count
  493. b'\x00\x00' # Additional count
  494. )
  495. MESSAGE_CHECKING_DISABLED_BYTES = (
  496. b'\x00\x00' # ID
  497. b'\x00' #
  498. b'\x10' # RA, Z, AD, CD=1, RCODE
  499. b'\x00\x00' # Query count
  500. b'\x00\x00' # Answer count
  501. b'\x00\x00' # Authority count
  502. b'\x00\x00' # Additional count
  503. )
  504. class MessageTests(unittest.SynchronousTestCase):
  505. """
  506. Tests for L{twisted.names.dns.Message}.
  507. """
  508. def test_authenticDataDefault(self):
  509. """
  510. L{dns.Message.authenticData} has default value 0.
  511. """
  512. self.assertEqual(dns.Message().authenticData, 0)
  513. def test_authenticDataOverride(self):
  514. """
  515. L{dns.Message.__init__} accepts a C{authenticData} argument which
  516. is assigned to L{dns.Message.authenticData}.
  517. """
  518. self.assertEqual(dns.Message(authenticData=1).authenticData, 1)
  519. def test_authenticDataEncode(self):
  520. """
  521. L{dns.Message.toStr} encodes L{dns.Message.authenticData} into
  522. byte4 of the byte string.
  523. """
  524. self.assertEqual(
  525. dns.Message(authenticData=1).toStr(),
  526. MESSAGE_AUTHENTIC_DATA_BYTES
  527. )
  528. def test_authenticDataDecode(self):
  529. """
  530. L{dns.Message.fromStr} decodes byte4 and assigns bit3 to
  531. L{dns.Message.authenticData}.
  532. """
  533. m = dns.Message()
  534. m.fromStr(MESSAGE_AUTHENTIC_DATA_BYTES)
  535. self.assertEqual(m.authenticData, 1)
  536. def test_checkingDisabledDefault(self):
  537. """
  538. L{dns.Message.checkingDisabled} has default value 0.
  539. """
  540. self.assertEqual(dns.Message().checkingDisabled, 0)
  541. def test_checkingDisabledOverride(self):
  542. """
  543. L{dns.Message.__init__} accepts a C{checkingDisabled} argument which
  544. is assigned to L{dns.Message.checkingDisabled}.
  545. """
  546. self.assertEqual(
  547. dns.Message(checkingDisabled=1).checkingDisabled, 1)
  548. def test_checkingDisabledEncode(self):
  549. """
  550. L{dns.Message.toStr} encodes L{dns.Message.checkingDisabled} into
  551. byte4 of the byte string.
  552. """
  553. self.assertEqual(
  554. dns.Message(checkingDisabled=1).toStr(),
  555. MESSAGE_CHECKING_DISABLED_BYTES
  556. )
  557. def test_checkingDisabledDecode(self):
  558. """
  559. L{dns.Message.fromStr} decodes byte4 and assigns bit4 to
  560. L{dns.Message.checkingDisabled}.
  561. """
  562. m = dns.Message()
  563. m.fromStr(MESSAGE_CHECKING_DISABLED_BYTES)
  564. self.assertEqual(m.checkingDisabled, 1)
  565. def test_reprDefaults(self):
  566. """
  567. L{dns.Message.__repr__} omits field values and sections which are
  568. identical to their defaults. The id field value is always shown.
  569. """
  570. self.assertEqual(
  571. '<Message id=0>',
  572. repr(dns.Message())
  573. )
  574. def test_reprFlagsIfSet(self):
  575. """
  576. L{dns.Message.__repr__} displays flags if they are L{True}.
  577. """
  578. m = dns.Message(answer=True, auth=True, trunc=True, recDes=True,
  579. recAv=True, authenticData=True, checkingDisabled=True)
  580. self.assertEqual(
  581. '<Message '
  582. 'id=0 '
  583. 'flags=answer,auth,trunc,recDes,recAv,authenticData,'
  584. 'checkingDisabled'
  585. '>',
  586. repr(m),
  587. )
  588. def test_reprNonDefautFields(self):
  589. """
  590. L{dns.Message.__repr__} displays field values if they differ from their
  591. defaults.
  592. """
  593. m = dns.Message(id=10, opCode=20, rCode=30, maxSize=40)
  594. self.assertEqual(
  595. '<Message '
  596. 'id=10 '
  597. 'opCode=20 '
  598. 'rCode=30 '
  599. 'maxSize=40'
  600. '>',
  601. repr(m),
  602. )
  603. def test_reprNonDefaultSections(self):
  604. """
  605. L{dns.Message.__repr__} displays sections which differ from their
  606. defaults.
  607. """
  608. m = dns.Message()
  609. m.queries = [1, 2, 3]
  610. m.answers = [4, 5, 6]
  611. m.authority = [7, 8, 9]
  612. m.additional = [10, 11, 12]
  613. self.assertEqual(
  614. '<Message '
  615. 'id=0 '
  616. 'queries=[1, 2, 3] '
  617. 'answers=[4, 5, 6] '
  618. 'authority=[7, 8, 9] '
  619. 'additional=[10, 11, 12]'
  620. '>',
  621. repr(m),
  622. )
  623. def test_emptyMessage(self):
  624. """
  625. Test that a message which has been truncated causes an EOFError to
  626. be raised when it is parsed.
  627. """
  628. msg = dns.Message()
  629. self.assertRaises(EOFError, msg.fromStr, b'')
  630. def test_emptyQuery(self):
  631. """
  632. Test that bytes representing an empty query message can be decoded
  633. as such.
  634. """
  635. msg = dns.Message()
  636. msg.fromStr(
  637. b'\x01\x00' # Message ID
  638. b'\x00' # answer bit, opCode nibble, auth bit, trunc bit, recursive bit
  639. b'\x00' # recursion bit, empty bit, authenticData bit,
  640. # checkingDisabled bit, response code nibble
  641. b'\x00\x00' # number of queries
  642. b'\x00\x00' # number of answers
  643. b'\x00\x00' # number of authorities
  644. b'\x00\x00' # number of additionals
  645. )
  646. self.assertEqual(msg.id, 256)
  647. self.assertFalse(
  648. msg.answer, "Message was not supposed to be an answer.")
  649. self.assertEqual(msg.opCode, dns.OP_QUERY)
  650. self.assertFalse(
  651. msg.auth, "Message was not supposed to be authoritative.")
  652. self.assertFalse(
  653. msg.trunc, "Message was not supposed to be truncated.")
  654. self.assertEqual(msg.queries, [])
  655. self.assertEqual(msg.answers, [])
  656. self.assertEqual(msg.authority, [])
  657. self.assertEqual(msg.additional, [])
  658. def test_NULL(self):
  659. """
  660. A I{NULL} record with an arbitrary payload can be encoded and decoded as
  661. part of a L{dns.Message}.
  662. """
  663. bytes = b''.join([dns._ord2bytes(i) for i in range(256)])
  664. rec = dns.Record_NULL(bytes)
  665. rr = dns.RRHeader(b'testname', dns.NULL, payload=rec)
  666. msg1 = dns.Message()
  667. msg1.answers.append(rr)
  668. s = BytesIO()
  669. msg1.encode(s)
  670. s.seek(0, 0)
  671. msg2 = dns.Message()
  672. msg2.decode(s)
  673. self.assertIsInstance(msg2.answers[0].payload, dns.Record_NULL)
  674. self.assertEqual(msg2.answers[0].payload.payload, bytes)
  675. def test_lookupRecordTypeDefault(self):
  676. """
  677. L{Message.lookupRecordType} returns C{dns.UnknownRecord} if it is
  678. called with an integer which doesn't correspond to any known record
  679. type.
  680. """
  681. # 65280 is the first value in the range reserved for private
  682. # use, so it shouldn't ever conflict with an officially
  683. # allocated value.
  684. self.assertIs(dns.Message().lookupRecordType(65280), dns.UnknownRecord)
  685. def test_nonAuthoritativeMessage(self):
  686. """
  687. The L{RRHeader} instances created by L{Message} from a non-authoritative
  688. message are marked as not authoritative.
  689. """
  690. buf = BytesIO()
  691. answer = dns.RRHeader(payload=dns.Record_A('1.2.3.4', ttl=0))
  692. answer.encode(buf)
  693. message = dns.Message()
  694. message.fromStr(
  695. b'\x01\x00' # Message ID
  696. # answer bit, opCode nibble, auth bit, trunc bit, recursive bit
  697. b'\x00'
  698. # recursion bit, empty bit, authenticData bit,
  699. # checkingDisabled bit, response code nibble
  700. b'\x00'
  701. b'\x00\x00' # number of queries
  702. b'\x00\x01' # number of answers
  703. b'\x00\x00' # number of authorities
  704. b'\x00\x00' # number of additionals
  705. + buf.getvalue()
  706. )
  707. self.assertEqual(message.answers, [answer])
  708. self.assertFalse(message.answers[0].auth)
  709. def test_authoritativeMessage(self):
  710. """
  711. The L{RRHeader} instances created by L{Message} from an authoritative
  712. message are marked as authoritative.
  713. """
  714. buf = BytesIO()
  715. answer = dns.RRHeader(payload=dns.Record_A('1.2.3.4', ttl=0))
  716. answer.encode(buf)
  717. message = dns.Message()
  718. message.fromStr(
  719. b'\x01\x00' # Message ID
  720. # answer bit, opCode nibble, auth bit, trunc bit, recursive bit
  721. b'\x04'
  722. # recursion bit, empty bit, authenticData bit,
  723. # checkingDisabled bit, response code nibble
  724. b'\x00'
  725. b'\x00\x00' # number of queries
  726. b'\x00\x01' # number of answers
  727. b'\x00\x00' # number of authorities
  728. b'\x00\x00' # number of additionals
  729. + buf.getvalue()
  730. )
  731. answer.auth = True
  732. self.assertEqual(message.answers, [answer])
  733. self.assertTrue(message.answers[0].auth)
  734. class MessageComparisonTests(ComparisonTestsMixin,
  735. unittest.SynchronousTestCase):
  736. """
  737. Tests for the rich comparison of L{dns.Message} instances.
  738. """
  739. def messageFactory(self, *args, **kwargs):
  740. """
  741. Create a L{dns.Message}.
  742. The L{dns.Message} constructor doesn't accept C{queries}, C{answers},
  743. C{authority}, C{additional} arguments, so we extract them from the
  744. kwargs supplied to this factory function and assign them to the message.
  745. @param args: Positional arguments.
  746. @param kwargs: Keyword arguments.
  747. @return: A L{dns.Message} instance.
  748. """
  749. queries = kwargs.pop('queries', [])
  750. answers = kwargs.pop('answers', [])
  751. authority = kwargs.pop('authority', [])
  752. additional = kwargs.pop('additional', [])
  753. m = dns.Message(**kwargs)
  754. if queries:
  755. m.queries = queries
  756. if answers:
  757. m.answers = answers
  758. if authority:
  759. m.authority = authority
  760. if additional:
  761. m.additional = additional
  762. return m
  763. def test_id(self):
  764. """
  765. Two L{dns.Message} instances compare equal if they have the same id
  766. value.
  767. """
  768. self.assertNormalEqualityImplementation(
  769. self.messageFactory(id=10),
  770. self.messageFactory(id=10),
  771. self.messageFactory(id=20),
  772. )
  773. def test_answer(self):
  774. """
  775. Two L{dns.Message} instances compare equal if they have the same answer
  776. flag.
  777. """
  778. self.assertNormalEqualityImplementation(
  779. self.messageFactory(answer=1),
  780. self.messageFactory(answer=1),
  781. self.messageFactory(answer=0),
  782. )
  783. def test_opCode(self):
  784. """
  785. Two L{dns.Message} instances compare equal if they have the same opCode
  786. value.
  787. """
  788. self.assertNormalEqualityImplementation(
  789. self.messageFactory(opCode=10),
  790. self.messageFactory(opCode=10),
  791. self.messageFactory(opCode=20),
  792. )
  793. def test_recDes(self):
  794. """
  795. Two L{dns.Message} instances compare equal if they have the same recDes
  796. flag.
  797. """
  798. self.assertNormalEqualityImplementation(
  799. self.messageFactory(recDes=1),
  800. self.messageFactory(recDes=1),
  801. self.messageFactory(recDes=0),
  802. )
  803. def test_recAv(self):
  804. """
  805. Two L{dns.Message} instances compare equal if they have the same recAv
  806. flag.
  807. """
  808. self.assertNormalEqualityImplementation(
  809. self.messageFactory(recAv=1),
  810. self.messageFactory(recAv=1),
  811. self.messageFactory(recAv=0),
  812. )
  813. def test_auth(self):
  814. """
  815. Two L{dns.Message} instances compare equal if they have the same auth
  816. flag.
  817. """
  818. self.assertNormalEqualityImplementation(
  819. self.messageFactory(auth=1),
  820. self.messageFactory(auth=1),
  821. self.messageFactory(auth=0),
  822. )
  823. def test_rCode(self):
  824. """
  825. Two L{dns.Message} instances compare equal if they have the same rCode
  826. value.
  827. """
  828. self.assertNormalEqualityImplementation(
  829. self.messageFactory(rCode=10),
  830. self.messageFactory(rCode=10),
  831. self.messageFactory(rCode=20),
  832. )
  833. def test_trunc(self):
  834. """
  835. Two L{dns.Message} instances compare equal if they have the same trunc
  836. flag.
  837. """
  838. self.assertNormalEqualityImplementation(
  839. self.messageFactory(trunc=1),
  840. self.messageFactory(trunc=1),
  841. self.messageFactory(trunc=0),
  842. )
  843. def test_maxSize(self):
  844. """
  845. Two L{dns.Message} instances compare equal if they have the same
  846. maxSize value.
  847. """
  848. self.assertNormalEqualityImplementation(
  849. self.messageFactory(maxSize=10),
  850. self.messageFactory(maxSize=10),
  851. self.messageFactory(maxSize=20),
  852. )
  853. def test_authenticData(self):
  854. """
  855. Two L{dns.Message} instances compare equal if they have the same
  856. authenticData flag.
  857. """
  858. self.assertNormalEqualityImplementation(
  859. self.messageFactory(authenticData=1),
  860. self.messageFactory(authenticData=1),
  861. self.messageFactory(authenticData=0),
  862. )
  863. def test_checkingDisabled(self):
  864. """
  865. Two L{dns.Message} instances compare equal if they have the same
  866. checkingDisabled flag.
  867. """
  868. self.assertNormalEqualityImplementation(
  869. self.messageFactory(checkingDisabled=1),
  870. self.messageFactory(checkingDisabled=1),
  871. self.messageFactory(checkingDisabled=0),
  872. )
  873. def test_queries(self):
  874. """
  875. Two L{dns.Message} instances compare equal if they have the same
  876. queries.
  877. """
  878. self.assertNormalEqualityImplementation(
  879. self.messageFactory(queries=[dns.Query(b'example.com')]),
  880. self.messageFactory(queries=[dns.Query(b'example.com')]),
  881. self.messageFactory(queries=[dns.Query(b'example.org')]),
  882. )
  883. def test_answers(self):
  884. """
  885. Two L{dns.Message} instances compare equal if they have the same
  886. answers.
  887. """
  888. self.assertNormalEqualityImplementation(
  889. self.messageFactory(answers=[dns.RRHeader(
  890. b'example.com', payload=dns.Record_A('1.2.3.4'))]),
  891. self.messageFactory(answers=[dns.RRHeader(
  892. b'example.com', payload=dns.Record_A('1.2.3.4'))]),
  893. self.messageFactory(answers=[dns.RRHeader(
  894. b'example.org', payload=dns.Record_A('4.3.2.1'))]),
  895. )
  896. def test_authority(self):
  897. """
  898. Two L{dns.Message} instances compare equal if they have the same
  899. authority records.
  900. """
  901. self.assertNormalEqualityImplementation(
  902. self.messageFactory(authority=[dns.RRHeader(
  903. b'example.com',
  904. type=dns.SOA, payload=dns.Record_SOA())]),
  905. self.messageFactory(authority=[dns.RRHeader(
  906. b'example.com',
  907. type=dns.SOA, payload=dns.Record_SOA())]),
  908. self.messageFactory(authority=[dns.RRHeader(
  909. b'example.org',
  910. type=dns.SOA, payload=dns.Record_SOA())]),
  911. )
  912. def test_additional(self):
  913. """
  914. Two L{dns.Message} instances compare equal if they have the same
  915. additional records.
  916. """
  917. self.assertNormalEqualityImplementation(
  918. self.messageFactory(additional=[dns.RRHeader(
  919. b'example.com', payload=dns.Record_A('1.2.3.4'))]),
  920. self.messageFactory(additional=[dns.RRHeader(
  921. b'example.com', payload=dns.Record_A('1.2.3.4'))]),
  922. self.messageFactory(additional=[dns.RRHeader(
  923. b'example.org', payload=dns.Record_A('1.2.3.4'))]),
  924. )
  925. class TestController(object):
  926. """
  927. Pretend to be a DNS query processor for a DNSDatagramProtocol.
  928. @ivar messages: the list of received messages.
  929. @type messages: C{list} of (msg, protocol, address)
  930. """
  931. def __init__(self):
  932. """
  933. Initialize the controller: create a list of messages.
  934. """
  935. self.messages = []
  936. def messageReceived(self, msg, proto, addr=None):
  937. """
  938. Save the message so that it can be checked during the tests.
  939. """
  940. self.messages.append((msg, proto, addr))
  941. class DatagramProtocolTests(unittest.TestCase):
  942. """
  943. Test various aspects of L{dns.DNSDatagramProtocol}.
  944. """
  945. def setUp(self):
  946. """
  947. Create a L{dns.DNSDatagramProtocol} with a deterministic clock.
  948. """
  949. self.clock = task.Clock()
  950. self.controller = TestController()
  951. self.proto = dns.DNSDatagramProtocol(self.controller)
  952. transport = proto_helpers.FakeDatagramTransport()
  953. self.proto.makeConnection(transport)
  954. self.proto.callLater = self.clock.callLater
  955. def test_truncatedPacket(self):
  956. """
  957. Test that when a short datagram is received, datagramReceived does
  958. not raise an exception while processing it.
  959. """
  960. self.proto.datagramReceived(
  961. b'', address.IPv4Address('UDP', '127.0.0.1', 12345))
  962. self.assertEqual(self.controller.messages, [])
  963. def test_simpleQuery(self):
  964. """
  965. Test content received after a query.
  966. """
  967. d = self.proto.query(('127.0.0.1', 21345), [dns.Query(b'foo')])
  968. self.assertEqual(len(self.proto.liveMessages.keys()), 1)
  969. m = dns.Message()
  970. m.id = next(iter(self.proto.liveMessages.keys()))
  971. m.answers = [dns.RRHeader(payload=dns.Record_A(address='1.2.3.4'))]
  972. def cb(result):
  973. self.assertEqual(result.answers[0].payload.dottedQuad(), '1.2.3.4')
  974. d.addCallback(cb)
  975. self.proto.datagramReceived(m.toStr(), ('127.0.0.1', 21345))
  976. return d
  977. def test_queryTimeout(self):
  978. """
  979. Test that query timeouts after some seconds.
  980. """
  981. d = self.proto.query(('127.0.0.1', 21345), [dns.Query(b'foo')])
  982. self.assertEqual(len(self.proto.liveMessages), 1)
  983. self.clock.advance(10)
  984. self.assertFailure(d, dns.DNSQueryTimeoutError)
  985. self.assertEqual(len(self.proto.liveMessages), 0)
  986. return d
  987. def test_writeError(self):
  988. """
  989. Exceptions raised by the transport's write method should be turned into
  990. C{Failure}s passed to errbacks of the C{Deferred} returned by
  991. L{DNSDatagramProtocol.query}.
  992. """
  993. def writeError(message, addr):
  994. raise RuntimeError("bar")
  995. self.proto.transport.write = writeError
  996. d = self.proto.query(('127.0.0.1', 21345), [dns.Query(b'foo')])
  997. return self.assertFailure(d, RuntimeError)
  998. def test_listenError(self):
  999. """
  1000. Exception L{CannotListenError} raised by C{listenUDP} should be turned
  1001. into a C{Failure} passed to errback of the C{Deferred} returned by
  1002. L{DNSDatagramProtocol.query}.
  1003. """
  1004. def startListeningError():
  1005. raise CannotListenError(None, None, None)
  1006. self.proto.startListening = startListeningError
  1007. # Clean up transport so that the protocol calls startListening again
  1008. self.proto.transport = None
  1009. d = self.proto.query(('127.0.0.1', 21345), [dns.Query(b'foo')])
  1010. return self.assertFailure(d, CannotListenError)
  1011. def test_receiveMessageNotInLiveMessages(self):
  1012. """
  1013. When receiving a message whose id is not in
  1014. L{DNSDatagramProtocol.liveMessages} or L{DNSDatagramProtocol.resends},
  1015. the message will be received by L{DNSDatagramProtocol.controller}.
  1016. """
  1017. message = dns.Message()
  1018. message.id = 1
  1019. message.answers = [dns.RRHeader(
  1020. payload=dns.Record_A(address='1.2.3.4'))]
  1021. self.proto.datagramReceived(message.toStr(), ('127.0.0.1', 21345))
  1022. self.assertEqual(self.controller.messages[-1][0].toStr(),
  1023. message.toStr())
  1024. class TestTCPController(TestController):
  1025. """
  1026. Pretend to be a DNS query processor for a DNSProtocol.
  1027. @ivar connections: A list of L{DNSProtocol} instances which have
  1028. notified this controller that they are connected and have not
  1029. yet notified it that their connection has been lost.
  1030. """
  1031. def __init__(self):
  1032. TestController.__init__(self)
  1033. self.connections = []
  1034. def connectionMade(self, proto):
  1035. self.connections.append(proto)
  1036. def connectionLost(self, proto):
  1037. self.connections.remove(proto)
  1038. class DNSProtocolTests(unittest.TestCase):
  1039. """
  1040. Test various aspects of L{dns.DNSProtocol}.
  1041. """
  1042. def setUp(self):
  1043. """
  1044. Create a L{dns.DNSProtocol} with a deterministic clock.
  1045. """
  1046. self.clock = task.Clock()
  1047. self.controller = TestTCPController()
  1048. self.proto = dns.DNSProtocol(self.controller)
  1049. self.proto.makeConnection(proto_helpers.StringTransport())
  1050. self.proto.callLater = self.clock.callLater
  1051. def test_connectionTracking(self):
  1052. """
  1053. L{dns.DNSProtocol} calls its controller's C{connectionMade}
  1054. method with itself when it is connected to a transport and its
  1055. controller's C{connectionLost} method when it is disconnected.
  1056. """
  1057. self.assertEqual(self.controller.connections, [self.proto])
  1058. self.proto.connectionLost(
  1059. Failure(ConnectionDone("Fake Connection Done")))
  1060. self.assertEqual(self.controller.connections, [])
  1061. def test_queryTimeout(self):
  1062. """
  1063. Test that query timeouts after some seconds.
  1064. """
  1065. d = self.proto.query([dns.Query(b'foo')])
  1066. self.assertEqual(len(self.proto.liveMessages), 1)
  1067. self.clock.advance(60)
  1068. self.assertFailure(d, dns.DNSQueryTimeoutError)
  1069. self.assertEqual(len(self.proto.liveMessages), 0)
  1070. return d
  1071. def test_simpleQuery(self):
  1072. """
  1073. Test content received after a query.
  1074. """
  1075. d = self.proto.query([dns.Query(b'foo')])
  1076. self.assertEqual(len(self.proto.liveMessages.keys()), 1)
  1077. m = dns.Message()
  1078. m.id = next(iter(self.proto.liveMessages.keys()))
  1079. m.answers = [dns.RRHeader(payload=dns.Record_A(address='1.2.3.4'))]
  1080. def cb(result):
  1081. self.assertEqual(result.answers[0].payload.dottedQuad(), '1.2.3.4')
  1082. d.addCallback(cb)
  1083. s = m.toStr()
  1084. s = struct.pack('!H', len(s)) + s
  1085. self.proto.dataReceived(s)
  1086. return d
  1087. def test_writeError(self):
  1088. """
  1089. Exceptions raised by the transport's write method should be turned into
  1090. C{Failure}s passed to errbacks of the C{Deferred} returned by
  1091. L{DNSProtocol.query}.
  1092. """
  1093. def writeError(message):
  1094. raise RuntimeError("bar")
  1095. self.proto.transport.write = writeError
  1096. d = self.proto.query([dns.Query(b'foo')])
  1097. return self.assertFailure(d, RuntimeError)
  1098. def test_receiveMessageNotInLiveMessages(self):
  1099. """
  1100. When receiving a message whose id is not in L{DNSProtocol.liveMessages}
  1101. the message will be received by L{DNSProtocol.controller}.
  1102. """
  1103. message = dns.Message()
  1104. message.id = 1
  1105. message.answers = [dns.RRHeader(
  1106. payload=dns.Record_A(address='1.2.3.4'))]
  1107. string = message.toStr()
  1108. string = struct.pack('!H', len(string)) + string
  1109. self.proto.dataReceived(string)
  1110. self.assertEqual(self.controller.messages[-1][0].toStr(),
  1111. message.toStr())
  1112. class ReprTests(unittest.TestCase):
  1113. """
  1114. Tests for the C{__repr__} implementation of record classes.
  1115. """
  1116. def test_ns(self):
  1117. """
  1118. The repr of a L{dns.Record_NS} instance includes the name of the
  1119. nameserver and the TTL of the record.
  1120. """
  1121. self.assertEqual(
  1122. repr(dns.Record_NS(b'example.com', 4321)),
  1123. "<NS name=example.com ttl=4321>")
  1124. def test_md(self):
  1125. """
  1126. The repr of a L{dns.Record_MD} instance includes the name of the
  1127. mail destination and the TTL of the record.
  1128. """
  1129. self.assertEqual(
  1130. repr(dns.Record_MD(b'example.com', 4321)),
  1131. "<MD name=example.com ttl=4321>")
  1132. def test_mf(self):
  1133. """
  1134. The repr of a L{dns.Record_MF} instance includes the name of the
  1135. mail forwarder and the TTL of the record.
  1136. """
  1137. self.assertEqual(
  1138. repr(dns.Record_MF(b'example.com', 4321)),
  1139. "<MF name=example.com ttl=4321>")
  1140. def test_cname(self):
  1141. """
  1142. The repr of a L{dns.Record_CNAME} instance includes the name of the
  1143. mail forwarder and the TTL of the record.
  1144. """
  1145. self.assertEqual(
  1146. repr(dns.Record_CNAME(b'example.com', 4321)),
  1147. "<CNAME name=example.com ttl=4321>")
  1148. def test_mb(self):
  1149. """
  1150. The repr of a L{dns.Record_MB} instance includes the name of the
  1151. mailbox and the TTL of the record.
  1152. """
  1153. self.assertEqual(
  1154. repr(dns.Record_MB(b'example.com', 4321)),
  1155. "<MB name=example.com ttl=4321>")
  1156. def test_mg(self):
  1157. """
  1158. The repr of a L{dns.Record_MG} instance includes the name of the
  1159. mail group member and the TTL of the record.
  1160. """
  1161. self.assertEqual(
  1162. repr(dns.Record_MG(b'example.com', 4321)),
  1163. "<MG name=example.com ttl=4321>")
  1164. def test_mr(self):
  1165. """
  1166. The repr of a L{dns.Record_MR} instance includes the name of the
  1167. mail rename domain and the TTL of the record.
  1168. """
  1169. self.assertEqual(
  1170. repr(dns.Record_MR(b'example.com', 4321)),
  1171. "<MR name=example.com ttl=4321>")
  1172. def test_ptr(self):
  1173. """
  1174. The repr of a L{dns.Record_PTR} instance includes the name of the
  1175. pointer and the TTL of the record.
  1176. """
  1177. self.assertEqual(
  1178. repr(dns.Record_PTR(b'example.com', 4321)),
  1179. "<PTR name=example.com ttl=4321>")
  1180. def test_dname(self):
  1181. """
  1182. The repr of a L{dns.Record_DNAME} instance includes the name of the
  1183. non-terminal DNS name redirection and the TTL of the record.
  1184. """
  1185. self.assertEqual(
  1186. repr(dns.Record_DNAME(b'example.com', 4321)),
  1187. "<DNAME name=example.com ttl=4321>")
  1188. def test_a(self):
  1189. """
  1190. The repr of a L{dns.Record_A} instance includes the dotted-quad
  1191. string representation of the address it is for and the TTL of the
  1192. record.
  1193. """
  1194. self.assertEqual(
  1195. repr(dns.Record_A('1.2.3.4', 567)),
  1196. '<A address=1.2.3.4 ttl=567>')
  1197. def test_soa(self):
  1198. """
  1199. The repr of a L{dns.Record_SOA} instance includes all of the
  1200. authority fields.
  1201. """
  1202. self.assertEqual(
  1203. repr(dns.Record_SOA(mname=b'mName', rname=b'rName', serial=123,
  1204. refresh=456, retry=789, expire=10,
  1205. minimum=11, ttl=12)),
  1206. "<SOA mname=mName rname=rName serial=123 refresh=456 "
  1207. "retry=789 expire=10 minimum=11 ttl=12>")
  1208. def test_null(self):
  1209. """
  1210. The repr of a L{dns.Record_NULL} instance includes the repr of its
  1211. payload and the TTL of the record.
  1212. """
  1213. self.assertEqual(
  1214. repr(dns.Record_NULL(b'abcd', 123)),
  1215. "<NULL payload='abcd' ttl=123>")
  1216. def test_wks(self):
  1217. """
  1218. The repr of a L{dns.Record_WKS} instance includes the dotted-quad
  1219. string representation of the address it is for, the IP protocol
  1220. number it is for, and the TTL of the record.
  1221. """
  1222. self.assertEqual(
  1223. repr(dns.Record_WKS('2.3.4.5', 7, ttl=8)),
  1224. "<WKS address=2.3.4.5 protocol=7 ttl=8>")
  1225. def test_aaaa(self):
  1226. """
  1227. The repr of a L{dns.Record_AAAA} instance includes the colon-separated
  1228. hex string representation of the address it is for and the TTL of the
  1229. record.
  1230. """
  1231. self.assertEqual(
  1232. repr(dns.Record_AAAA('8765::1234', ttl=10)),
  1233. "<AAAA address=8765::1234 ttl=10>")
  1234. def test_a6(self):
  1235. """
  1236. The repr of a L{dns.Record_A6} instance includes the colon-separated
  1237. hex string representation of the address it is for and the TTL of the
  1238. record.
  1239. """
  1240. self.assertEqual(
  1241. repr(dns.Record_A6(0, '1234::5678', b'foo.bar', ttl=10)),
  1242. "<A6 suffix=1234::5678 prefix=foo.bar ttl=10>")
  1243. def test_srv(self):
  1244. """
  1245. The repr of a L{dns.Record_SRV} instance includes the name and port of
  1246. the target and the priority, weight, and TTL of the record.
  1247. """
  1248. self.assertEqual(
  1249. repr(dns.Record_SRV(1, 2, 3, b'example.org', 4)),
  1250. "<SRV priority=1 weight=2 target=example.org port=3 ttl=4>")
  1251. def test_naptr(self):
  1252. """
  1253. The repr of a L{dns.Record_NAPTR} instance includes the order,
  1254. preference, flags, service, regular expression, replacement, and TTL of
  1255. the record.
  1256. """
  1257. record = dns.Record_NAPTR(
  1258. 5, 9, b"S", b"http", b"/foo/bar/i", b"baz", 3)
  1259. self.assertEqual(
  1260. repr(record),
  1261. "<NAPTR order=5 preference=9 flags=S service=http "
  1262. "regexp=/foo/bar/i replacement=baz ttl=3>")
  1263. def test_afsdb(self):
  1264. """
  1265. The repr of a L{dns.Record_AFSDB} instance includes the subtype,
  1266. hostname, and TTL of the record.
  1267. """
  1268. self.assertEqual(
  1269. repr(dns.Record_AFSDB(3, b'example.org', 5)),
  1270. "<AFSDB subtype=3 hostname=example.org ttl=5>")
  1271. def test_rp(self):
  1272. """
  1273. The repr of a L{dns.Record_RP} instance includes the mbox, txt, and TTL
  1274. fields of the record.
  1275. """
  1276. self.assertEqual(
  1277. repr(dns.Record_RP(b'alice.example.com', b'admin.example.com', 3)),
  1278. "<RP mbox=alice.example.com txt=admin.example.com ttl=3>")
  1279. def test_hinfo(self):
  1280. """
  1281. The repr of a L{dns.Record_HINFO} instance includes the cpu, os, and
  1282. TTL fields of the record.
  1283. """
  1284. self.assertEqual(
  1285. repr(dns.Record_HINFO(b'sparc', b'minix', 12)),
  1286. "<HINFO cpu='sparc' os='minix' ttl=12>")
  1287. def test_minfo(self):
  1288. """
  1289. The repr of a L{dns.Record_MINFO} instance includes the rmailbx,
  1290. emailbx, and TTL fields of the record.
  1291. """
  1292. record = dns.Record_MINFO(
  1293. b'alice.example.com', b'bob.example.com', 15)
  1294. self.assertEqual(
  1295. repr(record),
  1296. "<MINFO responsibility=alice.example.com "
  1297. "errors=bob.example.com ttl=15>")
  1298. def test_mx(self):
  1299. """
  1300. The repr of a L{dns.Record_MX} instance includes the preference, name,
  1301. and TTL fields of the record.
  1302. """
  1303. self.assertEqual(
  1304. repr(dns.Record_MX(13, b'mx.example.com', 2)),
  1305. "<MX preference=13 name=mx.example.com ttl=2>")
  1306. def test_txt(self):
  1307. """
  1308. The repr of a L{dns.Record_TXT} instance includes the data and ttl
  1309. fields of the record.
  1310. """
  1311. self.assertEqual(
  1312. repr(dns.Record_TXT(b"foo", b"bar", ttl=15)),
  1313. "<TXT data=['foo', 'bar'] ttl=15>")
  1314. def test_spf(self):
  1315. """
  1316. The repr of a L{dns.Record_SPF} instance includes the data and ttl
  1317. fields of the record.
  1318. """
  1319. self.assertEqual(
  1320. repr(dns.Record_SPF(b"foo", b"bar", ttl=15)),
  1321. "<SPF data=['foo', 'bar'] ttl=15>")
  1322. def test_unknown(self):
  1323. """
  1324. The repr of a L{dns.UnknownRecord} instance includes the data and ttl
  1325. fields of the record.
  1326. """
  1327. self.assertEqual(
  1328. repr(dns.UnknownRecord(b"foo\x1fbar", 12)),
  1329. "<UNKNOWN data='foo\\x1fbar' ttl=12>")
  1330. class EqualityTests(ComparisonTestsMixin, unittest.TestCase):
  1331. """
  1332. Tests for the equality and non-equality behavior of record classes.
  1333. """
  1334. def _equalityTest(self, firstValueOne, secondValueOne, valueTwo):
  1335. return self.assertNormalEqualityImplementation(
  1336. firstValueOne, secondValueOne, valueTwo)
  1337. def test_charstr(self):
  1338. """
  1339. Two L{dns.Charstr} instances compare equal if and only if they have the
  1340. same string value.
  1341. """
  1342. self._equalityTest(
  1343. dns.Charstr(b'abc'), dns.Charstr(b'abc'), dns.Charstr(b'def'))
  1344. def test_name(self):
  1345. """
  1346. Two L{dns.Name} instances compare equal if and only if they have the
  1347. same name value.
  1348. """
  1349. self._equalityTest(
  1350. dns.Name(b'abc'), dns.Name(b'abc'), dns.Name(b'def'))
  1351. def _simpleEqualityTest(self, cls):
  1352. """
  1353. Assert that instances of C{cls} with the same attributes compare equal
  1354. to each other and instances with different attributes compare as not
  1355. equal.
  1356. @param cls: A L{dns.SimpleRecord} subclass.
  1357. """
  1358. # Vary the TTL
  1359. self._equalityTest(
  1360. cls(b'example.com', 123),
  1361. cls(b'example.com', 123),
  1362. cls(b'example.com', 321))
  1363. # Vary the name
  1364. self._equalityTest(
  1365. cls(b'example.com', 123),
  1366. cls(b'example.com', 123),
  1367. cls(b'example.org', 123))
  1368. def test_rrheader(self):
  1369. """
  1370. Two L{dns.RRHeader} instances compare equal if and only if they have
  1371. the same name, type, class, time to live, payload, and authoritative
  1372. bit.
  1373. """
  1374. # Vary the name
  1375. self._equalityTest(
  1376. dns.RRHeader(b'example.com', payload=dns.Record_A('1.2.3.4')),
  1377. dns.RRHeader(b'example.com', payload=dns.Record_A('1.2.3.4')),
  1378. dns.RRHeader(b'example.org', payload=dns.Record_A('1.2.3.4')))
  1379. # Vary the payload
  1380. self._equalityTest(
  1381. dns.RRHeader(b'example.com', payload=dns.Record_A('1.2.3.4')),
  1382. dns.RRHeader(b'example.com', payload=dns.Record_A('1.2.3.4')),
  1383. dns.RRHeader(b'example.com', payload=dns.Record_A('1.2.3.5')))
  1384. # Vary the type. Leave the payload as None so that we don't have to
  1385. # provide non-equal values.
  1386. self._equalityTest(
  1387. dns.RRHeader(b'example.com', dns.A),
  1388. dns.RRHeader(b'example.com', dns.A),
  1389. dns.RRHeader(b'example.com', dns.MX))
  1390. # Probably not likely to come up. Most people use the internet.
  1391. self._equalityTest(
  1392. dns.RRHeader(b'example.com', cls=dns.IN, payload=dns.Record_A('1.2.3.4')),
  1393. dns.RRHeader(b'example.com', cls=dns.IN, payload=dns.Record_A('1.2.3.4')),
  1394. dns.RRHeader(b'example.com', cls=dns.CS, payload=dns.Record_A('1.2.3.4')))
  1395. # Vary the ttl
  1396. self._equalityTest(
  1397. dns.RRHeader(b'example.com', ttl=60, payload=dns.Record_A('1.2.3.4')),
  1398. dns.RRHeader(b'example.com', ttl=60, payload=dns.Record_A('1.2.3.4')),
  1399. dns.RRHeader(b'example.com', ttl=120, payload=dns.Record_A('1.2.3.4')))
  1400. # Vary the auth bit
  1401. self._equalityTest(
  1402. dns.RRHeader(b'example.com', auth=1, payload=dns.Record_A('1.2.3.4')),
  1403. dns.RRHeader(b'example.com', auth=1, payload=dns.Record_A('1.2.3.4')),
  1404. dns.RRHeader(b'example.com', auth=0, payload=dns.Record_A('1.2.3.4')))
  1405. def test_ns(self):
  1406. """
  1407. Two L{dns.Record_NS} instances compare equal if and only if they have
  1408. the same name and TTL.
  1409. """
  1410. self._simpleEqualityTest(dns.Record_NS)
  1411. def test_md(self):
  1412. """
  1413. Two L{dns.Record_MD} instances compare equal if and only if they have
  1414. the same name and TTL.
  1415. """
  1416. self._simpleEqualityTest(dns.Record_MD)
  1417. def test_mf(self):
  1418. """
  1419. Two L{dns.Record_MF} instances compare equal if and only if they have
  1420. the same name and TTL.
  1421. """
  1422. self._simpleEqualityTest(dns.Record_MF)
  1423. def test_cname(self):
  1424. """
  1425. Two L{dns.Record_CNAME} instances compare equal if and only if they
  1426. have the same name and TTL.
  1427. """
  1428. self._simpleEqualityTest(dns.Record_CNAME)
  1429. def test_mb(self):
  1430. """
  1431. Two L{dns.Record_MB} instances compare equal if and only if they have
  1432. the same name and TTL.
  1433. """
  1434. self._simpleEqualityTest(dns.Record_MB)
  1435. def test_mg(self):
  1436. """
  1437. Two L{dns.Record_MG} instances compare equal if and only if they have
  1438. the same name and TTL.
  1439. """
  1440. self._simpleEqualityTest(dns.Record_MG)
  1441. def test_mr(self):
  1442. """
  1443. Two L{dns.Record_MR} instances compare equal if and only if they have
  1444. the same name and TTL.
  1445. """
  1446. self._simpleEqualityTest(dns.Record_MR)
  1447. def test_ptr(self):
  1448. """
  1449. Two L{dns.Record_PTR} instances compare equal if and only if they have
  1450. the same name and TTL.
  1451. """
  1452. self._simpleEqualityTest(dns.Record_PTR)
  1453. def test_dname(self):
  1454. """
  1455. Two L{dns.Record_MD} instances compare equal if and only if they have
  1456. the same name and TTL.
  1457. """
  1458. self._simpleEqualityTest(dns.Record_DNAME)
  1459. def test_a(self):
  1460. """
  1461. Two L{dns.Record_A} instances compare equal if and only if they have
  1462. the same address and TTL.
  1463. """
  1464. # Vary the TTL
  1465. self._equalityTest(
  1466. dns.Record_A('1.2.3.4', 5),
  1467. dns.Record_A('1.2.3.4', 5),
  1468. dns.Record_A('1.2.3.4', 6))
  1469. # Vary the address
  1470. self._equalityTest(
  1471. dns.Record_A('1.2.3.4', 5),
  1472. dns.Record_A('1.2.3.4', 5),
  1473. dns.Record_A('1.2.3.5', 5))
  1474. def test_soa(self):
  1475. """
  1476. Two L{dns.Record_SOA} instances compare equal if and only if they have
  1477. the same mname, rname, serial, refresh, minimum, expire, retry, and
  1478. ttl.
  1479. """
  1480. # Vary the mname
  1481. self._equalityTest(
  1482. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 10, 20, 30),
  1483. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 10, 20, 30),
  1484. dns.Record_SOA(b'xname', b'rname', 123, 456, 789, 10, 20, 30))
  1485. # Vary the rname
  1486. self._equalityTest(
  1487. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 10, 20, 30),
  1488. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 10, 20, 30),
  1489. dns.Record_SOA(b'mname', b'xname', 123, 456, 789, 10, 20, 30))
  1490. # Vary the serial
  1491. self._equalityTest(
  1492. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 10, 20, 30),
  1493. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 10, 20, 30),
  1494. dns.Record_SOA(b'mname', b'rname', 1, 456, 789, 10, 20, 30))
  1495. # Vary the refresh
  1496. self._equalityTest(
  1497. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 10, 20, 30),
  1498. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 10, 20, 30),
  1499. dns.Record_SOA(b'mname', b'rname', 123, 1, 789, 10, 20, 30))
  1500. # Vary the minimum
  1501. self._equalityTest(
  1502. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 10, 20, 30),
  1503. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 10, 20, 30),
  1504. dns.Record_SOA(b'mname', b'rname', 123, 456, 1, 10, 20, 30))
  1505. # Vary the expire
  1506. self._equalityTest(
  1507. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 10, 20, 30),
  1508. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 10, 20, 30),
  1509. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 1, 20, 30))
  1510. # Vary the retry
  1511. self._equalityTest(
  1512. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 10, 20, 30),
  1513. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 10, 20, 30),
  1514. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 10, 1, 30))
  1515. # Vary the ttl
  1516. self._equalityTest(
  1517. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 10, 20, 30),
  1518. dns.Record_SOA(b'mname', b'rname', 123, 456, 789, 10, 20, 30),
  1519. dns.Record_SOA(b'mname', b'xname', 123, 456, 789, 10, 20, 1))
  1520. def test_null(self):
  1521. """
  1522. Two L{dns.Record_NULL} instances compare equal if and only if they have
  1523. the same payload and ttl.
  1524. """
  1525. # Vary the payload
  1526. self._equalityTest(
  1527. dns.Record_NULL('foo bar', 10),
  1528. dns.Record_NULL('foo bar', 10),
  1529. dns.Record_NULL('bar foo', 10))
  1530. # Vary the ttl
  1531. self._equalityTest(
  1532. dns.Record_NULL('foo bar', 10),
  1533. dns.Record_NULL('foo bar', 10),
  1534. dns.Record_NULL('foo bar', 100))
  1535. def test_wks(self):
  1536. """
  1537. Two L{dns.Record_WKS} instances compare equal if and only if they have
  1538. the same address, protocol, map, and ttl.
  1539. """
  1540. # Vary the address
  1541. self._equalityTest(
  1542. dns.Record_WKS('1.2.3.4', 1, 'foo', 2),
  1543. dns.Record_WKS('1.2.3.4', 1, 'foo', 2),
  1544. dns.Record_WKS('4.3.2.1', 1, 'foo', 2))
  1545. # Vary the protocol
  1546. self._equalityTest(
  1547. dns.Record_WKS('1.2.3.4', 1, 'foo', 2),
  1548. dns.Record_WKS('1.2.3.4', 1, 'foo', 2),
  1549. dns.Record_WKS('1.2.3.4', 100, 'foo', 2))
  1550. # Vary the map
  1551. self._equalityTest(
  1552. dns.Record_WKS('1.2.3.4', 1, 'foo', 2),
  1553. dns.Record_WKS('1.2.3.4', 1, 'foo', 2),
  1554. dns.Record_WKS('1.2.3.4', 1, 'bar', 2))
  1555. # Vary the ttl
  1556. self._equalityTest(
  1557. dns.Record_WKS('1.2.3.4', 1, 'foo', 2),
  1558. dns.Record_WKS('1.2.3.4', 1, 'foo', 2),
  1559. dns.Record_WKS('1.2.3.4', 1, 'foo', 200))
  1560. def test_aaaa(self):
  1561. """
  1562. Two L{dns.Record_AAAA} instances compare equal if and only if they have
  1563. the same address and ttl.
  1564. """
  1565. # Vary the address
  1566. self._equalityTest(
  1567. dns.Record_AAAA('1::2', 1),
  1568. dns.Record_AAAA('1::2', 1),
  1569. dns.Record_AAAA('2::1', 1))
  1570. # Vary the ttl
  1571. self._equalityTest(
  1572. dns.Record_AAAA('1::2', 1),
  1573. dns.Record_AAAA('1::2', 1),
  1574. dns.Record_AAAA('1::2', 10))
  1575. def test_a6(self):
  1576. """
  1577. Two L{dns.Record_A6} instances compare equal if and only if they have
  1578. the same prefix, prefix length, suffix, and ttl.
  1579. """
  1580. # Note, A6 is crazy, I'm not sure these values are actually legal.
  1581. # Hopefully that doesn't matter for this test. -exarkun
  1582. # Vary the prefix length
  1583. self._equalityTest(
  1584. dns.Record_A6(16, '::abcd', b'example.com', 10),
  1585. dns.Record_A6(16, '::abcd', b'example.com', 10),
  1586. dns.Record_A6(32, '::abcd', b'example.com', 10))
  1587. # Vary the suffix
  1588. self._equalityTest(
  1589. dns.Record_A6(16, '::abcd', b'example.com', 10),
  1590. dns.Record_A6(16, '::abcd', b'example.com', 10),
  1591. dns.Record_A6(16, '::abcd:0', b'example.com', 10))
  1592. # Vary the prefix
  1593. self._equalityTest(
  1594. dns.Record_A6(16, '::abcd', b'example.com', 10),
  1595. dns.Record_A6(16, '::abcd', b'example.com', 10),
  1596. dns.Record_A6(16, '::abcd', b'example.org', 10))
  1597. # Vary the ttl
  1598. self._equalityTest(
  1599. dns.Record_A6(16, '::abcd', b'example.com', 10),
  1600. dns.Record_A6(16, '::abcd', b'example.com', 10),
  1601. dns.Record_A6(16, '::abcd', b'example.com', 100))
  1602. def test_srv(self):
  1603. """
  1604. Two L{dns.Record_SRV} instances compare equal if and only if they have
  1605. the same priority, weight, port, target, and ttl.
  1606. """
  1607. # Vary the priority
  1608. self._equalityTest(
  1609. dns.Record_SRV(10, 20, 30, b'example.com', 40),
  1610. dns.Record_SRV(10, 20, 30, b'example.com', 40),
  1611. dns.Record_SRV(100, 20, 30, b'example.com', 40))
  1612. # Vary the weight
  1613. self._equalityTest(
  1614. dns.Record_SRV(10, 20, 30, b'example.com', 40),
  1615. dns.Record_SRV(10, 20, 30, b'example.com', 40),
  1616. dns.Record_SRV(10, 200, 30, b'example.com', 40))
  1617. # Vary the port
  1618. self._equalityTest(
  1619. dns.Record_SRV(10, 20, 30, b'example.com', 40),
  1620. dns.Record_SRV(10, 20, 30, b'example.com', 40),
  1621. dns.Record_SRV(10, 20, 300, b'example.com', 40))
  1622. # Vary the target
  1623. self._equalityTest(
  1624. dns.Record_SRV(10, 20, 30, b'example.com', 40),
  1625. dns.Record_SRV(10, 20, 30, b'example.com', 40),
  1626. dns.Record_SRV(10, 20, 30, b'example.org', 40))
  1627. # Vary the ttl
  1628. self._equalityTest(
  1629. dns.Record_SRV(10, 20, 30, b'example.com', 40),
  1630. dns.Record_SRV(10, 20, 30, b'example.com', 40),
  1631. dns.Record_SRV(10, 20, 30, b'example.com', 400))
  1632. def test_naptr(self):
  1633. """
  1634. Two L{dns.Record_NAPTR} instances compare equal if and only if they
  1635. have the same order, preference, flags, service, regexp, replacement,
  1636. and ttl.
  1637. """
  1638. # Vary the order
  1639. self._equalityTest(
  1640. dns.Record_NAPTR(1, 2, b"u", b"sip+E2U", b"/foo/bar/", b"baz", 12),
  1641. dns.Record_NAPTR(1, 2, b"u", b"sip+E2U", b"/foo/bar/", b"baz", 12),
  1642. dns.Record_NAPTR(2, 2, b"u", b"sip+E2U", b"/foo/bar/", b"baz", 12))
  1643. # Vary the preference
  1644. self._equalityTest(
  1645. dns.Record_NAPTR(1, 2, b"u", b"sip+E2U", b"/foo/bar/", b"baz", 12),
  1646. dns.Record_NAPTR(1, 2, b"u", b"sip+E2U", b"/foo/bar/", b"baz", 12),
  1647. dns.Record_NAPTR(1, 3, b"u", b"sip+E2U", b"/foo/bar/", b"baz", 12))
  1648. # Vary the flags
  1649. self._equalityTest(
  1650. dns.Record_NAPTR(1, 2, b"u", b"sip+E2U", b"/foo/bar/", b"baz", 12),
  1651. dns.Record_NAPTR(1, 2, b"u", b"sip+E2U", b"/foo/bar/", b"baz", 12),
  1652. dns.Record_NAPTR(1, 2, b"p", b"sip+E2U", b"/foo/bar/", b"baz", 12))
  1653. # Vary the service
  1654. self._equalityTest(
  1655. dns.Record_NAPTR(1, 2, b"u", b"sip+E2U", b"/foo/bar/", b"baz", 12),
  1656. dns.Record_NAPTR(1, 2, b"u", b"sip+E2U", b"/foo/bar/", b"baz", 12),
  1657. dns.Record_NAPTR(1, 2, b"u", b"http", b"/foo/bar/", b"baz", 12))
  1658. # Vary the regexp
  1659. self._equalityTest(
  1660. dns.Record_NAPTR(1, 2, b"u", b"sip+E2U", b"/foo/bar/", b"baz", 12),
  1661. dns.Record_NAPTR(1, 2, b"u", b"sip+E2U", b"/foo/bar/", b"baz", 12),
  1662. dns.Record_NAPTR(1, 2, b"u", b"sip+E2U", b"/bar/foo/", b"baz", 12))
  1663. # Vary the replacement
  1664. self._equalityTest(
  1665. dns.Record_NAPTR(1, 2, b"u", b"sip+E2U", b"/foo/bar/", b"baz", 12),
  1666. dns.Record_NAPTR(1, 2, b"u", b"sip+E2U", b"/foo/bar/", b"baz", 12),
  1667. dns.Record_NAPTR(1, 2, b"u", b"sip+E2U", b"/bar/foo/", b"quux", 12))
  1668. # Vary the ttl
  1669. self._equalityTest(
  1670. dns.Record_NAPTR(1, 2, b"u", b"sip+E2U", b"/foo/bar/", b"baz", 12),
  1671. dns.Record_NAPTR(1, 2, b"u", b"sip+E2U", b"/foo/bar/", b"baz", 12),
  1672. dns.Record_NAPTR(1, 2, b"u", b"sip+E2U", b"/bar/foo/", b"baz", 5))
  1673. def test_afsdb(self):
  1674. """
  1675. Two L{dns.Record_AFSDB} instances compare equal if and only if they
  1676. have the same subtype, hostname, and ttl.
  1677. """
  1678. # Vary the subtype
  1679. self._equalityTest(
  1680. dns.Record_AFSDB(1, b'example.com', 2),
  1681. dns.Record_AFSDB(1, b'example.com', 2),
  1682. dns.Record_AFSDB(2, b'example.com', 2))
  1683. # Vary the hostname
  1684. self._equalityTest(
  1685. dns.Record_AFSDB(1, b'example.com', 2),
  1686. dns.Record_AFSDB(1, b'example.com', 2),
  1687. dns.Record_AFSDB(1, b'example.org', 2))
  1688. # Vary the ttl
  1689. self._equalityTest(
  1690. dns.Record_AFSDB(1, b'example.com', 2),
  1691. dns.Record_AFSDB(1, b'example.com', 2),
  1692. dns.Record_AFSDB(1, b'example.com', 3))
  1693. def test_rp(self):
  1694. """
  1695. Two L{Record_RP} instances compare equal if and only if they have the
  1696. same mbox, txt, and ttl.
  1697. """
  1698. # Vary the mbox
  1699. self._equalityTest(
  1700. dns.Record_RP(b'alice.example.com', b'alice is nice', 10),
  1701. dns.Record_RP(b'alice.example.com', b'alice is nice', 10),
  1702. dns.Record_RP(b'bob.example.com', b'alice is nice', 10))
  1703. # Vary the txt
  1704. self._equalityTest(
  1705. dns.Record_RP(b'alice.example.com', b'alice is nice', 10),
  1706. dns.Record_RP(b'alice.example.com', b'alice is nice', 10),
  1707. dns.Record_RP(b'alice.example.com', b'alice is not nice', 10))
  1708. # Vary the ttl
  1709. self._equalityTest(
  1710. dns.Record_RP(b'alice.example.com', b'alice is nice', 10),
  1711. dns.Record_RP(b'alice.example.com', b'alice is nice', 10),
  1712. dns.Record_RP(b'alice.example.com', b'alice is nice', 100))
  1713. def test_hinfo(self):
  1714. """
  1715. Two L{dns.Record_HINFO} instances compare equal if and only if they
  1716. have the same cpu, os, and ttl.
  1717. """
  1718. # Vary the cpu
  1719. self._equalityTest(
  1720. dns.Record_HINFO('x86-64', 'plan9', 10),
  1721. dns.Record_HINFO('x86-64', 'plan9', 10),
  1722. dns.Record_HINFO('i386', 'plan9', 10))
  1723. # Vary the os
  1724. self._equalityTest(
  1725. dns.Record_HINFO('x86-64', 'plan9', 10),
  1726. dns.Record_HINFO('x86-64', 'plan9', 10),
  1727. dns.Record_HINFO('x86-64', 'plan11', 10))
  1728. # Vary the ttl
  1729. self._equalityTest(
  1730. dns.Record_HINFO('x86-64', 'plan9', 10),
  1731. dns.Record_HINFO('x86-64', 'plan9', 10),
  1732. dns.Record_HINFO('x86-64', 'plan9', 100))
  1733. def test_minfo(self):
  1734. """
  1735. Two L{dns.Record_MINFO} instances compare equal if and only if they
  1736. have the same rmailbx, emailbx, and ttl.
  1737. """
  1738. # Vary the rmailbx
  1739. self._equalityTest(
  1740. dns.Record_MINFO(b'rmailbox', b'emailbox', 10),
  1741. dns.Record_MINFO(b'rmailbox', b'emailbox', 10),
  1742. dns.Record_MINFO(b'someplace', b'emailbox', 10))
  1743. # Vary the emailbx
  1744. self._equalityTest(
  1745. dns.Record_MINFO(b'rmailbox', b'emailbox', 10),
  1746. dns.Record_MINFO(b'rmailbox', b'emailbox', 10),
  1747. dns.Record_MINFO(b'rmailbox', b'something', 10))
  1748. # Vary the ttl
  1749. self._equalityTest(
  1750. dns.Record_MINFO(b'rmailbox', b'emailbox', 10),
  1751. dns.Record_MINFO(b'rmailbox', b'emailbox', 10),
  1752. dns.Record_MINFO(b'rmailbox', b'emailbox', 100))
  1753. def test_mx(self):
  1754. """
  1755. Two L{dns.Record_MX} instances compare equal if and only if they have
  1756. the same preference, name, and ttl.
  1757. """
  1758. # Vary the preference
  1759. self._equalityTest(
  1760. dns.Record_MX(10, b'example.org', 20),
  1761. dns.Record_MX(10, b'example.org', 20),
  1762. dns.Record_MX(100, b'example.org', 20))
  1763. # Vary the name
  1764. self._equalityTest(
  1765. dns.Record_MX(10, b'example.org', 20),
  1766. dns.Record_MX(10, b'example.org', 20),
  1767. dns.Record_MX(10, b'example.net', 20))
  1768. # Vary the ttl
  1769. self._equalityTest(
  1770. dns.Record_MX(10, b'example.org', 20),
  1771. dns.Record_MX(10, b'example.org', 20),
  1772. dns.Record_MX(10, b'example.org', 200))
  1773. def test_txt(self):
  1774. """
  1775. Two L{dns.Record_TXT} instances compare equal if and only if they have
  1776. the same data and ttl.
  1777. """
  1778. # Vary the length of the data
  1779. self._equalityTest(
  1780. dns.Record_TXT('foo', 'bar', ttl=10),
  1781. dns.Record_TXT('foo', 'bar', ttl=10),
  1782. dns.Record_TXT('foo', 'bar', 'baz', ttl=10))
  1783. # Vary the value of the data
  1784. self._equalityTest(
  1785. dns.Record_TXT('foo', 'bar', ttl=10),
  1786. dns.Record_TXT('foo', 'bar', ttl=10),
  1787. dns.Record_TXT('bar', 'foo', ttl=10))
  1788. # Vary the ttl
  1789. self._equalityTest(
  1790. dns.Record_TXT('foo', 'bar', ttl=10),
  1791. dns.Record_TXT('foo', 'bar', ttl=10),
  1792. dns.Record_TXT('foo', 'bar', ttl=100))
  1793. def test_spf(self):
  1794. """
  1795. L{dns.Record_SPF} instances compare equal if and only if they have the
  1796. same data and ttl.
  1797. """
  1798. # Vary the length of the data
  1799. self._equalityTest(
  1800. dns.Record_SPF('foo', 'bar', ttl=10),
  1801. dns.Record_SPF('foo', 'bar', ttl=10),
  1802. dns.Record_SPF('foo', 'bar', 'baz', ttl=10))
  1803. # Vary the value of the data
  1804. self._equalityTest(
  1805. dns.Record_SPF('foo', 'bar', ttl=10),
  1806. dns.Record_SPF('foo', 'bar', ttl=10),
  1807. dns.Record_SPF('bar', 'foo', ttl=10))
  1808. # Vary the ttl
  1809. self._equalityTest(
  1810. dns.Record_SPF('foo', 'bar', ttl=10),
  1811. dns.Record_SPF('foo', 'bar', ttl=10),
  1812. dns.Record_SPF('foo', 'bar', ttl=100))
  1813. def test_unknown(self):
  1814. """
  1815. L{dns.UnknownRecord} instances compare equal if and only if they have
  1816. the same data and ttl.
  1817. """
  1818. # Vary the length of the data
  1819. self._equalityTest(
  1820. dns.UnknownRecord('foo', ttl=10),
  1821. dns.UnknownRecord('foo', ttl=10),
  1822. dns.UnknownRecord('foobar', ttl=10))
  1823. # Vary the value of the data
  1824. self._equalityTest(
  1825. dns.UnknownRecord('foo', ttl=10),
  1826. dns.UnknownRecord('foo', ttl=10),
  1827. dns.UnknownRecord('bar', ttl=10))
  1828. # Vary the ttl
  1829. self._equalityTest(
  1830. dns.UnknownRecord('foo', ttl=10),
  1831. dns.UnknownRecord('foo', ttl=10),
  1832. dns.UnknownRecord('foo', ttl=100))
  1833. class RRHeaderTests(unittest.TestCase):
  1834. """
  1835. Tests for L{twisted.names.dns.RRHeader}.
  1836. """
  1837. def test_negativeTTL(self):
  1838. """
  1839. Attempting to create a L{dns.RRHeader} instance with a negative TTL
  1840. causes L{ValueError} to be raised.
  1841. """
  1842. self.assertRaises(
  1843. ValueError, dns.RRHeader, "example.com", dns.A,
  1844. dns.IN, -1, dns.Record_A("127.0.0.1"))
  1845. def test_nonIntegralTTL(self):
  1846. """
  1847. L{dns.RRHeader} converts TTLs to integers.
  1848. """
  1849. ttlAsFloat = 123.45
  1850. header = dns.RRHeader("example.com",
  1851. dns.A,
  1852. dns.IN,
  1853. ttlAsFloat,
  1854. dns.Record_A("127.0.0.1"))
  1855. self.assertEqual(header.ttl, int(ttlAsFloat))
  1856. def test_nonNumericTTLRaisesTypeError(self):
  1857. """
  1858. Attempting to create a L{dns.RRHeader} instance with a TTL
  1859. that L{int} cannot convert to an integer raises a L{TypeError}.
  1860. """
  1861. self.assertRaises(
  1862. ValueError, dns.RRHeader, "example.com", dns.A,
  1863. dns.IN, "this is not a number", dns.Record_A("127.0.0.1"))
  1864. class NameToLabelsTests(unittest.SynchronousTestCase):
  1865. """
  1866. Tests for L{twisted.names.dns._nameToLabels}.
  1867. """
  1868. def test_empty(self):
  1869. """
  1870. L{dns._nameToLabels} returns a list containing a single
  1871. empty label for an empty name.
  1872. """
  1873. self.assertEqual(dns._nameToLabels(b''), [b''])
  1874. def test_onlyDot(self):
  1875. """
  1876. L{dns._nameToLabels} returns a list containing a single
  1877. empty label for a name containing only a dot.
  1878. """
  1879. self.assertEqual(dns._nameToLabels(b'.'), [b''])
  1880. def test_withoutTrailingDot(self):
  1881. """
  1882. L{dns._nameToLabels} returns a list ending with an empty
  1883. label for a name without a trailing dot.
  1884. """
  1885. self.assertEqual(dns._nameToLabels(b'com'), [b'com', b''])
  1886. def test_withTrailingDot(self):
  1887. """
  1888. L{dns._nameToLabels} returns a list ending with an empty
  1889. label for a name with a trailing dot.
  1890. """
  1891. self.assertEqual(dns._nameToLabels(b'com.'), [b'com', b''])
  1892. def test_subdomain(self):
  1893. """
  1894. L{dns._nameToLabels} returns a list containing entries
  1895. for all labels in a subdomain name.
  1896. """
  1897. self.assertEqual(
  1898. dns._nameToLabels(b'foo.bar.baz.example.com.'),
  1899. [b'foo', b'bar', b'baz', b'example', b'com', b''])
  1900. def test_casePreservation(self):
  1901. """
  1902. L{dns._nameToLabels} preserves the case of ascii
  1903. characters in labels.
  1904. """
  1905. self.assertEqual(
  1906. dns._nameToLabels(b'EXAMPLE.COM'),
  1907. [b'EXAMPLE', b'COM', b''])
  1908. def assertIsSubdomainOf(testCase, descendant, ancestor):
  1909. """
  1910. Assert that C{descendant} *is* a subdomain of C{ancestor}.
  1911. @type testCase: L{unittest.SynchronousTestCase}
  1912. @param testCase: The test case on which to run the assertions.
  1913. @type descendant: C{str}
  1914. @param descendant: The subdomain name to test.
  1915. @type ancestor: C{str}
  1916. @param ancestor: The superdomain name to test.
  1917. """
  1918. testCase.assertTrue(
  1919. dns._isSubdomainOf(descendant, ancestor),
  1920. '%r is not a subdomain of %r' % (descendant, ancestor))
  1921. def assertIsNotSubdomainOf(testCase, descendant, ancestor):
  1922. """
  1923. Assert that C{descendant} *is not* a subdomain of C{ancestor}.
  1924. @type testCase: L{unittest.SynchronousTestCase}
  1925. @param testCase: The test case on which to run the assertions.
  1926. @type descendant: C{str}
  1927. @param descendant: The subdomain name to test.
  1928. @type ancestor: C{str}
  1929. @param ancestor: The superdomain name to test.
  1930. """
  1931. testCase.assertFalse(
  1932. dns._isSubdomainOf(descendant, ancestor),
  1933. '%r is a subdomain of %r' % (descendant, ancestor))
  1934. class IsSubdomainOfTests(unittest.SynchronousTestCase):
  1935. """
  1936. Tests for L{twisted.names.dns._isSubdomainOf}.
  1937. """
  1938. def test_identical(self):
  1939. """
  1940. L{dns._isSubdomainOf} returns C{True} for identical
  1941. domain names.
  1942. """
  1943. assertIsSubdomainOf(self, b'example.com', b'example.com')
  1944. def test_parent(self):
  1945. """
  1946. L{dns._isSubdomainOf} returns C{True} when the first
  1947. name is an immediate descendant of the second name.
  1948. """
  1949. assertIsSubdomainOf(self, b'foo.example.com', b'example.com')
  1950. def test_distantAncestor(self):
  1951. """
  1952. L{dns._isSubdomainOf} returns C{True} when the first
  1953. name is a distant descendant of the second name.
  1954. """
  1955. assertIsSubdomainOf(self, b'foo.bar.baz.example.com', b'com')
  1956. def test_superdomain(self):
  1957. """
  1958. L{dns._isSubdomainOf} returns C{False} when the first
  1959. name is an ancestor of the second name.
  1960. """
  1961. assertIsNotSubdomainOf(self, b'example.com', b'foo.example.com')
  1962. def test_sibling(self):
  1963. """
  1964. L{dns._isSubdomainOf} returns C{False} if the first name
  1965. is a sibling of the second name.
  1966. """
  1967. assertIsNotSubdomainOf(self, b'foo.example.com', b'bar.example.com')
  1968. def test_unrelatedCommonSuffix(self):
  1969. """
  1970. L{dns._isSubdomainOf} returns C{False} even when domain
  1971. names happen to share a common suffix.
  1972. """
  1973. assertIsNotSubdomainOf(self, b'foo.myexample.com', b'example.com')
  1974. def test_subdomainWithTrailingDot(self):
  1975. """
  1976. L{dns._isSubdomainOf} returns C{True} if the first name
  1977. is a subdomain of the second name but the first name has a
  1978. trailing ".".
  1979. """
  1980. assertIsSubdomainOf(self, b'foo.example.com.', b'example.com')
  1981. def test_superdomainWithTrailingDot(self):
  1982. """
  1983. L{dns._isSubdomainOf} returns C{True} if the first name
  1984. is a subdomain of the second name but the second name has a
  1985. trailing ".".
  1986. """
  1987. assertIsSubdomainOf(self, b'foo.example.com', b'example.com.')
  1988. def test_bothWithTrailingDot(self):
  1989. """
  1990. L{dns._isSubdomainOf} returns C{True} if the first name
  1991. is a subdomain of the second name and both names have a
  1992. trailing ".".
  1993. """
  1994. assertIsSubdomainOf(self, b'foo.example.com.', b'example.com.')
  1995. def test_emptySubdomain(self):
  1996. """
  1997. L{dns._isSubdomainOf} returns C{False} if the first name
  1998. is empty and the second name is not.
  1999. """
  2000. assertIsNotSubdomainOf(self, b'', b'example.com')
  2001. def test_emptySuperdomain(self):
  2002. """
  2003. L{dns._isSubdomainOf} returns C{True} if the second name
  2004. is empty and the first name is not.
  2005. """
  2006. assertIsSubdomainOf(self, b'foo.example.com', b'')
  2007. def test_caseInsensitiveComparison(self):
  2008. """
  2009. L{dns._isSubdomainOf} does case-insensitive comparison
  2010. of name labels.
  2011. """
  2012. assertIsSubdomainOf(self, b'foo.example.com', b'EXAMPLE.COM')
  2013. assertIsSubdomainOf(self, b'FOO.EXAMPLE.COM', b'example.com')
  2014. class OPTNonStandardAttributes(object):
  2015. """
  2016. Generate byte and instance representations of an L{dns._OPTHeader}
  2017. where all attributes are set to non-default values.
  2018. For testing whether attributes have really been read from the byte
  2019. string during decoding.
  2020. """
  2021. @classmethod
  2022. def bytes(cls, excludeName=False, excludeOptions=False):
  2023. """
  2024. Return L{bytes} representing an encoded OPT record.
  2025. @param excludeName: A flag that controls whether to exclude
  2026. the name field. This allows a non-standard name to be
  2027. prepended during the test.
  2028. @type excludeName: L{bool}
  2029. @param excludeOptions: A flag that controls whether to exclude
  2030. the RDLEN field. This allows encoded variable options to be
  2031. appended during the test.
  2032. @type excludeOptions: L{bool}
  2033. @return: L{bytes} representing the encoded OPT record returned
  2034. by L{object}.
  2035. """
  2036. rdlen = b'\x00\x00' # RDLEN 0
  2037. if excludeOptions:
  2038. rdlen = b''
  2039. return (
  2040. b'\x00' # 0 root zone
  2041. b'\x00\x29' # type 41
  2042. b'\x02\x00' # udpPayloadsize 512
  2043. b'\x03' # extendedRCODE 3
  2044. b'\x04' # version 4
  2045. b'\x80\x00' # DNSSEC OK 1 + Z
  2046. ) + rdlen
  2047. @classmethod
  2048. def object(cls):
  2049. """
  2050. Return a new L{dns._OPTHeader} instance.
  2051. @return: A L{dns._OPTHeader} instance with attributes that
  2052. match the encoded record returned by L{bytes}.
  2053. """
  2054. return dns._OPTHeader(
  2055. udpPayloadSize=512,
  2056. extendedRCODE=3,
  2057. version=4,
  2058. dnssecOK=True)
  2059. class OPTHeaderTests(ComparisonTestsMixin, unittest.TestCase):
  2060. """
  2061. Tests for L{twisted.names.dns._OPTHeader}.
  2062. """
  2063. def test_interface(self):
  2064. """
  2065. L{dns._OPTHeader} implements L{dns.IEncodable}.
  2066. """
  2067. verifyClass(dns.IEncodable, dns._OPTHeader)
  2068. def test_name(self):
  2069. """
  2070. L{dns._OPTHeader.name} is an instance attribute whose value is
  2071. fixed as the root domain
  2072. """
  2073. self.assertEqual(dns._OPTHeader().name, dns.Name(b''))
  2074. def test_nameReadonly(self):
  2075. """
  2076. L{dns._OPTHeader.name} is readonly.
  2077. """
  2078. h = dns._OPTHeader()
  2079. self.assertRaises(
  2080. AttributeError, setattr, h, 'name', dns.Name(b'example.com'))
  2081. def test_type(self):
  2082. """
  2083. L{dns._OPTHeader.type} is an instance attribute with fixed value
  2084. 41.
  2085. """
  2086. self.assertEqual(dns._OPTHeader().type, 41)
  2087. def test_typeReadonly(self):
  2088. """
  2089. L{dns._OPTHeader.type} is readonly.
  2090. """
  2091. h = dns._OPTHeader()
  2092. self.assertRaises(
  2093. AttributeError, setattr, h, 'type', dns.A)
  2094. def test_udpPayloadSize(self):
  2095. """
  2096. L{dns._OPTHeader.udpPayloadSize} defaults to 4096 as
  2097. recommended in rfc6891 section-6.2.5.
  2098. """
  2099. self.assertEqual(dns._OPTHeader().udpPayloadSize, 4096)
  2100. def test_udpPayloadSizeOverride(self):
  2101. """
  2102. L{dns._OPTHeader.udpPayloadSize} can be overridden in the
  2103. constructor.
  2104. """
  2105. self.assertEqual(dns._OPTHeader(udpPayloadSize=512).udpPayloadSize, 512)
  2106. def test_extendedRCODE(self):
  2107. """
  2108. L{dns._OPTHeader.extendedRCODE} defaults to 0.
  2109. """
  2110. self.assertEqual(dns._OPTHeader().extendedRCODE, 0)
  2111. def test_extendedRCODEOverride(self):
  2112. """
  2113. L{dns._OPTHeader.extendedRCODE} can be overridden in the
  2114. constructor.
  2115. """
  2116. self.assertEqual(dns._OPTHeader(extendedRCODE=1).extendedRCODE, 1)
  2117. def test_version(self):
  2118. """
  2119. L{dns._OPTHeader.version} defaults to 0.
  2120. """
  2121. self.assertEqual(dns._OPTHeader().version, 0)
  2122. def test_versionOverride(self):
  2123. """
  2124. L{dns._OPTHeader.version} can be overridden in the
  2125. constructor.
  2126. """
  2127. self.assertEqual(dns._OPTHeader(version=1).version, 1)
  2128. def test_dnssecOK(self):
  2129. """
  2130. L{dns._OPTHeader.dnssecOK} defaults to False.
  2131. """
  2132. self.assertFalse(dns._OPTHeader().dnssecOK)
  2133. def test_dnssecOKOverride(self):
  2134. """
  2135. L{dns._OPTHeader.dnssecOK} can be overridden in the
  2136. constructor.
  2137. """
  2138. self.assertTrue(dns._OPTHeader(dnssecOK=True).dnssecOK)
  2139. def test_options(self):
  2140. """
  2141. L{dns._OPTHeader.options} defaults to empty list.
  2142. """
  2143. self.assertEqual(dns._OPTHeader().options, [])
  2144. def test_optionsOverride(self):
  2145. """
  2146. L{dns._OPTHeader.options} can be overridden in the
  2147. constructor.
  2148. """
  2149. h = dns._OPTHeader(options=[(1, 1, b'\x00')])
  2150. self.assertEqual(h.options, [(1, 1, b'\x00')])
  2151. def test_encode(self):
  2152. """
  2153. L{dns._OPTHeader.encode} packs the header fields and writes
  2154. them to a file like object passed in as an argument.
  2155. """
  2156. b = BytesIO()
  2157. OPTNonStandardAttributes.object().encode(b)
  2158. self.assertEqual(
  2159. b.getvalue(),
  2160. OPTNonStandardAttributes.bytes()
  2161. )
  2162. def test_encodeWithOptions(self):
  2163. """
  2164. L{dns._OPTHeader.options} is a list of L{dns._OPTVariableOption}
  2165. instances which are packed into the rdata area of the header.
  2166. """
  2167. h = OPTNonStandardAttributes.object()
  2168. h.options = [
  2169. dns._OPTVariableOption(1, b'foobarbaz'),
  2170. dns._OPTVariableOption(2, b'qux'),
  2171. ]
  2172. b = BytesIO()
  2173. h.encode(b)
  2174. self.assertEqual(
  2175. b.getvalue(),
  2176. OPTNonStandardAttributes.bytes(excludeOptions=True) + (
  2177. b'\x00\x14' # RDLEN 20
  2178. b'\x00\x01' # OPTION-CODE
  2179. b'\x00\x09' # OPTION-LENGTH
  2180. b'foobarbaz' # OPTION-DATA
  2181. b'\x00\x02' # OPTION-CODE
  2182. b'\x00\x03' # OPTION-LENGTH
  2183. b'qux' # OPTION-DATA
  2184. ))
  2185. def test_decode(self):
  2186. """
  2187. L{dns._OPTHeader.decode} unpacks the header fields from a file
  2188. like object and populates the attributes of an existing
  2189. L{dns._OPTHeader} instance.
  2190. """
  2191. decodedHeader = dns._OPTHeader()
  2192. decodedHeader.decode(BytesIO(OPTNonStandardAttributes.bytes()))
  2193. self.assertEqual(
  2194. decodedHeader,
  2195. OPTNonStandardAttributes.object())
  2196. def test_decodeAllExpectedBytes(self):
  2197. """
  2198. L{dns._OPTHeader.decode} reads all the bytes of the record
  2199. that is being decoded.
  2200. """
  2201. # Check that all the input data has been consumed.
  2202. b = BytesIO(OPTNonStandardAttributes.bytes())
  2203. decodedHeader = dns._OPTHeader()
  2204. decodedHeader.decode(b)
  2205. self.assertEqual(b.tell(), len(b.getvalue()))
  2206. def test_decodeOnlyExpectedBytes(self):
  2207. """
  2208. L{dns._OPTHeader.decode} reads only the bytes from the current
  2209. file position to the end of the record that is being
  2210. decoded. Trailing bytes are not consumed.
  2211. """
  2212. b = BytesIO(OPTNonStandardAttributes.bytes()
  2213. + b'xxxx') # Trailing bytes
  2214. decodedHeader = dns._OPTHeader()
  2215. decodedHeader.decode(b)
  2216. self.assertEqual(b.tell(), len(b.getvalue())-len(b'xxxx'))
  2217. def test_decodeDiscardsName(self):
  2218. """
  2219. L{dns._OPTHeader.decode} discards the name which is encoded in
  2220. the supplied bytes. The name attribute of the resulting
  2221. L{dns._OPTHeader} instance will always be L{dns.Name(b'')}.
  2222. """
  2223. b = BytesIO(OPTNonStandardAttributes.bytes(excludeName=True)
  2224. + b'\x07example\x03com\x00')
  2225. h = dns._OPTHeader()
  2226. h.decode(b)
  2227. self.assertEqual(h.name, dns.Name(b''))
  2228. def test_decodeRdlengthTooShort(self):
  2229. """
  2230. L{dns._OPTHeader.decode} raises an exception if the supplied
  2231. RDLEN is too short.
  2232. """
  2233. b = BytesIO(
  2234. OPTNonStandardAttributes.bytes(excludeOptions=True) + (
  2235. b'\x00\x05' # RDLEN 5 Too short - should be 6
  2236. b'\x00\x01' # OPTION-CODE
  2237. b'\x00\x02' # OPTION-LENGTH
  2238. b'\x00\x00' # OPTION-DATA
  2239. ))
  2240. h = dns._OPTHeader()
  2241. self.assertRaises(EOFError, h.decode, b)
  2242. def test_decodeRdlengthTooLong(self):
  2243. """
  2244. L{dns._OPTHeader.decode} raises an exception if the supplied
  2245. RDLEN is too long.
  2246. """
  2247. b = BytesIO(
  2248. OPTNonStandardAttributes.bytes(excludeOptions=True) + (
  2249. b'\x00\x07' # RDLEN 7 Too long - should be 6
  2250. b'\x00\x01' # OPTION-CODE
  2251. b'\x00\x02' # OPTION-LENGTH
  2252. b'\x00\x00' # OPTION-DATA
  2253. ))
  2254. h = dns._OPTHeader()
  2255. self.assertRaises(EOFError, h.decode, b)
  2256. def test_decodeWithOptions(self):
  2257. """
  2258. If the OPT bytes contain variable options,
  2259. L{dns._OPTHeader.decode} will populate a list
  2260. L{dns._OPTHeader.options} with L{dns._OPTVariableOption}
  2261. instances.
  2262. """
  2263. b = BytesIO(
  2264. OPTNonStandardAttributes.bytes(excludeOptions=True) + (
  2265. b'\x00\x14' # RDLEN 20
  2266. b'\x00\x01' # OPTION-CODE
  2267. b'\x00\x09' # OPTION-LENGTH
  2268. b'foobarbaz' # OPTION-DATA
  2269. b'\x00\x02' # OPTION-CODE
  2270. b'\x00\x03' # OPTION-LENGTH
  2271. b'qux' # OPTION-DATA
  2272. ))
  2273. h = dns._OPTHeader()
  2274. h.decode(b)
  2275. self.assertEqual(
  2276. h.options,
  2277. [dns._OPTVariableOption(1, b'foobarbaz'),
  2278. dns._OPTVariableOption(2, b'qux'),]
  2279. )
  2280. def test_fromRRHeader(self):
  2281. """
  2282. L{_OPTHeader.fromRRHeader} accepts an L{RRHeader} instance and
  2283. returns an L{_OPTHeader} instance whose attribute values have
  2284. been derived from the C{cls}, C{ttl} and C{payload} attributes
  2285. of the original header.
  2286. """
  2287. genericHeader = dns.RRHeader(
  2288. b'example.com',
  2289. type=dns.OPT,
  2290. cls=0xffff,
  2291. ttl=(0xfe << 24
  2292. | 0xfd << 16
  2293. | True << 15),
  2294. payload=dns.UnknownRecord(b'\xff\xff\x00\x03abc'))
  2295. decodedOptHeader = dns._OPTHeader.fromRRHeader(genericHeader)
  2296. expectedOptHeader = dns._OPTHeader(
  2297. udpPayloadSize=0xffff,
  2298. extendedRCODE=0xfe,
  2299. version=0xfd,
  2300. dnssecOK=True,
  2301. options=[dns._OPTVariableOption(code=0xffff, data=b'abc')])
  2302. self.assertEqual(decodedOptHeader, expectedOptHeader)
  2303. def test_repr(self):
  2304. """
  2305. L{dns._OPTHeader.__repr__} displays the name and type and all
  2306. the fixed and extended header values of the OPT record.
  2307. """
  2308. self.assertEqual(
  2309. repr(dns._OPTHeader()),
  2310. '<_OPTHeader '
  2311. 'name= '
  2312. 'type=41 '
  2313. 'udpPayloadSize=4096 '
  2314. 'extendedRCODE=0 '
  2315. 'version=0 '
  2316. 'dnssecOK=False '
  2317. 'options=[]>')
  2318. def test_equalityUdpPayloadSize(self):
  2319. """
  2320. Two L{OPTHeader} instances compare equal if they have the same
  2321. udpPayloadSize.
  2322. """
  2323. self.assertNormalEqualityImplementation(
  2324. dns._OPTHeader(udpPayloadSize=512),
  2325. dns._OPTHeader(udpPayloadSize=512),
  2326. dns._OPTHeader(udpPayloadSize=4096))
  2327. def test_equalityExtendedRCODE(self):
  2328. """
  2329. Two L{OPTHeader} instances compare equal if they have the same
  2330. extendedRCODE.
  2331. """
  2332. self.assertNormalEqualityImplementation(
  2333. dns._OPTHeader(extendedRCODE=1),
  2334. dns._OPTHeader(extendedRCODE=1),
  2335. dns._OPTHeader(extendedRCODE=2))
  2336. def test_equalityVersion(self):
  2337. """
  2338. Two L{OPTHeader} instances compare equal if they have the same
  2339. version.
  2340. """
  2341. self.assertNormalEqualityImplementation(
  2342. dns._OPTHeader(version=1),
  2343. dns._OPTHeader(version=1),
  2344. dns._OPTHeader(version=2))
  2345. def test_equalityDnssecOK(self):
  2346. """
  2347. Two L{OPTHeader} instances compare equal if they have the same
  2348. dnssecOK flags.
  2349. """
  2350. self.assertNormalEqualityImplementation(
  2351. dns._OPTHeader(dnssecOK=True),
  2352. dns._OPTHeader(dnssecOK=True),
  2353. dns._OPTHeader(dnssecOK=False))
  2354. def test_equalityOptions(self):
  2355. """
  2356. Two L{OPTHeader} instances compare equal if they have the same
  2357. options.
  2358. """
  2359. self.assertNormalEqualityImplementation(
  2360. dns._OPTHeader(options=[dns._OPTVariableOption(1, b'x')]),
  2361. dns._OPTHeader(options=[dns._OPTVariableOption(1, b'x')]),
  2362. dns._OPTHeader(options=[dns._OPTVariableOption(2, b'y')]))
  2363. class OPTVariableOptionTests(ComparisonTestsMixin, unittest.TestCase):
  2364. """
  2365. Tests for L{dns._OPTVariableOption}.
  2366. """
  2367. def test_interface(self):
  2368. """
  2369. L{dns._OPTVariableOption} implements L{dns.IEncodable}.
  2370. """
  2371. verifyClass(dns.IEncodable, dns._OPTVariableOption)
  2372. def test_constructorArguments(self):
  2373. """
  2374. L{dns._OPTVariableOption.__init__} requires code and data
  2375. arguments which are saved as public instance attributes.
  2376. """
  2377. h = dns._OPTVariableOption(1, b'x')
  2378. self.assertEqual(h.code, 1)
  2379. self.assertEqual(h.data, b'x')
  2380. def test_repr(self):
  2381. """
  2382. L{dns._OPTVariableOption.__repr__} displays the code and data
  2383. of the option.
  2384. """
  2385. self.assertEqual(
  2386. repr(dns._OPTVariableOption(1, b'x')),
  2387. '<_OPTVariableOption '
  2388. 'code=1 '
  2389. "data=x"
  2390. '>')
  2391. def test_equality(self):
  2392. """
  2393. Two OPTVariableOption instances compare equal if they have the same
  2394. code and data values.
  2395. """
  2396. self.assertNormalEqualityImplementation(
  2397. dns._OPTVariableOption(1, b'x'),
  2398. dns._OPTVariableOption(1, b'x'),
  2399. dns._OPTVariableOption(2, b'x'))
  2400. self.assertNormalEqualityImplementation(
  2401. dns._OPTVariableOption(1, b'x'),
  2402. dns._OPTVariableOption(1, b'x'),
  2403. dns._OPTVariableOption(1, b'y'))
  2404. def test_encode(self):
  2405. """
  2406. L{dns._OPTVariableOption.encode} encodes the code and data
  2407. instance attributes to a byte string which also includes the
  2408. data length.
  2409. """
  2410. o = dns._OPTVariableOption(1, b'foobar')
  2411. b = BytesIO()
  2412. o.encode(b)
  2413. self.assertEqual(
  2414. b.getvalue(),
  2415. b'\x00\x01' # OPTION-CODE 1
  2416. b'\x00\x06' # OPTION-LENGTH 6
  2417. b'foobar' # OPTION-DATA
  2418. )
  2419. def test_decode(self):
  2420. """
  2421. L{dns._OPTVariableOption.decode} is a classmethod that decodes
  2422. a byte string and returns a L{dns._OPTVariableOption} instance.
  2423. """
  2424. b = BytesIO(
  2425. b'\x00\x01' # OPTION-CODE 1
  2426. b'\x00\x06' # OPTION-LENGTH 6
  2427. b'foobar' # OPTION-DATA
  2428. )
  2429. o = dns._OPTVariableOption()
  2430. o.decode(b)
  2431. self.assertEqual(o.code, 1)
  2432. self.assertEqual(o.data, b'foobar')
  2433. class RaisedArgs(Exception):
  2434. """
  2435. An exception which can be raised by fakes to test that the fake is called
  2436. with expected arguments.
  2437. """
  2438. def __init__(self, args, kwargs):
  2439. """
  2440. Store the positional and keyword arguments as attributes.
  2441. @param args: The positional args.
  2442. @param kwargs: The keyword args.
  2443. """
  2444. self.args = args
  2445. self.kwargs = kwargs
  2446. class MessageEmpty(object):
  2447. """
  2448. Generate byte string and constructor arguments for an empty
  2449. L{dns._EDNSMessage}.
  2450. """
  2451. @classmethod
  2452. def bytes(cls):
  2453. """
  2454. Bytes which are expected when encoding an instance constructed using
  2455. C{kwargs} and which are expected to result in an identical instance when
  2456. decoded.
  2457. @return: The L{bytes} of a wire encoded message.
  2458. """
  2459. return (
  2460. b'\x01\x00' # id: 256
  2461. b'\x97' # QR: 1, OPCODE: 2, AA: 0, TC: 0, RD: 1
  2462. b'\x8f' # RA: 1, Z, RCODE: 15
  2463. b'\x00\x00' # number of queries
  2464. b'\x00\x00' # number of answers
  2465. b'\x00\x00' # number of authorities
  2466. b'\x00\x00' # number of additionals
  2467. )
  2468. @classmethod
  2469. def kwargs(cls):
  2470. """
  2471. Keyword constructor arguments which are expected to result in an
  2472. instance which returns C{bytes} when encoded.
  2473. @return: A L{dict} of keyword arguments.
  2474. """
  2475. return dict(
  2476. id=256,
  2477. answer=True,
  2478. opCode=dns.OP_STATUS,
  2479. auth=True,
  2480. trunc=True,
  2481. recDes=True,
  2482. recAv=True,
  2483. rCode=15,
  2484. ednsVersion=None,
  2485. )
  2486. class MessageTruncated(object):
  2487. """
  2488. An empty response message whose TR bit is set to 1.
  2489. """
  2490. @classmethod
  2491. def bytes(cls):
  2492. """
  2493. Bytes which are expected when encoding an instance constructed using
  2494. C{kwargs} and which are expected to result in an identical instance when
  2495. decoded.
  2496. @return: The L{bytes} of a wire encoded message.
  2497. """
  2498. return (
  2499. b'\x01\x00' # ID: 256
  2500. b'\x82' # QR: 1, OPCODE: 0, AA: 0, TC: 1, RD: 0
  2501. b'\x00' # RA: 0, Z, RCODE: 0
  2502. b'\x00\x00' # Number of queries
  2503. b'\x00\x00' # Number of answers
  2504. b'\x00\x00' # Number of authorities
  2505. b'\x00\x00' # Number of additionals
  2506. )
  2507. @classmethod
  2508. def kwargs(cls):
  2509. """
  2510. Keyword constructor arguments which are expected to result in an
  2511. instance which returns C{bytes} when encoded.
  2512. @return: A L{dict} of keyword arguments.
  2513. """
  2514. return dict(
  2515. id=256,
  2516. answer=1,
  2517. opCode=0,
  2518. auth=0,
  2519. trunc=1,
  2520. recDes=0,
  2521. recAv=0,
  2522. rCode=0,
  2523. ednsVersion=None,)
  2524. class MessageNonAuthoritative(object):
  2525. """
  2526. A minimal non-authoritative message.
  2527. """
  2528. @classmethod
  2529. def bytes(cls):
  2530. """
  2531. Bytes which are expected when encoding an instance constructed using
  2532. C{kwargs} and which are expected to result in an identical instance when
  2533. decoded.
  2534. @return: The L{bytes} of a wire encoded message.
  2535. """
  2536. return (
  2537. b'\x01\x00' # ID 256
  2538. b'\x00' # QR: 0, OPCODE: 0, AA: 0, TC: 0, RD: 0
  2539. b'\x00' # RA: 0, Z, RCODE: 0
  2540. b'\x00\x00' # Query count
  2541. b'\x00\x01' # Answer count
  2542. b'\x00\x00' # Authorities count
  2543. b'\x00\x00' # Additionals count
  2544. # Answer
  2545. b'\x00' # RR NAME (root)
  2546. b'\x00\x01' # RR TYPE 1 (A)
  2547. b'\x00\x01' # RR CLASS 1 (IN)
  2548. b'\x00\x00\x00\x00' # RR TTL
  2549. b'\x00\x04' # RDLENGTH 4
  2550. b'\x01\x02\x03\x04' # IPv4 1.2.3.4
  2551. )
  2552. @classmethod
  2553. def kwargs(cls):
  2554. """
  2555. Keyword constructor arguments which are expected to result in an
  2556. instance which returns C{bytes} when encoded.
  2557. @return: A L{dict} of keyword arguments.
  2558. """
  2559. return dict(
  2560. id=256,
  2561. auth=0,
  2562. ednsVersion=None,
  2563. answers=[
  2564. dns.RRHeader(
  2565. b'',
  2566. payload=dns.Record_A('1.2.3.4', ttl=0),
  2567. auth=False)])
  2568. class MessageAuthoritative(object):
  2569. """
  2570. A minimal authoritative message.
  2571. """
  2572. @classmethod
  2573. def bytes(cls):
  2574. """
  2575. Bytes which are expected when encoding an instance constructed using
  2576. C{kwargs} and which are expected to result in an identical instance when
  2577. decoded.
  2578. @return: The L{bytes} of a wire encoded message.
  2579. """
  2580. return (
  2581. b'\x01\x00' # ID: 256
  2582. b'\x04' # QR: 0, OPCODE: 0, AA: 1, TC: 0, RD: 0
  2583. b'\x00' # RA: 0, Z, RCODE: 0
  2584. b'\x00\x00' # Query count
  2585. b'\x00\x01' # Answer count
  2586. b'\x00\x00' # Authorities count
  2587. b'\x00\x00' # Additionals count
  2588. # Answer
  2589. b'\x00' # RR NAME (root)
  2590. b'\x00\x01' # RR TYPE 1 (A)
  2591. b'\x00\x01' # RR CLASS 1 (IN)
  2592. b'\x00\x00\x00\x00' # RR TTL
  2593. b'\x00\x04' # RDLENGTH 4
  2594. b'\x01\x02\x03\x04' # IPv4 1.2.3.4
  2595. )
  2596. @classmethod
  2597. def kwargs(cls):
  2598. """
  2599. Keyword constructor arguments which are expected to result in an
  2600. instance which returns C{bytes} when encoded.
  2601. @return: A L{dict} of keyword arguments.
  2602. """
  2603. return dict(
  2604. id=256,
  2605. auth=1,
  2606. ednsVersion=None,
  2607. answers=[
  2608. dns.RRHeader(
  2609. b'',
  2610. payload=dns.Record_A('1.2.3.4', ttl=0),
  2611. auth=True)])
  2612. class MessageComplete:
  2613. """
  2614. An example of a fully populated non-edns response message.
  2615. Contains name compression, answers, authority, and additional records.
  2616. """
  2617. @classmethod
  2618. def bytes(cls):
  2619. """
  2620. Bytes which are expected when encoding an instance constructed using
  2621. C{kwargs} and which are expected to result in an identical instance when
  2622. decoded.
  2623. @return: The L{bytes} of a wire encoded message.
  2624. """
  2625. return (
  2626. b'\x01\x00' # ID: 256
  2627. b'\x95' # QR: 1, OPCODE: 2, AA: 1, TC: 0, RD: 1
  2628. b'\x8f' # RA: 1, Z, RCODE: 15
  2629. b'\x00\x01' # Query count
  2630. b'\x00\x01' # Answer count
  2631. b'\x00\x01' # Authorities count
  2632. b'\x00\x01' # Additionals count
  2633. # Query begins at Byte 12
  2634. b'\x07example\x03com\x00' # QNAME
  2635. b'\x00\x06' # QTYPE 6 (SOA)
  2636. b'\x00\x01' # QCLASS 1 (IN)
  2637. # Answers
  2638. b'\xc0\x0c' # RR NAME (compression ref b12)
  2639. b'\x00\x06' # RR TYPE 6 (SOA)
  2640. b'\x00\x01' # RR CLASS 1 (IN)
  2641. b'\xff\xff\xff\xff' # RR TTL
  2642. b'\x00\x27' # RDLENGTH 39
  2643. b'\x03ns1\xc0\x0c' # Mname (ns1.example.com (compression ref b15)
  2644. b'\x0ahostmaster\xc0\x0c' # rname (hostmaster.example.com)
  2645. b'\xff\xff\xff\xfe' # Serial
  2646. b'\x7f\xff\xff\xfd' # Refresh
  2647. b'\x7f\xff\xff\xfc' # Retry
  2648. b'\x7f\xff\xff\xfb' # Expire
  2649. b'\xff\xff\xff\xfa' # Minimum
  2650. # Authority
  2651. b'\xc0\x0c' # RR NAME (example.com compression ref b12)
  2652. b'\x00\x02' # RR TYPE 2 (NS)
  2653. b'\x00\x01' # RR CLASS 1 (IN)
  2654. b'\xff\xff\xff\xff' # RR TTL
  2655. b'\x00\x02' # RDLENGTH
  2656. b'\xc0\x29' # RDATA (ns1.example.com (compression ref b41)
  2657. # Additional
  2658. b'\xc0\x29' # RR NAME (ns1.example.com compression ref b41)
  2659. b'\x00\x01' # RR TYPE 1 (A)
  2660. b'\x00\x01' # RR CLASS 1 (IN)
  2661. b'\xff\xff\xff\xff' # RR TTL
  2662. b'\x00\x04' # RDLENGTH
  2663. b'\x05\x06\x07\x08' # RDATA 5.6.7.8
  2664. )
  2665. @classmethod
  2666. def kwargs(cls):
  2667. """
  2668. Keyword constructor arguments which are expected to result in an
  2669. instance which returns C{bytes} when encoded.
  2670. @return: A L{dict} of keyword arguments.
  2671. """
  2672. return dict(
  2673. id=256,
  2674. answer=1,
  2675. opCode=dns.OP_STATUS,
  2676. auth=1,
  2677. recDes=1,
  2678. recAv=1,
  2679. rCode=15,
  2680. ednsVersion=None,
  2681. queries=[dns.Query(b'example.com', dns.SOA)],
  2682. answers=[
  2683. dns.RRHeader(
  2684. b'example.com',
  2685. type=dns.SOA,
  2686. ttl=0xffffffff,
  2687. auth=True,
  2688. payload=dns.Record_SOA(
  2689. ttl=0xffffffff,
  2690. mname=b'ns1.example.com',
  2691. rname=b'hostmaster.example.com',
  2692. serial=0xfffffffe,
  2693. refresh=0x7ffffffd,
  2694. retry=0x7ffffffc,
  2695. expire=0x7ffffffb,
  2696. minimum=0xfffffffa,
  2697. ))],
  2698. authority=[
  2699. dns.RRHeader(
  2700. b'example.com',
  2701. type=dns.NS,
  2702. ttl=0xffffffff,
  2703. auth=True,
  2704. payload=dns.Record_NS(
  2705. 'ns1.example.com', ttl=0xffffffff))],
  2706. additional=[
  2707. dns.RRHeader(
  2708. b'ns1.example.com',
  2709. type=dns.A,
  2710. ttl=0xffffffff,
  2711. auth=True,
  2712. payload=dns.Record_A(
  2713. '5.6.7.8', ttl=0xffffffff))])
  2714. class MessageEDNSQuery(object):
  2715. """
  2716. A minimal EDNS query message.
  2717. """
  2718. @classmethod
  2719. def bytes(cls):
  2720. """
  2721. Bytes which are expected when encoding an instance constructed using
  2722. C{kwargs} and which are expected to result in an identical instance when
  2723. decoded.
  2724. @return: The L{bytes} of a wire encoded message.
  2725. """
  2726. return (
  2727. b'\x00\x00' # ID: 0
  2728. b'\x00' # QR: 0, OPCODE: 0, AA: 0, TC: 0, RD: 0
  2729. b'\x00' # RA: 0, Z, RCODE: 0
  2730. b'\x00\x01' # Queries count
  2731. b'\x00\x00' # Anwers count
  2732. b'\x00\x00' # Authority count
  2733. b'\x00\x01' # Additionals count
  2734. # Queries
  2735. b'\x03www\x07example\x03com\x00' # QNAME
  2736. b'\x00\x01' # QTYPE (A)
  2737. b'\x00\x01' # QCLASS (IN)
  2738. # Additional OPT record
  2739. b'\x00' # NAME (.)
  2740. b'\x00\x29' # TYPE (OPT 41)
  2741. b'\x10\x00' # UDP Payload Size (4096)
  2742. b'\x00' # Extended RCODE
  2743. b'\x03' # EDNS version
  2744. b'\x00\x00' # DO: False + Z
  2745. b'\x00\x00' # RDLENGTH
  2746. )
  2747. @classmethod
  2748. def kwargs(cls):
  2749. """
  2750. Keyword constructor arguments which are expected to result in an
  2751. instance which returns C{bytes} when encoded.
  2752. @return: A L{dict} of keyword arguments.
  2753. """
  2754. return dict(
  2755. id=0,
  2756. answer=0,
  2757. opCode=dns.OP_QUERY,
  2758. auth=0,
  2759. recDes=0,
  2760. recAv=0,
  2761. rCode=0,
  2762. ednsVersion=3,
  2763. dnssecOK=False,
  2764. queries=[dns.Query(b'www.example.com', dns.A)],
  2765. additional=[])
  2766. class MessageEDNSComplete(object):
  2767. """
  2768. An example of a fully populated edns response message.
  2769. Contains name compression, answers, authority, and additional records.
  2770. """
  2771. @classmethod
  2772. def bytes(cls):
  2773. """
  2774. Bytes which are expected when encoding an instance constructed using
  2775. C{kwargs} and which are expected to result in an identical instance when
  2776. decoded.
  2777. @return: The L{bytes} of a wire encoded message.
  2778. """
  2779. return (
  2780. b'\x01\x00' # ID: 256
  2781. b'\x95' # QR: 1, OPCODE: 2, AA: 1, TC: 0, RD: 1
  2782. b'\xbf' # RA: 1, AD: 1, RCODE: 15
  2783. b'\x00\x01' # Query count
  2784. b'\x00\x01' # Answer count
  2785. b'\x00\x01' # Authorities count
  2786. b'\x00\x02' # Additionals count
  2787. # Query begins at Byte 12
  2788. b'\x07example\x03com\x00' # QNAME
  2789. b'\x00\x06' # QTYPE 6 (SOA)
  2790. b'\x00\x01' # QCLASS 1 (IN)
  2791. # Answers
  2792. b'\xc0\x0c' # RR NAME (compression ref b12)
  2793. b'\x00\x06' # RR TYPE 6 (SOA)
  2794. b'\x00\x01' # RR CLASS 1 (IN)
  2795. b'\xff\xff\xff\xff' # RR TTL
  2796. b'\x00\x27' # RDLENGTH 39
  2797. b'\x03ns1\xc0\x0c' # mname (ns1.example.com (compression ref b15)
  2798. b'\x0ahostmaster\xc0\x0c' # rname (hostmaster.example.com)
  2799. b'\xff\xff\xff\xfe' # Serial
  2800. b'\x7f\xff\xff\xfd' # Refresh
  2801. b'\x7f\xff\xff\xfc' # Retry
  2802. b'\x7f\xff\xff\xfb' # Expire
  2803. b'\xff\xff\xff\xfa' # Minimum
  2804. # Authority
  2805. b'\xc0\x0c' # RR NAME (example.com compression ref b12)
  2806. b'\x00\x02' # RR TYPE 2 (NS)
  2807. b'\x00\x01' # RR CLASS 1 (IN)
  2808. b'\xff\xff\xff\xff' # RR TTL
  2809. b'\x00\x02' # RDLENGTH
  2810. b'\xc0\x29' # RDATA (ns1.example.com (compression ref b41)
  2811. # Additional
  2812. b'\xc0\x29' # RR NAME (ns1.example.com compression ref b41)
  2813. b'\x00\x01' # RR TYPE 1 (A)
  2814. b'\x00\x01' # RR CLASS 1 (IN)
  2815. b'\xff\xff\xff\xff' # RR TTL
  2816. b'\x00\x04' # RDLENGTH
  2817. b'\x05\x06\x07\x08' # RDATA 5.6.7.8
  2818. # Additional OPT record
  2819. b'\x00' # NAME (.)
  2820. b'\x00\x29' # TYPE (OPT 41)
  2821. b'\x04\x00' # UDP Payload Size (1024)
  2822. b'\x00' # Extended RCODE
  2823. b'\x03' # EDNS version
  2824. b'\x80\x00' # DO: True + Z
  2825. b'\x00\x00' # RDLENGTH
  2826. )
  2827. @classmethod
  2828. def kwargs(cls):
  2829. """
  2830. Keyword constructor arguments which are expected to result in an
  2831. instance which returns C{bytes} when encoded.
  2832. @return: A L{dict} of keyword arguments.
  2833. """
  2834. return dict(
  2835. id=256,
  2836. answer=1,
  2837. opCode=dns.OP_STATUS,
  2838. auth=1,
  2839. trunc=0,
  2840. recDes=1,
  2841. recAv=1,
  2842. rCode=15,
  2843. ednsVersion=3,
  2844. dnssecOK=True,
  2845. authenticData=True,
  2846. checkingDisabled=True,
  2847. maxSize=1024,
  2848. queries=[dns.Query(b'example.com', dns.SOA)],
  2849. answers=[
  2850. dns.RRHeader(
  2851. b'example.com',
  2852. type=dns.SOA,
  2853. ttl=0xffffffff,
  2854. auth=True,
  2855. payload=dns.Record_SOA(
  2856. ttl=0xffffffff,
  2857. mname=b'ns1.example.com',
  2858. rname=b'hostmaster.example.com',
  2859. serial=0xfffffffe,
  2860. refresh=0x7ffffffd,
  2861. retry=0x7ffffffc,
  2862. expire=0x7ffffffb,
  2863. minimum=0xfffffffa,
  2864. ))],
  2865. authority=[
  2866. dns.RRHeader(
  2867. b'example.com',
  2868. type=dns.NS,
  2869. ttl=0xffffffff,
  2870. auth=True,
  2871. payload=dns.Record_NS(
  2872. 'ns1.example.com', ttl=0xffffffff))],
  2873. additional=[
  2874. dns.RRHeader(
  2875. b'ns1.example.com',
  2876. type=dns.A,
  2877. ttl=0xffffffff,
  2878. auth=True,
  2879. payload=dns.Record_A(
  2880. '5.6.7.8', ttl=0xffffffff))])
  2881. class MessageEDNSExtendedRCODE(object):
  2882. """
  2883. An example of an EDNS message with an extended RCODE.
  2884. """
  2885. @classmethod
  2886. def bytes(cls):
  2887. """
  2888. Bytes which are expected when encoding an instance constructed using
  2889. C{kwargs} and which are expected to result in an identical instance when
  2890. decoded.
  2891. @return: The L{bytes} of a wire encoded message.
  2892. """
  2893. return (
  2894. b'\x00\x00'
  2895. b'\x00'
  2896. b'\x0c' # RA: 0, Z, RCODE: 12
  2897. b'\x00\x00'
  2898. b'\x00\x00'
  2899. b'\x00\x00'
  2900. b'\x00\x01' # 1 additionals
  2901. # Additional OPT record
  2902. b'\x00'
  2903. b'\x00\x29'
  2904. b'\x10\x00'
  2905. b'\xab' # Extended RCODE: 171
  2906. b'\x00'
  2907. b'\x00\x00'
  2908. b'\x00\x00'
  2909. )
  2910. @classmethod
  2911. def kwargs(cls):
  2912. """
  2913. Keyword constructor arguments which are expected to result in an
  2914. instance which returns C{bytes} when encoded.
  2915. @return: A L{dict} of keyword arguments.
  2916. """
  2917. return dict(
  2918. id=0,
  2919. answer=False,
  2920. opCode=dns.OP_QUERY,
  2921. auth=False,
  2922. trunc=False,
  2923. recDes=False,
  2924. recAv=False,
  2925. rCode=0xabc, # Combined OPT extended RCODE + Message RCODE
  2926. ednsVersion=0,
  2927. dnssecOK=False,
  2928. maxSize=4096,
  2929. queries=[],
  2930. answers=[],
  2931. authority=[],
  2932. additional=[],
  2933. )
  2934. class MessageComparable(FancyEqMixin, FancyStrMixin, object):
  2935. """
  2936. A wrapper around L{dns.Message} which is comparable so that it can be tested
  2937. using some of the L{dns._EDNSMessage} tests.
  2938. """
  2939. showAttributes = compareAttributes = (
  2940. 'id', 'answer', 'opCode', 'auth', 'trunc',
  2941. 'recDes', 'recAv', 'rCode',
  2942. 'queries', 'answers', 'authority', 'additional')
  2943. def __init__(self, original):
  2944. self.original = original
  2945. def __getattr__(self, key):
  2946. return getattr(self.original, key)
  2947. def verifyConstructorArgument(testCase, cls, argName, defaultVal, altVal,
  2948. attrName=None):
  2949. """
  2950. Verify that an attribute has the expected default value and that a
  2951. corresponding argument passed to a constructor is assigned to that
  2952. attribute.
  2953. @param testCase: The L{TestCase} whose assert methods will be
  2954. called.
  2955. @type testCase: L{unittest.TestCase}
  2956. @param cls: The constructor under test.
  2957. @type cls: L{type}
  2958. @param argName: The name of the constructor argument under test.
  2959. @type argName: L{str}
  2960. @param defaultVal: The expected default value of C{attrName} /
  2961. C{argName}
  2962. @type defaultVal: L{object}
  2963. @param altVal: A value which is different from the default. Used to
  2964. test that supplied constructor arguments are actually assigned to the
  2965. correct attribute.
  2966. @type altVal: L{object}
  2967. @param attrName: The name of the attribute under test if different
  2968. from C{argName}. Defaults to C{argName}
  2969. @type attrName: L{str}
  2970. """
  2971. if attrName is None:
  2972. attrName = argName
  2973. actual = {}
  2974. expected = {'defaultVal': defaultVal, 'altVal': altVal}
  2975. o = cls()
  2976. actual['defaultVal'] = getattr(o, attrName)
  2977. o = cls(**{argName: altVal})
  2978. actual['altVal'] = getattr(o, attrName)
  2979. testCase.assertEqual(expected, actual)
  2980. class ConstructorTestsMixin(object):
  2981. """
  2982. Helper methods for verifying default attribute values and corresponding
  2983. constructor arguments.
  2984. """
  2985. def _verifyConstructorArgument(self, argName, defaultVal, altVal):
  2986. """
  2987. Wrap L{verifyConstructorArgument} to provide simpler interface for
  2988. testing Message and _EDNSMessage constructor arguments.
  2989. @param argName: The name of the constructor argument.
  2990. @param defaultVal: The expected default value.
  2991. @param altVal: An alternative value which is expected to be assigned to
  2992. a correspondingly named attribute.
  2993. """
  2994. verifyConstructorArgument(testCase=self, cls=self.messageFactory,
  2995. argName=argName, defaultVal=defaultVal,
  2996. altVal=altVal)
  2997. def _verifyConstructorFlag(self, argName, defaultVal):
  2998. """
  2999. Wrap L{verifyConstructorArgument} to provide simpler interface for
  3000. testing _EDNSMessage constructor flags.
  3001. @param argName: The name of the constructor flag argument
  3002. @param defaultVal: The expected default value of the flag
  3003. """
  3004. assert defaultVal in (True, False)
  3005. verifyConstructorArgument(testCase=self, cls=self.messageFactory,
  3006. argName=argName, defaultVal=defaultVal,
  3007. altVal=not defaultVal,)
  3008. class CommonConstructorTestsMixin(object):
  3009. """
  3010. Tests for constructor arguments and their associated attributes that are
  3011. common to both L{twisted.names.dns._EDNSMessage} and L{dns.Message}.
  3012. TestCase classes that use this mixin must provide a C{messageFactory} method
  3013. which accepts any argment supported by L{dns.Message.__init__}.
  3014. TestCases must also mixin ConstructorTestsMixin which provides some custom
  3015. assertions for testing constructor arguments.
  3016. """
  3017. def test_id(self):
  3018. """
  3019. L{dns._EDNSMessage.id} defaults to C{0} and can be overridden in
  3020. the constructor.
  3021. """
  3022. self._verifyConstructorArgument('id', defaultVal=0, altVal=1)
  3023. def test_answer(self):
  3024. """
  3025. L{dns._EDNSMessage.answer} defaults to C{False} and can be overridden in
  3026. the constructor.
  3027. """
  3028. self._verifyConstructorFlag('answer', defaultVal=False)
  3029. def test_opCode(self):
  3030. """
  3031. L{dns._EDNSMessage.opCode} defaults to L{dns.OP_QUERY} and can be
  3032. overridden in the constructor.
  3033. """
  3034. self._verifyConstructorArgument(
  3035. 'opCode', defaultVal=dns.OP_QUERY, altVal=dns.OP_STATUS)
  3036. def test_auth(self):
  3037. """
  3038. L{dns._EDNSMessage.auth} defaults to C{False} and can be overridden in
  3039. the constructor.
  3040. """
  3041. self._verifyConstructorFlag('auth', defaultVal=False)
  3042. def test_trunc(self):
  3043. """
  3044. L{dns._EDNSMessage.trunc} defaults to C{False} and can be overridden in
  3045. the constructor.
  3046. """
  3047. self._verifyConstructorFlag('trunc', defaultVal=False)
  3048. def test_recDes(self):
  3049. """
  3050. L{dns._EDNSMessage.recDes} defaults to C{False} and can be overridden in
  3051. the constructor.
  3052. """
  3053. self._verifyConstructorFlag('recDes', defaultVal=False)
  3054. def test_recAv(self):
  3055. """
  3056. L{dns._EDNSMessage.recAv} defaults to C{False} and can be overridden in
  3057. the constructor.
  3058. """
  3059. self._verifyConstructorFlag('recAv', defaultVal=False)
  3060. def test_rCode(self):
  3061. """
  3062. L{dns._EDNSMessage.rCode} defaults to C{0} and can be overridden in the
  3063. constructor.
  3064. """
  3065. self._verifyConstructorArgument('rCode', defaultVal=0, altVal=123)
  3066. def test_maxSize(self):
  3067. """
  3068. L{dns._EDNSMessage.maxSize} defaults to C{512} and can be overridden in
  3069. the constructor.
  3070. """
  3071. self._verifyConstructorArgument('maxSize', defaultVal=512, altVal=1024)
  3072. def test_queries(self):
  3073. """
  3074. L{dns._EDNSMessage.queries} defaults to C{[]}.
  3075. """
  3076. self.assertEqual(self.messageFactory().queries, [])
  3077. def test_answers(self):
  3078. """
  3079. L{dns._EDNSMessage.answers} defaults to C{[]}.
  3080. """
  3081. self.assertEqual(self.messageFactory().answers, [])
  3082. def test_authority(self):
  3083. """
  3084. L{dns._EDNSMessage.authority} defaults to C{[]}.
  3085. """
  3086. self.assertEqual(self.messageFactory().authority, [])
  3087. def test_additional(self):
  3088. """
  3089. L{dns._EDNSMessage.additional} defaults to C{[]}.
  3090. """
  3091. self.assertEqual(self.messageFactory().additional, [])
  3092. class EDNSMessageConstructorTests(ConstructorTestsMixin,
  3093. CommonConstructorTestsMixin,
  3094. unittest.SynchronousTestCase):
  3095. """
  3096. Tests for L{twisted.names.dns._EDNSMessage} constructor arguments that are
  3097. shared with L{dns.Message}.
  3098. """
  3099. messageFactory = dns._EDNSMessage
  3100. class MessageConstructorTests(ConstructorTestsMixin,
  3101. CommonConstructorTestsMixin,
  3102. unittest.SynchronousTestCase):
  3103. """
  3104. Tests for L{twisted.names.dns.Message} constructor arguments that are shared
  3105. with L{dns._EDNSMessage}.
  3106. """
  3107. messageFactory = dns.Message
  3108. class EDNSMessageSpecificsTests(ConstructorTestsMixin,
  3109. unittest.SynchronousTestCase):
  3110. """
  3111. Tests for L{dns._EDNSMessage}.
  3112. These tests are for L{dns._EDNSMessage} APIs which are not shared with
  3113. L{dns.Message}.
  3114. """
  3115. messageFactory = dns._EDNSMessage
  3116. def test_ednsVersion(self):
  3117. """
  3118. L{dns._EDNSMessage.ednsVersion} defaults to C{0} and can be overridden
  3119. in the constructor.
  3120. """
  3121. self._verifyConstructorArgument(
  3122. 'ednsVersion', defaultVal=0, altVal=None)
  3123. def test_dnssecOK(self):
  3124. """
  3125. L{dns._EDNSMessage.dnssecOK} defaults to C{False} and can be overridden
  3126. in the constructor.
  3127. """
  3128. self._verifyConstructorFlag('dnssecOK', defaultVal=False)
  3129. def test_authenticData(self):
  3130. """
  3131. L{dns._EDNSMessage.authenticData} defaults to C{False} and can be
  3132. overridden in the constructor.
  3133. """
  3134. self._verifyConstructorFlag('authenticData', defaultVal=False)
  3135. def test_checkingDisabled(self):
  3136. """
  3137. L{dns._EDNSMessage.checkingDisabled} defaults to C{False} and can be
  3138. overridden in the constructor.
  3139. """
  3140. self._verifyConstructorFlag('checkingDisabled', defaultVal=False)
  3141. def test_queriesOverride(self):
  3142. """
  3143. L{dns._EDNSMessage.queries} can be overridden in the constructor.
  3144. """
  3145. msg = self.messageFactory(queries=[dns.Query(b'example.com')])
  3146. self.assertEqual(
  3147. msg.queries,
  3148. [dns.Query(b'example.com')])
  3149. def test_answersOverride(self):
  3150. """
  3151. L{dns._EDNSMessage.answers} can be overridden in the constructor.
  3152. """
  3153. msg = self.messageFactory(
  3154. answers=[
  3155. dns.RRHeader(
  3156. b'example.com',
  3157. payload=dns.Record_A('1.2.3.4'))])
  3158. self.assertEqual(
  3159. msg.answers,
  3160. [dns.RRHeader(b'example.com', payload=dns.Record_A('1.2.3.4'))])
  3161. def test_authorityOverride(self):
  3162. """
  3163. L{dns._EDNSMessage.authority} can be overridden in the constructor.
  3164. """
  3165. msg = self.messageFactory(
  3166. authority=[
  3167. dns.RRHeader(
  3168. b'example.com',
  3169. type=dns.SOA,
  3170. payload=dns.Record_SOA())])
  3171. self.assertEqual(
  3172. msg.authority,
  3173. [dns.RRHeader(b'example.com', type=dns.SOA,
  3174. payload=dns.Record_SOA())])
  3175. def test_additionalOverride(self):
  3176. """
  3177. L{dns._EDNSMessage.authority} can be overridden in the constructor.
  3178. """
  3179. msg = self.messageFactory(
  3180. additional=[
  3181. dns.RRHeader(
  3182. b'example.com',
  3183. payload=dns.Record_A('1.2.3.4'))])
  3184. self.assertEqual(
  3185. msg.additional,
  3186. [dns.RRHeader(b'example.com', payload=dns.Record_A('1.2.3.4'))])
  3187. def test_reprDefaults(self):
  3188. """
  3189. L{dns._EDNSMessage.__repr__} omits field values and sections which are
  3190. identical to their defaults. The id field value is always shown.
  3191. """
  3192. self.assertEqual(
  3193. '<_EDNSMessage id=0>',
  3194. repr(self.messageFactory())
  3195. )
  3196. def test_reprFlagsIfSet(self):
  3197. """
  3198. L{dns._EDNSMessage.__repr__} displays flags if they are L{True}.
  3199. """
  3200. m = self.messageFactory(answer=True, auth=True, trunc=True, recDes=True,
  3201. recAv=True, authenticData=True,
  3202. checkingDisabled=True, dnssecOK=True)
  3203. self.assertEqual(
  3204. '<_EDNSMessage '
  3205. 'id=0 '
  3206. 'flags=answer,auth,trunc,recDes,recAv,authenticData,'
  3207. 'checkingDisabled,dnssecOK'
  3208. '>',
  3209. repr(m),
  3210. )
  3211. def test_reprNonDefautFields(self):
  3212. """
  3213. L{dns._EDNSMessage.__repr__} displays field values if they differ from
  3214. their defaults.
  3215. """
  3216. m = self.messageFactory(id=10, opCode=20, rCode=30, maxSize=40,
  3217. ednsVersion=50)
  3218. self.assertEqual(
  3219. '<_EDNSMessage '
  3220. 'id=10 '
  3221. 'opCode=20 '
  3222. 'rCode=30 '
  3223. 'maxSize=40 '
  3224. 'ednsVersion=50'
  3225. '>',
  3226. repr(m),
  3227. )
  3228. def test_reprNonDefaultSections(self):
  3229. """
  3230. L{dns.Message.__repr__} displays sections which differ from their
  3231. defaults.
  3232. """
  3233. m = self.messageFactory()
  3234. m.queries = [1, 2, 3]
  3235. m.answers = [4, 5, 6]
  3236. m.authority = [7, 8, 9]
  3237. m.additional = [10, 11, 12]
  3238. self.assertEqual(
  3239. '<_EDNSMessage '
  3240. 'id=0 '
  3241. 'queries=[1, 2, 3] '
  3242. 'answers=[4, 5, 6] '
  3243. 'authority=[7, 8, 9] '
  3244. 'additional=[10, 11, 12]'
  3245. '>',
  3246. repr(m),
  3247. )
  3248. def test_fromStrCallsMessageFactory(self):
  3249. """
  3250. L{dns._EDNSMessage.fromString} calls L{dns._EDNSMessage._messageFactory}
  3251. to create a new L{dns.Message} instance which is used to decode the
  3252. supplied bytes.
  3253. """
  3254. class FakeMessageFactory(object):
  3255. """
  3256. Fake message factory.
  3257. """
  3258. def fromStr(self, *args, **kwargs):
  3259. """
  3260. Fake fromStr method which raises the arguments it was passed.
  3261. @param args: positional arguments
  3262. @param kwargs: keyword arguments
  3263. """
  3264. raise RaisedArgs(args, kwargs)
  3265. m = dns._EDNSMessage()
  3266. m._messageFactory = FakeMessageFactory
  3267. dummyBytes = object()
  3268. e = self.assertRaises(RaisedArgs, m.fromStr, dummyBytes)
  3269. self.assertEqual(
  3270. ((dummyBytes,), {}),
  3271. (e.args, e.kwargs)
  3272. )
  3273. def test_fromStrCallsFromMessage(self):
  3274. """
  3275. L{dns._EDNSMessage.fromString} calls L{dns._EDNSMessage._fromMessage}
  3276. with a L{dns.Message} instance
  3277. """
  3278. m = dns._EDNSMessage()
  3279. class FakeMessageFactory():
  3280. """
  3281. Fake message factory.
  3282. """
  3283. def fromStr(self, bytes):
  3284. """
  3285. A noop fake version of fromStr
  3286. @param bytes: the bytes to be decoded
  3287. """
  3288. fakeMessage = FakeMessageFactory()
  3289. m._messageFactory = lambda: fakeMessage
  3290. def fakeFromMessage(*args, **kwargs):
  3291. raise RaisedArgs(args, kwargs)
  3292. m._fromMessage = fakeFromMessage
  3293. e = self.assertRaises(RaisedArgs, m.fromStr, b'')
  3294. self.assertEqual(
  3295. ((fakeMessage,), {}),
  3296. (e.args, e.kwargs)
  3297. )
  3298. def test_toStrCallsToMessage(self):
  3299. """
  3300. L{dns._EDNSMessage.toStr} calls L{dns._EDNSMessage._toMessage}
  3301. """
  3302. m = dns._EDNSMessage()
  3303. def fakeToMessage(*args, **kwargs):
  3304. raise RaisedArgs(args, kwargs)
  3305. m._toMessage = fakeToMessage
  3306. e = self.assertRaises(RaisedArgs, m.toStr)
  3307. self.assertEqual(
  3308. ((), {}),
  3309. (e.args, e.kwargs)
  3310. )
  3311. def test_toStrCallsToMessageToStr(self):
  3312. """
  3313. L{dns._EDNSMessage.toStr} calls C{toStr} on the message returned by
  3314. L{dns._EDNSMessage._toMessage}.
  3315. """
  3316. m = dns._EDNSMessage()
  3317. dummyBytes = object()
  3318. class FakeMessage(object):
  3319. """
  3320. Fake Message
  3321. """
  3322. def toStr(self):
  3323. """
  3324. Fake toStr which returns dummyBytes.
  3325. @return: dummyBytes
  3326. """
  3327. return dummyBytes
  3328. def fakeToMessage(*args, **kwargs):
  3329. return FakeMessage()
  3330. m._toMessage = fakeToMessage
  3331. self.assertEqual(
  3332. dummyBytes,
  3333. m.toStr()
  3334. )
  3335. class EDNSMessageEqualityTests(ComparisonTestsMixin, unittest.SynchronousTestCase):
  3336. """
  3337. Tests for equality between L(dns._EDNSMessage} instances.
  3338. These tests will not work with L{dns.Message} because it does not use
  3339. L{twisted.python.util.FancyEqMixin}.
  3340. """
  3341. messageFactory = dns._EDNSMessage
  3342. def test_id(self):
  3343. """
  3344. Two L{dns._EDNSMessage} instances compare equal if they have the same
  3345. id.
  3346. """
  3347. self.assertNormalEqualityImplementation(
  3348. self.messageFactory(id=1),
  3349. self.messageFactory(id=1),
  3350. self.messageFactory(id=2),
  3351. )
  3352. def test_answer(self):
  3353. """
  3354. Two L{dns._EDNSMessage} instances compare equal if they have the same
  3355. answer flag.
  3356. """
  3357. self.assertNormalEqualityImplementation(
  3358. self.messageFactory(answer=True),
  3359. self.messageFactory(answer=True),
  3360. self.messageFactory(answer=False),
  3361. )
  3362. def test_opCode(self):
  3363. """
  3364. Two L{dns._EDNSMessage} instances compare equal if they have the same
  3365. opCode.
  3366. """
  3367. self.assertNormalEqualityImplementation(
  3368. self.messageFactory(opCode=dns.OP_STATUS),
  3369. self.messageFactory(opCode=dns.OP_STATUS),
  3370. self.messageFactory(opCode=dns.OP_INVERSE),
  3371. )
  3372. def test_auth(self):
  3373. """
  3374. Two L{dns._EDNSMessage} instances compare equal if they have the same
  3375. auth flag.
  3376. """
  3377. self.assertNormalEqualityImplementation(
  3378. self.messageFactory(auth=True),
  3379. self.messageFactory(auth=True),
  3380. self.messageFactory(auth=False),
  3381. )
  3382. def test_trunc(self):
  3383. """
  3384. Two L{dns._EDNSMessage} instances compare equal if they have the same
  3385. trunc flag.
  3386. """
  3387. self.assertNormalEqualityImplementation(
  3388. self.messageFactory(trunc=True),
  3389. self.messageFactory(trunc=True),
  3390. self.messageFactory(trunc=False),
  3391. )
  3392. def test_recDes(self):
  3393. """
  3394. Two L{dns._EDNSMessage} instances compare equal if they have the same
  3395. recDes flag.
  3396. """
  3397. self.assertNormalEqualityImplementation(
  3398. self.messageFactory(recDes=True),
  3399. self.messageFactory(recDes=True),
  3400. self.messageFactory(recDes=False),
  3401. )
  3402. def test_recAv(self):
  3403. """
  3404. Two L{dns._EDNSMessage} instances compare equal if they have the same
  3405. recAv flag.
  3406. """
  3407. self.assertNormalEqualityImplementation(
  3408. self.messageFactory(recAv=True),
  3409. self.messageFactory(recAv=True),
  3410. self.messageFactory(recAv=False),
  3411. )
  3412. def test_rCode(self):
  3413. """
  3414. Two L{dns._EDNSMessage} instances compare equal if they have the same
  3415. rCode.
  3416. """
  3417. self.assertNormalEqualityImplementation(
  3418. self.messageFactory(rCode=16),
  3419. self.messageFactory(rCode=16),
  3420. self.messageFactory(rCode=15),
  3421. )
  3422. def test_ednsVersion(self):
  3423. """
  3424. Two L{dns._EDNSMessage} instances compare equal if they have the same
  3425. ednsVersion.
  3426. """
  3427. self.assertNormalEqualityImplementation(
  3428. self.messageFactory(ednsVersion=1),
  3429. self.messageFactory(ednsVersion=1),
  3430. self.messageFactory(ednsVersion=None),
  3431. )
  3432. def test_dnssecOK(self):
  3433. """
  3434. Two L{dns._EDNSMessage} instances compare equal if they have the same
  3435. dnssecOK.
  3436. """
  3437. self.assertNormalEqualityImplementation(
  3438. self.messageFactory(dnssecOK=True),
  3439. self.messageFactory(dnssecOK=True),
  3440. self.messageFactory(dnssecOK=False),
  3441. )
  3442. def test_authenticData(self):
  3443. """
  3444. Two L{dns._EDNSMessage} instances compare equal if they have the same
  3445. authenticData flags.
  3446. """
  3447. self.assertNormalEqualityImplementation(
  3448. self.messageFactory(authenticData=True),
  3449. self.messageFactory(authenticData=True),
  3450. self.messageFactory(authenticData=False),
  3451. )
  3452. def test_checkingDisabled(self):
  3453. """
  3454. Two L{dns._EDNSMessage} instances compare equal if they have the same
  3455. checkingDisabled flags.
  3456. """
  3457. self.assertNormalEqualityImplementation(
  3458. self.messageFactory(checkingDisabled=True),
  3459. self.messageFactory(checkingDisabled=True),
  3460. self.messageFactory(checkingDisabled=False),
  3461. )
  3462. def test_maxSize(self):
  3463. """
  3464. Two L{dns._EDNSMessage} instances compare equal if they have the same
  3465. maxSize.
  3466. """
  3467. self.assertNormalEqualityImplementation(
  3468. self.messageFactory(maxSize=2048),
  3469. self.messageFactory(maxSize=2048),
  3470. self.messageFactory(maxSize=1024),
  3471. )
  3472. def test_queries(self):
  3473. """
  3474. Two L{dns._EDNSMessage} instances compare equal if they have the same
  3475. queries.
  3476. """
  3477. self.assertNormalEqualityImplementation(
  3478. self.messageFactory(queries=[dns.Query(b'example.com')]),
  3479. self.messageFactory(queries=[dns.Query(b'example.com')]),
  3480. self.messageFactory(queries=[dns.Query(b'example.org')]),
  3481. )
  3482. def test_answers(self):
  3483. """
  3484. Two L{dns._EDNSMessage} instances compare equal if they have the same
  3485. answers.
  3486. """
  3487. self.assertNormalEqualityImplementation(
  3488. self.messageFactory(answers=[dns.RRHeader(
  3489. b'example.com', payload=dns.Record_A('1.2.3.4'))]),
  3490. self.messageFactory(answers=[dns.RRHeader(
  3491. b'example.com', payload=dns.Record_A('1.2.3.4'))]),
  3492. self.messageFactory(answers=[dns.RRHeader(
  3493. b'example.org', payload=dns.Record_A('4.3.2.1'))]),
  3494. )
  3495. def test_authority(self):
  3496. """
  3497. Two L{dns._EDNSMessage} instances compare equal if they have the same
  3498. authority records.
  3499. """
  3500. self.assertNormalEqualityImplementation(
  3501. self.messageFactory(authority=[dns.RRHeader(
  3502. b'example.com',
  3503. type=dns.SOA, payload=dns.Record_SOA())]),
  3504. self.messageFactory(authority=[dns.RRHeader(
  3505. b'example.com',
  3506. type=dns.SOA, payload=dns.Record_SOA())]),
  3507. self.messageFactory(authority=[dns.RRHeader(
  3508. b'example.org',
  3509. type=dns.SOA, payload=dns.Record_SOA())]),
  3510. )
  3511. def test_additional(self):
  3512. """
  3513. Two L{dns._EDNSMessage} instances compare equal if they have the same
  3514. additional records.
  3515. """
  3516. self.assertNormalEqualityImplementation(
  3517. self.messageFactory(additional=[dns.RRHeader(
  3518. b'example.com', payload=dns.Record_A('1.2.3.4'))]),
  3519. self.messageFactory(additional=[dns.RRHeader(
  3520. b'example.com', payload=dns.Record_A('1.2.3.4'))]),
  3521. self.messageFactory(additional=[dns.RRHeader(
  3522. b'example.org', payload=dns.Record_A('1.2.3.4'))]),
  3523. )
  3524. class StandardEncodingTestsMixin(object):
  3525. """
  3526. Tests for the encoding and decoding of various standard (not EDNS) messages.
  3527. These tests should work with both L{dns._EDNSMessage} and L{dns.Message}.
  3528. TestCase classes that use this mixin must provide a C{messageFactory} method
  3529. which accepts any argment supported by L{dns._EDNSMessage.__init__}.
  3530. EDNS specific arguments may be discarded if not supported by the message
  3531. class under construction.
  3532. """
  3533. def test_emptyMessageEncode(self):
  3534. """
  3535. An empty message can be encoded.
  3536. """
  3537. self.assertEqual(
  3538. self.messageFactory(**MessageEmpty.kwargs()).toStr(),
  3539. MessageEmpty.bytes())
  3540. def test_emptyMessageDecode(self):
  3541. """
  3542. An empty message byte sequence can be decoded.
  3543. """
  3544. m = self.messageFactory()
  3545. m.fromStr(MessageEmpty.bytes())
  3546. self.assertEqual(m, self.messageFactory(**MessageEmpty.kwargs()))
  3547. def test_completeQueryEncode(self):
  3548. """
  3549. A fully populated query message can be encoded.
  3550. """
  3551. self.assertEqual(
  3552. self.messageFactory(**MessageComplete.kwargs()).toStr(),
  3553. MessageComplete.bytes())
  3554. def test_completeQueryDecode(self):
  3555. """
  3556. A fully populated message byte string can be decoded.
  3557. """
  3558. m = self.messageFactory()
  3559. m.fromStr(MessageComplete.bytes()),
  3560. self.assertEqual(m, self.messageFactory(**MessageComplete.kwargs()))
  3561. def test_NULL(self):
  3562. """
  3563. A I{NULL} record with an arbitrary payload can be encoded and decoded as
  3564. part of a message.
  3565. """
  3566. bytes = b''.join([dns._ord2bytes(i) for i in range(256)])
  3567. rec = dns.Record_NULL(bytes)
  3568. rr = dns.RRHeader(b'testname', dns.NULL, payload=rec)
  3569. msg1 = self.messageFactory()
  3570. msg1.answers.append(rr)
  3571. s = msg1.toStr()
  3572. msg2 = self.messageFactory()
  3573. msg2.fromStr(s)
  3574. self.assertIsInstance(msg2.answers[0].payload, dns.Record_NULL)
  3575. self.assertEqual(msg2.answers[0].payload.payload, bytes)
  3576. def test_nonAuthoritativeMessageEncode(self):
  3577. """
  3578. If the message C{authoritative} attribute is set to 0, the encoded bytes
  3579. will have AA bit 0.
  3580. """
  3581. self.assertEqual(
  3582. self.messageFactory(**MessageNonAuthoritative.kwargs()).toStr(),
  3583. MessageNonAuthoritative.bytes())
  3584. def test_nonAuthoritativeMessageDecode(self):
  3585. """
  3586. The L{dns.RRHeader} instances created by a message from a
  3587. non-authoritative message byte string are marked as not authoritative.
  3588. """
  3589. m = self.messageFactory()
  3590. m.fromStr(MessageNonAuthoritative.bytes())
  3591. self.assertEqual(
  3592. m, self.messageFactory(**MessageNonAuthoritative.kwargs()))
  3593. def test_authoritativeMessageEncode(self):
  3594. """
  3595. If the message C{authoritative} attribute is set to 1, the encoded bytes
  3596. will have AA bit 1.
  3597. """
  3598. self.assertEqual(
  3599. self.messageFactory(**MessageAuthoritative.kwargs()).toStr(),
  3600. MessageAuthoritative.bytes())
  3601. def test_authoritativeMessageDecode(self):
  3602. """
  3603. The message and its L{dns.RRHeader} instances created by C{decode} from
  3604. an authoritative message byte string, are marked as authoritative.
  3605. """
  3606. m = self.messageFactory()
  3607. m.fromStr(MessageAuthoritative.bytes())
  3608. self.assertEqual(
  3609. m, self.messageFactory(**MessageAuthoritative.kwargs()))
  3610. def test_truncatedMessageEncode(self):
  3611. """
  3612. If the message C{trunc} attribute is set to 1 the encoded bytes will
  3613. have TR bit 1.
  3614. """
  3615. self.assertEqual(
  3616. self.messageFactory(**MessageTruncated.kwargs()).toStr(),
  3617. MessageTruncated.bytes())
  3618. def test_truncatedMessageDecode(self):
  3619. """
  3620. The message instance created by decoding a truncated message is marked
  3621. as truncated.
  3622. """
  3623. m = self.messageFactory()
  3624. m.fromStr(MessageTruncated.bytes())
  3625. self.assertEqual(m, self.messageFactory(**MessageTruncated.kwargs()))
  3626. class EDNSMessageStandardEncodingTests(StandardEncodingTestsMixin,
  3627. unittest.SynchronousTestCase):
  3628. """
  3629. Tests for the encoding and decoding of various standard (non-EDNS) messages
  3630. by L{dns._EDNSMessage}.
  3631. """
  3632. messageFactory = dns._EDNSMessage
  3633. class MessageStandardEncodingTests(StandardEncodingTestsMixin,
  3634. unittest.SynchronousTestCase):
  3635. """
  3636. Tests for the encoding and decoding of various standard (non-EDNS) messages
  3637. by L{dns.Message}.
  3638. """
  3639. @staticmethod
  3640. def messageFactory(**kwargs):
  3641. """
  3642. This function adapts constructor arguments expected by
  3643. _EDNSMessage.__init__ to arguments suitable for use with the
  3644. Message.__init__.
  3645. Also handles the fact that unlike L{dns._EDNSMessage},
  3646. L{dns.Message.__init__} does not accept queries, answers etc as
  3647. arguments.
  3648. Also removes any L{dns._EDNSMessage} specific arguments.
  3649. @param args: The positional arguments which will be passed to
  3650. L{dns.Message.__init__}.
  3651. @param kwargs: The keyword arguments which will be stripped of EDNS
  3652. specific arguments before being passed to L{dns.Message.__init__}.
  3653. @return: An L{dns.Message} instance.
  3654. """
  3655. queries = kwargs.pop('queries', [])
  3656. answers = kwargs.pop('answers', [])
  3657. authority = kwargs.pop('authority', [])
  3658. additional = kwargs.pop('additional', [])
  3659. kwargs.pop('ednsVersion', None)
  3660. m = dns.Message(**kwargs)
  3661. m.queries = queries
  3662. m.answers = answers
  3663. m.authority = authority
  3664. m.additional = additional
  3665. return MessageComparable(m)
  3666. class EDNSMessageEDNSEncodingTests(unittest.SynchronousTestCase):
  3667. """
  3668. Tests for the encoding and decoding of various EDNS messages.
  3669. These test will not work with L{dns.Message}.
  3670. """
  3671. messageFactory = dns._EDNSMessage
  3672. def test_ednsMessageDecodeStripsOptRecords(self):
  3673. """
  3674. The L(_EDNSMessage} instance created by L{dns._EDNSMessage.decode} from
  3675. an EDNS query never includes OPT records in the additional section.
  3676. """
  3677. m = self.messageFactory()
  3678. m.fromStr(MessageEDNSQuery.bytes())
  3679. self.assertEqual(m.additional, [])
  3680. def test_ednsMessageDecodeMultipleOptRecords(self):
  3681. """
  3682. An L(_EDNSMessage} instance created from a byte string containing
  3683. multiple I{OPT} records will discard all the C{OPT} records.
  3684. C{ednsVersion} will be set to L{None}.
  3685. @see: U{https://tools.ietf.org/html/rfc6891#section-6.1.1}
  3686. """
  3687. m = dns.Message()
  3688. m.additional = [
  3689. dns._OPTHeader(version=2),
  3690. dns._OPTHeader(version=3)]
  3691. ednsMessage = dns._EDNSMessage()
  3692. ednsMessage.fromStr(m.toStr())
  3693. self.assertIsNone(ednsMessage.ednsVersion)
  3694. def test_fromMessageCopiesSections(self):
  3695. """
  3696. L{dns._EDNSMessage._fromMessage} returns an L{_EDNSMessage} instance
  3697. whose queries, answers, authority and additional lists are copies (not
  3698. references to) the original message lists.
  3699. """
  3700. standardMessage = dns.Message()
  3701. standardMessage.fromStr(MessageEDNSQuery.bytes())
  3702. ednsMessage = dns._EDNSMessage._fromMessage(standardMessage)
  3703. duplicates = []
  3704. for attrName in ('queries', 'answers', 'authority', 'additional'):
  3705. if (getattr(standardMessage, attrName)
  3706. is getattr(ednsMessage, attrName)):
  3707. duplicates.append(attrName)
  3708. if duplicates:
  3709. self.fail(
  3710. 'Message and _EDNSMessage shared references to the following '
  3711. 'section lists after decoding: %s' % (duplicates,))
  3712. def test_toMessageCopiesSections(self):
  3713. """
  3714. L{dns._EDNSMessage.toStr} makes no in place changes to the message
  3715. instance.
  3716. """
  3717. ednsMessage = dns._EDNSMessage(ednsVersion=1)
  3718. ednsMessage.toStr()
  3719. self.assertEqual(ednsMessage.additional, [])
  3720. def test_optHeaderPosition(self):
  3721. """
  3722. L{dns._EDNSMessage} can decode OPT records, regardless of their position
  3723. in the additional records section.
  3724. "The OPT RR MAY be placed anywhere within the additional data section."
  3725. @see: U{https://tools.ietf.org/html/rfc6891#section-6.1.1}
  3726. """
  3727. # XXX: We need an _OPTHeader.toRRHeader method. See #6779.
  3728. b = BytesIO()
  3729. optRecord = dns._OPTHeader(version=1)
  3730. optRecord.encode(b)
  3731. optRRHeader = dns.RRHeader()
  3732. b.seek(0)
  3733. optRRHeader.decode(b)
  3734. m = dns.Message()
  3735. m.additional = [optRRHeader]
  3736. actualMessages = []
  3737. actualMessages.append(dns._EDNSMessage._fromMessage(m).ednsVersion)
  3738. m.additional.append(dns.RRHeader(type=dns.A))
  3739. actualMessages.append(
  3740. dns._EDNSMessage._fromMessage(m).ednsVersion)
  3741. m.additional.insert(0, dns.RRHeader(type=dns.A))
  3742. actualMessages.append(
  3743. dns._EDNSMessage._fromMessage(m).ednsVersion)
  3744. self.assertEqual(
  3745. [1] * 3,
  3746. actualMessages
  3747. )
  3748. def test_ednsDecode(self):
  3749. """
  3750. The L(_EDNSMessage} instance created by L{dns._EDNSMessage.fromStr}
  3751. derives its edns specific values (C{ednsVersion}, etc) from the supplied
  3752. OPT record.
  3753. """
  3754. m = self.messageFactory()
  3755. m.fromStr(MessageEDNSComplete.bytes())
  3756. self.assertEqual(m, self.messageFactory(**MessageEDNSComplete.kwargs()))
  3757. def test_ednsEncode(self):
  3758. """
  3759. The L(_EDNSMessage} instance created by L{dns._EDNSMessage.toStr}
  3760. encodes its edns specific values (C{ednsVersion}, etc) into an OPT
  3761. record added to the additional section.
  3762. """
  3763. self.assertEqual(
  3764. self.messageFactory(**MessageEDNSComplete.kwargs()).toStr(),
  3765. MessageEDNSComplete.bytes())
  3766. def test_extendedRcodeEncode(self):
  3767. """
  3768. The L(_EDNSMessage.toStr} encodes the extended I{RCODE} (>=16) by
  3769. assigning the lower 4bits to the message RCODE field and the upper 4bits
  3770. to the OPT pseudo record.
  3771. """
  3772. self.assertEqual(
  3773. self.messageFactory(**MessageEDNSExtendedRCODE.kwargs()).toStr(),
  3774. MessageEDNSExtendedRCODE.bytes())
  3775. def test_extendedRcodeDecode(self):
  3776. """
  3777. The L(_EDNSMessage} instance created by L{dns._EDNSMessage.fromStr}
  3778. derives RCODE from the supplied OPT record.
  3779. """
  3780. m = self.messageFactory()
  3781. m.fromStr(MessageEDNSExtendedRCODE.bytes())
  3782. self.assertEqual(
  3783. m, self.messageFactory(**MessageEDNSExtendedRCODE.kwargs()))
  3784. def test_extendedRcodeZero(self):
  3785. """
  3786. Note that EXTENDED-RCODE value 0 indicates that an unextended RCODE is
  3787. in use (values 0 through 15).
  3788. https://tools.ietf.org/html/rfc6891#section-6.1.3
  3789. """
  3790. ednsMessage = self.messageFactory(rCode=15, ednsVersion=0)
  3791. standardMessage = ednsMessage._toMessage()
  3792. self.assertEqual(
  3793. (15, 0),
  3794. (standardMessage.rCode, standardMessage.additional[0].extendedRCODE)
  3795. )
  3796. class ResponseFromMessageTests(unittest.SynchronousTestCase):
  3797. """
  3798. Tests for L{dns._responseFromMessage}.
  3799. """
  3800. def test_responseFromMessageResponseType(self):
  3801. """
  3802. L{dns.Message._responseFromMessage} is a constructor function which
  3803. generates a new I{answer} message from an existing L{dns.Message} like
  3804. instance.
  3805. """
  3806. request = dns.Message()
  3807. response = dns._responseFromMessage(responseConstructor=dns.Message,
  3808. message=request)
  3809. self.assertIsNot(request, response)
  3810. def test_responseType(self):
  3811. """
  3812. L{dns._responseFromMessage} returns a new instance of C{cls}
  3813. """
  3814. class SuppliedClass(object):
  3815. id = 1
  3816. queries = []
  3817. expectedClass = dns.Message
  3818. self.assertIsInstance(
  3819. dns._responseFromMessage(responseConstructor=expectedClass,
  3820. message=SuppliedClass()),
  3821. expectedClass
  3822. )
  3823. def test_responseId(self):
  3824. """
  3825. L{dns._responseFromMessage} copies the C{id} attribute of the original
  3826. message.
  3827. """
  3828. self.assertEqual(
  3829. 1234,
  3830. dns._responseFromMessage(responseConstructor=dns.Message,
  3831. message=dns.Message(id=1234)).id
  3832. )
  3833. def test_responseAnswer(self):
  3834. """
  3835. L{dns._responseFromMessage} sets the C{answer} flag to L{True}
  3836. """
  3837. request = dns.Message()
  3838. response = dns._responseFromMessage(responseConstructor=dns.Message,
  3839. message=request)
  3840. self.assertEqual(
  3841. (False, True),
  3842. (request.answer, response.answer)
  3843. )
  3844. def test_responseQueries(self):
  3845. """
  3846. L{dns._responseFromMessage} copies the C{queries} attribute of the
  3847. original message.
  3848. """
  3849. request = dns.Message()
  3850. expectedQueries = [object(), object(), object()]
  3851. request.queries = expectedQueries[:]
  3852. self.assertEqual(
  3853. expectedQueries,
  3854. dns._responseFromMessage(responseConstructor=dns.Message,
  3855. message=request).queries
  3856. )
  3857. def test_responseKwargs(self):
  3858. """
  3859. L{dns._responseFromMessage} accepts other C{kwargs} which are assigned
  3860. to the new message before it is returned.
  3861. """
  3862. self.assertEqual(
  3863. 123,
  3864. dns._responseFromMessage(
  3865. responseConstructor=dns.Message, message=dns.Message(),
  3866. rCode=123).rCode
  3867. )
  3868. class Foo(object):
  3869. """
  3870. An example class for use in L{dns._compactRepr} tests.
  3871. It follows the pattern of initialiser settable flags, fields and sections
  3872. found in L{dns.Message} and L{dns._EDNSMessage}.
  3873. """
  3874. def __init__(self,
  3875. field1=1, field2=2, alwaysShowField='AS',
  3876. flagTrue=True, flagFalse=False, section1=None):
  3877. """
  3878. Set some flags, fields and sections as public attributes.
  3879. """
  3880. self.field1 = field1
  3881. self.field2 = field2
  3882. self.alwaysShowField = alwaysShowField
  3883. self.flagTrue = flagTrue
  3884. self.flagFalse = flagFalse
  3885. if section1 is None:
  3886. section1 = []
  3887. self.section1 = section1
  3888. def __repr__(self):
  3889. """
  3890. Call L{dns._compactRepr} to generate a string representation.
  3891. """
  3892. return dns._compactRepr(
  3893. self,
  3894. alwaysShow='alwaysShowField'.split(),
  3895. fieldNames='field1 field2 alwaysShowField'.split(),
  3896. flagNames='flagTrue flagFalse'.split(),
  3897. sectionNames='section1 section2'.split()
  3898. )
  3899. class CompactReprTests(unittest.SynchronousTestCase):
  3900. """
  3901. Tests for L[dns._compactRepr}.
  3902. """
  3903. messageFactory = Foo
  3904. def test_defaults(self):
  3905. """
  3906. L{dns._compactRepr} omits field values and sections which have the
  3907. default value. Flags which are True are always shown.
  3908. """
  3909. self.assertEqual(
  3910. "<Foo alwaysShowField='AS' flags=flagTrue>",
  3911. repr(self.messageFactory())
  3912. )
  3913. def test_flagsIfSet(self):
  3914. """
  3915. L{dns._compactRepr} displays flags if they have a non-default value.
  3916. """
  3917. m = self.messageFactory(flagTrue=True, flagFalse=True)
  3918. self.assertEqual(
  3919. '<Foo '
  3920. "alwaysShowField='AS' "
  3921. 'flags=flagTrue,flagFalse'
  3922. '>',
  3923. repr(m),
  3924. )
  3925. def test_nonDefautFields(self):
  3926. """
  3927. L{dns._compactRepr} displays field values if they differ from their
  3928. defaults.
  3929. """
  3930. m = self.messageFactory(field1=10, field2=20)
  3931. self.assertEqual(
  3932. '<Foo '
  3933. 'field1=10 '
  3934. 'field2=20 '
  3935. "alwaysShowField='AS' "
  3936. 'flags=flagTrue'
  3937. '>',
  3938. repr(m),
  3939. )
  3940. def test_nonDefaultSections(self):
  3941. """
  3942. L{dns._compactRepr} displays sections which differ from their defaults.
  3943. """
  3944. m = self.messageFactory()
  3945. m.section1 = [1, 1, 1]
  3946. m.section2 = [2, 2, 2]
  3947. self.assertEqual(
  3948. '<Foo '
  3949. "alwaysShowField='AS' "
  3950. 'flags=flagTrue '
  3951. 'section1=[1, 1, 1] '
  3952. 'section2=[2, 2, 2]'
  3953. '>',
  3954. repr(m),
  3955. )