Commit abd65c5b authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[2903] make sure UDPServer don't die due to a failure of close().

also don't stop receiving due to errors from async_receive_from().
some other minor cleanups are made too.
parent c7fd8cf0
......@@ -75,6 +75,14 @@ If you see a single occurrence of this message, it probably does not
indicate any significant problem, but if it is logged often, it is probably
a good idea to inspect your network traffic.
% ASIODNS_UDP_RECEIVE_FAIL failed to accept UDP DNS packet: %1
Receiving a UDP packet from a DNS client failed due to an error that
could happen but should be very rare. The server still keeps
receiving UDP packets on this socket. The reason for the error is
included in the log message. This log message is basically not
expected to appear at all in practice; if it does, there may be some
system level failure and other system logs may have to be checked.
% ASIODNS_UDP_SYNC_SEND_FAIL Error sending UDP packet to %1: %2
The low-level ASIO library reported an error when trying to send a UDP
packet in synchronous UDP mode. See ASIODNS_UDP_ASYNC_SEND_FAIL for
......
......@@ -212,14 +212,19 @@ UDPServer::operator()(asio::error_code ec, size_t length) {
buffer(data_->data_.get(), MAX_LENGTH), *data_->sender_,
*this);
// Abort on fatal errors
// TODO: add log
// See TCPServer::operator() for details on error handling.
if (ec) {
using namespace asio::error;
if (ec.value() != would_block && ec.value() != try_again &&
ec.value() != interrupted) {
const error_code::value_type err_val = ec.value();
if (err_val == operation_aborted ||
err_val == bad_descriptor) {
return;
}
if (err_val != would_block && err_val != try_again &&
err_val != interrupted) {
LOG_ERROR(logger, ASIODNS_UDP_RECEIVE_FAIL).
arg(ec.message());
}
}
} while (ec || length == 0);
......@@ -270,7 +275,7 @@ UDPServer::operator()(asio::error_code ec, size_t length) {
// If we don't have a DNS Lookup provider, there's no point in
// continuing; we exit the coroutine permanently.
if (data_->lookup_callback_ == NULL) {
CORO_YIELD return;
return;
}
// Instantiate objects that will be needed by the
......@@ -287,7 +292,7 @@ UDPServer::operator()(asio::error_code ec, size_t length) {
// The 'done_' flag indicates whether we have an answer
// to send back. If not, exit the coroutine permanently.
if (!data_->done_) {
CORO_YIELD return;
return;
}
// Call the DNS answer provider to render the answer into
......@@ -322,6 +327,10 @@ UDPServer::asyncLookup() {
/// Stop the UDPServer
void
UDPServer::stop() {
// passing error_code to avoid getting exception; we simply ignore any
// error on close().
asio::error_code ec;
/// Using close instead of cancel, because cancel
/// will only cancel the asynchronized event already submitted
/// to io service, the events post to io service after
......@@ -330,7 +339,7 @@ UDPServer::stop() {
/// for it won't be scheduled by io service not matter it is
/// submit to io service before or after close call. And we will
// get bad_descriptor error.
data_->socket_->close();
data_->socket_->close(ec);
}
/// Post this coroutine on the ASIO service queue so that it will
......@@ -339,7 +348,7 @@ UDPServer::stop() {
void
UDPServer::resume(const bool done) {
data_->done_ = done;
data_->io_.post(*this);
data_->io_.post(*this); // this can throw, but can be considered fatal.
}
} // namespace asiodns
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment