Example #1
0
        public void パケット生成_MX()
        {
            //setUp

            //exercise
            //パケットの生成
            const ushort id = (ushort) 0xf00f;
            const bool qr = true; //応答
            const bool rd = false; //再帰要求(有効)
            const bool aa = true; //権限(あり)
            const bool ra = true;
            var sut = new PacketDns(id, qr, aa, rd, ra);
            sut.AddRr(RrKind.QD, new RrQuery("google.com.", DnsType.Mx));
            sut.AddRr(RrKind.AN, new RrMx("google.com.", 0xa7d, 10, "smtp.google.com."));
            sut.AddRr(RrKind.NS, new RrNs("google.com.", 0xa7d, "ns3.google.com."));
            //生成したパケットのバイト配列で、再度パケットクラスを生成する
            byte[] b = sut.GetBytes();
            var p = new PacketDns(b);

            //verify
            Assert.That(p.GetAa(), Is.EqualTo(true));
            Assert.That(p.GetId(), Is.EqualTo((ushort) 0xf00f));
            Assert.That(p.GetDnsType(), Is.EqualTo(DnsType.Mx));
            Assert.That(p.GetCount(RrKind.QD), Is.EqualTo(1));
            Assert.That(p.GetCount(RrKind.AN), Is.EqualTo(1));
            Assert.That(p.GetCount(RrKind.NS), Is.EqualTo(1));
            Assert.That(p.GetCount(RrKind.AR), Is.EqualTo(0));
            Assert.That(p.GetRcode(), Is.EqualTo((short) 0));

            //DEBUG
            //OneRr r = p.GetRr(RrKind.AN, 0);

            Assert.That(p.GetRr(RrKind.AN, 0).ToString(), Is.EqualTo(new RrMx("google.com.", 0xa7d, 10, "smtp.google.com.").ToString()));
            Assert.That(p.GetRr(RrKind.NS, 0).ToString(), Is.EqualTo(new RrNs("google.com.", 0xa7d, "ns3.google.com.").ToString()));
            //		Assert.That(p.GetRr(RrKind.NS, 1).ToString(), Is.EqualTo(new RrNs("google.com.", 0xa7d, "ns1.google.com.").ToString()));
            //		Assert.That(p.GetRr(RrKind.NS, 2).ToString(), Is.EqualTo(new RrNs("google.com.", 0xa7d, "ns4.google.com.").ToString()));
            //		Assert.That(p.GetRr(RrKind.NS, 3).ToString(), Is.EqualTo(new RrNs("google.com.", 0xa7d, "ns2.google.com.").ToString()));
            //
            //		Assert.That(p.GetRr(RrKind.AR, 0).ToString(), Is.EqualTo(new RrA("ns1.google.com.", 0xb5e, new Ip("216.239.32.10")).ToString()));
            //		Assert.That(p.GetRr(RrKind.AR, 1).ToString(), Is.EqualTo(new RrA("ns2.google.com.", 0xbde, new Ip("216.239.34.10")).ToString()));
            //		Assert.That(p.GetRr(RrKind.AR, 2).ToString(), Is.EqualTo(new RrA("ns3.google.com.", 0xaf5, new Ip("216.239.36.10")).ToString()));
            //		Assert.That(p.GetRr(RrKind.AR, 3).ToString(), Is.EqualTo(new RrA("ns4.google.com.", 0xab3, new Ip("216.239.38.10")).ToString()));
        }
Example #2
0
        public void パケット生成_A_NS()
        {
            //setUp

            //exercise
            //パケットの生成
            const ushort id = 0x0005;
            const bool qr = true; //応答
            const bool rd = true; //再帰要求(有効)
            const bool aa = false; //権限(なし)
            const bool ra = true;
            var sut = new PacketDns(id, qr, aa, rd, ra);
            sut.AddRr(RrKind.QD, new RrQuery("www.google.com.", DnsType.Aaaa));
            sut.AddRr(RrKind.NS, new RrNs("google.com.", 0xa7d, "ns3.google.com."));
            sut.AddRr(RrKind.NS, new RrNs("google.com.", 0xa7d, "ns1.google.com."));
            sut.AddRr(RrKind.NS, new RrNs("google.com.", 0xa7d, "ns4.google.com."));
            sut.AddRr(RrKind.NS, new RrNs("google.com.", 0xa7d, "ns2.google.com."));
            sut.AddRr(RrKind.AR, new RrA("ns1.google.com.", 0xb5e, new Ip("216.239.32.10")));
            sut.AddRr(RrKind.AR, new RrA("ns2.google.com.", 0xbde, new Ip("216.239.34.10")));
            sut.AddRr(RrKind.AR, new RrA("ns3.google.com.", 0xaf5, new Ip("216.239.36.10")));
            sut.AddRr(RrKind.AR, new RrA("ns4.google.com.", 0xab3, new Ip("216.239.38.10")));
            //生成したパケットのバイト配列で、再度パケットクラスを生成する
            var p = new PacketDns(sut.GetBytes());

            //verify
            Assert.That(p.GetAa(), Is.EqualTo(false));
            Assert.That(p.GetId(), Is.EqualTo((short) 0x0005));
            Assert.That(p.GetDnsType(), Is.EqualTo(DnsType.Aaaa));
            Assert.That(p.GetCount(RrKind.QD), Is.EqualTo(1));
            Assert.That(p.GetCount(RrKind.AN), Is.EqualTo(0));
            Assert.That(p.GetCount(RrKind.NS), Is.EqualTo(4));
            Assert.That(p.GetCount(RrKind.AR), Is.EqualTo(4));
            Assert.That(p.GetRcode(), Is.EqualTo((short) 0));
            Assert.That(p.GetRr(RrKind.NS, 0).ToString(), Is.EqualTo(new RrNs("google.com.", 0xa7d, "ns3.google.com.").ToString()));
            Assert.That(p.GetRr(RrKind.NS, 1).ToString(), Is.EqualTo(new RrNs("google.com.", 0xa7d, "ns1.google.com.").ToString()));
            Assert.That(p.GetRr(RrKind.NS, 2).ToString(), Is.EqualTo(new RrNs("google.com.", 0xa7d, "ns4.google.com.").ToString()));
            Assert.That(p.GetRr(RrKind.NS, 3).ToString(), Is.EqualTo(new RrNs("google.com.", 0xa7d, "ns2.google.com.").ToString()));

            Assert.That(p.GetRr(RrKind.AR, 0).ToString(), Is.EqualTo(new RrA("ns1.google.com.", 0xb5e, new Ip("216.239.32.10")).ToString()));
            Assert.That(p.GetRr(RrKind.AR, 1).ToString(), Is.EqualTo(new RrA("ns2.google.com.", 0xbde, new Ip("216.239.34.10")).ToString()));
            Assert.That(p.GetRr(RrKind.AR, 2).ToString(), Is.EqualTo(new RrA("ns3.google.com.", 0xaf5, new Ip("216.239.36.10")).ToString()));
            Assert.That(p.GetRr(RrKind.AR, 3).ToString(), Is.EqualTo(new RrA("ns4.google.com.", 0xab3, new Ip("216.239.38.10")).ToString()));
        }
Example #3
0
 public void パケット解釈_str2()
 {
     //exercise
     var sut = new PacketDns(TestUtil.HexStream2Bytes(Str2));
     //verify
     Assert.That(sut.GetId(), Is.EqualTo((short) 0x0004));
     Assert.That(sut.GetCount(RrKind.QD), Is.EqualTo(1));
     Assert.That(sut.GetCount(RrKind.AN), Is.EqualTo(1));
     Assert.That(sut.GetCount(RrKind.NS), Is.EqualTo(2));
     Assert.That(sut.GetCount(RrKind.AR), Is.EqualTo(2));
     Assert.That(sut.GetRcode(), Is.EqualTo((short) 0));
     Assert.That(sut.GetAa(), Is.EqualTo(false));
     Assert.That(sut.GetRd(), Is.EqualTo(true));
     Assert.That(sut.GetDnsType(), Is.EqualTo(DnsType.Soa));
     Assert.That(sut.GetRequestName(), Is.EqualTo("nifty.com."));
     Assert.That(sut.GetRr(RrKind.QD, 0).ToString(), Is.EqualTo((new RrQuery("nifty.com.", DnsType.Soa)).ToString()));
     Assert.That(sut.GetRr(RrKind.AN, 0).ToString(), Is.EqualTo((new RrSoa("nifty.com.", 0x616, "ons0.nifty.ad.jp", "hostmaster.nifty.ad.jp", 0x0bfe4128, 0xe10, 0x384, 0x36ee80, 0x384)).ToString()));
     Assert.That(sut.GetRr(RrKind.NS, 0).ToString(), Is.EqualTo((new RrNs("nifty.com.", 0x6d2, "ons0.nifty.ad.jp.")).ToString()));
     Assert.That(sut.GetRr(RrKind.NS, 1).ToString(), Is.EqualTo((new RrNs("nifty.com.", 0x6d2, "ons1.nifty.ad.jp.")).ToString()));
     Assert.That(sut.GetRr(RrKind.AR, 0).ToString(), Is.EqualTo((new RrA("ons0.nifty.ad.jp.", 0x712, new Ip("202.248.37.77"))).ToString()));
     Assert.That(sut.GetRr(RrKind.AR, 1).ToString(), Is.EqualTo((new RrA("ons1.nifty.ad.jp.", 0x6da, new Ip("202.248.20.156"))).ToString()));
 }
Example #4
0
 public void パケット解釈_str0()
 {
     //exercise
     var sut = new PacketDns(TestUtil.HexStream2Bytes(Str0));
     //verify
     Assert.That(sut.GetId(), Is.EqualTo((short) 0x0003));
     Assert.That(sut.GetCount(RrKind.QD), Is.EqualTo(1));
     Assert.That(sut.GetCount(RrKind.AN), Is.EqualTo(0));
     Assert.That(sut.GetCount(RrKind.NS), Is.EqualTo(4));
     Assert.That(sut.GetCount(RrKind.AR), Is.EqualTo(4));
     Assert.That(sut.GetRcode(), Is.EqualTo((short) 0));
     Assert.That(sut.GetAa(), Is.EqualTo(false));
     Assert.That(sut.GetRd(), Is.EqualTo(true));
     Assert.That(sut.GetDnsType(), Is.EqualTo(DnsType.Aaaa));
     Assert.That(sut.GetRequestName(), Is.EqualTo("www.google.com."));
     Assert.That(sut.GetRr(RrKind.QD, 0).ToString(), Is.EqualTo((new RrQuery("www.google.com.", DnsType.Aaaa)).ToString()));
     Assert.That(sut.GetRr(RrKind.NS, 0).ToString(), Is.EqualTo((new RrNs("google.com.", 83400, "ns4.google.com.")).ToString()));
     Assert.That(sut.GetRr(RrKind.NS, 1).ToString(), Is.EqualTo((new RrNs("google.com.", 83400, "ns2.google.com.")).ToString()));
     Assert.That(sut.GetRr(RrKind.NS, 2).ToString(), Is.EqualTo((new RrNs("google.com.", 83400, "ns3.google.com.")).ToString()));
     Assert.That(sut.GetRr(RrKind.NS, 3).ToString(), Is.EqualTo((new RrNs("google.com.", 83400, "ns1.google.com.")).ToString()));
     Assert.That(sut.GetRr(RrKind.AR, 0).ToString(), Is.EqualTo((new RrA("ns1.google.com.", 83465, new Ip("216.239.32.10"))).ToString()));
     Assert.That(sut.GetRr(RrKind.AR, 1).ToString(), Is.EqualTo((new RrA("ns2.google.com.", 83563, new Ip("216.239.34.10"))).ToString()));
     Assert.That(sut.GetRr(RrKind.AR, 2).ToString(), Is.EqualTo((new RrA("ns3.google.com.", 83465, new Ip("216.239.36.10"))).ToString()));
     Assert.That(sut.GetRr(RrKind.AR, 3).ToString(), Is.EqualTo((new RrA("ns4.google.com.", 83465, new Ip("216.239.38.10"))).ToString()));
 }
Example #5
0
 public void パケット解釈_str1()
 {
     //exercise
     var sut = new PacketDns(TestUtil.HexStream2Bytes(Str1));
     //verify
     Assert.That(sut.GetId(), Is.EqualTo((short) 0x0002));
     Assert.That(sut.GetCount(RrKind.QD), Is.EqualTo(1));
     Assert.That(sut.GetCount(RrKind.AN), Is.EqualTo(5));
     Assert.That(sut.GetCount(RrKind.NS), Is.EqualTo(4));
     Assert.That(sut.GetCount(RrKind.AR), Is.EqualTo(7));
     Assert.That(sut.GetRcode(), Is.EqualTo((short) 0));
     Assert.That(sut.GetAa(), Is.EqualTo(false));
     Assert.That(sut.GetRd(), Is.EqualTo(true));
     Assert.That(sut.GetDnsType(), Is.EqualTo(DnsType.Mx));
     Assert.That(sut.GetRequestName(), Is.EqualTo("gmail.com."));
     Assert.That(sut.GetRr(RrKind.QD, 0).ToString(), Is.EqualTo((new RrQuery("gmail.com.", DnsType.Mx)).ToString()));
     Assert.That(sut.GetRr(RrKind.AN, 0).ToString(), Is.EqualTo((new RrMx("gmail.com.", 3427, 10, "alt1.gmail-smtp-in.l.google.com.")).ToString()));
     Assert.That(sut.GetRr(RrKind.AN, 1).ToString(), Is.EqualTo((new RrMx("gmail.com.", 3427, 20, "alt2.gmail-smtp-in.l.google.com.")).ToString()));
     Assert.That(sut.GetRr(RrKind.AN, 2).ToString(), Is.EqualTo((new RrMx("gmail.com.", 3427, 30, "alt3.gmail-smtp-in.l.google.com.")).ToString()));
     Assert.That(sut.GetRr(RrKind.AN, 3).ToString(), Is.EqualTo((new RrMx("gmail.com.", 3427, 40, "alt4.gmail-smtp-in.l.google.com.")).ToString()));
     Assert.That(sut.GetRr(RrKind.AN, 4).ToString(), Is.EqualTo((new RrMx("gmail.com.", 3427, 5, "gmail-smtp-in.l.google.com.")).ToString()));
     Assert.That(sut.GetRr(RrKind.NS, 0).ToString(), Is.EqualTo((new RrNs("gmail.com.", 54413, "ns4.google.com.")).ToString()));
     Assert.That(sut.GetRr(RrKind.NS, 1).ToString(), Is.EqualTo((new RrNs("gmail.com.", 54413, "ns2.google.com.")).ToString()));
     Assert.That(sut.GetRr(RrKind.NS, 2).ToString(), Is.EqualTo((new RrNs("gmail.com.", 54413, "ns1.google.com.")).ToString()));
     Assert.That(sut.GetRr(RrKind.NS, 3).ToString(), Is.EqualTo((new RrNs("gmail.com.", 54413, "ns3.google.com.")).ToString()));
     Assert.That(sut.GetRr(RrKind.AR, 0).ToString(), Is.EqualTo((new RrA("gmail-smtp-in.l.google.com.", 295, new Ip("74.125.25.27"))).ToString()));
     Assert.That(sut.GetRr(RrKind.AR, 1).ToString(), Is.EqualTo((new RrA("alt2.gmail-smtp-in.l.google.com.", 60, new Ip("74.125.140.27"))).ToString()));
     Assert.That(sut.GetRr(RrKind.AR, 2).ToString(), Is.EqualTo((new RrA("alt4.gmail-smtp-in.l.google.com.", 149, new Ip("74.125.131.27"))).ToString()));
     Assert.That(sut.GetRr(RrKind.AR, 3).ToString(), Is.EqualTo((new RrA("ns1.google.com.", 54584, new Ip("216.239.32.10"))).ToString()));
     Assert.That(sut.GetRr(RrKind.AR, 4).ToString(), Is.EqualTo((new RrA("ns2.google.com.", 54578, new Ip("216.239.34.10"))).ToString()));
     Assert.That(sut.GetRr(RrKind.AR, 5).ToString(), Is.EqualTo((new RrA("ns3.google.com.", 54641, new Ip("216.239.36.10"))).ToString()));
     Assert.That(sut.GetRr(RrKind.AR, 6).ToString(), Is.EqualTo((new RrA("ns4.google.com.", 54520, new Ip("216.239.38.10"))).ToString()));
 }
Example #6
0
        // 共通メソッド
        // リクエスト送信して、サーバから返ったデータをDNSパケットとしてデコードする
        // レスポンスが無い場合は、1秒でタイムアウトしてnullを返す
        // rd = 再帰要求
        private PacketDns lookup(DnsType dnsType, string name,bool rd=false)
        {
            //乱数で識別子生成
            var id = (ushort) (new Random()).Next(100);
            //送信パケット生成
            var sp = new PacketDns(id, false, false, rd, false);
            //質問フィールド追加
            sp.AddRr(RrKind.QD, new RrQuery(name, dnsType));
            //クライアントソケット生成、及び送信
            var cl = new SockUdp(new Kernel(), new Ip(IpKind.V4Localhost), 53, null, sp.GetBytes());
            //受信
            //byte[] recvBuf = cl.Recv(1000);
            var recvBuf = cl.Recv(3);

            if (recvBuf.Length == 0){
                //受信データが無い場合
                return null;
            }
            //System.out.println(string.Format("lookup(%s,\"%s\") recv().Length=%d", dnsType, name, recvBuf.Length));
            //デコード
            var p = new PacketDns(recvBuf);
            //System.out.println(print(p));
            return p;
        }
Example #7
0
 // 共通メソッド
 //リソースレコードのToString()
 private string Print(PacketDns p, RrKind rrKind, int n)
 {
     var o = p.GetRr(rrKind, n);
     if (rrKind == RrKind.QD){
         return o.ToString();
     }
     return Print(o);
 }
Example #8
0
        //addrは通常オーダで指定されている
        //private PacketDns Lookup(Ip ip, string requestName, DNS_TYPE dnsType,RemoteInfo remoteInfo) {
        private PacketDns Lookup(Ip ip, string requestName, DnsType dnsType, Ip remoteAddr)
        {
            //Ip ip = new Ip(addr);
            Logger.Set(LogKind.Detail, null, 17, string.Format("{0} Server={1} Type={2}", requestName, ip, dnsType));
            //"Lookup"

            //受信タイムアウト
            const int timeout = 3;

            //		var random = new Random(Environment.TickCount);
            //		var id = (ushort) random.Next(0xFFFF);//識別子をランダムに決定する
            var random = new Random();
            var id = (ushort) random.Next(0xFFFF);
            const bool qr = false; //要求
            const bool aa = false; //権威なし
            var rd = (bool) Conf.Get("useRD"); //再帰要求を使用するかどうか
            const bool ra = false; //再帰無効

            //リクエストパケットの生成
            var sp = new PacketDns(id, qr, aa, rd, ra);

            AppendRr(sp, RrKind.QD, new RrQuery(requestName, dnsType)); //QR(質問)フィールド追加

            const int port = 53;
            //SockUdp sockUdp = new UdpObj(Kernel, getLogger(), ip, port);
            byte[] sendBuf = sp.GetBytes();
            var sockUdp = new SockUdp(_kernel, ip, port, null, sendBuf); //送信

            //この辺のロジックを動作確認する必要がある
            byte[] recvBuf = sockUdp.Recv(timeout);

            if (recvBuf != null && 12 <= recvBuf.Length) {
                //受信

                try {
                    var rp = new PacketDns(recvBuf);

                    var str = string.Format("{0} count[{1},{2},{3},{4}] rcode={5} AA={6}", requestName,
                        rp.GetCount(RrKind.QD), rp.GetCount(RrKind.AN), rp.GetCount(RrKind.NS), rp.GetCount(RrKind.AR),
                        rp.GetRcode(), rp.GetAa());
                    Logger.Set(LogKind.Detail, sockUdp, 18, str); //"Lookup"

                    //質問フィールの以外のリソースデータをキャッシュする
                    //for (int rr = 1; rr < 4; rr++) {
                    foreach (RrKind rr in Enum.GetValues(typeof (RrKind))) {
                        if (rr == RrKind.QD) {
                            continue; //質問フィールの以外のリソースデータをキャッシュする
                        }
                        var m = rp.GetCount(rr);
                        for (var n = 0; n < m; n++) {
                            var oneRr = rp.GetRr(rr, n);
                            _rootCache.Add(oneRr);
                            Logger.Set(LogKind.Detail, sockUdp, 24,
                                string.Format("{0} _rootCache.Count={1}", oneRr, _rootCache.Count)); //_rootCache.Add
                        }
                    }
                    return rp;
                }
                catch (IOException) {
                    //ここでのエラーログも必要?
                    return null;
                }
            }

            Logger.Set(LogKind.Error, sockUdp, 5,
                string.Format("addr={0} requestName={1} dnsType={2}", remoteAddr, requestName, dnsType));
            //Lookup() パケット受信でタイムアウトが発生しました。
            return null;
        }
Example #9
0
 //共通メソッド
 //リソースレコードの数を表示する
 private static string Print(PacketDns p)
 {
     return string.Format("QD={0} AN={1} NS={2} AR={3}", p.GetCount(RrKind.QD), p.GetCount(RrKind.AN), p.GetCount(RrKind.NS), p.GetCount(RrKind.AR));
 }
Example #10
0
 //レスポンス情報追加をまとめて記述
 private void AppendRr(PacketDns packetDns, RrKind rrKind, OneRr oneRr)
 {
     Logger.Set(LogKind.Detail, null, 23, string.Format("[{0}] {1}", rrKind, oneRr)); //"Append RR"
     packetDns.AddRr(rrKind, oneRr);
 }
Example #11
0
        protected override void OnSubThread(SockObj sockObj)
        {
            var sockUdp = (SockUdp) sockObj;
            //セッションごとの情報
            //Session session = new Session((SockTcp) sockObj);

            PacketDns rp; //受信パケット
            try {
                //パケットの読込(受信パケットrp)
                var buf = sockUdp.RecvBuf;
                if (buf.Length < 12) {
                    return;
                }
                rp = new PacketDns(sockUdp.RecvBuf);
            }
            catch (IOException) {
                //データ解釈に失敗した場合は、処理なし
                Logger.Set(LogKind.Secure, sockUdp, 4, ""); //不正パケットの可能性あり
                return;
            }
            //リクエストのドメイン名を取得する
            var domainName = InitRequestDomain(rp.GetRequestName(), rp.GetDnsType());

            //リクエスト解釈完了
            Logger.Set(LogKind.Normal, sockUdp, 8,
                string.Format("{0} {1} domain={2}", rp.GetDnsType(), rp.GetRequestName(), domainName)); //Query

            var aa = false; // ドメインオーソリティ(管理ドメインかそうでないか)
            const bool ra = true; //再帰可能

            var targetCache = _rootCache; //デフォルトはルートキャッシュ

            if (rp.GetDnsType() == DnsType.Ptr) {
                if (rp.GetRequestName().ToUpper() == "1.0.0.127.IN-ADDR.ARPA." ||
                    rp.GetRequestName().ToUpper() ==
                    "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA." ||
                    rp.GetRequestName().ToUpper() == "LOCALHOST.") {
                    //キャッシュはデフォルトであるルートキャッシュが使用される
                    aa = true;
                    Logger.Set(LogKind.Detail, sockUdp, 9, ""); //"request to a domain under auto (localhost)"
                }
                else {
                    foreach (var cache in _cacheList) {
                        if (cache.Find(rp.GetRequestName(), DnsType.Ptr)) {
                            targetCache = cache;
                            aa = true;
                            Logger.Set(LogKind.Detail, sockUdp, 10,
                                string.Format("Resource={0}", targetCache.GetDomainName()));
                            //"request to a domain under management"
                            break;
                        }
                    }
                }
            }
            else {
                //A
                if (rp.GetRequestName().ToUpper() == "LOCALHOST.") {
                    //キャッシュはデフォルトであるルートキャッシュが使用される
                    aa = true;
                    Logger.Set(LogKind.Detail, sockUdp, 11, ""); //"request to a domain under auto (localhost)"
                }
                else {
                    foreach (var cache in _cacheList) {
                        if (cache.GetDomainName().ToUpper() == domainName.ToUpper()) {
                            //大文字で比較される
                            targetCache = cache;
                            aa = true;
                            Logger.Set(LogKind.Detail, sockUdp, 12, string.Format("Resource={0}", domainName));
                            //"request to a domain under management"
                            break;
                        }
                    }

                }
            }

            //管理するドメインでなく、かつ 再帰要求が無い場合は、処理を終わる
            if (!(aa) && !(rp.GetRd())) {
                return;
            }

            //aa ドメインオーソリティ
            //rs 再帰可能
            //rd 再起要求あり

            // (A)「ヘッダ」作成
            const bool qr = true; //応答

            //********************************************************
            //パケットの生成(送信パケットsp)
            //********************************************************
            //Ver6.1.0
            again:
            var sp = new PacketDns(rp.GetId(), qr, aa, rp.GetRd(), ra);

            // (B)「質問セクション」の追加
            AppendRr(sp, RrKind.QD, new RrQuery(rp.GetRequestName(), rp.GetDnsType())); //質問フィールドの追加
            if (!aa) {
                //ドメインオーソリティ(権威サーバ)で無い場合
                //ルートキャッシュにターゲットのデータが蓄積されるまで、再帰的に検索する
                try {
                    SearchLoop(rp.GetRequestName(), rp.GetDnsType(), sockUdp.RemoteIp);
                }
                catch (IOException) {
                    // ここはどうやって扱えばいいか???
                    //e.printStackTrace();
                }
            }

            // (B)「回答セクション」作成
            var ansList = targetCache.GetList(rp.GetRequestName(), rp.GetDnsType());

            //Ver6.1.0 (リソースに無い場合は、再帰検索に入る)
            if (ansList.Count == 0 && aa && !targetCache.Authority) {
                targetCache = _rootCache; //ルートキャッシュに戻す
                aa = false;
                goto again;
            }

            //Ver5.9.4 Aレコードを検索してCNAMEしか帰らない場合の処理
            //            if (ansList.Count == 0 && rp.GetDnsType() == DnsType.A){
            //                foreach (RrCname o in targetCache.GetList(rp.GetRequestName(), DnsType.Cname)) {
            //                    ansList.Add(o);
            //                    var list = targetCache.GetList(o.CName, DnsType.A);
            //                    foreach (var l in list){
            //                        ansList.Add(l);
            //                    }
            //                }
            //            }

            Logger.Set(LogKind.Detail, sockUdp, 13,
                string.Format("{0} ansList.Count={1}", rp.GetDnsType(), ansList.Count)); //"Create Response (AN)"
            if (0 < ansList.Count) {
                //検索でヒットした場合
                foreach (var oneRr in ansList) {
                    AppendRr(sp, RrKind.AN,
                        DnsUtil.CreateRr(rp.GetRequestName(), rp.GetDnsType(), oneRr.Ttl, oneRr.Data));

                    if (rp.GetDnsType() == DnsType.Mx || rp.GetDnsType() == DnsType.Cname ||
                        rp.GetDnsType() == DnsType.Ns) {

                        var targetName = "";
                        if (rp.GetDnsType() == DnsType.Mx) {
                            targetName = ((RrMx) oneRr).MailExchangeHost;
                        }
                        else if (rp.GetDnsType() == DnsType.Ns) {
                            targetName = ((RrNs) oneRr).NsName;
                        }
                        else if (rp.GetDnsType() == DnsType.Cname) {
                            targetName = ((RrCname) oneRr).CName;
                        }
                        else {
                            Util.RuntimeException("not implement [Server.onSubThread()]");
                        }

                        //追加情報が必要な場合 (Aレコード)をパケットに追加する
                        var rr = targetCache.GetList(targetName, DnsType.A);
                        foreach (OneRr r in rr) {
                            AppendRr(sp, RrKind.AR, new RrA(targetName, r.Ttl, r.Data));
                        }

                        //追加情報が必要な場合 (AAAAレコード)をパケットに追加する
                        rr = targetCache.GetList(targetName, DnsType.Aaaa);
                        foreach (var r in rr) {
                            AppendRr(sp, RrKind.AR, new RrAaaa(targetName, r.Ttl, r.Data));
                        }
                    }
                }
            }
            else {
                //検索でヒットしない場合
                if (rp.GetDnsType() == DnsType.A) {
                    // CNAMEに定義されていないかどうかを確認する
                    //Ver5.9.4 再帰的にCNAMEを検索する
                    //var cnameList = targetCache.GetList(rp.GetRequestName(), DnsType.Cname);

                    var cnameList = new List<OneRr>();
                    cnameList = GetAllCname(targetCache, rp.GetRequestName(), cnameList);

                    foreach (var o in cnameList) {
                        Logger.Set(LogKind.Detail, sockUdp, 16, o.ToString()); //"Append RR"
                        AppendRr(sp, RrKind.AN, o);

                        var cname = ((RrCname) o).CName;
                        var aList = targetCache.GetList(cname, DnsType.A);
                        foreach (var a in aList) {
            //                            Logger.Set(LogKind.Detail, sockUdp, 16, o.ToString()); //"Append RR"
            //                            AppendRr(sp, RrKind.AN, o);
                            Logger.Set(LogKind.Detail, sockUdp, 16, a.ToString()); //"Append RR"
                            AppendRr(sp, RrKind.AN, a);
                        }
                    }
                }
            }

            if (rp.GetDnsType() == DnsType.A || rp.GetDnsType() == DnsType.Aaaa || rp.GetDnsType() == DnsType.Soa ||
                rp.GetDnsType() == DnsType.Cname) {
                // (C)「権威セクション」「追加情報セクション」作成
                var nsList = targetCache.GetList(domainName, DnsType.Ns);
                Logger.Set(LogKind.Detail, sockUdp, 22, string.Format("{0} nsList.Count={1}", DnsType.Ns, nsList.Count));
                // Create Response (AR)
                foreach (var o in nsList) {
                    var ns = (RrNs) o;

                    AppendRr(sp, RrKind.NS, new RrNs(ns.Name, ns.Ttl, ns.Data));

                    if (domainName.ToUpper() != "LOCALHOST.") {
                        //localhost検索の場合は、追加情報はない
                        //「追加情報」
                        var addList = targetCache.GetList(ns.NsName, DnsType.A);
                        foreach (OneRr rr in addList) {
                            AppendRr(sp, RrKind.AR, new RrA(ns.NsName, rr.Ttl, rr.Data));
                        }
                        addList = targetCache.GetList(ns.NsName, DnsType.Aaaa);
                        foreach (OneRr rr in addList) {
                            AppendRr(sp, RrKind.AR, new RrAaaa(ns.NsName, rr.Ttl, rr.Data));
                        }
                    }
                }
            }

            sockUdp.Send(sp.GetBytes()); //送信
            //sockUdp.Close();UDPソケット(sockUdp)はクローンなのでクローズしても、処理されない※Close()を呼び出しても問題はない
            sockUdp.Close();
        }
Example #12
0
        //addrは通常オーダで指定されている
        //private PacketDns Lookup(Ip ip, string requestName, DNS_TYPE dnsType,RemoteInfo remoteInfo) {
        private PacketDns Lookup(Ip ip, string requestName, DnsType dnsType, Ip remoteAddr)
        {
            //Ip ip = new Ip(addr);
            Logger.Set(LogKind.Detail, null, 17, string.Format("{0} Server={1} Type={2}", requestName, ip, dnsType));
            //"Lookup"

            //受信タイムアウト
            const int timeout = 3;

            //		var random = new Random(Environment.TickCount);
            //		var id = (ushort) random.Next(0xFFFF);//識別子をランダムに決定する
            var        random = new Random();
            var        id     = (ushort)random.Next(0xFFFF);
            const bool qr     = false;                   //要求
            const bool aa     = false;                   //権威なし
            var        rd     = (bool)Conf.Get("useRD"); //再帰要求を使用するかどうか
            const bool ra     = false;                   //再帰無効

            //リクエストパケットの生成
            var sp = new PacketDns(id, qr, aa, rd, ra);

            AppendRr(sp, RrKind.QD, new RrQuery(requestName, dnsType)); //QR(質問)フィールド追加

            const int port = 53;

            //SockUdp sockUdp = new UdpObj(Kernel, getLogger(), ip, port);
            byte[] sendBuf = sp.GetBytes();
            var    sockUdp = new SockUdp(_kernel, ip, port, null, sendBuf); //送信

            //この辺のロジックを動作確認する必要がある
            byte[] recvBuf = sockUdp.Recv(timeout);

            if (recvBuf != null && 12 <= recvBuf.Length)
            {
                //受信

                try {
                    var rp = new PacketDns(recvBuf);

                    var str = string.Format("{0} count[{1},{2},{3},{4}] rcode={5} AA={6}", requestName,
                                            rp.GetCount(RrKind.QD), rp.GetCount(RrKind.AN), rp.GetCount(RrKind.NS), rp.GetCount(RrKind.AR),
                                            rp.GetRcode(), rp.GetAa());
                    Logger.Set(LogKind.Detail, sockUdp, 18, str); //"Lookup"

                    //質問フィールの以外のリソースデータをキャッシュする
                    //for (int rr = 1; rr < 4; rr++) {
                    foreach (RrKind rr in Enum.GetValues(typeof(RrKind)))
                    {
                        if (rr == RrKind.QD)
                        {
                            continue; //質問フィールの以外のリソースデータをキャッシュする
                        }
                        var m = rp.GetCount(rr);
                        for (var n = 0; n < m; n++)
                        {
                            var oneRr = rp.GetRr(rr, n);
                            _rootCache.Add(oneRr);
                            Logger.Set(LogKind.Detail, sockUdp, 24,
                                       string.Format("{0} _rootCache.Count={1}", oneRr, _rootCache.Count)); //_rootCache.Add
                        }
                    }
                    return(rp);
                }
                catch (IOException) {
                    //ここでのエラーログも必要?
                    return(null);
                }
            }

            Logger.Set(LogKind.Error, sockUdp, 5,
                       string.Format("addr={0} requestName={1} dnsType={2}", remoteAddr, requestName, dnsType));
            //Lookup() パケット受信でタイムアウトが発生しました。
            return(null);
        }
Example #13
0
 //レスポンス情報追加をまとめて記述
 private void AppendRr(PacketDns packetDns, RrKind rrKind, OneRr oneRr)
 {
     Logger.Set(LogKind.Detail, null, 23, string.Format("[{0}] {1}", rrKind, oneRr)); //"Append RR"
     packetDns.AddRr(rrKind, oneRr);
 }
Example #14
0
        protected override void OnSubThread(SockObj sockObj)
        {
            var sockUdp = (SockUdp)sockObj;
            //セッションごとの情報
            //Session session = new Session((SockTcp) sockObj);

            PacketDns rp; //受信パケット

            try {
                //パケットの読込(受信パケットrp)
                var buf = sockUdp.RecvBuf;
                if (buf.Length < 12)
                {
                    return;
                }
                rp = new PacketDns(sockUdp.RecvBuf);
            }
            catch (IOException) {
                //データ解釈に失敗した場合は、処理なし
                Logger.Set(LogKind.Secure, sockUdp, 4, ""); //不正パケットの可能性あり
                return;
            }
            //リクエストのドメイン名を取得する
            var domainName = InitRequestDomain(rp.GetRequestName(), rp.GetDnsType());

            //リクエスト解釈完了
            Logger.Set(LogKind.Normal, sockUdp, 8,
                       string.Format("{0} {1} domain={2}", rp.GetDnsType(), rp.GetRequestName(), domainName)); //Query

            var        aa = false;                                                                             // ドメインオーソリティ(管理ドメインかそうでないか)
            const bool ra = true;                                                                              //再帰可能

            var targetCache = _rootCache;                                                                      //デフォルトはルートキャッシュ

            if (rp.GetDnsType() == DnsType.Ptr)
            {
                if (rp.GetRequestName().ToUpper() == "1.0.0.127.IN-ADDR.ARPA." ||
                    rp.GetRequestName().ToUpper() ==
                    "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA." ||
                    rp.GetRequestName().ToUpper() == "LOCALHOST.")
                {
                    //キャッシュはデフォルトであるルートキャッシュが使用される
                    aa = true;
                    Logger.Set(LogKind.Detail, sockUdp, 9, ""); //"request to a domain under auto (localhost)"
                }
                else
                {
                    foreach (var cache in _cacheList)
                    {
                        if (cache.Find(rp.GetRequestName(), DnsType.Ptr))
                        {
                            targetCache = cache;
                            aa          = true;
                            Logger.Set(LogKind.Detail, sockUdp, 10,
                                       string.Format("Resource={0}", targetCache.GetDomainName()));
                            //"request to a domain under management"
                            break;
                        }
                    }
                }
            }
            else
            {
                //A
                if (rp.GetRequestName().ToUpper() == "LOCALHOST.")
                {
                    //キャッシュはデフォルトであるルートキャッシュが使用される
                    aa = true;
                    Logger.Set(LogKind.Detail, sockUdp, 11, ""); //"request to a domain under auto (localhost)"
                }
                else
                {
                    foreach (var cache in _cacheList)
                    {
                        if (cache.GetDomainName().ToUpper() == domainName.ToUpper())
                        {
                            //大文字で比較される
                            targetCache = cache;
                            aa          = true;
                            Logger.Set(LogKind.Detail, sockUdp, 12, string.Format("Resource={0}", domainName));
                            //"request to a domain under management"
                            break;
                        }
                    }
                }
            }

            //管理するドメインでなく、かつ 再帰要求が無い場合は、処理を終わる
            if (!(aa) && !(rp.GetRd()))
            {
                return;
            }

            //aa ドメインオーソリティ
            //rs 再帰可能
            //rd 再起要求あり

            // (A)「ヘッダ」作成
            const bool qr = true; //応答

            //********************************************************
            //パケットの生成(送信パケットsp)
            //********************************************************
            //Ver6.1.0
again:
            var sp = new PacketDns(rp.GetId(), qr, aa, rp.GetRd(), ra);

            // (B)「質問セクション」の追加
            AppendRr(sp, RrKind.QD, new RrQuery(rp.GetRequestName(), rp.GetDnsType())); //質問フィールドの追加
            if (!aa)
            {
                //ドメインオーソリティ(権威サーバ)で無い場合
                //ルートキャッシュにターゲットのデータが蓄積されるまで、再帰的に検索する
                try {
                    SearchLoop(rp.GetRequestName(), rp.GetDnsType(), sockUdp.RemoteIp);
                }
                catch (IOException) {
                    // ここはどうやって扱えばいいか???
                    //e.printStackTrace();
                }
            }

            // (B)「回答セクション」作成
            var ansList = targetCache.GetList(rp.GetRequestName(), rp.GetDnsType());

            //Ver6.1.0 (リソースに無い場合は、再帰検索に入る)
            if (ansList.Count == 0 && aa && !targetCache.Authority)
            {
                targetCache = _rootCache; //ルートキャッシュに戻す
                aa          = false;
                goto again;
            }

            //Ver5.9.4 Aレコードを検索してCNAMEしか帰らない場合の処理
//            if (ansList.Count == 0 && rp.GetDnsType() == DnsType.A){
//                foreach (RrCname o in targetCache.GetList(rp.GetRequestName(), DnsType.Cname)) {
//                    ansList.Add(o);
//                    var list = targetCache.GetList(o.CName, DnsType.A);
//                    foreach (var l in list){
//                        ansList.Add(l);
//                    }
//                }
//            }

            Logger.Set(LogKind.Detail, sockUdp, 13,
                       string.Format("{0} ansList.Count={1}", rp.GetDnsType(), ansList.Count)); //"Create Response (AN)"
            if (0 < ansList.Count)
            {
                //検索でヒットした場合
                foreach (var oneRr in ansList)
                {
                    AppendRr(sp, RrKind.AN,
                             DnsUtil.CreateRr(rp.GetRequestName(), rp.GetDnsType(), oneRr.Ttl, oneRr.Data));

                    if (rp.GetDnsType() == DnsType.Mx || rp.GetDnsType() == DnsType.Cname ||
                        rp.GetDnsType() == DnsType.Ns)
                    {
                        var targetName = "";
                        if (rp.GetDnsType() == DnsType.Mx)
                        {
                            targetName = ((RrMx)oneRr).MailExchangeHost;
                        }
                        else if (rp.GetDnsType() == DnsType.Ns)
                        {
                            targetName = ((RrNs)oneRr).NsName;
                        }
                        else if (rp.GetDnsType() == DnsType.Cname)
                        {
                            targetName = ((RrCname)oneRr).CName;
                        }
                        else
                        {
                            Util.RuntimeException("not implement [Server.onSubThread()]");
                        }

                        //追加情報が必要な場合 (Aレコード)をパケットに追加する
                        var rr = targetCache.GetList(targetName, DnsType.A);
                        foreach (OneRr r in rr)
                        {
                            AppendRr(sp, RrKind.AR, new RrA(targetName, r.Ttl, r.Data));
                        }

                        //追加情報が必要な場合 (AAAAレコード)をパケットに追加する
                        rr = targetCache.GetList(targetName, DnsType.Aaaa);
                        foreach (var r in rr)
                        {
                            AppendRr(sp, RrKind.AR, new RrAaaa(targetName, r.Ttl, r.Data));
                        }
                    }
                }
            }
            else
            {
                //検索でヒットしない場合
                if (rp.GetDnsType() == DnsType.A)
                {
                    // CNAMEに定義されていないかどうかを確認する
                    //Ver5.9.4 再帰的にCNAMEを検索する
                    //var cnameList = targetCache.GetList(rp.GetRequestName(), DnsType.Cname);

                    var cnameList = new List <OneRr>();
                    cnameList = GetAllCname(targetCache, rp.GetRequestName(), cnameList);

                    foreach (var o in cnameList)
                    {
                        Logger.Set(LogKind.Detail, sockUdp, 16, o.ToString()); //"Append RR"
                        AppendRr(sp, RrKind.AN, o);

                        var cname = ((RrCname)o).CName;
                        var aList = targetCache.GetList(cname, DnsType.A);
                        foreach (var a in aList)
                        {
//                            Logger.Set(LogKind.Detail, sockUdp, 16, o.ToString()); //"Append RR"
//                            AppendRr(sp, RrKind.AN, o);
                            Logger.Set(LogKind.Detail, sockUdp, 16, a.ToString()); //"Append RR"
                            AppendRr(sp, RrKind.AN, a);
                        }
                    }
                }
            }

            if (rp.GetDnsType() == DnsType.A || rp.GetDnsType() == DnsType.Aaaa || rp.GetDnsType() == DnsType.Soa ||
                rp.GetDnsType() == DnsType.Cname)
            {
                // (C)「権威セクション」「追加情報セクション」作成
                var nsList = targetCache.GetList(domainName, DnsType.Ns);
                Logger.Set(LogKind.Detail, sockUdp, 22, string.Format("{0} nsList.Count={1}", DnsType.Ns, nsList.Count));
                // Create Response (AR)
                foreach (var o in nsList)
                {
                    var ns = (RrNs)o;

                    AppendRr(sp, RrKind.NS, new RrNs(ns.Name, ns.Ttl, ns.Data));

                    if (domainName.ToUpper() != "LOCALHOST.")
                    {
                        //localhost検索の場合は、追加情報はない
                        //「追加情報」
                        var addList = targetCache.GetList(ns.NsName, DnsType.A);
                        foreach (OneRr rr in addList)
                        {
                            AppendRr(sp, RrKind.AR, new RrA(ns.NsName, rr.Ttl, rr.Data));
                        }
                        addList = targetCache.GetList(ns.NsName, DnsType.Aaaa);
                        foreach (OneRr rr in addList)
                        {
                            AppendRr(sp, RrKind.AR, new RrAaaa(ns.NsName, rr.Ttl, rr.Data));
                        }
                    }
                }
            }

            sockUdp.Send(sp.GetBytes()); //送信
            //sockUdp.Close();UDPソケット(sockUdp)はクローンなのでクローズしても、処理されない※Close()を呼び出しても問題はない
            sockUdp.Close();
        }