public override DnsDatagram Query(DnsDatagram request) { //serialize request byte[] requestBuffer; using (MemoryStream mS = new MemoryStream(32)) { request.WriteTo(mS); requestBuffer = mS.ToArray(); } //DoH wire format request DateTime sentAt = DateTime.UtcNow; byte[] responseBuffer; using (WebClientEx wC = new WebClientEx()) { wC.AddHeader("content-type", "application/dns-message"); wC.AddHeader("accept", "application/dns-message"); wC.AddHeader("host", _server.DnsOverHttpEndPoint.Host + ":" + _server.DnsOverHttpEndPoint.Port); wC.UserAgent = "DoH client"; wC.Proxy = _proxy; wC.Timeout = _timeout; if (_proxy == null) { if (_server.IPEndPoint == null) { _server.RecursiveResolveIPAddress(); } responseBuffer = wC.UploadData(new Uri(_server.DnsOverHttpEndPoint.Scheme + "://" + _server.IPEndPoint.ToString() + _server.DnsOverHttpEndPoint.PathAndQuery), requestBuffer); } else { responseBuffer = wC.UploadData(_server.DnsOverHttpEndPoint, requestBuffer); } } //parse response using (MemoryStream mS = new MemoryStream(responseBuffer, false)) { DnsDatagram response = new DnsDatagram(mS); response.SetMetadata(new DnsDatagramMetadata(_server, _protocol, responseBuffer.Length, (DateTime.UtcNow - sentAt).TotalMilliseconds)); if (response.Header.Identifier == request.Header.Identifier) { return(response); } } return(null); }
public override DnsDatagram Query(DnsDatagram request) { //DoH JSON format request DateTime sentAt = DateTime.UtcNow; byte[] responseBuffer; using (WebClientEx wC = new WebClientEx()) { wC.AddHeader("accept", "application/dns-json"); wC.AddHeader("host", _server.DnsOverHttpEndPoint.Host + ":" + _server.DnsOverHttpEndPoint.Port); wC.UserAgent = "DoH client"; wC.Proxy = _proxy; wC.Timeout = _timeout; Uri queryUri; if (_proxy == null) { if (_server.IPEndPoint == null) { _server.RecursiveResolveIPAddress(new SimpleDnsCache()); } queryUri = new Uri(_server.DnsOverHttpEndPoint.Scheme + "://" + _server.IPEndPoint.ToString() + _server.DnsOverHttpEndPoint.PathAndQuery); } else { queryUri = _server.DnsOverHttpEndPoint; } wC.QueryString.Clear(); wC.QueryString.Add("name", request.Question[0].Name); wC.QueryString.Add("type", Convert.ToString(((int)request.Question[0].Type))); responseBuffer = wC.DownloadData(queryUri); } //parse response dynamic jsonResponse = JsonConvert.DeserializeObject(Encoding.ASCII.GetString(responseBuffer)); DnsDatagram response = new DnsDatagram(jsonResponse); response.SetMetadata(new DnsDatagramMetadata(_server, _protocol, responseBuffer.Length, (DateTime.UtcNow - sentAt).TotalMilliseconds)); return(response); }
protected override void UpdateTracker(TrackerClientEvent @event, IPEndPoint clientEP) { string queryString; queryString = "?info_hash=" + Uri.EscapeDataString(Encoding.ASCII.GetString(_infoHash)) + "&peer_id=" + Uri.EscapeDataString(Encoding.ASCII.GetString(_clientID.PeerID)); switch (clientEP.Address.ToString()) { case "0.0.0.0": case "127.0.0.1": case "::": case "::1": break; default: if (clientEP.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) { queryString += "&ipv6=" + clientEP.Address.ToString(); } else { queryString += "&ip=" + clientEP.Address.ToString(); } break; } queryString += "&port=" + clientEP.Port + "&uploaded=0&downloaded=0&left=0&corrupt=0" + "&key=" + BitConverter.ToString(_clientID.ClientKey).Replace("-", ""); switch (@event) { case TrackerClientEvent.Started: queryString += "&event=started"; break; case TrackerClientEvent.Stopped: queryString += "&event=stopped"; break; case TrackerClientEvent.Completed: queryString += "&event=completed"; break; } queryString += "&numwant=" + _clientID.NumWant; if (_clientID.Compact) { queryString += "&compact=1"; } else { queryString += "&compact=0"; } if (_clientID.NoPeerID) { queryString += "&no_peer_id=1"; } using (WebClientEx webClient = new WebClientEx()) { webClient.Proxy = _proxy; webClient.Timeout = 30000; //30 sec timeout webClient.UserAgent = _clientID.HttpUserAgent; webClient.AddHeader("Accept-Encoding", _clientID.HttpAcceptEncoding); webClient.KeepAlive = false; using (Stream responseStream = webClient.OpenRead(_trackerURI.AbsoluteUri + queryString)) { switch (@event) { case TrackerClientEvent.None: case TrackerClientEvent.Started: Bencoding x = Bencoding.Decode(responseStream); switch (x.Type) { case BencodingType.Dictionary: _peers.Clear(); foreach (var item in x.ValueDictionary) { switch (item.Key) { case "peers": switch (item.Value.Type) { case BencodingType.String: ParseCompactPeersIPv4(item.Value.Value as byte[], _peers); break; case BencodingType.List: foreach (var peerObj in item.Value.ValueList) { var peer = peerObj.ValueDictionary; _peers.Add(new IPEndPoint(IPAddress.Parse(peer["ip"].ValueString), Convert.ToInt32(peer["port"].ValueInteger))); } break; } break; case "peers_ipv6": case "peers6": switch (item.Value.Type) { case BencodingType.String: ParseCompactPeersIPv6(item.Value.Value as byte[], _peers); break; } break; case "interval": if (item.Value.Type == BencodingType.Integer) { _interval = Convert.ToInt32(item.Value.Value); } break; case "min interval": if (item.Value.Type == BencodingType.Integer) { _minInterval = Convert.ToInt32(item.Value.Value); } break; } } break; default: throw new TrackerClientException("Invalid data received from tracker. Expected bencoded dictionary."); } break; } } } }