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; }
public override void PacketHandler(N2HBinaryReader reader) { if (!Checked) base.PacketHandler(reader); else MiddleSession.SendStream(reader.BaseStream, (int) (reader.BaseStream as InputStream).Published); }
protected Message(MemoryStream stream, bool repeatable) { _stream = stream; Reader = new N2HBinaryReader(stream); Repeatable = repeatable; }
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); }
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); }
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); }
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); }
public InputStream() { Reader = new N2HBinaryReader(this); }
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); }
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; } }
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; }
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; }
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; }
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(); }
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); } }
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); } }
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); }
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)); }
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; } }