Read7BitLongValue() public method

public Read7BitLongValue ( ) : ulong
return ulong
Example #1
0
        public void Acknowledgment(N2HBinaryReader reader)
        {
            var bufferSize = reader.Read7BitLongValue();
            if (bufferSize == 0)
            {
                Fail("Negative acknowledgment");
                return;
            }
            ulong stageAckPrec = _stageAck;
            var stageReaden = reader.Read7BitLongValue();
            Debug.WriteLine("ack:id:{0},stage:{1},accId:{2}",Id, stageReaden,FlowId);
            var stage = _stageAck + 1;
            if (stageReaden > _stage)
            {
                Logger.FATAL(
                    "Acknowledgment received {0} superior than the current sending stage {1} on flowWriter {2}",
                    stageReaden, _stage, Id);
                _stageAck = _stage;
            }
            else if (stageReaden <= _stageAck)
            {
                if (reader.BaseStream.GetAvaliableByteCounts() == 0)
                    Logger.Debug("Acknowledgment {0} obsolete on flowWriter {1}", stageReaden, Id);
            }
            else
            {
                _stageAck = stageReaden;
            }

            var maxStageRecv = stageReaden;
            var pos = reader.BaseStream.Position;
            while (reader.BaseStream.GetAvaliableByteCounts() > 0)
            {
                maxStageRecv += reader.Read7BitLongValue() + reader.Read7BitLongValue() + 2;
            }
            if (pos != reader.BaseStream.Position)
            {
                reader.BaseStream.Position = pos;
            }
            ulong lostCount = 0;
            ulong lostStage = 0;
            bool repeated = false;
            bool header = true;
            bool stop = false;
            var messageNode = _messagesSent.First;
            while (messageNode!=null)
            {
               var message = messageNode.Value;
               //if (stop) break;
               // if (message.Fragments.Count == 0) continue;
                //var fragmentsLen = message.Fragments.Count;

                    for (var itFrag = 0; itFrag < message.Fragments.Count;)
                    {
                        if (_stageAck >= message.Fragments[itFrag].Stage)
                        {
                            stage++;
                            _ackCount++;
                            message.Fragments.RemoveAt(itFrag);
                            continue;
                        }
                        while (!stop)
                        {
                            if (lostCount == 0)
                            {
                                if (reader.BaseStream.GetAvaliableByteCounts() > 0)
                                {
                                    lostCount = reader.Read7BitLongValue() + 1;
                                    lostStage = stageReaden + 1;
                                    stageReaden = lostStage + lostCount + reader.Read7BitLongValue();
                                }
                                else
                                {
                                    stop = true;
                                    break;
                                }
                            }
                            if (lostStage > _stage)
                            {
                                Logger.FATAL("Lost information received {0} have not been yet sent on flowWriter {1}",
                                    lostStage, Id);
                                stop = true;
                            }
                            else if (lostStage <= _stageAck)
                            {
                                --lostCount;
                                ++lostStage;
                                continue;
                            }
                            break;
                        }
                        if (stop) break;
                        if (lostStage != stage)
                        {
                            if (repeated)
                            {
                                ++stage;
                                ++itFrag;
                                header = true;
                            }
                            else
                            {
                                _stageAck = stage;
                            }
                            continue;
                        }
                        if (!message.Repeatable)
                        {
                            if (repeated)
                            {
                                itFrag++;
                                stage++;
                                header = true;
                            }
                            else
                            {
                                Logger.INFO("FlowWriter {0} : message {1} lost", Id, stage);
                                --_ackCount;
                                ++_lostCount;
                                _stageAck = stage;
                            }
                            --lostCount;
                            ++lostStage;
                            continue;
                        }
                        repeated = true;
                        if (message.Fragments[itFrag].Stage >= maxStageRecv)
                        {
                            ++stage;
                            header = true;
                            --lostCount;
                            ++lostStage;
                            itFrag++;
                            continue;
                        }
                        Logger.Debug("FlowWriter {0} : stage {1} reapeated", Id, stage);
                        uint available;
                        var fragmentOffset = message.Fragments[itFrag].Offset;
                        var content = message.GetReader(fragmentOffset, out available);

                        message.Fragments[itFrag] = new Message.FragmentInfo(fragmentOffset, _stage);
                        var contentSize = available;
                        itFrag++;

                        byte flags = 0;
                        if (fragmentOffset > 0) flags |= MESSAGE_WITH_BEFOREPART;
                        if (itFrag != message.Fragments.Count)
                        {
                            flags |= MESSAGE_WITH_AFTERPART;
                            contentSize = message.Fragments[itFrag].Offset - fragmentOffset;
                        }
                        var size = contentSize + 4;
                        var bandWriter = Band.Writer;
                        if (!header && size > bandWriter.AvaliableBufferCounts)
                        {
                            Band.Flush();
                            header = true;
                        }
                        if (header) size += HeaderSize(stage);
                        if (size > bandWriter.AvaliableBufferCounts) Band.Flush();
                        size -= 3;
                        Flush(Band.WriteMessage((byte)(header ? 0x10 : 0x11), (ushort)size), stage, flags, header,
                            content, (ushort)contentSize);
                        available -= contentSize;
                        header = false;
                        --lostCount;
                        ++lostStage;
                        ++stage;
                    }
                if (message.Fragments.Count == 0)
                {
                    if (message.Repeatable) --_repeatable;
                    if (_ackCount > 0)
                    {
                        uint available;
                        uint size;
                        var reader1 = message.MemAck(out available, out size);
                        AckMessageHandler(_ackCount, _lostCount, reader1, available, size);
                        _ackCount = _lostCount = 0;
                    }
                    _messagesSent.Remove(messageNode);
                    Debug.WriteLine("sentremove{0} on flowWriter {1}", _stageAck, Id);
                    message.Recycle();
                }
                messageNode = messageNode.Next;
            }
            if (lostCount > 0 && reader.BaseStream.GetAvaliableByteCounts() > 0)
                Logger.FATAL("Some lost information received have not been yet sent on flowWriter {0}", Id);

            // rest messages repeatable?
            if (_repeatable == 0)
                _trigger.Stop();
            else if (_stageAck > stageAckPrec || repeated)
                _trigger.Reset();
        }
Example #2
0
        private byte PerformHandshake(byte id, N2HBinaryReader reader, long oldPos)
        {
            //Logger.Debug("PerformHandshake{0}", id);
            switch (id)
            {
                case 0x30:
                    reader.ReadByte();
                    var epdLen = reader.ReadByte() - 1;
                    var type = reader.ReadByte();
                    var epd = reader.ReadBytes(epdLen);
                    var tag = reader.ReadBytes(16);
                    Writer.Write((byte)tag.Length);
                    Writer.Write(tag);
                    if (type == 0x0F)
                        return Handler.PerformHandshake(tag, Writer,Peer.Address, epd);
                    if (type == 0x0a)
                    {

                        var tagstr = tag.BytesToString();
                        var attempt = GetHelloAttempt<HelloAttempt>(tagstr);

                        ushort port;
                        string host;
                        RtmfpUtils.UnpackUrl(epd.BytesToString(), out host, out port, out Peer.Path,out Peer.Properties);

                        var addresses = new List<string>();
                        Peer.OnHandshake(attempt.Count + 1, addresses);
                        if (addresses.Count > 0)
                        {
                            for (var i = 0; i < addresses.Count; i++)
                            {
                                if (addresses[i] == "again")
                                {
                                   addresses[i] = host + ":" + port;
                                    Writer.WriteAddress(new IPEndPoint(IPAddress.Parse(host),port),i==0 );
                                }
                            }
                      
                            return 0x71;
                        }
                        CreateCookie(Writer, attempt, tag, epd.BytesToString());
                        Writer.Write(_certificat);
                        return 0x70;
                    }
                    else
                    {
                        Logger.FATAL("Unkown handshake first way with '{0}' type", type);
                    }
                    return 0;
                case 0x38:
                    FarId = reader.ReadUInt32();
                   
                    if (reader.Read7BitLongValue() != CookieComputing.COOKIE_SIZE)
                    {
                        return 0;
                    }
                    var cookieKey = reader.ReadBytes(CookieComputing.COOKIE_SIZE).BytesToString();
                    reader.BaseStream.Position -= CookieComputing.COOKIE_SIZE;
                    if (!_cookies.ContainsKey(cookieKey))
                    {
                        Logger.WARN("Cookie {0} unknown, maybe already connected (udpBuffer congested?)", cookieKey);
                        return 0;
                    }
                    var cookie = _cookies[cookieKey];
                    cookie.PeerAddress = Peer.Address;
                    if (cookie.FarId == 0)
                    {
                        cookie.FarId = FarId;
                        reader.BaseStream.Position += CookieComputing.COOKIE_SIZE;
                        var size = reader.Read7BitLongValue();
                        var buffer = reader.ReadBytes((int) size);
                        uint tempSize = 0;
                        cookie.PeerId = Target.Sha256.ComputeHash(buffer, 0, (int)size);
                        //Native.EVP_Digest(buffer, (uint)size, cookie.PeerId, ref tempSize, Native.EVP_sha256(), IntPtr.Zero);
                        reader.BaseStream.Position -= (long) size;
                        var initiatorKeySize = (int) (reader.Read7BitValue() - 2);
                        reader.BaseStream.Position += 2;
                        cookie.CookieComputing.InitiatorKey = new byte[initiatorKeySize];
                        reader.BaseStream.Read(cookie.CookieComputing.InitiatorKey, 0, initiatorKeySize);
                        //cookie.CookieComputing.InitiatorKey = reader.ReadBytes((int) initiatorKeySize);
                        cookie.CookieComputing.InitiatorNonce = reader.ReadBytes((int) reader.Read7BitValue());
                        Writer.BaseStream.Position = oldPos;
                        tempSize = reader.ReadByte();//0x58
                        if(tempSize!=0x58)Logger.WARN("not 0x58!!");
                        cookie.ComputeKeys();
                    }
                    else if(cookie.Id>0)
                    {
                        cookie.Read(Writer.BaseStream);
                        return 0x78;
                    }
                    return 0;
                default:
                    Logger.FATAL("Unkown handshake packet id {0}", id);
                    return 0;
            }
        }
        public override void PacketHandler(N2HBinaryReader reader)
        {
            if(Checked){
                lock (Writer)
                {
                    base.PacketHandler(reader);
                }
                return;
            }
            var marker = reader.ReadByte();
            if (marker != 0x0b)
            {
                Logger.FATAL("Marker hand shake wrong:should be 0b and not {0:X}", marker);
                return;
            }
            var time = reader.ReadUInt16();
            var type = reader.ReadByte();
            var length = reader.ReadUInt16();
            byte[] tag;
            Logger.Debug("handshake {0:X} len:{1}",type,length);
            switch (type)
            {
                case 0x70:
              
                    tag = reader.ReadBytes(reader.ReadByte());
                    var cookieBytes = reader.ReadBytes(reader.ReadByte());
                    var targetCertificat = reader.ReadBytes((int)reader.BaseStream.GetAvaliableByteCounts());
                    var nonce = new byte[0];
                    _dh = RtmfpUtils.BeginDiffieHellman(ref nonce, true);
                    Peer.Id = Target.Sha256.ComputeHash(nonce, 0, nonce.Length);
                    HandShake38(cookieBytes, nonce);
                    _handshake = () => HandShake38(cookieBytes, nonce);
                    break;
                case 0x71:
                    tag = reader.ReadBytes(reader.ReadByte());
                    var flag = reader.ReadByte();
                    var address = new IPEndPoint(new IPAddress(reader.ReadBytes(4)), reader.ReadInt16());
                    Target.Address.Port = address.Port;
                    Logger.Debug("redirect to {0}",address.ToString());
                    Handler.FarProtocol.IOHandler.Socket.Connect(Target.Address);
                    _handshake();
                    break;
                case 0x78:
                  
                    FarId = reader.ReadUInt32();
                    var targetNonce = reader.ReadBytes((int)reader.Read7BitLongValue());
                    var must58 = reader.ReadByte();
                    Debug.WriteLineIf(must58!=0x58,$"must58!{must58}");
                    var key = new byte[RtmfpUtils.KEY_SIZE];
                    Buffer.BlockCopy(targetNonce, targetNonce.Length - RtmfpUtils.KEY_SIZE, key, 0, RtmfpUtils.KEY_SIZE);
                    var  sharedSecret = _dh.CreateSharedKey(key);
                    byte[] decryptKey;
                    byte[] encryptKey;
                    RtmfpUtils.ComputeAsymetricKeys(sharedSecret, _certificat, targetNonce, out encryptKey, out decryptKey);
                    Checked = true;
                    _handshakeTimeoutTimer.Stop();
                    AesEncrypt = new AESEngine(encryptKey, AESEngine.Direction.ENCRYPT);
                    AesDecrypt = new AESEngine(decryptKey);
                    PrevAesType = AESEngine.AESType.DEFAULT;
                    Application = Handler.Application;
                    Handler.CreateSession(Peer, null);

                    break;
                default:

                    break;
            }

        }