Ejemplo n.º 1
0
        public virtual void Decode(N2HBinaryReader reader)
        {
            var type = FarId == 0 ? AESEngine.AESType.SYMMETRIC : AESEngine.AESType.DEFAULT;

            RtmfpUtils.Decode(AesDecrypt.Next(type), reader);
            PrevAesType = type;
        }
Ejemplo n.º 2
0
        public override void PacketHandler(N2HBinaryReader reader)
        {
            var marker = reader.ReadByte();

            if (marker != 0x0b)
            {
                Logger.FATAL("Marker hand shake wrong:should be 0b and not {0}", marker);
                return;
            }
            var time   = reader.ReadUInt16();
            var id     = reader.ReadByte();
            var length = reader.ReadUInt16();

            reader.Shrink(length);
            var pos = Writer.BaseStream.Position;

            Writer.BaseStream.Position += 3;
            var idResponse = PerformHandshake(id, reader, pos);

            if (idResponse > 0)
            {
                Writer.BaseStream.Position = pos;
                Writer.Write(idResponse);
                Writer.Write((short)(Writer.BaseStream.GetAvaliableByteCounts() - 2));
                Flush(0x0b);
            }
            FarId = 0;
        }
Ejemplo n.º 3
0
        public void PushAudioPacket(uint time, N2HBinaryReader packet, uint numberLostFragments)
        {
            if (PublisherId == 0)
            {
                Logger.FATAL("Audio packet pushed on a publication {0} who is idle", PublisherId);
                return;
            }
            var pos = packet.BaseStream.Position;

            if (numberLostFragments > 0)
            {
                Logger.INFO("");
            }
            AudioQOS.Add(time, packet.Fragments, numberLostFragments, (uint)(packet.BaseStream.GetAvaliableByteCounts() + 5), (uint)(_publisher != null?_publisher.Ping:0));
            var temp  = packet.ReadByte();
            var temp2 = packet.ReadByte();

            packet.BaseStream.Position = pos;
            if (((temp >> 4) == 0x0a) && temp2 == 0)
            {
                packet.BaseStream.CopyDataTo(AudioCodecBuffer);
                AudioCodecBuffer.Position = 0;
            }

            foreach (var listener in Listeners)
            {
                listener.Value.PushAudioPacket(time, packet);
                //packet.BaseStream.Position = pos;
            }
            _publisher.OnAudioPacket(this, time, packet);
        }
Ejemplo n.º 4
0
    internal static bool Deserialize(Stream raw, StreamCapabilities _streamCapabilities)
    {
        var reader = new N2HBinaryReader(raw);
        //var length = raw.GetAvaliableByteCounts();
        //if (length < 28)
        //{
        //    Logger.FATAL("Not enough data");
        //    return false;
        //}
        var ver = reader.ReadUInt64();

        if (ver != Utils.__STREAM_CAPABILITIES_VERSION)
        {
            Logger.FATAL("Invalid stream capabilities version. Wanted: {0}; Got: {1}",
                         Utils.__STREAM_CAPABILITIES_VERSION, ver);
            return(false);
        }
        _streamCapabilities.Clear();
        _streamCapabilities.VideoCodecId  = (VideoCodec)reader.ReadByte();
        _streamCapabilities.AudioCodecId  = (AudioCodec)reader.ReadByte();
        _streamCapabilities.BandwidthHint = reader.ReadUInt32();

        if (_streamCapabilities.VideoCodecId == VideoCodec.H264 && !VideoAvc.Deserialize(raw, out _streamCapabilities.Avc))
        {
            Logger.FATAL("Unable to deserialize avc");
            return(false);
        }
        if (_streamCapabilities.AudioCodecId == AudioCodec.Aac &&
            !AudioAac.Deserialize(raw, out _streamCapabilities.Aac))
        {
            Logger.FATAL("Unable to deserialize aac");
            return(false);
        }
        return(true);
    }
Ejemplo n.º 5
0
        public static bool Deserialize(Stream src, out AudioAac dest)
        {
            dest = new AudioAac();
            var length = src.GetAvaliableByteCounts();

            if (length < 4)
            {
                Logger.FATAL("Not enough data");
                return(false);
            }
            using (var reader = new N2HBinaryReader(src))
            {
                dest._aacLength = reader.ReadUInt32();
                if (length < 4 + dest._aacLength)
                {
                    Logger.FATAL("Not enough data");
                    return(false);
                }
                if (!dest.Init(src, (int)dest._aacLength))
                {
                    Logger.FATAL("Unable to init AAC");
                    return(false);
                }
            }
            return(true);
        }
Ejemplo n.º 6
0
        public static bool Deserialize(Stream src, out VideoAvc dest)
        {
            dest = new VideoAvc();
            if (src.GetAvaliableByteCounts() < 2)
            {
                Logger.FATAL("Not enough data");
                return(false);
            }
            var reader = new N2HBinaryReader(src);

            var _spsLength = reader.ReadUInt16();

            if (src.GetAvaliableByteCounts() < _spsLength + 2 + 8)
            {
                Logger.FATAL("Not enough data");
                return(false);
            }
            var psps       = reader.ReadBytes(_spsLength);
            var _ppsLength = reader.ReadUInt16();

            if (src.GetAvaliableByteCounts() < _ppsLength + 2 + 8)
            {
                Logger.FATAL("Not enough data");
                return(false);
            }
            var ppps = reader.ReadBytes(_ppsLength);

            dest.Init(psps, ppps);
            dest._widthOverride  = reader.ReadUInt32();
            dest._heightOverride = reader.ReadUInt32();

            return(true);
        }
Ejemplo n.º 7
0
 public void PushAudioPacket(uint time, N2HBinaryReader packet)
 {
     if (!ReceiveAudio)
     {
         _firstAudio = true;
         return;
     }
     if (_audioWriter == null)
     {
         Logger.FATAL("Listener {0} must be initialized before to be used", Id);
         return;
     }
     if (_audioWriter.Reseted)
     {
         _audioWriter.Reseted = false;
         WriteBounds();
     }
     time = ComputeTime(time);
     if (_firstAudio)
     {
         _firstAudio = false;
         var size = Publication.AudioCodecBuffer.GetAvaliableByteCounts();
         if (size > 0)
         {
             _audioWriter.Write(time, Publication.AudioCodecBuffer, false);
         }
     }
     _audioWriter.Write(time, packet.BaseStream, _unbuffered);
 }
Ejemplo n.º 8
0
        public static bool ReadCRC(N2HBinaryReader packet)
        {
            // Check the first 2 CRC bytes
            packet.BaseStream.Position = 4;
            UInt16 sum = packet.ReadUInt16();

            return(sum == CheckSum(packet.BaseStream));
        }
Ejemplo n.º 9
0
 public static bool Decode(AESEngine aesDecrypt, N2HBinaryReader packet)
 {
     //var pos = packet.BaseStream.Position;
     //var buffer = packet.ReadBytes((int) packet.BaseStream.GetAvaliableByteCounts());
     // Decrypt
     // packet.BaseStream.Position = pos;
     aesDecrypt.Process(packet.BaseStream as MemoryStream);
     //packet.BaseStream.Write(buffer,0,buffer.Length);
     return(ReadCRC(packet));
 }
Ejemplo n.º 10
0
 public override void PacketHandler(N2HBinaryReader reader)
 {
     if (!Checked)
     {
         base.PacketHandler(reader);
     }
     else
     {
         MiddleSession.SendStream(reader.BaseStream, (int)(reader.BaseStream as InputStream).Published);
     }
 }
Ejemplo n.º 11
0
        public override bool FeedData(Stream pData, uint dataLength, uint processedLength, uint totalLength, uint absoluteTimestamp,
                                      bool isAudio)
        {
            var pos        = pData.Position;
            var firstByte  = pData.ReadByte();
            var secondByte = pData.ReadByte();

            pData.Position = pos;
            if (isAudio)
            {
                if ((firstByte >> 4) == 10 && secondByte == 0)
                {
                    pData.CopyDataTo(AudioCodecBuffer);
                    AudioCodecBuffer.Position = 0;
                    if (!Capabilities.InitAudioAAC(AudioCodecBuffer, (int)(AudioCodecBuffer.Length - 2)))
                    {
                        Logger.FATAL("InitAudioAAC failed");
                        return(false);
                    }
                    AudioCodecBuffer.Position = 0;
                }
                _lastAudioTime = absoluteTimestamp;
            }
            else
            {
                if (firstByte == 0x17 && secondByte == 0)
                {
                    pData.CopyDataTo(VideoCodecBuffer);
                    VideoCodecBuffer.Position = 0;
                    var reader    = new N2HBinaryReader(VideoCodecBuffer);
                    var spsLength = reader.ReadUInt16();
                    var pSPS      = reader.ReadBytes(spsLength);
                    reader.ReadByte();
                    var ppsLength = reader.ReadUInt16();
                    var pPPS      = reader.ReadBytes(ppsLength);
                    if (!Capabilities.InitVideoH264(pSPS, pPPS))
                    {
                        Logger.FATAL("InitVideoH264 failed");
                        return(false);
                    }
                    VideoCodecBuffer.Position = 0;
                }
                _lastVideoTime = absoluteTimestamp;
            }
            //var temp = OutStreams.Where(x => !x.IsEnqueueForDelete() && !x.FeedData(pData, dataLength, processedLength, totalLength, absoluteTimestamp, isAudio));
            //foreach (var baseOutNetRtmpStream in temp)
            //{
            //    this.Log().Info("Unable to feed OS:" + baseOutNetRtmpStream);
            //    baseOutNetRtmpStream.EnqueueForDelete();
            //    if (Protocol == baseOutNetRtmpStream.GetProtocol()) return false;
            //}
            base.FeedData(pData, dataLength, processedLength, totalLength, absoluteTimestamp, isAudio);
            return(true);
        }
Ejemplo n.º 12
0
 public void PushDataPacket(string name, N2HBinaryReader packet)
 {
     if (_unbuffered)
     {
         var offset = name.Length + 9;
         if (packet.BaseStream.Position >= offset)
         {
             packet.BaseStream.Position -= offset;
             _writer.WriteUnbufferedMessage(packet.BaseStream as MemoryStream);
             return;
         }
     }
     packet.BaseStream.CopyDataTo(_writer.WriteAMFPacket(name).BaseStream);
     //packet.BaseStream.CopyTo(_writer.WriteAMFPacket(name).BaseStream);
 }
Ejemplo n.º 13
0
        public override void PacketHandler(N2HBinaryReader reader)
        {
            reader.BaseStream.Position = 0;
            var ms = new MemoryStream();

            reader.BaseStream.CopyPartTo(ms, (int)reader.BaseStream.GetAvaliableByteCounts());
            ms.Position = 6;
            if (_outboundRtmfpProtocol.Session.Checked)
            {
                _outboundRtmfpProtocol.Session.SendStream(ms, (int)ms.Length);
            }
            else
            {
                _buffer.Add(ms);
            }
        }
Ejemplo n.º 14
0
        public void PushVideoPacket(uint time, N2HBinaryReader packet, uint numberLostFragments)
        {
            if (PublisherId == 0)
            {
                Logger.FATAL("Video packet pushed on a publication {0} who is idle", PublisherId);
                return;
            }
            if (numberLostFragments > 0)
            {
                _firstKeyFrame = false;
            }
            VideoQOS.Add(time, packet.Fragments, numberLostFragments, (uint)(packet.BaseStream.GetAvaliableByteCounts() + 5), (uint)(_publisher != null?_publisher.Ping:0));
            if (numberLostFragments > 0)
            {
                Logger.INFO("{0} video fragments lost on publication {1}", numberLostFragments, PublisherId);
            }
            var pos   = packet.BaseStream.Position;
            var temp  = packet.ReadByte();
            var temp2 = packet.ReadByte();

            packet.BaseStream.Position = pos;
            if ((temp & 0xF0) == 0x10)
            {
                _firstKeyFrame = true;
                if (temp == 0x17 && temp2 == 0)
                {
                    packet.BaseStream.CopyDataTo(VideoCodecBuffer);
                    VideoCodecBuffer.Position = 0;
                }
            }
            if (!_firstKeyFrame)
            {
                VideoQOS.DroppedFrames++;
                return;
            }

            foreach (var listener in Listeners)
            {
                listener.Value.PushVideoPacket(time, packet);
                //packet.BaseStream.Position = pos;
            }
            _publisher.OnVideoPacket(this, time, packet);
        }
Ejemplo n.º 15
0
 public void PushVideoPacket(uint time, N2HBinaryReader packet)
 {
     if (!ReceiveVideo)
     {
         //_firstKeyFrame = false;
         _firstVideo = true;
         return;
     }
     if (_videoWriter == null)
     {
         Logger.FATAL("Listener {0} must be initialized before to be used", Id);
         return;
     }
     //var temp = packet.ReadByte();
     //packet.BaseStream.Position--;
     //if ((temp & 0xF0) == 0x10) _firstKeyFrame = true;
     //if (!_firstKeyFrame)
     //{
     //    _videoWriter.QOS.DroppedFrames++;
     //    return;
     //}
     if (_videoWriter.Reseted)
     {
         _videoWriter.Reseted = false;
         WriteBounds();
     }
     time = ComputeTime(time);
     if (_firstVideo)
     {
         _firstVideo = false;
         var size = Publication.VideoCodecBuffer.GetAvaliableByteCounts();
         if (size > 0)
         {
             _videoWriter.Write(time, Publication.VideoCodecBuffer, false);
         }
     }
     _videoWriter.Write(time, packet.BaseStream, _unbuffered);
 }
Ejemplo n.º 16
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();
            }
        }
Ejemplo n.º 17
0
 public void Flush(H2NBinaryWriter writer, ulong stage, byte flags, bool header, N2HBinaryReader reader, ushort size)
 {
     Debug.WriteLine("sent:{0} stage {1}", Id, stage);
     if (_stageAck == 0 && header)
     {
         flags |= MESSAGE_HEADER;
     }
     if (size == 0)
     {
         flags |= MESSAGE_ABANDONMENT;
     }
     if (Closed && _messages.Count == 1)
     {
         flags |= MESSAGE_END;
     }
     writer.Write(flags);
     if (header)
     {
         writer.Write7BitLongValue(Id);
         writer.Write7BitLongValue(stage);
         writer.Write7BitLongValue(stage - _stageAck);
         if (_stageAck == 0)
         {
             writer.WriteString8(Signature);
             if (FlowId > 0)
             {
                 writer.Write((byte)(1 + H2NBinaryWriter.Get7BitValueSize(FlowId)));
                 writer.Write((byte)0x0a);
                 writer.Write7BitLongValue(FlowId);
             }
             writer.Write((byte)0);
         }
     }
     if (size > 0)
     {
         reader.BaseStream.CopyPartTo(writer.BaseStream, size);
     }
 }
Ejemplo n.º 18
0
 protected Message(MemoryStream stream, bool repeatable)
 {
     _stream    = stream;
     Reader     = new N2HBinaryReader(stream);
     Repeatable = repeatable;
 }
Ejemplo n.º 19
0
        public virtual void PacketHandler(N2HBinaryReader reader)
        {
            if (IsEnqueueForDelete)
            {
                return;
            }
            RecTimestamp.Restart();
            var marker = reader.ReadByte() | 0xF0;

            TimeSent = reader.ReadUInt16();
            if (marker == (Target == null?0xFD:0xFE))
            {
                var time     = RtmfpUtils.TimeNow();
                var timeEcho = reader.ReadUInt16();
                if (timeEcho > time)
                {
                    if (timeEcho - time < 30)
                    {
                        time = 0;
                    }
                    else
                    {
                        time += (ushort)(0xFFFF - timeEcho);
                    }
                    timeEcho = 0;
                }
                Peer.Ping = (ushort)((time - timeEcho) * Defines.RTMFP_TIMESTAMP_SCALE);
            }
            else if (marker != (Target == null ? 0xF9 : 0xFA))
            {
                Logger.WARN("Packet marker unknown:{0}", marker);
                return;
            }
            byte  flags     = 0;
            Flow  flow      = null;
            ulong stage     = 0;
            ulong deltaNAck = 0;
            var   type      = reader.BaseStream.GetAvaliableByteCounts() > 0 ? reader.ReadByte() : (byte)0xFF;

            //Debug.WriteLine("rec:{0:x}",type);
            while (type != 0xFF)
            {
                var  size         = reader.ReadUInt16();
                long nextPos      = reader.BaseStream.Position + size;
                var  oldPublished = (reader.BaseStream as InputStream).Published;
                (reader.BaseStream as InputStream).Published = (uint)nextPos;
                switch (type)
                {
                case 0x0c:
                    Fail("failed on client side");
                    break;

                case 0x4c:
                    _failed = true;
                    EnqueueForDelete();
                    return;

                case 0x01:
                    if (!Peer.Connected)
                    {
                        Fail("Timeout connection client");
                    }
                    else
                    {
                        WriteMessage(0x41, 0);
                    }
                    goto case 0x41;

                case 0x41:
                    Logger.INFO("keepAlive!");
                    _timesKeepalive = 0;
                    break;

                case 0x5e:
                    var idFlow = reader.Read7BitLongValue();
                    if (!FlowWriters.ContainsKey(idFlow))
                    {
                        Logger.WARN("FlowWriter {0} unfound for acknowledgment on session {1}", idFlow, Id);
                    }
                    else
                    {
                        var flowWriter = FlowWriters[idFlow];
                        flowWriter.Fail("flowWriter rejected on session " + Id);
                    }
                    break;

                case 0x18:
                    Fail("ack negative from server");
                    break;

                case 0x51:
                    //Acknowledgment
                    idFlow = reader.Read7BitLongValue();
                    if (FlowWriters.ContainsKey(idFlow))
                    {
                        FlowWriters[idFlow].Acknowledgment(reader);
                    }
                    else
                    {
                        Logger.WARN("FlowWriter {0} unfound for acknowledgment on session {1}", idFlow, Id);
                    }
                    break;

                case 0x10:
                    flags     = reader.ReadByte();
                    idFlow    = reader.Read7BitLongValue();
                    stage     = reader.Read7BitLongValue() - 1;
                    deltaNAck = reader.Read7BitLongValue() - 1;
                    //Debug.WriteLine("10:{0},{1},{2}",idFlow,stage,deltaNAck);
                    if (_failed)
                    {
                        break;
                    }
                    if (Flows.ContainsKey(idFlow))
                    {
                        flow = Flows[idFlow];
                    }
                    if ((flags & FlowWriter.MESSAGE_HEADER) != 0)
                    {
                        var   signature   = reader.ReadString8();
                        ulong assocFlowId = 0;
                        if (reader.ReadByte() > 0)
                        {
                            if (reader.ReadByte() != 0x0A)
                            {
                                Logger.WARN("Unknown fullduplex header part for the flow {0}", idFlow);
                            }
                            else
                            {
                                assocFlowId = reader.Read7BitLongValue();
                            }
                            var length = reader.ReadByte();
                            while (length > 0 && reader.BaseStream.GetAvaliableByteCounts() > 0)
                            {
                                Logger.WARN("Unknown message part on flow {0}", idFlow);
                                reader.BaseStream.Position += length;
                                length = reader.ReadByte();
                            }
                            if (length > 0)
                            {
                                Logger.FATAL("Bad header message part, finished before scheduled");
                            }
                        }
                        if (flow == null)
                        {
                            flow = CreateFlow(idFlow, signature, assocFlowId);
                        }
                    }
                    if (flow == null)
                    {
                    }
                    goto case 0x11;

                case 0x11:
                    ++stage;
                    ++deltaNAck;
                    if (type == 0x11)
                    {
                        flags = reader.ReadByte();
                    }
                    if (flow != null)
                    {
                        flow.FragmentHandler(stage, deltaNAck, reader.BaseStream, flags);
                        if (!string.IsNullOrEmpty(flow.Error))
                        {
                            Fail(flow.Error);
                            flow = null;
                        }
                    }
                    break;

                default:
                    Logger.FATAL("Message type {0} unknown", type);
                    break;
                }

                reader.BaseStream.Position = nextPos;
                (reader.BaseStream as InputStream).Published = oldPublished;
                type = (byte)(reader.BaseStream.GetAvaliableByteCounts() > 0 ? reader.ReadByte() : 0xFF);
                if (flow != null && type != 0x11)
                {
                    flow.Commit();
                    if (flow.Completed)
                    {
                        Flows.Remove(flow.Id);
                        flow.Dispose();
                    }
                    flow = null;
                }
                //else
                //{
                //    Debug.WriteLine("no commit:{0},{1:X}",flow?.Id.ToString() ?? "no flow",type);
                //}
            }
            SFlush(true);
        }
Ejemplo n.º 20
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);
            Debug.WriteLine("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;
            }
        }
Ejemplo n.º 21
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);
            }
        }