private async void ProcessUdp(IAsyncResult ar) { try { if (_socket == null) { return; } EndPoint endPoint = new IPEndPoint(0, 0); var bytesTransferred = _socket.EndReceiveFrom(ar, ref endPoint); var remoteEndPoint = (IPEndPoint)endPoint; if (bytesTransferred == 0) { return; } using (var data = new PooledMemoryStream(_pipe.Service.ArrayPool)) { data.Write(_buffer, 0, bytesTransferred); data.Position = 0; ushort flag; ushort sessionId; int length; int id; int fragId; using (var r = data.ToBinaryReader(true)) { flag = r.ReadUInt16(); sessionId = r.ReadUInt16(); length = r.ReadInt32(); id = r.ReadInt32(); fragId = r.ReadInt32(); } if (flag != 43981) { Logger.Warn() .Message("Received Fragment instead of FullFragment") .Write(); DoUdpReceive(); return; } var message = (CoreMessage)_protocol.Deserialize(null, data); message.IsUdp = true; message.RemoteEndPoint = remoteEndPoint; Logger.Trace() .Message("Client:{0} Received:{1}", remoteEndPoint.ToString(), message.GetType().Name) .Write(); var holepunch = message as ServerHolepunchMessage; if (holepunch != null) { var session = (ProudSession)_pipe.Service[holepunch.MagicNumber]; if (session == null) { Logger.Warn() .Message("Client:{0} Invalid MagicNumber", remoteEndPoint.ToString()) .Write(); DoUdpReceive(); return; } Logger.Debug() .Message("Client:{0} Received ServerHolepunch", session.HostId) .Write(); if (session.UdpEnabled) { Logger.Warn() .Message("Client:{0} UDP relaying is already enabled", session.HostId) .Write(); DoUdpReceive(); return; } session.UdpSessionId = sessionId; session.UdpEndPoint = remoteEndPoint; Send(session, new ServerHolepunchAckMessage(holepunch.MagicNumber, remoteEndPoint)); } else { // ToDo Add a lookup for UdpSessionId var session = _pipe.Service.Sessions.Cast <ProudSession>().FirstOrDefault(s => s.UdpSessionId == sessionId); if (session == null) { Logger.Warn() .Message("Client:{0} Invalid session id", remoteEndPoint.ToString()) .Write(); } else { try { var deferral = new DeferralManager(); _pipe.OnMessageReceived(new MessageReceivedEventArgs(session, message, deferral)); await deferral.WaitAsync().ConfigureAwait(false); } catch (Exception ex) { _pipe.Service.Pipeline.OnError(new ExceptionEventArgs(session, ex)); session.Dispose(); } } } DoUdpReceive(); } } catch (ObjectDisposedException) { } catch (Exception ex) { _pipe.Service.Pipeline.OnError(new ExceptionEventArgs(ex)); } }