예제 #1
0
        internal void OnReceivedDmpPing(IPEndPoint remoteEndpoint, byte[] udpData) // engine thread
        {
            WriteToLog_detail($">> OnReceivedDmpPing(remoteEndpoint={remoteEndpoint})");
            if (!remoteEndpoint.Equals(RemoteSessionDescription.DirectChannelEndPoint))
            {
                throw new PossibleAttackException();
            }
            if (SharedPingPongHmacKey == null)
            {
                WriteToLog_detail($"ignoring received DMP PING: SharedPingPongHmacKey is not initialized yet");
                return;
            }

            var ping = DmpPingPacket.DecodeAndVerify(udpData, this);

            var pong = new DmpPongPacket
            {
                DirectChannelToken32 = RemoteSessionDescription.DirectChannelToken32,
                PingRequestId32      = ping.PingRequestId32,
            };

            if (ping.PublicEcdheKey != null)
            {
                pong.PublicEcdheKey = new EcdhPublicKey {
                    Ecdh25519PublicKey = this.LocalDirectChannelEcdhePublicKey
                };
                this.DeriveDirectChannelSharedDhSecret(ping.PublicEcdheKey.Ecdh25519PublicKey);
            }
            pong.PingPongHMAC = GetPingPongHMAC(pong.GetSignedFieldsForPingPongHMAC);

            var pongUdpData = pong.Encode();

            _localDrpPeer.Engine.SendPacket(pongUdpData, remoteEndpoint);
        }
예제 #2
0
        internal void OnReceivedDmpPing(IPEndPoint remoteEndpoint, byte[] udpData) // engine thread
        {
            WriteToLog_detail($">> OnReceivedDmpPing(remoteEndpoint={remoteEndpoint})");

            if (!remoteEndpoint.Address.Equals(RemoteSessionDescription.DirectChannelEndPoint.Address))
            {
                throw new PossibleAttackException($"receibed DMP PING from bad IP address {remoteEndpoint.Address}, expected from {RemoteSessionDescription.DirectChannelEndPoint.Address}");
            }

            if (SharedPingPongHmacKey == null)
            {
                WriteToLog_detail($"ignoring received DMP PING: SharedPingPongHmacKey is not initialized yet");
                return;
            }

            var ping = DmpPingPacket.DecodeAndVerify(udpData, this);


            if (this.RemoteSessionDescription.DirectChannelEndPoint.Port != remoteEndpoint.Port)
            {
                WriteToLog_detail($"updating remote peer DirectChannel port from {this.RemoteSessionDescription.DirectChannelEndPoint} to {remoteEndpoint} (when remote peer opens another port in NAT)");
                this.RemoteSessionDescription.DirectChannelEndPoint = remoteEndpoint;
                if (this.InitialPendingPingRequest != null)
                {
                    this.InitialPendingPingRequest.ResponderEndpoint = remoteEndpoint;
                }
            }


            var pong = new DmpPongPacket
            {
                DirectChannelToken32 = RemoteSessionDescription.DirectChannelToken32,
                PingRequestId32      = ping.PingRequestId32,
            };

            if (ping.PublicEcdheKey != null)
            {
                pong.PublicEcdheKey = new EcdhPublicKey {
                    Ecdh25519PublicKey = this.LocalDirectChannelEcdhePublicKey
                };
                this.DeriveDirectChannelSharedDhSecret(ping.PublicEcdheKey.Ecdh25519PublicKey);
            }
            pong.PingPongHMAC = GetPingPongHMAC(pong.GetSignedFieldsForPingPongHMAC);

            var pongUdpData = pong.Encode();

            _localDrpPeer.Engine.SendPacket(pongUdpData, remoteEndpoint);
        }
예제 #3
0
        public DmpPingPacket CreatePing(bool sendPublicEcdhKey)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(ToString());
            }
            var r = new DmpPingPacket
            {
                DirectChannelToken32 = RemoteSessionDescription.DirectChannelToken32,
                PingRequestId32      = (uint)_insecureRandom.Next(),
            };

            if (sendPublicEcdhKey)
            {
                r.PublicEcdheKey = new EcdhPublicKey {
                    Ecdh25519PublicKey = this.LocalDirectChannelEcdhePublicKey
                };
            }
            r.PingPongHMAC = GetPingPongHMAC(r.GetSignedFieldsForPingPongHMAC);
            return(r);
        }