public CoapDtlsServerClientEndPoint(IPEndPoint endPoint, QueueDatagramTransport udpTransport, DateTime sessionStartTime) { BaseUri = new UriBuilder() { Scheme = "coaps://", Host = endPoint.Address.ToString(), Port = endPoint.Port }.Uri; EndPoint = endPoint; _udpTransport = udpTransport; SessionStartTime = sessionStartTime; }
private async Task HandleIncoming() { while (!_cts.IsCancellationRequested) { try { UdpReceiveResult data; try { data = await _socket.ReceiveAsync(); _logger.LogDebug("Received DTLS Packet from {EndPoint}", data.RemoteEndPoint); } catch (ObjectDisposedException) { // Happens when the Connection is being closed continue; } catch (SocketException sockEx) { // Some clients send an ICMP Port Unreachable when they receive data after they stopped listening. // If we knew from which client it came we could get rid of the connection, but we can't, so we just ignore the exception. if (sockEx.SocketErrorCode == SocketError.ConnectionReset) { _logger.LogInformation("Connection Closed by remote host"); continue; } _logger.LogError("SocketException with SocketErrorCode {SocketErrorCode}", sockEx.SocketErrorCode); throw; } // if there is an existing session, we pass the datagram to the session. if (_sessions.TryGetValue(data.RemoteEndPoint, out CoapDtlsServerClientEndPoint session)) { session.EnqueueDatagram(data.Buffer); continue; } // if there isn't an existing session for this remote endpoint, we start a new one and pass the first datagram to the session var transport = new QueueDatagramTransport(NetworkMtu, bytes => _sendQueue.Add(new UdpSendPacket(bytes, data.RemoteEndPoint))); session = new CoapDtlsServerClientEndPoint(data.RemoteEndPoint, transport, DateTime.UtcNow); session.EnqueueDatagram(data.Buffer); _sessions.TryAdd(data.RemoteEndPoint, session); try { _logger.LogInformation("New connection from {EndPoint}; Active Sessions: {ActiveSessions}", data.RemoteEndPoint, _sessions.Count); #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed Task.Factory.StartNew(() => HandleSession(session), TaskCreationOptions.LongRunning); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed } catch (Exception ex) { _logger.LogError(ex, "Exception while starting session handler!"); _sessions.TryRemove(session.EndPoint, out _); } } catch (Exception ex) { _logger.LogError(ex, "Error while handling incoming datagrams"); } } }