Пример #1
0
        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;
            }
        }