1 module heaploop.networking.dns;
2 import duv.c;
3 import duv.types;
4 import heaploop.looping;
5 import std.string : toStringz;
6 
7 private:
8 public:
9 
10 enum AddressFamily {
11     None,
12     INETv4,
13     INETv6
14 }
15 
16 class NetworkAddress {
17     private:
18         string _ip;
19         int _port;
20         AddressFamily _family;
21 
22     package:
23         this(string ip, int port, AddressFamily family) {
24             _ip = ip;
25             _port = port;
26             _family = family;
27         }
28 
29     public:
30 
31         @property{
32 
33             string IP() {
34                 return _ip;
35             }
36 
37             int port() {
38                 return _port;
39             }
40 
41             AddressFamily family() {
42                 return _family;
43             }
44         }
45 }
46 
47 
48 
49 class DnsClient : Looper {
50 
51     private:
52         Loop _loop;
53         class resolveOperation : OperationContext!DnsClient {
54             public:
55                 NetworkAddress[] addresses;
56                 this(DnsClient client) {
57                     super(client);
58                 }
59         }
60 
61     public:
62         this(Loop loop = Loop.current) {
63             _loop = loop;
64         }
65 
66         @property Loop loop() {
67             return _loop;
68         }
69 
70         public NetworkAddress[] resolveHost(string host) {
71             auto wc = new resolveOperation(this);
72             duv_getaddrinfo(this.loop.handle, wc, host, null, function (ctx, status, duv_addresses) {
73                     auto wc = cast(resolveOperation)ctx;
74                     if(duv_addresses !is null) {
75                         foreach(addr; duv_addresses) {
76                             AddressFamily family = void;
77                             switch(addr.family) {
78                                 case duv_addr_family.INETv4:
79                                     family = AddressFamily.INETv4;
80                                 break;
81                                 case duv_addr_family.INETv6:
82                                     family = AddressFamily.INETv6;
83                                 break;
84                                 default:
85                                     assert(0, "Unknown address family, failure in uv.d?");
86                             }
87                             NetworkAddress address = new NetworkAddress(addr.ip, 0, family);
88                             wc.addresses ~= address;
89                         }
90                     }
91                     wc.update(status);
92                     wc.resume();
93             });
94             scope (exit) delete wc;
95             wc.yield;
96             wc.completed;
97             return wc.addresses;
98         }
99 }
100 
101 class Dns {
102     public:
103         static NetworkAddress[] resolveHost(string host) {
104             return new DnsClient().resolveHost(host);
105         }
106 }