public override void Flush(byte type) { Writer.BaseStream.Position = 6; Writer.Write((byte)0x0b); Writer.Write(RtmfpUtils.TimeNow()); Writer.Write(type); Writer.Write((short)(Writer.BaseStream.GetAvaliableByteCounts() - 2)); var encoder = AesEncrypt.Next(AESEngine.AESType.SYMMETRIC); RtmfpUtils.EncodeAndPack(encoder, Writer, 0); EnqueueForOutbound(OutputBuffer); Writer.Clear(11); }
public void Flush(byte marker, bool echoTime, AESEngine.AESType aesType) { _lastFlowWriter = null; if (IsEnqueueForDelete) { return; } var outputBuffer = Writer.BaseStream; if (outputBuffer.Length >= Defines.RTMFP_MIN_PACKET_SIZE) { //Debug.WriteLine(outputBuffer.Length); if (RecTimestamp.Elapsed > TimeSpan.FromSeconds(30)) { echoTime = false; } var offset = 0; if (echoTime) { marker += 4; } else { offset = 2; } var timeStamp = RtmfpUtils.TimeNow(); //_outputBuffer.Ignore(offset); outputBuffer.Position = 6 + offset; outputBuffer.WriteByte(marker); Writer.Write(timeStamp); if (echoTime) { Writer.Write((ushort)(TimeSent + RtmfpUtils.Time(RecTimestamp.Elapsed))); } RtmfpUtils.EncodeAndPack(AesEncrypt.Next(aesType), Writer, FarId, offset); EnqueueForOutbound(outputBuffer as MemoryStream, offset); Writer.Clear(11); } }
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); }