PageRenderTime 42ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/code/classes/Daemon/DNSd/TCP_Client.class.php

https://github.com/blekkzor/pinetd2
PHP | 113 lines | 85 code | 19 blank | 9 comment | 9 complexity | 182fa6b5476da537898f30db703384c1 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. namespace Daemon\DNSd;
  3. use pinetd\Logger;
  4. class TCP_Client extends \pinetd\TCP\Client {
  5. private $engine;
  6. private $syncmode = false;
  7. public function welcomeUser() {
  8. $this->setMsgEnd('');
  9. return true; // nothing to say
  10. }
  11. public function sendBanner() {
  12. $class = relativeclass($this, 'Engine');
  13. $this->engine = new $class($this, $this->IPC, $this->IPC->getLocalConfig());
  14. }
  15. protected function receivePacket($pkt) {
  16. if (substr($pkt, 0, 5) == 'BEGIN') {
  17. $pkt = substr($pkt, 5);
  18. // read packet
  19. list(,$stamp) = @unpack('N', substr($pkt, -24, 4));
  20. $node = substr($pkt, 0, -24);
  21. // check signature
  22. $peer = $this->IPC->getUpdateSignature($node);
  23. if (is_null($peer)) {
  24. // unknown peer
  25. Logger::log(Logger::LOG_WARN, 'Unknown DNS peer name (remember, those are case-sensitive) from client at '.$this->peer[0]);
  26. $resp = 'BAD';
  27. $this->sendMsg(pack('n', strlen($resp)).$resp);
  28. $this->close();
  29. return;
  30. }
  31. $signature = sha1(substr($pkt, 0, -20).$peer['Signature'], true);
  32. if ($signature != substr($pkt, -20)) {
  33. // bad signature
  34. Logger::log(Logger::LOG_WARN, 'Bad signature from client at '.$this->peer[0]);
  35. $resp = 'BAD';
  36. $this->sendMsg(pack('n', strlen($resp)).$resp);
  37. $this->close();
  38. return;
  39. }
  40. // check stamp
  41. if (abs(time() - $stamp) > 5) {
  42. // bad timestamp
  43. $resp = 'BAD';
  44. $this->sendMsg(pack('n', strlen($resp)).$resp);
  45. $this->close();
  46. return;
  47. }
  48. switch($peer['Type']) {
  49. case 'control':
  50. $class = 'TCP_Peer';
  51. break;
  52. case 'slave':
  53. $class = 'TCP_Slave';
  54. break;
  55. default:
  56. Logger::log(Logger::LOG_WARN, 'Bad type for identified client at '.$this->peer[0]);
  57. $resp = 'BAD';
  58. $this->sendMsg(pack('n', strlen($resp)).$resp);
  59. $this->close();
  60. return;
  61. }
  62. // auth OK, enable advanced protocol
  63. $this->syncmode = true;
  64. $resp = $this->IPC->getNodeName().pack('N', time());
  65. // add signature
  66. $resp .= sha1($resp.$peer['Signature'], true);
  67. $this->sendMsg(pack('n', strlen($resp)).$resp);
  68. if (!$this->IPC->forkIfYouCan($this->fd, $this->peer, $class, $peer['Type'])) {
  69. // couldn't fork...
  70. Logger::log(Logger::LOG_WARN, 'Could not fork client at '.$this->peer[0]);
  71. $resp = 'BAD';
  72. $this->sendMsg(pack('n', strlen($resp)).$resp);
  73. $this->close();
  74. return;
  75. }
  76. return;
  77. }
  78. $this->engine->handlePacket($pkt, $this->peer);
  79. }
  80. public function sendReply($pkt, $peer) {
  81. $this->sendMsg(pack('n', strlen($pkt)) . $pkt);
  82. }
  83. protected function parseBuffer() {
  84. while($this->ok) {
  85. if (strlen($this->buf) < 2) break;
  86. $len = unpack('n', $this->buf);
  87. $len = $len[1];
  88. if (strlen($this->buf) < (2+$len)) break;
  89. $dat = substr($this->buf, 2, $len);
  90. $this->buf = substr($this->buf, $len+2);
  91. $this->receivePacket($dat);
  92. }
  93. }
  94. }