I'm trying to write a python script that sends multiple DNS requests, using a different name server for each request.
Implementing a sequential solution is easy using dnspython but too slow for me. Adding concurrency using thread pool is not possible as, in my particular case, all requests use the same source port (REUSE_ADDRESS won't help here either).
For the above reasons I'm thinking about using the following solution (ditching the use of dnspython's resolver module but taking advantage of its message building and parsing modules):
- Allowing up to X requests to be in progress
- Send X requests simultaneously (just sending dns request packets using udp. Probably with added delay between sends to avoid bursts)
- A different thread wait for responses
- When a response arrives match it with the request (by address) and allow a new request to run
- If a response to request does not arrive within TIMEOUT seconds mark it as completed and allow a new request to run
My main issues here are:
- How to implement the task timeout easily
- Is it possible to implement it without the use of thread synchronization (e.g. using event loop?)
- Is there any existing library that can help implementing it (it really feels like I'm trying to reinvent the wheel here, I looked into the asycnio module but couldn't figure out a way to take advantage of it for my problem). Note that I don't want to use existing dns or network libraries as I need the flexibility of changing core functionality (e.g. using raw sockets, changing DNS header fields, etc.).
Did you try
aiodns
package? https://pypi.python.org/pypi/aiodns/For timeouts asyncio has standard
wait_for
coroutine (https://docs.python.org/3/library/asyncio-task.html#asyncio.wait_for).Using a simple select loop works well here. Here is a code snippet for completion: