private void Udp(SockUdp sockUdp) { var buf = sockUdp.RecvBuf; sockUdp.Send(buf); //echoしたらセッションを閉じる }
//モードの取得 bool GetMode(SockUdp sockUdp, ref TftpMode tftpMode, ref int offset) { string modeStr = GetString(sockUdp.RecvBuf, offset); if (modeStr == null) { Logger.Set(LogKind.Error, sockUdp, 3, "mode=null"); return(false); } if (modeStr.ToLower() == "netascii") { tftpMode = TftpMode.Netascii; Logger.Set(LogKind.Normal, sockUdp, 15, "mode=netascii"); } else if (modeStr.ToLower() == "octet") { tftpMode = TftpMode.Octet; Logger.Set(LogKind.Normal, sockUdp, 15, "mode=octet"); } else { Logger.Set(LogKind.Error, sockUdp, 4, string.Format("mode={0}", modeStr)); return(false); } offset += modeStr.Length + 1; return(true); }
//���X�|���X�p�P�b�g�̑��M void Send(SockUdp sockUdp, PacketDhcp sp) { //���M sockUdp.Send(sp.GetBuffer()); //this.Logger.Set(LogKind.Detail,sockUdp,4,string.Format("{0} {1} {2}",sp.Mac,(sp.RequestIp == null) ? "0.0.0.0" : sp.RequestIp.ToString(),sp.Type.ToString())); Log(sockUdp, 4, sp.Mac, sp.RequestIp, sp.Type); }
// 共通メソッド // リクエスト送信して、サーバから返ったデータを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); }
//ファイル名の取得 bool GetFileName(SockUdp sockUdp, ref string fileName, ref int offset) { fileName = GetString(sockUdp.RecvBuf, offset); if (fileName == null) { Logger.Set(LogKind.Error, sockUdp, 2, "fileName=null"); return(false); } offset += fileName.Length + 1; return(true); }
void Log(SockUdp sockUdp, int messageNo, Mac mac, Ip ip, DhcpType type) { string macStr = mac.ToString(); foreach (var m in _macAcl) { if (m.StrList[0].ToUpper() == mac.ToString()) { macStr = string.Format("{0}({1})", mac, m.StrList[2]); break; } } Logger.Set(LogKind.Detail, sockUdp, messageNo, string.Format("{0} {1} {2}", macStr, (ip == null) ? "0.0.0.0" : ip.ToString(), type.ToString())); }
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(); }
//オペコードの取得 bool GetOpCode(SockUdp sockUdp, ref Opcode opCode, ref int offset) { //オペコードの取得 byte n = 0; try { n = sockUdp.RecvBuf[1]; opCode = (Opcode)n; } catch { opCode = Opcode.Unknown; } if (opCode < Opcode.Rrq || Opcode.Oack < opCode) { Logger.Set(LogKind.Error, sockUdp, 1, string.Format("OPCODE=0x{0:x}", n)); return(false); } offset += 2; return(true); }
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(); }
//接続単位の処理 override protected void OnSubThread(SockObj sockObj) { var sockUdp = (SockUdp)sockObj; //作業フォルダの確認 if (_workDir == "") { Logger.Set(LogKind.Error, null, 5, ""); goto end; } if (!Directory.Exists(_workDir)) { Logger.Set(LogKind.Error, null, 6, string.Format("workDir = {0}", _workDir)); goto end; } Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US"); Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); var offset = 0; var opCode = Opcode.Unknown; var fileName = ""; var tftpMode = TftpMode.Netascii; if (!GetOpCode(sockUdp, ref opCode, ref offset))//オペコードの取得 { goto end; } if (opCode != Opcode.Wrq && opCode != Opcode.Rrq) { //クライアントからのリクエストでWRQ及びRRQ以外はエラーとして受け付けない goto end; } if (!GetFileName(sockUdp, ref fileName, ref offset))//ファイル名の取得 { goto end; } if (!GetMode(sockUdp, ref tftpMode, ref offset))//モードの取得 { goto end; } var path = string.Format("{0}\\{1}", _workDir, fileName); //リクエスト元に対するソケットを新規に作成する var ip = sockUdp.RemoteIp; var port = sockUdp.RemoteAddress.Port; var childObj = new SockUdp(Kernel, ip, port, null, new byte[0]); if (opCode == Opcode.Wrq) //アップロード処理 { if (!UpLoad(childObj, path)) { //エラー } } else if (opCode == Opcode.Rrq) //ダウンロード処理 { if (!DownLoad(childObj, path)) { goto end; } } end: if (sockUdp != null) { sockUdp.Close(); } }
//アップロード(ファイル受信) 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); }
//ダウンロード(ファイル送信) 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); // Init retry counter. var retryCount = (int)Conf.Get("retryCount"); 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; //} // //某所で頻繁にパケットが落ちてACK番号が整合しないケースを救済する 2021.6.27 if (no == 1 + ackNo) { if (retryCount > 0) { total -= data.Length; //pull back total count. fs.Position -= data.Length; //pull back filestream position. retryCount--; Logger.Set(LogKind.Error, childObj, 14, string.Format("no={0} ack={1} marginal count={2}", no, ackNo, retryCount)); continue; } } else if (no != ackNo) { Logger.Set(LogKind.Error, childObj, 14, string.Format("no={0} ack={1} Abort!", no, ackNo)); //エラーとして処理する childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Error), Util.htons(2), "unmatch ACK")); goto end; } if ((bool)Conf.Get("printCounter")) { // debug option. Logger.Set(LogKind.Debug, childObj, 16, string.Format("br_count={0} fs_position={1}", no, fs.Position)); } no++;//次のデータ // Reset retry counter. retryCount = (int)Conf.Get("retryCount"); } end: if (br != null) { br.Close(); } if (fs != null) { fs.Close(); } return(ret); }
void UdpTunnel(SockUdp udpObj) { //int timeout = this.OpBase.ValInt("timeOut"); var sock = new Dictionary <CS, SockUdp>(2); sock[CS.Client] = udpObj; sock[CS.Server] = null; //*************************************************************** // �T�[�o�Ƃ̐ڑ� //*************************************************************** { int port = _targetPort; //var ip = new Ip(_targetServer); //if (ip.ToString() == "0.0.0.0") { // try { // var iphe = Dns.GetHostEntry(_targetServer); // if (iphe.AddressList.Length == 0) { // goto end; // } // ip = new Ip(iphe.AddressList[0].ToString()); // } catch {//���O�Ɏ��s�����ꍇ // Logger.Set(LogKind.Normal,null, 4, string.Format("{0}:{1}", _targetServer, _targetPort)); // goto end; // } //} Ip ip; try{ ip = new Ip(_targetServer); }catch (ValidObjException) { try { var iphe = Dns.GetHostEntry(_targetServer); if (iphe.AddressList.Length == 0) { goto end; } ip = new Ip(iphe.AddressList[0].ToString()); } catch {//���O�Ɏ��s�����ꍇ Logger.Set(LogKind.Normal, null, 4, string.Format("{0}:{1}", _targetServer, _targetPort)); goto end; } } sock[CS.Server] = new SockUdp(Kernel, ip, port, null, new byte[0]); if (sock[CS.Server].SockState == Bjd.sock.SockState.Error) { goto end; } } sock[CS.Server].Send(sock[CS.Client].RecvBuf);//�T�[�o�֑��M //if (sock[CS.Server].Recv(Timeout)) {//�T�[�o����̎�M var buf = sock[CS.Server].Recv(Timeout); if (buf.Length == 0) { sock[CS.Client].Send(buf);//�N���C�A���g�֑��M } Logger.Set(LogKind.Normal, sock[CS.Server], 7, string.Format("UDP {0}:{1} - {2}:{3} {4}byte", sock[CS.Client].RemoteHostname, sock[CS.Client].RemoteAddress.Port, _targetServer, _targetPort, buf.Length)); end: //udpObj.Close();UDP�\�P�b�g(udpObj)�̓N���[���Ȃ̂ŃN���[�Y���Ă�A��������Ȃ���Close()��Ăяo���Ă���͂Ȃ� if (sock[CS.Client] != null) { sock[CS.Client].Close(); } if (sock[CS.Server] != null) { sock[CS.Server].Close(); } }
//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); }
//ダウンロード(ファイル送信) 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); }