[bind10-dev] msgq and dhcp4
Stephen Morris
stephen at isc.org
Mon May 14 15:40:05 UTC 2012
On 11/05/12 17:36, Tomek Mrugalski wrote:
> Hi,
>
> I'm trying to integrate dhcp4 into msgq support. Currently it is a
> stand-alone component that just happens to be in bind10 source
> tree.
>
> Current code creates sockets using standard POSIX calls, not asio.
> The reason it was written that was is that we need to do extra DHCP
> tricks, like binding sockets to specific interface, joining
> multicast groups or eventually receiving/sending data to hosts that
> do not have address configured yet. Also, we need to receive/send
> packets using recvmsg()/sendmsg().
>
> When I tried to mimic auth or resolver implementation, I got stuck
> when calling io_service.run(). I created ModuleCCSession with
> config and command handlers and started session. However, when I
> called io_service.run(), it blocks, so I can't get into main dhcp
> loop.
By itself, io_service.run() never exits. It executes event handlers
as the events occur. These handlers should queue new operations (e.g.
reads, writes, timers) with associated handlers and exit.
If necessary, the handlers can cause run() to exit by calling
io_service.stop().
> It seems that current traffic handling model is not compatible with
> msgq. Doh!
I don't think it is.
> During normal dhcp operation 3 types of events may occur: 1. a
> packet was received over one of many sockets (typically one socket
> per interface, but it may vary) 2. a timer expires (e.g. lease
> expires) 3. a command or new config arrives over msgq
>
> Doing 1 and 2 is easy (select() + calculated timeout). Doing 1-3 is
> more complicated.
>
> I have couple of questions regarding that matter: 1. Is it possible
> to use recvmsg/sendmsg call with asio? How to do that?
Call the socket's async_send_to()/async_receive_from() and specify a
handler. When the send or receive call completes, run() will call
your handler.
> 2. How to organize data reception? Ideally, I would like to have
> something that waits until first packet arrives or timer is
> expired (basically a select() equivalent) or process_one_event()
> and would call it in a loop until shutdown conditions are detected.
> Is there such a thing in asio?
Ideally there should be an async_receive_with_timeout() method, but
there appears not to be. You can set up a timer and specify a handler
for the timeout. Then call async_receive_from(). When one of the
operations completes, have its handler cancel the other operation
before performing whatever processing is necessary. This would
usually end with starting another timer and another I/O.
src/lib/asiodns/io_fetch.cc may be a useful example.
> 3. Concurrency model. Taking into consideration current state of
> affairs, I think there are at least 2 possible ways forward: a)
> asio way. We will create sockets in our own special dhcp way and
> then use basic_datagram_socket::assign() to create asio wrappers
> around them. Then we will call io_service.run() (or run_one() in a
> loop). The problem I have with that approach is that I'm not sure
> how to use recvmsg to get details about the sender. I will keep
> looking at asio documentation and hopefully will find it out.
socket::async_recv_from() (where socket any of the socket classes)
takes as an argument an endpoint which receives the address of the sender.
> b) mixed way. We could fork()/pthread_create() and have separate
> process/thread for msgq handling and the main process for dhcp
> operations. This approach would be much easier to implement now,
> but in the long run would require more work as data incoming via
> msgq be more complicated.
I think you are right. Ideally we should have an asio interface into
the message queue.
Stephen
More information about the bind10-dev
mailing list