diff --git a/README.md b/README.md index 457d0c1..870c2a0 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ $stackableResolver = new yswery\DNS\Resolver\StackableResolver([$jsonResolver, $ // Create the eventDispatcher and add the event subscribers $eventDispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher(); -$eventDispatcher->addSubscriber(new \yswery\DNS\EchoLogger()); +$eventDispatcher->addSubscriber(new \yswery\DNS\Event\Subscriber\EchoLogger()); // Create a new instance of Server class $server = new yswery\DNS\Server($stackableResolver, $eventDispatcher); diff --git a/composer.json b/composer.json index 7f10fe9..a057fd7 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ } ], "require": { - "react/socket": "^0.8.10", + "react/socket": "~1.2", "react/datagram": "^1.4", "php": "~7.1", "ext-json": "~1.0", diff --git a/docs/Event-Dispatcher.md b/docs/Event-Dispatcher.md index a6a187c..71191ba 100644 --- a/docs/Event-Dispatcher.md +++ b/docs/Event-Dispatcher.md @@ -38,9 +38,11 @@ $eventDispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher(); $eventDispatcher->addSubscriber(new ExampleEventSubscriber()); $server = new Server(new JsonResolver('./record.json'), $eventDispatcher); ``` + ## Supported events * `Events::SERVER_START` - Server is started and listening for queries. +* `Events::SERVER_START_FAIL` - The server failed to start at all. * `Events::SERVER_EXCEPTION` - Exception is thrown when processing and responding to query. * `Events::MESSAGE` - Message is received from client in raw format. * `Events::QUERY_RECEIVE` - Query is parsed to dns message class. diff --git a/src/Resolver/AbstractResolver.php b/src/Resolver/AbstractResolver.php index 9cc8ce3..57783c7 100644 --- a/src/Resolver/AbstractResolver.php +++ b/src/Resolver/AbstractResolver.php @@ -146,7 +146,7 @@ protected function findWildcardEntry(ResourceRecord $query): array } if (array_key_exists('*', $array)) { - $wildcards = $array['*'][$query->getClass()][$query->getType()] ?? null; + $wildcards = $array['*'][$query->getClass()][$query->getType()] ?? []; } } diff --git a/src/Server.php b/src/Server.php index 3995b52..21c8d24 100644 --- a/src/Server.php +++ b/src/Server.php @@ -15,6 +15,7 @@ use React\Datagram\SocketInterface; use React\EventLoop\LoopInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\EventDispatcher\Event; use yswery\DNS\Event\ServerExceptionEvent; use yswery\DNS\Event\MessageEvent; use yswery\DNS\Event\QueryReceiveEvent; @@ -60,7 +61,7 @@ class Server * * @throws \Exception */ - public function __construct(ResolverInterface $resolver, EventDispatcherInterface $dispatcher, string $ip = '0.0.0.0', int $port = 53) + public function __construct(ResolverInterface $resolver, ?EventDispatcherInterface $dispatcher = null, string $ip = '0.0.0.0', int $port = 53) { if (!function_exists('socket_create') || !extension_loaded('sockets')) { throw new \Exception('Socket extension or socket_create() function not found.'); @@ -74,10 +75,10 @@ public function __construct(ResolverInterface $resolver, EventDispatcherInterfac $this->loop = \React\EventLoop\Factory::create(); $factory = new \React\Datagram\Factory($this->loop); $factory->createServer($this->ip.':'.$this->port)->then(function (Socket $server) { - $this->dispatcher->dispatch(Events::SERVER_START, new ServerStartEvent($server)); + $this->dispatch(Events::SERVER_START, new ServerStartEvent($server)); $server->on('message', [$this, 'onMessage']); })->otherwise(function (\Exception $exception) { - $this->dispatcher->dispatch(Events::SERVER_START_FAIL, new ServerExceptionEvent($exception)); + $this->dispatch(Events::SERVER_START_FAIL, new ServerExceptionEvent($exception)); }); } @@ -100,10 +101,10 @@ public function start(): void public function onMessage(string $message, string $address, SocketInterface $socket) { try { - $this->dispatcher->dispatch(Events::MESSAGE, new MessageEvent($socket, $address, $message)); + $this->dispatch(Events::MESSAGE, new MessageEvent($socket, $address, $message)); $socket->send($this->handleQueryFromStream($message), $address); } catch (\Exception $exception) { - $this->dispatcher->dispatch(Events::SERVER_EXCEPTION, new ServerExceptionEvent($exception)); + $this->dispatch(Events::SERVER_EXCEPTION, new ServerExceptionEvent($exception)); } } @@ -119,7 +120,7 @@ public function onMessage(string $message, string $address, SocketInterface $soc public function handleQueryFromStream(string $buffer): string { $message = Decoder::decodeMessage($buffer); - $this->dispatcher->dispatch(Events::QUERY_RECEIVE, new QueryReceiveEvent($message)); + $this->dispatch(Events::QUERY_RECEIVE, new QueryReceiveEvent($message)); $responseMessage = clone $message; $responseMessage->getHeader() @@ -131,15 +132,14 @@ public function handleQueryFromStream(string $buffer): string $answers = $this->resolver->getAnswer($responseMessage->getQuestions()); $responseMessage->setAnswers($answers); $this->needsAdditionalRecords($responseMessage); - - $this->dispatcher->dispatch(Events::QUERY_RESPONSE, new QueryResponseEvent($responseMessage)); + $this->dispatch(Events::QUERY_RESPONSE, new QueryResponseEvent($responseMessage)); return Encoder::encodeMessage($responseMessage); } catch (UnsupportedTypeException $e) { $responseMessage ->setAnswers([]) ->getHeader()->setRcode(Header::RCODE_NOT_IMPLEMENTED); - $this->dispatcher->dispatch(Events::QUERY_RESPONSE, new QueryResponseEvent($responseMessage)); + $this->dispatch(Events::QUERY_RESPONSE, new QueryResponseEvent($responseMessage)); return Encoder::encodeMessage($responseMessage); } @@ -238,4 +238,19 @@ private function isAuthoritative(array $query): bool return $authoritative; } + + /** + * @param string $eventName + * @param Event|null $event + * + * @return Event|null + */ + private function dispatch($eventName, ?Event $event = null): ?Event + { + if (null === $this->dispatcher) { + return null; + } + + return $this->dispatcher->dispatch($eventName, $event); + } }