Opened 5 years ago

#13468 new Bugs

asio receive buffer overwritten before handler called

Reported by: Gary Bayliss <gary.bayliss@…> Owned by: chris_kohlhoff
Milestone: To Be Determined Component: asio
Version: Boost 1.66.0 Severity: Problem
Keywords: Cc:

Description

I am developing on linux CentOS6.8

Whilst using boost::asio::ip::udp::socket::async_receive_from, I have found that if packets arrive too quickly the receive buffer is overwritten before the handler is called, resulting in a loss of data.

In order to resolve this in my implementation I have modified epoll_reactor::descriptor_state::perform_io to only process one entry from the EPOLLIN queue as below marked +++

operation* epoll_reactor::descriptor_state::perform_io(uint32_t events)
{
  mutex_.lock();
  perform_io_cleanup_on_block_exit io_cleanup(reactor_);
  mutex::scoped_lock descriptor_lock(mutex_, mutex::scoped_lock::adopt_lock);

  // Exception operations must be processed first to ensure that any
  // out-of-band data is read before normal data.
  static const int flag[max_ops] = { EPOLLIN, EPOLLOUT, EPOLLPRI };
  for (int j = max_ops - 1; j >= 0; --j)
  {
    if (events & (flag[j] | EPOLLERR | EPOLLHUP))
    {
      try_speculative_[j] = true;
      while (reactor_op* op = op_queue_[j].front())
      {
        if (reactor_op::status status = op->perform())
        {
          op_queue_[j].pop();
          io_cleanup.ops_.push(op);
          if (status == reactor_op::done_and_exhausted)
          {
            try_speculative_[j] = false;
            break;
          }
+++       if ((events & EPOLLIN) && (flag[j] == EPOLLIN))
+++	  {
+++	    // only read one packet at a time
+++            break;
+++	  }
        }
        else
          break;
      }
    }
  }

The first operation will be returned for completion now. The others will be posted for later by the io_cleanup object's destructor. io_cleanup.first_op_ = io_cleanup.ops_.front(); io_cleanup.ops_.pop(); return io_cleanup.first_op_;

}

Change History (0)

Note: See TracTickets for help on using tickets.