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 }