private async Task <IObservable <IHttpRequestReponse> > GetUdpRequestResponseObservable( int port, ICommunicationInterface communicationInterface = null, bool allowMultipleBindToSamePort = false) { IUdpSocketReceiver udpListener = new UdpSocketReceiver(); var observeUdpRequest = await udpListener.ObservableUnicastListener( port, communicationInterface, allowMultipleBindToSamePort); var observable = Observable.Create <IHttpRequestReponse>( obs => { var disp = observeUdpRequest.Subscribe( udpSocket => { var stream = new MemoryStream(udpSocket.ByteData); var requestHandler = new HttpParserDelegate { HttpRequestReponse = { RemoteAddress = udpSocket.RemoteAddress, RemotePort = int.Parse(udpSocket.RemotePort), RequestType = RequestType.UDP } }; var result = _httpStreamParser.Parse(requestHandler, stream, Timeout); obs.OnNext(result); }, ex => { Cleanup(); obs.OnError(ex); }, () => { Cleanup(); obs.OnCompleted(); }); return(disp); void Cleanup() { _udpReceiverPortToObservable.Remove(port); udpListener.Dispose(); } }); return(observable); }
public static async Task <DnsServer> Create(string ip, int port, IRecordResolver recordResolver, IAuthority areWeAuthority, IExceptionHandler onError) { var networkInterface = Network.Interfaces.FirstOrDefault(x => x.IpAddress == ip); var udpReceiver = new UdpSocketReceiver(); var observerUdpReceiver = await udpReceiver.ObservableUnicastListener( port : port, communicationInterface : networkInterface, allowMultipleBindToSamePort : false); var subscriberUpdReceiver = observerUdpReceiver.Subscribe( async udpMsg => { var req = Reader.ReadRequest(new MemoryStream(udpMsg.ByteData)); var response = new Response(req); foreach (var q in req) { var record = recordResolver.Resolve(q.Class, q.Type, q.Name); if (record == null) { continue; } if (areWeAuthority?.AreWeAuthority(q.Name) ?? false) { response.Authorities.Add(record); } else { response.Answers.Add(record); } } await udpReceiver.SendToAsync(Writer.Serialize(response), udpMsg.RemoteAddress, int.Parse(udpMsg.RemotePort)); }, x => onError?.OnError(x)); return(new UDPServer { udpReceiver = udpReceiver, observerUdpReceiver = observerUdpReceiver, subscriberUpdReceiver = subscriberUpdReceiver, RecordResolver = recordResolver }); }