예제 #1
0
파일: DnsCache.cs 프로젝트: jsakamoto/bjd5
        //リソース定義(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));
                }
            }
        }