public DnsResponse Response; // The DNS response /// <summary> /// Constructor. /// </summary> /// <param name="dnsSocket">The socket used to transmit the request.</param> /// <param name="request">The DNS request.</param> /// <param name="timeout">The maximum time to wait.</param> /// <param name="callback">The delegate to call when the operation completes (or <c>null</c>).</param> /// <param name="state">The application state (or <c>null</c>).</param> public DnsAsyncResult(DnsSocket dnsSocket, DnsRequest request, TimeSpan timeout, AsyncCallback callback, object state) : base(null, callback, state) { this.DnsSocket = dnsSocket; this.Request = request; this.TTD = SysTime.Now + timeout; this.TimerStart = 0; this.Response = null; }
public void HandlerMsg(FastTunnelClient cleint, Message <JObject> Msg) { var request = Msg.Content.ToObject <NewCustomerMassage>(); var interval = long.Parse(DateTime.Now.GetChinaTicks()) - long.Parse(request.MsgId.Split('_')[0]); _logger.LogDebug($"Start SwapMassage {request.MsgId} 服务端耗时:{interval}ms"); var connecter = new DnsSocket(cleint.Server.ServerAddr, cleint.Server.ServerPort); connecter.Connect(); connecter.Send(new Message <SwapMassage> { MessageType = MessageType.C_SwapMsg, Content = new SwapMassage(request.MsgId) }); _logger.LogDebug($"连接server成功 {request.MsgId}"); var localConnecter = new DnsSocket(request.WebConfig.LocalIp, request.WebConfig.LocalPort); try { localConnecter.Connect(); _logger.LogDebug($"连接本地成功 {request.MsgId}"); new SocketSwap(connecter.Socket, localConnecter.Socket, _logger, request.MsgId).StartSwap(); } catch (SocketException sex) { localConnecter.Close(); if (sex.ErrorCode == 10061) { // 内网的站点不存在或无法访问 string statusLine = "HTTP/1.1 200 OK\r\n"; string responseHeader = "Content-Type: text/html\r\n"; byte[] responseBody; responseBody = Encoding.UTF8.GetBytes(TunnelResource.Page_NoSite); connecter.Send(Encoding.UTF8.GetBytes(statusLine)); connecter.Send(Encoding.UTF8.GetBytes(responseHeader)); connecter.Send(Encoding.UTF8.GetBytes("\r\n")); connecter.Send(responseBody); connecter.Socket.Disconnect(false); connecter.Socket.Close(); return; } else { throw; } } catch (Exception) { localConnecter.Close(); throw; } }
public void HandlerMsg(FastTunnelClient cleint, Message <JObject> Msg) { var request_ssh = Msg.Content.ToObject <NewSSHRequest>(); var connecter_ssh = new DnsSocket(cleint.Server.ServerAddr, cleint.Server.ServerPort); connecter_ssh.Connect(); connecter_ssh.Send(new Message <SwapMassage> { MessageType = MessageType.C_SwapMsg, Content = new SwapMassage(request_ssh.MsgId) }); var localConnecter_ssh = new DnsSocket(request_ssh.SSHConfig.LocalIp, request_ssh.SSHConfig.LocalPort); localConnecter_ssh.Connect(); new SocketSwap(connecter_ssh.Socket, localConnecter_ssh.Socket, _logger, request_ssh.MsgId).StartSwap(); }
protected virtual Socket login() { var ClientConfig = _configuration.Get <AppSettings>().ClientSettings; Server = ClientConfig.Server; DnsSocket _client = null; _logger.LogInformation($"正在连接服务端 {Server.ServerAddr}:{Server.ServerPort}"); try { // 连接到的目标IP if (_client == null) { _client = new DnsSocket(Server.ServerAddr, Server.ServerPort); } _client.Connect(); _logger.LogInformation("连接成功"); } catch (Exception) { throw; } loginMsg = new Message <LogInMassage> { MessageType = MessageType.C_LogIn, Content = new LogInMassage { Webs = ClientConfig.Webs, SSH = ClientConfig.SSH, Token = ClientConfig.Token }, }; // 登录 _client.Send(loginMsg); return(_client.Socket); }
/// <summary> /// Called when an async packet receive operation completes on one of the DNS sockets. /// </summary> /// <param name="ar">The operation's async result instance.</param> private static void OnReceive(IAsyncResult ar) { DnsSocket dnsSock = (DnsSocket)ar.AsyncState; DnsResponse response; DnsAsyncResult arDns; int cbPacket; int requestKey; lock (syncLock) { try { cbPacket = dnsSock.Socket.EndReceiveFrom(ar, ref dnsSock.FromEP); response = new DnsResponse(); if (!response.ParsePacket(dnsSock.RecvPacket, cbPacket)) { NetTrace.Write(TraceSubSystem, 0, "Bad DNS message", string.Empty, Helper.HexDump(dnsSock.RecvPacket, 0, cbPacket, 16, HexDumpOption.ShowAll)); BadPacket(dnsSock.RecvPacket, cbPacket); return; } response.Trace(TraceSubSystem, 0, ((IPEndPoint)dnsSock.FromEP).Address, null); // We've parsed a valid DNS response so attempt to match it // up with the corresponding request and signal that the // query operation is complete. requestKey = GenRequestKey(dnsSock.SocketID, response.QID); if (requests.TryGetValue(requestKey, out arDns)) { if (response.RCode != DnsFlag.RCODE_OK) { arDns.Notify(new DnsException(response.RCode)); return; } response.Latency = HiResTimer.CalcTimeSpan(arDns.TimerStart); arDns.Response = response; arDns.Notify(); } else { response.Trace(TraceSubSystem, 0, ((IPEndPoint)dnsSock.FromEP).Address, "Orphan DNS Response"); } } catch (SocketException) { // We're going to get SocketException(10054) "Connection Reset" errors if // we send a packet to a port that's not actually open on the remote // machine. Ignore these exceptions and let the operation timeout. } finally { if (dnsSock.Socket.IsOpen) { dnsSock.Socket.BeginReceiveFrom(dnsSock.RecvPacket, 0, 512, SocketFlags.None, ref dnsSock.FromEP, onReceive, dnsSock); } } } }
/// <summary> /// Specifies a new set of client network endpoints to be used for performing /// DNS query operations. /// </summary> /// <param name="endpoints">The set of one or more valid endpoints.</param> /// <param name="cbSendBuf">Socket send buffer size in bytes (or 0 for a reasonable default).</param> /// <param name="cbRecvBuf">Socket receive buffer size in bytes(or 0 for a reasonable default).</param> /// <remarks> /// <para> /// By default, this class uses only a single socket bound to an operating /// selected network interface and port. Some applications may find it necessary /// to bind to a specific network endpoint if the computer is multi-homed. /// Other high, performance applications may need to load balance across /// several sockets to avoid issues with the 16-bit <see cref="DnsMessage.QID" /> /// property wrapping around too quickly. /// </para> /// <para> /// The endpoints passed may specify the IP address as IPAddress.Any and/or /// the port=0, indicating that the a reasonable default value should /// be selected. If a socket cannot be opened for any of the /// endpoints, then all of the sockets opened so far will be closed and /// the current bindings will be retained. /// </para> /// <note> /// The existing sockets will be closed by this method any any /// outstanding requests will fail with a <see cref="CancelException" />. /// </note> /// </remarks> public static void Bind(IPEndPoint[] endpoints, int cbSendBuf, int cbRecvBuf) { EnhancedSocket[] newSocks; int cbBuf; if (endpoints.Length == 0 || endpoints.Length > 128) { throw new ArgumentException("Between 1 and 128 endpoints can be specified."); } // Create and bind the new sockets, aborting the entire // operation if there's an error. newSocks = new EnhancedSocket[endpoints.Length]; for (int i = 0; i < endpoints.Length; i++) { try { newSocks[i] = new EnhancedSocket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); newSocks[i].Bind(endpoints[i]); cbBuf = 64 * 1024; if (cbSendBuf == 0) { newSocks[i].SendBufferSize = cbBuf; } else { newSocks[i].SendBufferSize = cbSendBuf; } if (cbRecvBuf == 0) { newSocks[i].ReceiveBufferSize = cbBuf; } else { newSocks[i].ReceiveBufferSize = cbRecvBuf; } } catch { for (int j = 0; j < i; j++) { if (newSocks[i] != null) { newSocks[i].Close(); } } throw; } } // Cancel any outstanding requests, close the current sockets, // and then setup the new ones. lock (syncLock) { CancelAll(); if (sockets != null) { for (int i = 0; i < sockets.Length; i++) { sockets[i].Socket.Close(); } } sockets = new DnsSocket[newSocks.Length]; for (int i = 0; i < newSocks.Length; i++) { sockets[i] = new DnsSocket(newSocks[i], (ushort)i); sockets[i].Socket.BeginReceiveFrom(sockets[i].RecvPacket, 0, 512, SocketFlags.None, ref sockets[i].FromEP, onReceive, sockets[i]); } } }