public MockTurnServer(IPAddress listenAddress, int port) { _listenAddress = listenAddress; _listenPort = port; NetServices.CreateRtpSocket(false, _listenAddress, 0, out _clientSocket, out _); ListeningEndPoint = _clientSocket.LocalEndPoint as IPEndPoint; logger.LogDebug($"MockTurnServer listening on {ListeningEndPoint}."); _listener = new UdpReceiver(_clientSocket); _listener.OnPacketReceived += OnPacketReceived; _listener.OnClosed += (reason) => logger.LogDebug($"MockTurnServer on {ListeningEndPoint} closed."); _listener.BeginReceiveFrom(); }
private void OnPacketReceived(UdpReceiver receiver, int localPort, IPEndPoint remoteEndPoint, byte[] packet) { STUNMessage stunMessage = STUNMessage.ParseSTUNMessage(packet, packet.Length); switch (stunMessage.Header.MessageType) { case STUNMessageTypesEnum.Allocate: logger.LogDebug($"MockTurnServer received Allocate request from {remoteEndPoint}."); if (_relaySocket == null) { _clientEndPoint = remoteEndPoint; // Create a new relay socket. NetServices.CreateRtpSocket(false, _listenAddress, 0, out _relaySocket, out _); _relayEndPoint = _relaySocket.LocalEndPoint as IPEndPoint; logger.LogDebug($"MockTurnServer created relay socket on {_relayEndPoint}."); _relayListener = new UdpReceiver(_relaySocket); _relayListener.OnPacketReceived += OnRelayPacketReceived; _relayListener.OnClosed += (reason) => logger.LogDebug($"MockTurnServer relay on {_relayEndPoint} closed."); _relayListener.BeginReceiveFrom(); } STUNMessage allocateResponse = new STUNMessage(STUNMessageTypesEnum.AllocateSuccessResponse); allocateResponse.Header.TransactionId = stunMessage.Header.TransactionId; allocateResponse.AddXORMappedAddressAttribute(remoteEndPoint.Address, remoteEndPoint.Port); allocateResponse.AddXORAddressAttribute(STUNAttributeTypesEnum.XORRelayedAddress, _relayEndPoint.Address, _relayEndPoint.Port); _clientSocket.SendTo(allocateResponse.ToByteBuffer(null, false), remoteEndPoint); break; case STUNMessageTypesEnum.BindingRequest: logger.LogDebug($"MockTurnServer received Binding request from {remoteEndPoint}."); STUNMessage stunResponse = new STUNMessage(STUNMessageTypesEnum.BindingSuccessResponse); stunResponse.Header.TransactionId = stunMessage.Header.TransactionId; stunResponse.AddXORMappedAddressAttribute(remoteEndPoint.Address, remoteEndPoint.Port); _clientSocket.SendTo(stunResponse.ToByteBuffer(null, false), remoteEndPoint); break; case STUNMessageTypesEnum.CreatePermission: logger.LogDebug($"MockTurnServer received CreatePermission request from {remoteEndPoint}."); STUNMessage permResponse = new STUNMessage(STUNMessageTypesEnum.CreatePermissionSuccessResponse); permResponse.Header.TransactionId = stunMessage.Header.TransactionId; _clientSocket.SendTo(permResponse.ToByteBuffer(null, false), remoteEndPoint); break; case STUNMessageTypesEnum.SendIndication: logger.LogDebug($"MockTurnServer received SendIndication request from {remoteEndPoint}."); var buffer = stunMessage.Attributes.Single(x => x.AttributeType == STUNAttributeTypesEnum.Data).Value; var destEP = (stunMessage.Attributes.Single(x => x.AttributeType == STUNAttributeTypesEnum.XORPeerAddress) as STUNXORAddressAttribute).GetIPEndPoint(); logger.LogDebug($"MockTurnServer relaying {buffer.Length} bytes to {destEP}."); _relaySocket.SendTo(buffer, destEP); break; default: logger.LogDebug($"MockTurnServer received unknown STUN message from {remoteEndPoint}."); break; } }