Пример #1
0
        void ThreadEntry()
        {
            IPEndPoint remoteEndpoint = default(IPEndPoint);

            while (!_disposing)
            {
                try
                {
                    _actionsQueue.ExecuteQueued();

                    var udpData = UdpSocket.Receive(ref remoteEndpoint);

                    var timestamp32 = _localPeer.Time32;
                    if (_previousTimestamp32.HasValue)
                    {
                        var timePassed32 = unchecked (timestamp32 - _previousTimestamp32.Value);
                        _pps.Input(1, timePassed32);
                        _bps.Input((udpData.Length + LocalLogicConfiguration.IpAndUdpHeadersSizeBytes) * 8, timePassed32);
                    }
                    _previousTimestamp32 = timestamp32;

                    var manager = _localPeer.Manager;
                    if (manager != null && _localPeer.Firewall.PacketIsAllowed(remoteEndpoint) && udpData.Length > 4)
                    {
                        if (udpData[0] == (byte)PacketTypes.NatTest1Request)
                        {
                            manager.ProcessReceivedNat1TestRequest(this, udpData, remoteEndpoint);
                            return;
                        }

                        var packetType = P2ptpCommon.DecodeHeader(udpData);
                        if (packetType.HasValue)
                        {
                            switch (packetType.Value)
                            {
                            case PacketTypes.hello:
                                manager.ProcessReceivedHello(udpData, remoteEndpoint, this, timestamp32);
                                break;

                            case PacketTypes.peersListIpv4:
                                manager.ProcessReceivedSharedPeers(udpData, remoteEndpoint);
                                break;

                            case PacketTypes.extensionSignaling:
                                manager.ProcessReceivedExtensionSignalingPacket(BinaryProcedures.CreateBinaryReader(udpData, P2ptpCommon.HeaderSize), remoteEndpoint);
                                break;
                            }
                        }
                        else
                        {
                            (var extension, var streamId, var index) = ExtensionProcedures.ParseReceivedExtensionPayloadPacket(udpData, _localPeer.Configuration.Extensions);
                            if (extension != null)
                            {
                                if (_streams.TryGetValue(streamId, out var stream))
                                {
                                    stream.Extensions.TryGetValue(extension, out var streamExtension);
                                    streamExtension.OnReceivedPayloadPacket(udpData, index);
                                }
                                //else _localPeer.WriteToLog(LogModules.Receiver, $"receiver {SocketInfo} got packet from bad stream id {streamId}");
                            }
                        }
                    }
                }
                //   catch (InvalidOperationException)
                //   {// intentionally ignored   (before "connection")
                //   }
                catch (SocketException exc)
                {
                    if (_disposing)
                    {
                        return;
                    }
                    if (exc.ErrorCode != 10054) // forcibly closed - ICMP port unreachable - it is normal when peer gets down
                    {
                        _localPeer.HandleException(LogModules.Receiver, exc);
                    }
                    // else ignore it
                }
                catch (Exception exc)
                {
                    _localPeer.HandleException(LogModules.Receiver, exc);
                }
            }
        }