//リソース定義(Dat)で初期化する場合 public DnsCache(Logger logger, OneOption oneOption, Dat dat, string dName) { const uint ttl = 0; //有効期限なし var ns = "";//SOA追加時に使用するため、NSレコードを見つけたときにサーバ名を保存しておく //オプションを読み込んで、ローカルデータを初期化する //this.oneOption = oneOption; _soaExpire = (uint)(int)oneOption.GetValue("soaExpire"); DomainName = dName; foreach (var o in dat) { if (o.Enable) { var type = Convert.ToInt32(o.StrList[0]); var name = o.StrList[1]; var alias = o.StrList[2]; var ip = new Ip(o.StrList[3]); var n = Convert.ToInt32(o.StrList[4]); var dnsType = DnsType.A; if (type == 1) { dnsType = DnsType.Ns; } else if (type == 2) { dnsType = DnsType.Mx; } else if (type == 3) { dnsType = DnsType.Cname; } else if (type == 4) { dnsType = DnsType.Aaaa; } var priority = (ushort)n; //uint addr = ip.AddrV4; //class Ip -> uint; //最後に.がついていない場合、ドメイン名を追加する if (name.LastIndexOf('.') != name.Length - 1) { name = name + "." + DomainName; } if (alias.LastIndexOf('.') != alias.Length - 1) { alias = alias + "." + DomainName; } //CNAME以外は、PTRレコードを自動的に生成する if (dnsType != DnsType.Cname) { //PTR名を作成 [例] 192.168.0.1 -> 1.0.168.192.in-addr.arpa; if (ip.InetKind == InetKind.V4) { //IPv4 string ptrName = string.Format("{0}.{1}.{2}.{3}.in-addr.arpa.", ip.IpV4[3], ip.IpV4[2], ip.IpV4[1], ip.IpV4[0]); Add(new OneRR(ptrName, DnsType.Ptr, ttl, DnsUtil.Str2DnsName(name))); } else { //IPv6 var sb = new StringBuilder(); foreach (var a in ip.IpV6) { sb.Append(string.Format("{0:x4}", a)); } string ipStr = sb.ToString(); if (ipStr.Length == 32) { sb = new StringBuilder(); for (int e = 31; e >= 0; e--) { sb.Append(ipStr[e]); sb.Append('.'); } Add(new OneRR(sb + "ip6.arpa.", DnsType.Ptr, ttl, DnsUtil.Str2DnsName(name))); } } } //データベースへの追加 if (dnsType == DnsType.A) { if (ip.InetKind == InetKind.V4) { //ネットワークバイト配列の取得 Add(new OneRR(name, DnsType.A, ttl, ip.NetBytes())); } else { logger.Set(LogKind.Error, null, 19, string.Format("address {0}", ip)); } } else if (dnsType == DnsType.Aaaa) { if (ip.InetKind == InetKind.V6) { Add(new OneRR(name, DnsType.Aaaa, ttl, ip.NetBytes())); } else { logger.Set(LogKind.Error, null, 20, string.Format("address {0}", ip)); } } else if (dnsType == DnsType.Ns) { ns = name;//SOA追加時に使用するため、ネームサーバの名前を保存する // A or AAAAレコードも追加 Add(new OneRR(name, (ip.InetKind == InetKind.V4) ? DnsType.A : DnsType.Aaaa, ttl, ip.NetBytes())); Add(new OneRR(DomainName, DnsType.Ns, ttl, DnsUtil.Str2DnsName(name))); } else if (dnsType == DnsType.Mx) { // A or AAAAレコードも追加 Add(new OneRR(name, DnsType.A, ttl, ip.NetBytes())); //プライオリィ byte[] dataName = DnsUtil.Str2DnsName(name);//DNS名前形式に変換 byte[] data = Bytes.Create(Util.htons(priority), dataName); Add(new OneRR(DomainName, DnsType.Mx, ttl, data)); } else if (dnsType == DnsType.Cname) { Add(new OneRR(alias, DnsType.Cname, ttl, DnsUtil.Str2DnsName(name))); } } //SOAレコードの追加 if (ns != "") { //NSサーバ名が必須 var soaMail = (string)oneOption.GetValue("soaMail"); soaMail.Replace('@', '.');//@を.に置き換える soaMail = soaMail + ".";//最後に.を追加する var soaSerial = (uint)(int)oneOption.GetValue("soaSerial"); var soaRefresh = (uint)(int)oneOption.GetValue("soaRefresh"); var soaRetry = (uint)(int)oneOption.GetValue("soaRetry"); var soaExpire = (uint)(int)oneOption.GetValue("soaExpire"); var soaMinimum = (uint)(int)oneOption.GetValue("soaMinimum"); byte[] data = Bytes.Create( DnsUtil.Str2DnsName(ns), DnsUtil.Str2DnsName(soaMail), Util.htonl(soaSerial), Util.htonl(soaRefresh), Util.htonl(soaRetry), Util.htonl(soaExpire), Util.htonl(soaMinimum)); Add(new OneRR(DomainName, DnsType.Soa, ttl, data)); } } }