Пример #1
0
        public void Echoサーバにsendしてlength分ずつRecvする()
        {
            //setUp
            const string addr = "127.0.0.1";
            const int port = 53;
            var echoServer = new EchoServer(addr, port);
            echoServer.Start();

            const int timeout = 3;

            const int max = 1500;
            const int loop = 10;
            var tmp = new byte[max];
            for (int i = 0; i < max; i++){
                tmp[i] = (byte) i;
            }

            var ip = new Ip(addr);
            for (var i = 0; i < loop; i++){
                var sockUdp = new SockUdp(new Kernel(), ip, port, null, tmp);
            //                while (sockUdp.Length() == 0){
            //                    Thread.Sleep(10);
            //                }
                var b = sockUdp.Recv(timeout);

                //verify
                for (var m = 0; m < max; m += 10){
                    Assert.That(b[m], Is.EqualTo(tmp[m])); //送信したデータと受信したデータが同一かどうかのテスト
                }
                sockUdp.Close();
            }

            //TearDown
            echoServer.Stop();
        }
Пример #2
0
        public void OneServerを継承したEchoServer_UDP版_を使用して接続する()
        {
            const string addr = "127.0.0.1";
            const int port = 9991;
            const int timeout = 300;
            Ip ip = null;
            try{
                ip = new Ip(addr);
            } catch (ValidObjException ex){
                Assert.Fail(ex.Message);
            }
            var oneBind = new OneBind(ip, ProtocolKind.Udp);
            var conf = TestUtil.CreateConf("OptionSample");
            conf.Set("port", port);
            conf.Set("multiple", 10);
            conf.Set("acl", new Dat(new CtrlType[0]));
            conf.Set("enableAcl", 1);
            conf.Set("timeOut", timeout);

            var echoServer = new EchoServer(conf, oneBind);
            echoServer.Start();

            //TCPクライアント

            const int max = 1600;
            var buf = new byte[max];
            buf[8] = 100; //CheckData

            for (int i = 0; i < 3; i++){
                var sockUdp = new SockUdp(new Kernel(), ip, port, null, buf);
                var b = sockUdp.Recv(timeout);
                Assert.That(b[8], Is.EqualTo(buf[8])); //CheckData
                Assert.That(max,  Is.EqualTo(b.Length));

                sockUdp.Close();
            }

            echoServer.Dispose();
        }
Пример #3
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;
        }
Пример #4
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;
        }
Пример #5
0
        //アップロード(ファイル受信)
        bool UpLoad(SockUdp childObj,string path)
        {
            var ret = false;

            ushort no = 0;
            var totalSize = 0;
            FileStream fs = null;
            BinaryWriter bw = null;

            if (!(bool)Conf.Get("write")) {//「書込み」が許可されていない
                Logger.Set(LogKind.Secure,childObj,11,path);
                //エラーコード(2) アクセス違反
                childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Error),Util.htons(2),"Transmission of a message prohibition"));
                goto end;
            }
            if (!(bool)Conf.Get("override")) {//「上書き」が許可されていない
                if (File.Exists(path)) {
                    Logger.Set(LogKind.Secure,childObj,12,path);
                    //エラーコード(6) アクセス違反
                    childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Error),Util.htons(6),"There is already a file"));
                    goto end;
                }
            }

            //ACK(0)送信
            childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Ack),Util.htons(no)));

            try {
                fs = new FileStream(path,FileMode.OpenOrCreate,FileAccess.Write);
            } catch (Exception e) {
                //エラーコード(2) アクセス違反
                childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Error),Util.htons(2),e.Message));
                goto end;
            }

            bw = new BinaryWriter(fs);

            while (true) {
                //受信
            //                if (!childObj.Recv(Timeout)) {
                var buf = childObj.Recv(Timeout);
                if (buf.Length==0) {
                    Logger.Set(LogKind.Error,childObj,7,string.Format("{0}sec",Timeout));
                    break;
                }
                if ((Opcode)(buf[1]) != Opcode.Data) {
                    break;
                }

                //次のデータかどうかの確認
                if (Util.htons(BitConverter.ToUInt16(buf,2)) != no + 1)
                    continue;
                no++;

                int size = buf.Length - 4;
                bw.Write(buf,4,size); //Write
                totalSize += size;

                //ACK送信
                childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Ack),Util.htons(no)));

                if (size != 512) {
                    Logger.Set(LogKind.Normal,childObj,8,string.Format("{0} {1}byte",path,totalSize));
                    ret = true;
                    goto end;
                }
                Thread.Sleep(1);
            }
            end:
            if(bw!=null)
                bw.Close();
            if(fs!=null)
                fs.Close();
            return ret;
        }
Пример #6
0
        //ダウンロード(ファイル送信)
        bool DownLoad(SockUdp childObj,string path)
        {
            var ret = false;
            var no = (ushort)1;
            var total = 0;
            FileStream fs = null;
            BinaryReader br = null;

            if (!(bool)Conf.Get("read")) {//「読込み」が許可されていない
                Logger.Set(LogKind.Secure,childObj,10,path);
                //エラーコード(2) アクセス違反
                childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Error),Util.htons(2),"Receive of a message prohibition"));
                goto end;
            }

            if (!File.Exists(path)) {//ファイルが見つからない
                Logger.Set(LogKind.Secure,childObj,13,path);
                //エラーコード(1) ファイルが見つからない
                childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Error),Util.htons(1),"A file is not found"));
                goto end;
            }

            try {
                fs = new FileStream(path,FileMode.OpenOrCreate,FileAccess.Read);
            } catch (Exception e) {
                //エラーコード(2) アクセス違反
                childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Error),Util.htons(2),e.Message));
                goto end;
            }

            br = new BinaryReader(fs);

            while (true) {
                var data = br.ReadBytes(512);

                //DATA 送信
                childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Data),Util.htons(no),data));
                total += data.Length;

                if (data.Length < 512) {
                    if (data.Length == 0) {
                        //最後の 0bytes データを送る
                        childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Data),Util.htons(no)));
                    }
                    Logger.Set(LogKind.Normal,childObj,9,string.Format("{0} {1}byte",path,total));
                    ret = true;
                    goto end;
                }

                Thread.Sleep(10);

                // ACK待ち
                //if (!childObj.Recv(Timeout)) {
                var buf = childObj.Recv(Timeout);
                if (buf.Length==0) {
                    Logger.Set(LogKind.Error,childObj,7,string.Format("{0}sec",Timeout));
                    break;
                }
                if ((Opcode)(buf[1]) != Opcode.Ack)
                    break;
                //ACK番号が整合しているかどうかの確認
                var ackNo = Util.htons(BitConverter.ToUInt16(buf,2));
                if (no != ackNo) {
                    Logger.Set(LogKind.Error,childObj,14,string.Format("no={0} ack={1}",no,ackNo));
                    //エラーとして処理する
                    childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Error),Util.htons(2),"unmatch ACK"));
                    goto end;
                }
                no++;//次のデータ
            }
            end:
            if (br != null)
                br.Close();
            if (fs != null)
                fs.Close();
            return ret;
        }