PageRenderTime 54ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/React/Tests/Dns/Protocol/ParserTest.php

https://github.com/jurajseffer/react
PHP | 246 lines | 198 code | 43 blank | 5 comment | 0 complexity | 5fe89c32e4eccef1a0466daf5f563406 MD5 | raw file
  1. <?php
  2. namespace React\Tests\Dns\Protocol;
  3. use React\Dns\Protocol\Parser;
  4. use React\Dns\Model\Message;
  5. class ParserTest extends \PHPUnit_Framework_TestCase
  6. {
  7. /**
  8. * @dataProvider provideConvertTcpDumpToBinary
  9. */
  10. public function testConvertTcpDumpToBinary($expected, $data)
  11. {
  12. $this->assertSame($expected, $this->convertTcpDumpToBinary($data));
  13. }
  14. public function provideConvertTcpDumpToBinary()
  15. {
  16. return array(
  17. array(chr(0x72).chr(0x62), "72 62"),
  18. array(chr(0x72).chr(0x62).chr(0x01).chr(0x00), "72 62 01 00"),
  19. array(chr(0x72).chr(0x62).chr(0x01).chr(0x00).chr(0x00).chr(0x01), "72 62 01 00 00 01"),
  20. array(chr(0x01).chr(0x00).chr(0x01), "01 00 01"),
  21. );
  22. }
  23. public function testParseRequest()
  24. {
  25. $data = "";
  26. $data .= "72 62 01 00 00 01 00 00 00 00 00 00"; // header
  27. $data .= "04 69 67 6f 72 02 69 6f 00"; // question: igor.io
  28. $data .= "00 01 00 01"; // question: type A, class IN
  29. $data = $this->convertTcpDumpToBinary($data);
  30. $request = new Message();
  31. $parser = new Parser();
  32. $parser->parseChunk($data, $request);
  33. $header = $request->header;
  34. $this->assertSame(0x7262, $header->get('id'));
  35. $this->assertSame(1, $header->get('qdCount'));
  36. $this->assertSame(0, $header->get('anCount'));
  37. $this->assertSame(0, $header->get('nsCount'));
  38. $this->assertSame(0, $header->get('arCount'));
  39. $this->assertSame(0, $header->get('qr'));
  40. $this->assertSame(Message::OPCODE_QUERY, $header->get('opcode'));
  41. $this->assertSame(0, $header->get('aa'));
  42. $this->assertSame(0, $header->get('tc'));
  43. $this->assertSame(1, $header->get('rd'));
  44. $this->assertSame(0, $header->get('ra'));
  45. $this->assertSame(0, $header->get('z'));
  46. $this->assertSame(Message::RCODE_OK, $header->get('rcode'));
  47. $this->assertCount(1, $request->questions);
  48. $this->assertSame('igor.io', $request->questions[0]['name']);
  49. $this->assertSame(Message::TYPE_A, $request->questions[0]['type']);
  50. $this->assertSame(Message::CLASS_IN, $request->questions[0]['class']);
  51. }
  52. public function testParseResponse()
  53. {
  54. $data = "";
  55. $data .= "72 62 81 80 00 01 00 01 00 00 00 00"; // header
  56. $data .= "04 69 67 6f 72 02 69 6f 00"; // question: igor.io
  57. $data .= "00 01 00 01"; // question: type A, class IN
  58. $data .= "c0 0c"; // answer: offset pointer to igor.io
  59. $data .= "00 01 00 01"; // answer: type A, class IN
  60. $data .= "00 01 51 80"; // answer: ttl 86400
  61. $data .= "00 04"; // answer: rdlength 4
  62. $data .= "b2 4f a9 83"; // answer: rdata 178.79.169.131
  63. $data = $this->convertTcpDumpToBinary($data);
  64. $response = new Message();
  65. $parser = new Parser();
  66. $parser->parseChunk($data, $response);
  67. $header = $response->header;
  68. $this->assertSame(0x7262, $header->get('id'));
  69. $this->assertSame(1, $header->get('qdCount'));
  70. $this->assertSame(1, $header->get('anCount'));
  71. $this->assertSame(0, $header->get('nsCount'));
  72. $this->assertSame(0, $header->get('arCount'));
  73. $this->assertSame(1, $header->get('qr'));
  74. $this->assertSame(Message::OPCODE_QUERY, $header->get('opcode'));
  75. $this->assertSame(0, $header->get('aa'));
  76. $this->assertSame(0, $header->get('tc'));
  77. $this->assertSame(1, $header->get('rd'));
  78. $this->assertSame(1, $header->get('ra'));
  79. $this->assertSame(0, $header->get('z'));
  80. $this->assertSame(Message::RCODE_OK, $header->get('rcode'));
  81. $this->assertCount(1, $response->questions);
  82. $this->assertSame('igor.io', $response->questions[0]['name']);
  83. $this->assertSame(Message::TYPE_A, $response->questions[0]['type']);
  84. $this->assertSame(Message::CLASS_IN, $response->questions[0]['class']);
  85. $this->assertCount(1, $response->answers);
  86. $this->assertSame('igor.io', $response->answers[0]->name);
  87. $this->assertSame(Message::TYPE_A, $response->answers[0]->type);
  88. $this->assertSame(Message::CLASS_IN, $response->answers[0]->class);
  89. $this->assertSame(86400, $response->answers[0]->ttl);
  90. $this->assertSame('178.79.169.131', $response->answers[0]->data);
  91. }
  92. public function testParseQuestionWithTwoQuestions()
  93. {
  94. $data = "";
  95. $data .= "04 69 67 6f 72 02 69 6f 00"; // question: igor.io
  96. $data .= "00 01 00 01"; // question: type A, class IN
  97. $data .= "03 77 77 77 04 69 67 6f 72 02 69 6f 00"; // question: www.igor.io
  98. $data .= "00 01 00 01"; // question: type A, class IN
  99. $data = $this->convertTcpDumpToBinary($data);
  100. $request = new Message();
  101. $request->header->set('qdCount', 2);
  102. $request->data = $data;
  103. $parser = new Parser();
  104. $parser->parseQuestion($request);
  105. $this->assertCount(2, $request->questions);
  106. $this->assertSame('igor.io', $request->questions[0]['name']);
  107. $this->assertSame(Message::TYPE_A, $request->questions[0]['type']);
  108. $this->assertSame(Message::CLASS_IN, $request->questions[0]['class']);
  109. $this->assertSame('www.igor.io', $request->questions[1]['name']);
  110. $this->assertSame(Message::TYPE_A, $request->questions[1]['type']);
  111. $this->assertSame(Message::CLASS_IN, $request->questions[1]['class']);
  112. }
  113. public function testParseAnswerWithInlineData()
  114. {
  115. $data = "";
  116. $data .= "04 69 67 6f 72 02 69 6f 00"; // answer: igor.io
  117. $data .= "00 01 00 01"; // answer: type A, class IN
  118. $data .= "00 01 51 80"; // answer: ttl 86400
  119. $data .= "00 04"; // answer: rdlength 4
  120. $data .= "b2 4f a9 83"; // answer: rdata 178.79.169.131
  121. $data = $this->convertTcpDumpToBinary($data);
  122. $response = new Message();
  123. $response->header->set('anCount', 1);
  124. $response->data = $data;
  125. $parser = new Parser();
  126. $parser->parseAnswer($response);
  127. $this->assertCount(1, $response->answers);
  128. $this->assertSame('igor.io', $response->answers[0]->name);
  129. $this->assertSame(Message::TYPE_A, $response->answers[0]->type);
  130. $this->assertSame(Message::CLASS_IN, $response->answers[0]->class);
  131. $this->assertSame(86400, $response->answers[0]->ttl);
  132. $this->assertSame('178.79.169.131', $response->answers[0]->data);
  133. }
  134. public function testParseResponseWithCnameAndOffsetPointers()
  135. {
  136. $data = "";
  137. $data .= "9e 8d 81 80 00 01 00 01 00 00 00 00"; // header
  138. $data .= "04 6d 61 69 6c 06 67 6f 6f 67 6c 65 03 63 6f 6d 00"; // question: mail.google.com
  139. $data .= "00 05 00 01"; // question: type CNAME, class IN
  140. $data .= "c0 0c"; // answer: offset pointer to mail.google.com
  141. $data .= "00 05 00 01"; // answer: type CNAME, class IN
  142. $data .= "00 00 a8 9c"; // answer: ttl 43164
  143. $data .= "00 0f"; // answer: rdlength 15
  144. $data .= "0a 67 6f 6f 67 6c 65 6d 61 69 6c 01 6c"; // answer: rdata googlemail.l.
  145. $data .= "c0 11"; // answer: rdata offset pointer to google.com
  146. $data = $this->convertTcpDumpToBinary($data);
  147. $response = new Message();
  148. $parser = new Parser();
  149. $parser->parseChunk($data, $response);
  150. $this->assertCount(1, $response->questions);
  151. $this->assertSame('mail.google.com', $response->questions[0]['name']);
  152. $this->assertSame(Message::TYPE_CNAME, $response->questions[0]['type']);
  153. $this->assertSame(Message::CLASS_IN, $response->questions[0]['class']);
  154. $this->assertCount(1, $response->answers);
  155. $this->assertSame('mail.google.com', $response->answers[0]->name);
  156. $this->assertSame(Message::TYPE_CNAME, $response->answers[0]->type);
  157. $this->assertSame(Message::CLASS_IN, $response->answers[0]->class);
  158. $this->assertSame(43164, $response->answers[0]->ttl);
  159. $this->assertSame('googlemail.l.google.com', $response->answers[0]->data);
  160. }
  161. public function testParseResponseWithTwoAnswers()
  162. {
  163. $data = "";
  164. $data .= "bc 73 81 80 00 01 00 02 00 00 00 00"; // header
  165. $data .= "02 69 6f 0d 77 68 6f 69 73 2d 73 65 72 76 65 72 73 03 6e 65 74 00";
  166. // question: io.whois-servers.net
  167. $data .= "00 01 00 01"; // question: type A, class IN
  168. $data .= "c0 0c"; // answer: offset pointer to io.whois-servers.net
  169. $data .= "00 05 00 01"; // answer: type CNAME, class IN
  170. $data .= "00 00 00 29"; // answer: ttl 41
  171. $data .= "00 0e"; // answer: rdlength 14
  172. $data .= "05 77 68 6f 69 73 03 6e 69 63 02 69 6f 00"; // answer: rdata whois.nic.io
  173. $data .= "c0 32"; // answer: offset pointer to whois.nic.io
  174. $data .= "00 01 00 01"; // answer: type CNAME, class IN
  175. $data .= "00 00 0d f7"; // answer: ttl 3575
  176. $data .= "00 04"; // answer: rdlength 4
  177. $data .= "c1 df 4e 98"; // answer: rdata 193.223.78.152
  178. $data = $this->convertTcpDumpToBinary($data);
  179. $response = new Message();
  180. $parser = new Parser();
  181. $parser->parseChunk($data, $response);
  182. $this->assertCount(1, $response->questions);
  183. $this->assertSame('io.whois-servers.net', $response->questions[0]['name']);
  184. $this->assertSame(Message::TYPE_A, $response->questions[0]['type']);
  185. $this->assertSame(Message::CLASS_IN, $response->questions[0]['class']);
  186. $this->assertCount(2, $response->answers);
  187. $this->assertSame('io.whois-servers.net', $response->answers[0]->name);
  188. $this->assertSame(Message::TYPE_CNAME, $response->answers[0]->type);
  189. $this->assertSame(Message::CLASS_IN, $response->answers[0]->class);
  190. $this->assertSame(41, $response->answers[0]->ttl);
  191. $this->assertSame('whois.nic.io', $response->answers[0]->data);
  192. $this->assertSame('whois.nic.io', $response->answers[1]->name);
  193. $this->assertSame(Message::TYPE_A, $response->answers[1]->type);
  194. $this->assertSame(Message::CLASS_IN, $response->answers[1]->class);
  195. $this->assertSame(3575, $response->answers[1]->ttl);
  196. $this->assertSame('193.223.78.152', $response->answers[1]->data);
  197. }
  198. private function convertTcpDumpToBinary($input)
  199. {
  200. // sudo ngrep -d en1 -x port 53
  201. return pack('H*', str_replace(' ', '', $input));
  202. }
  203. }