Asynchronous DNS resolver | |
C# .NET Core Tasks | |
Assigned: | 2.3.2023 |
Deadline: | 15.3.2023 12:00 (CET) |
Supervisor: | Martin Kruliš |
ReCodEx: | assignment |
Results: | w201 (32 threads), w202 (64 threads) |
speedup | points |
---|---|
1× or less | 0 |
1× to 2× | 1 |
2× to 4× | 2 |
4× or more | 3 |
(possible bonus) | +1 point |
The objective is to write a recursive DNS resolver in C# .NET Core using already implemented methods for individual DNS queries. Of course, all network operations will be simulated by mocks. And since DNS resolving is rather complex, we have simplified it significantly for this assignment:
mff.cuni.cz
, one must first resolve cuni.cz
and then ask it for the address of mff
). Your implementation will get an object implementing IDNSClient
interface. The interface will provide the following methods:
IReadOnlyList<IP4Addr> GetRootServers()
-- will give you the list IPs of root serversTask<IP4Addr> Resolve(IP4Addr server, string subDomain)
-- perform single resolving (you can ask specific server for immediate subdomain)Task<string> Reverse(IP4Addr server)
-- performs reverse translation (will give you the full domain name of an IP address); this might be handy if you implement some sort of cache and you need to quickly find out whether an IP address is still validYour job is to implement a class with IRecursiveResolver
interface, which has only one method -- Task<IP4Addr> ResolveRecursive(string domain)
. This method gets the full domain name and yields its address. File Serial.cs
holds a trivial implementation of the resolver. Your codes go into Solution.cs
file, which is also the only file you should submit.
All the interfaces yield Task
s, which might suggest a course of action. Besides low-level tasks, you may also employ async/await
approach. The main objective is to use parallelism to lower (average) query latency and increase throughput.
We would suggest implementing the following optimizations: First, when two similar queries are executed simultaneously (e.g., mff.cuni.cz
and ff.cuni.cz
) the common part may be resolved only once. It can save time by saving resources and it may reduce the latency of the query which was started later. Second, you may use whatever caching you deem necessary, but beware that the addresses may change in time. Therefore, you need to verify data from the cache (e.g., by reverse translation) before yielding the result.
On the other hand, it is expected that you will not employ any hacking techniques or aggressive methods that might work in the real world. E.g., you are forbidden from trying to guess the IP addresses of the server or scanning the entire IP range.
Your solution will be tested on .NET Core 7.0 (which is both in ReCodEx and on Parlab). The initial solution is in /home/_teaching/para/01-dns-netcore
or you may simply download it here. You may compile it using dotnet command:
$> dotnet build -c Release ./dns-netcore.sln
The compiled binary will appear in the ./bin
sub dir.
Please note that ReCodEx is only a first-instance verification. Your solution will be subjected to performance evaluation on Parlab after the deadline (all solutions are collected and tested together). It will be measured using 32
and 64
cores on w20x
machines. You may (and should) try it yourselves using
srun -c 32 -n 1 -p mpi-homo-short -A nprg42s ...
so you get some idea about your speedups (i.e., about how many points you could expect).