示例#1
0
	void add(PacketReader& fragment) {
		string::size_type old = _pBuffer->size();
		_pBuffer->resize(old + fragment.available(),true);
		if(_pBuffer->size()>old)
			memcpy(_pBuffer->data()+old,fragment.current(),fragment.available());
		++(UInt16&)fragments;
	}
示例#2
0
	void add(PacketReader& fragment) {
		string::size_type old = _buffer.size();
		_buffer.resize(old + (string::size_type)fragment.available());
		if(_buffer.size()>old)
			memcpy(&_buffer[old],fragment.current(),(size_t)fragment.available());
		++(UInt16&)fragments;
	}
示例#3
0
bool WSSession::buildPacket(PacketReader& packet) {
	if (packet.available()<2)
		return false;
	UInt8 type = packet.read8() & 0x0F;
	UInt8 lengthByte = packet.read8();

	UInt32 size=lengthByte&0x7f;
	if (size==127) {
		if (packet.available()<8)
			return false;
		size = (UInt32)packet.read64();
	} else if (size==126) {
		if (packet.available()<2)
			return false;
		size = packet.read16();
	}

	if(lengthByte&0x80)
		size += 4;

	if (packet.available()<size)
		return false;

	packet.shrink(size);

	if (lengthByte & 0x80) {
		shared_ptr<WSUnmasking> pWSUnmasking(new WSUnmasking(invoker, packet.current(),packet.available(), type));
		decode<WSUnmasking>(pWSUnmasking);
	} else {
		packet.reset(packet.position()-1);
		*(UInt8*)packet.current() = type;
	}
	return true;
}
示例#4
0
void ServerConnection::packetHandler(PacketReader& packet) {

	UInt8 marker = packet.read8();
	if(marker!=0x0b) {
		ERROR("ServerConnection with an unknown %u marker, it should be 0x0b",marker);
		return;
	}

	packet.next(2);
	UInt8 id = packet.read8();
	switch(id) {
		case 0x71: {
			packet.next(2);
			string tag;
			packet.readString8(tag);
			map<string,P2PHandshakerAddress>::iterator it = _p2pHandshakers.find(tag);
			if(it==_p2pHandshakers.end()) {
				ERROR("Unknown ServerConnection tag %s on P2P handshake",tag.c_str());
				break;
			}

			(SocketAddress&)_handshake.peer.address = it->second;
			packet.reset(0);
			PacketWriter writer(packet.current(),packet.available()+16); // +16 for futur 0xFFFF padding
			writer.clear(packet.available());
			_handshake.send(writer);
			_p2pHandshakers.erase(it);

			break;
		}
		case 0x40: {
			if(!_connected) {
				// Edge hello response
				_connected=true;
				return;
			}
			// Edge keepalive
			PacketWriter& packet(writer());
			packet.write8(0x41);
			packet.write16(0);
			flush();
			INFO("Keepalive RTMFP server");
			break;
		}
		case 0x45: {
			// Server is death!
			(bool&)died=true;
			break;
		}
		default:
			ERROR("Unkown ServerConnection packet id %u",id);
	}


}
示例#5
0
Message::Type Flow::unpack(PacketReader& reader) {
	if(reader.available()==0)
		return Message::EMPTY;
	Message::Type type = (Message::Type)reader.read8();
	switch(type) {
		// amf content
		case 0x11:
			reader.next(1);
		case Message::AMF_WITH_HANDLER:
			reader.next(4);
			return Message::AMF_WITH_HANDLER;
		case Message::AMF:
			reader.next(5);
		case Message::AUDIO:
		case Message::VIDEO:
			break;
		// raw data
		case 0x04:
			reader.next(4);
		case 0x01:
			break;
		default:
			ERROR("Unpacking type '%02x' unknown",type);
			break;
	}
	return type;
}
示例#6
0
AMF::ContentType RTMFPFlow::unpack(PacketReader& packet,UInt32& time) {
	if(packet.available()==0)
		return AMF::EMPTY;
	AMF::ContentType type = (AMF::ContentType)packet.read8();
	switch(type) {
		// amf content
		case AMF::INVOCATION_AMF3:
			packet.next(1);
		case AMF::INVOCATION:
			packet.next(4);
			return AMF::INVOCATION;
		case AMF::AUDIO:
		case AMF::VIDEO:
			time = packet.read32();
			break;
		case AMF::DATA:
			packet.next(1);
		case AMF::RAW:
			packet.next(4);
		case AMF::CHUNKSIZE:
			break;
		default:
			ERROR("Unpacking type '",Format<UInt8>("%02x",(UInt8)type),"' unknown");
			break;
	}
	return type;
}
示例#7
0
bool RTMFP::Decode(Exception& ex,RTMFPEngine& aesDecrypt,PacketReader& packet) {
	// Decrypt
	aesDecrypt.process(packet.current(),(UInt8*)packet.current(),packet.available());
	bool result = ReadCRC(packet);
	if (!result)
		ex.set(Exception::CRYPTO, "Bad RTMFP CRC sum computing");
	return result;
}
示例#8
0
文件: RTMFP.cpp 项目: agazso/Cumulus
bool RTMFP::Decode(AESEngine& aesDecrypt,PacketReader& packet) {
	// Decrypt
	aesDecrypt.process(packet.current(),packet.current(),packet.available());

	// Check the first 2 CRC bytes 
	packet.reset(4);
	UInt16 sum = packet.read16();
	return (sum == CheckSum(packet));
}
示例#9
0
void Listener::pushDataPacket(const string& name,PacketReader& packet) {
	// TODO create _dataWriter ??
	if(_unbuffered) {
		UInt16 offset = name.size()+9;
		if(packet.position()>=offset) {
			packet.reset(packet.position()-offset);
			_writer.writeUnbufferedMessage(packet.current(),packet.available());
			return;
		}
		WARN("Written unbuffered impossible, it requires %u head bytes available on PacketReader given",offset);
	}
	StreamCopier::copyStream(packet.stream(),_writer.writeAMFPacket(name).writer.stream());
}
示例#10
0
bool WSWriter::writeMedia(MediaType type,UInt32 time,PacketReader& packet,Parameters& properties) {
	if(state()==CLOSED)
		return true;
	switch(type) {
		case START:
			writeInvocation("__publishing").writeString(string((const char*)packet.current(),packet.available()));
			break;
		case STOP:
			writeInvocation("__unpublishing").writeString(string((const char*)packet.current(),packet.available()));
			break;
		case DATA: {
			JSONWriter& writer = newDataWriter();
			writer.packet.write8('[');
			writer.packet.writeRaw(packet.current(),packet.available());
			writer.packet.write8(']');
			break;
		}
		case INIT:
			break;
		default:
			return Writer::writeMedia(type,time,packet,properties);
	}
	return true;
}
示例#11
0
	void write(UInt32 time,PacketReader& data,bool unbuffered) {
	//	if(_type==0x08)
	//		time=0;
	/*	if(_type==0x09)
			TRACE("Video timestamp : %u",_time)
		else
			TRACE("Audio timestamp : %u",_time);*/
		if(unbuffered) {
			if(data.position()>=5) {
				data.reset(data.position()-5);
				PacketWriter writer(data.current(),5);
				writer.write8(_type);
				writer.write32(time);
				writeUnbufferedMessage(data.current(),data.available(),data.current(),5);
				return;
			}
			WARN("Written unbuffered impossible, it requires 5 head bytes available on PacketReader given");
		}
		BinaryWriter& out = writeRawMessage(true);
		out.write8(_type);
		out.write32(time);
		StreamCopier::copyStream(data.stream(),out.stream());

	}
示例#12
0
void Middle::targetPacketHandler(PacketReader& packet) {

	if(_firstResponse)
		((Timestamp&)peer.lastReceptionTime).update(); // To emulate a long ping corresponding, otherwise client send multiple times each packet
	_firstResponse = false;

	UInt8 marker = packet.read8();
	
	_timeSent = packet.read16(); // time

	UInt16 timeEcho(0);
	if((marker|0xF0) == 0xFE)
		timeEcho = packet.read16(); // time echo

	PacketWriter& packetOut = writer();

	int pos = packetOut.position();

	UInt8 type = packet.available()>0 ? packet.read8() : 0xFF;

	UInt64 idFlow,stage;
	UInt8 nbPeerSent = 0;

	while(type!=0xFF) {
		int posType = packetOut.position();
		packetOut.write8(type);

		UInt16 size = packet.read16();
		PacketReader content(packet.current(),size);packetOut.write16(size);

		if(type==0x10 || type==0x11) {
			UInt8 flag = content.read8();packetOut.write8(flag);
			if(type==0x10) {
				idFlow = content.read7BitLongValue();packetOut.write7BitLongValue(idFlow);
				stage = content.read7BitLongValue();packetOut.write7BitLongValue(stage);
				packetOut.write7BitLongValue(content.read7BitLongValue());
			} else
				++stage;
			
			if(!(flag&MESSAGE_WITH_BEFOREPART)) {

				if(flag&MESSAGE_HEADER) {
					UInt8 len = content.read8(); packetOut.write8(len);
					while(len!=0) {
						packetOut.writeRaw(content.current(),len);
						content.next(len);
						len = content.read8(); packetOut.write8(len);
					}
				}

				UInt8 flagType = content.read8(); packetOut.write8(flagType);
				if(flagType==0x09) {
					UInt32 time = content.read32(); packetOut.write32(time);
					TRACE("Timestamp/Flag video : %u/%2x",time,*content.current());
				} else if(flagType==0x08) {
					UInt32 time = content.read32(); packetOut.write32(time);
					TRACE("Timestamp/Flag audio : %u/%2x",time,*content.current());
				} else if(flagType==0x04) {
					packetOut.write32(content.read32());
					UInt16 a = content.read16();packetOut.write16(a);
					UInt32 b = content.read32(); packetOut.write32(b);
					if(content.available()>0) {
						UInt32 c = content.read32(); packetOut.write32(c);
						if(a!=0x22) {
							DEBUG("Raw %llu : %.2x %u %u",idFlow,a,b,c)
						} else {
							TRACE("Bound %llu : %.2x %u %u",idFlow,a,b,c);
						}
					} else
						DEBUG("Raw %llu : %.2x %u",idFlow,a,b)
					
				/*	if(a==0x1F) {
						packetOut.reset(posType);
						content.next(content.available());
					}*/
				}
示例#13
0
void Middle::packetHandler(PacketReader& packet) {
	if(!_pMiddleAesEncrypt)
		manage(); // to wait the target handshake response

	// Middle to target
	PacketWriter& request = requester();

	UInt8 marker = packet.read8();
	request << marker;

	request << packet.read16();

	if((marker|0xF0) == 0xFD)
		request.write16(packet.read16()); // time echo

	int pos = request.position();

	UInt8 type = packet.available()>0 ? packet.read8() : 0xFF;
	while(type!=0xFF) {
		UInt16 size = packet.read16();
		PacketReader content(packet.current(),size);

		PacketWriter out(request.begin()+request.position(),request.available()); // 3 for future type and size
		out.clear(3);

		if(type==0x10) {

			out.write8(content.read8());
			UInt64 idFlow = content.read7BitLongValue();out.write7BitLongValue(idFlow);
			UInt64 stage = content.read7BitLongValue();out.write7BitLongValue(stage);

			if(idFlow==0x02 && stage==0x01) {
				if(!_isPeer) {
				
					/// Replace NetConnection infos

					out.writeRaw(content.current(),14);content.next(14);

					// first string
					string tmp;
					content.readString16(tmp);out.writeString16(tmp);

					AMFWriter writer(out);
					writer.amf0Preference=true;
					AMFReader reader(content);
					writer.writeNumber(reader.readNumber()); // double
					
					AMFSimpleObject obj;
					reader.readSimpleObject(obj);
					
					/// Replace tcUrl
					if(obj.has("tcUrl"))
						obj.setString("tcUrl",_queryUrl);
					
					writer.writeSimpleObject(obj);

				} else {

					out.writeRaw(content.current(),3);content.next(3);
					UInt16 netGroupHeader = content.read16();out.write16(netGroupHeader);
					if(netGroupHeader==0x4752) {

						map<string,string>::const_iterator it = peer.properties.find("groupspec");
						if(it!=peer.properties.end()) {
							out.writeRaw(content.current(),71);content.next(71);
							UInt8 result1[AES_KEY_SIZE];
							UInt8 result2[AES_KEY_SIZE];
							HMAC(EVP_sha256(),&_sharedSecret[0],_sharedSecret.size(),&_targetNonce[0],_targetNonce.size(),result1,NULL);
							HMAC(EVP_sha256(),it->second.c_str(),it->second.size(),result1,AES_KEY_SIZE,result2,NULL);
							out.writeRaw(result2,AES_KEY_SIZE);content.next(AES_KEY_SIZE);
							out.writeRaw(content.current(),4);content.next(4);
							out.writeRaw(_target.peerId,ID_SIZE);content.next(ID_SIZE);
						} else
							WARN("No groupspec client property indicated to make working the 'man-in-the-middle' mode between peers in a NetGroup case");
						
					}
				}
			}

		}  else if(type == 0x4C) {
			 kill();
			 return;
		}  else if(type == 0x51) {
			//printf("%s\n",Util::FormatHex(content.current(),content.available()).c_str());
		}
		out.writeRaw(content.current(),content.available());

		packet.next(size);

		if(out.length()>=3) {
			request<<type;
			size = out.length()-3;
			request.write16(size);request.next(size);
		}


		type = packet.available()>0 ? packet.read8() : 0xFF;
	}

	if(request.length()>pos)
		sendToTarget();
}
示例#14
0
	Fragment(PacketReader& data,UInt8 flags) : flags(flags),Buffer<UInt8>(data.available()) {
		data.readRaw(begin(),size());
	}
示例#15
0
文件: RTMFP.cpp 项目: 191919/Cumulus
bool RTMFP::Decode(AESEngine& aesDecrypt,PacketReader& packet) {
	// Decrypt
	aesDecrypt.process(packet.current(),packet.current(),packet.available());
	return ReadCRC(packet);
}
示例#16
0
void WSSession::packetHandler(PacketReader& packet) {
	UInt8 type = 0;
	Exception ex;
	if(peer.connected) {
		type = packet.read8();	
		
		switch(type) {
			case WS::TYPE_BINARY: {
				RawReader reader(packet);
				peer.onMessage(ex, "onMessage",reader,WS::TYPE_BINARY);
				break;
			}
			case WS::TYPE_TEXT: {
				if(!JSONReader::IsValid(packet)) {
					RawReader reader(packet);
					peer.onMessage(ex, "onMessage",reader);
					break;
				}
				JSONReader reader(packet);
				if(reader.followingType()!=JSONReader::STRING) {
					peer.onMessage(ex, "onMessage",reader);
					break;
				}
				string name;
				reader.readString(name);
				if(name=="__publish") {
					if(reader.followingType()!=JSONReader::STRING) {
						ex.set(Exception::PROTOCOL, "__publish method takes a stream name in first parameter",WS::CODE_MALFORMED_PAYLOAD);
						break;
					}
					reader.readString(name);
					if(_pPublication)
						invoker.unpublish(peer,_pPublication->name());
					_pPublication = invoker.publish(ex, peer,name);
				} else if(name=="__play") {
					if(reader.followingType()!=JSONReader::STRING) {
						ex.set(Exception::PROTOCOL, "__play method takes a stream name in first parameter",WS::CODE_MALFORMED_PAYLOAD);
						break;
					}
					reader.readString(name);
					
					closeSusbcription();
				} else if(name=="__closePublish") {
					closePublication();
				} else if(name=="__closePlay") {
					closeSusbcription();
				} else if (name == "__close") {
					closePublication();
					closeSusbcription();
					
				} else if(_pPublication) {
					reader.reset();
					_pPublication->pushData(reader);
				} else
					peer.onMessage(ex, name,reader);
				break;
			}
			case WS::TYPE_CLOSE:
				_writer.close(packet.available() ? packet.read16() : 0);
				break;
			case WS::TYPE_PING:
				_writer.writePong(packet.current(),packet.available());
				break;
			case WS::TYPE_PONG:
				peer.setPing(_writer.ping = (UInt16)(_time.elapsed()/1000));
				break;
			default:
				ex.set(Exception::PROTOCOL, Format<UInt8>("Type %#x unknown", type), WS::CODE_MALFORMED_PAYLOAD);
				break;
		}
		
		if (ex) {
			ERROR(ex.error());
			_writer.close((ex.code()==Exception::APPLICATION || ex.code() == Exception::SOFTWARE) ? WS::CODE_PROTOCOL_ERROR : ex.code());	
		}
		
	}

	if(!peer.connected || type==WS::TYPE_CLOSE)
		kill();
	else
		_writer.flush();
}
示例#17
0
	Packet(PacketReader& fragment) : fragments(1),_pMessage(NULL),_buffer((string::size_type)fragment.available()) {
		if(_buffer.size()>0)
			memcpy(&_buffer[0],fragment.current(),_buffer.size());
	}
示例#18
0
void Session::packetHandler(PacketReader& packet) {

	_recvTimestamp.update();

	// Read packet
	UInt8 marker = packet.read8()|0xF0;
	
	_timeSent = packet.read16();

	// with time echo
	if(marker == 0xFD)
		_peer.setPing(RTMFP::Time(_recvTimestamp.epochMicroseconds())-packet.read16());
	else if(marker != 0xF9)
		WARN("Packet marker unknown : %02x",marker);


	// Variables for request (0x10 and 0x11)
	UInt8 flags;
	Flow* pFlow=NULL;
	UInt32 stage=0;
	UInt32 deltaNAck=0;

	UInt8 type = packet.available()>0 ? packet.read8() : 0xFF;
	bool answer = false;

	// Can have nested queries
	while(type!=0xFF) {

		UInt16 size = packet.read16();

		PacketReader message(packet.current(),size);		

		switch(type) {
			case 0x0c :
				fail("Session failed on the client side");
				break;

			case 0x4c :
				/// Session death!
				kill();
				break;

			/// KeepAlive
			case 0x01 :
				writeMessage(0x41,0);
			case 0x41 :
				_timesKeepalive=0;
				break;

			case 0x5e : {
				// Flow exception!
				UInt32 id = message.read7BitValue();
				
				FlowWriter* pFlowWriter = flowWriter(id);
				if(pFlowWriter)
					pFlowWriter->fail("receiver has rejected the flow");
				else
					WARN("FlowWriter %u unfound for failed signal",id);
				break;

			}
			case 0x18 :
				/// This response is sent when we answer with a Acknowledgment negative
				// It contains the id flow
				// I don't unsertand the usefulness...
				//pFlow = &flow(message.read8());
				//stage = pFlow->stageSnd();
				// For the moment, we considerate it like a exception
				fail("ack negative from server"); // send fail message immediatly
				break;

			case 0x51 : {
				/// Acknowledgment
				UInt32 id = message.read7BitValue();
				FlowWriter* pFlowWriter = flowWriter(id);
				if(pFlowWriter) {
					UInt8 ack = message.read8();
					while(ack==0xFF)
						ack = message.read8();
					if(ack>0)
						pFlowWriter->acknowledgment(message.read7BitValue());
					else {
						// In fact here, we should send a 0x18 message (with id flow),
						// but it can create a loop... We prefer the following behavior
						pFlowWriter->fail("ack negative from client");
					}

				} else
					WARN("FlowWriter %u unfound for acknowledgment",id);
				break;
			}
			/// Request
			// 0x10 normal request
			// 0x11 special request, in repeat case (following stage request)
			case 0x10 : {
				flags = message.read8();
				UInt32 idFlow = message.read7BitValue();
				stage = message.read7BitValue()-1;
				deltaNAck = message.read7BitValue()-1;

				map<UInt32,Flow*>::const_iterator it = _flows.find(idFlow);
				pFlow = it==_flows.end() ? NULL : it->second;

				// Header part if present
				if(flags & MESSAGE_HEADER) {
					string signature;
					message.readString8(signature);

					if(!pFlow)
						pFlow = createFlow(idFlow,signature);

					if(message.read8()>0) {

						// Fullduplex header part
						if(message.read8()!=0x0A)
							WARN("Unknown fullduplex header part for the flow '%u'",idFlow)
						else
							message.read7BitValue(); // Fullduplex useless here! Because we are creating a new Flow!

						// Useless header part 
						UInt8 length=message.read8();
						while(length>0 && message.available()) {
							WARN("Unknown message part on flow '%u'",idFlow);
							message.next(length);
							length=message.read8();
						}
						if(length>0)
							ERROR("Bad header message part, finished before scheduled");
					}

				}
				
				if(!pFlow) {
					WARN("Flow %u unfound",idFlow);
					((UInt32&)_pFlowNull->id) = idFlow;
					pFlow = _pFlowNull;
				}

			}	
			case 0x11 : {
				++stage;
				++deltaNAck;

				// has Header?
				if(type==0x11)
					flags = message.read8();

				// Process request
				pFlow->fragmentHandler(stage,deltaNAck,message,flags);
				if(!pFlow->error().empty())
					fail(pFlow->error()); // send fail message immediatly

				break;
			}
			default :
				ERROR("Message type '%02x' unknown",type);
		}

		// Next
		packet.next(size);
		type = packet.available()>0 ? packet.read8() : 0xFF;

		// Commit Flow
		if(pFlow && stage>0 && type!= 0x11) {
			pFlow->commit();
			if(pFlow->consumed()) {
				_flows.erase(pFlow->id);
				delete pFlow;
			}
			pFlow=NULL;
		}
	}
示例#19
0
void Middle::targetPacketHandler(PacketReader& packet) {

	if(_firstResponse)
		_recvTimestamp.update(); // To emulate a long ping corresponding, otherwise client send multiple times each packet
	_firstResponse = false;

	UInt8 marker = packet.read8();
	
	UInt16 timestamp = packet.read16(); // time

	if((marker|0xF0) == 0xFE)
		_timeSent = packet.read16(); // time echo

	PacketWriter& packetOut = writer();

	int pos = packetOut.position();

	UInt8 type = packet.available()>0 ? packet.read8() : 0xFF;

	UInt32 idFlow,stage;
	UInt8 nbPeerSent = 0;

	while(type!=0xFF) {
		int posType = packetOut.position();
		packetOut.write8(type);

		UInt16 size = packet.read16();
		PacketReader content(packet.current(),size);packetOut.write16(size);
		
		if(type==0x10 || type==0x11) {
			UInt8 flag = content.read8();packetOut.write8(flag);
			if(type==0x10) {
				idFlow = content.read7BitValue();packetOut.write7BitValue(idFlow);
				stage = content.read7BitValue();packetOut.write7BitValue(stage);
			} else
				++stage;

			packetOut.write7BitValue(content.read7BitValue());
			
			if(!(flag&MESSAGE_WITH_BEFOREPART)) {

				if(flag&MESSAGE_HEADER) {
					UInt8 len = content.read8(); packetOut.write8(len);
					while(len!=0) {
						packetOut.writeRaw(content.current(),len);
						content.next(len);
						len = content.read8(); packetOut.write8(len);
					}
				}

				UInt8 flagType = content.read8(); packetOut.write8(flagType);
				if(flagType==0x09) {
					UInt32 time = content.read32(); packetOut.write32(time);
					//TRACE("Timestamp/Flag video : %u/%2x",time,*content.current());
				} else if(flagType==0x08) {
					UInt32 time = content.read32(); packetOut.write32(time);
					//TRACE("Timestamp/Flag audio : %u/%2x",time,*content.current());
				} else if(flagType==0x04) {
					packetOut.write32(content.read32());
					UInt16 a = content.read16(); packetOut.write16(a);
					UInt32 b = content.read32(); packetOut.write32(b);
					UInt32 c = content.read32(); packetOut.write32(c);
					//TRACE("Bound %u : %u %u %u",idFlow,a,b,c);
				}

				if(flagType==0x0b && stage==0x01 && ((marker==0x4e && idFlow==0x03) || (marker==0x8e && idFlow==0x05))) {
					/// Replace "middleId" by "peerId"	

					UInt8 middlePeerIdWanted[ID_SIZE];
					content.readRaw(middlePeerIdWanted,ID_SIZE);

					++nbPeerSent;

					Sessions::Iterator it;
					for(it=_sessions.begin();it!=_sessions.end();++it) {
						Middle* pMiddle = (Middle*)it->second;
						if(pMiddle->middlePeer() == middlePeerIdWanted) {
							memcpy(middlePeerIdWanted,pMiddle->peer.id,ID_SIZE);
							break;
						}
					}
					packetOut.writeRaw(middlePeerIdWanted,ID_SIZE);	

				} else if(flagType == 0x01) {

					packetOut.writeRaw(content.current(),68);content.next(68);
					
					Entities<Group>::Iterator it;
					for(it = _invoker.groups.begin();it!=_invoker.groups.end();++it) {

						Group& group = *it->second;						
			
						Group::Iterator itP;
						for(itP=group.begin();itP!=group.end();++itP) {
							if((**itP)==_target.id) {
								UInt8 result1[AES_KEY_SIZE];
								UInt8 result2[AES_KEY_SIZE];
								HMAC(EVP_sha256(),_target.sharedSecret,KEY_SIZE,&_target.initiatorNonce[0],_target.initiatorNonce.size(),result1,NULL);
								HMAC(EVP_sha256(),group.id,ID_SIZE,result1,AES_KEY_SIZE,result2,NULL);
								packetOut.writeRaw(result2,AES_KEY_SIZE);content.next(AES_KEY_SIZE);
								packetOut.writeRaw(content.current(),4);content.next(4);
								packetOut.writeRaw(peer.id,ID_SIZE);content.next(ID_SIZE);
								break;
							}
						}
						if(itP!=group.end())
							break;

					}
				
					if(it==_invoker.groups.end())
						ERROR("Handshake NetGroup packet between peers without corresponding Group");

				}
			}

		} else if(type == 0x0F) {
			packetOut.writeRaw(content.current(),3);content.next(3);
			UInt8 peerId[ID_SIZE];
			content.readRaw(peerId,ID_SIZE);

			if(memcmp(peerId,peer.id,ID_SIZE)!=0 && memcmp(peerId,_middlePeer.id,ID_SIZE)!=0)
				WARN("The p2pHandshake target packet doesn't match the peerId (or the middlePeerId)");
			// Replace by the peer.id
			packetOut.writeRaw(peer.id,ID_SIZE);
		}

		packetOut.writeRaw(content.current(),content.available());
		packet.next(size);

		type = packet.available()>0 ? packet.read8() : 0xFF;
	}

	if(nbPeerSent>0)
		INFO("%02x peers sending",nbPeerSent);

	if(packetOut.length()>pos)
		flush();

}
示例#20
0
void Middle::packetHandler(PacketReader& packet) {
	if(!_pMiddleAesEncrypt) {
		DEBUG("500ms sleeping to wait target handshaking");
		Thread::sleep(500); // to wait the target handshake response
		manage();
	}

	// Middle to target
	PacketWriter& request = requester();

	UInt8 marker = packet.read8();
	request << marker;

	request << packet.read16();

	if((marker|0xF0) == 0xFD)
		request.write16(packet.read16()); // time echo

	int pos = request.position();

	UInt8 type = packet.available()>0 ? packet.read8() : 0xFF;
	while(type!=0xFF) {
		UInt16 size = packet.read16();
		PacketReader content(packet.current(),size);

		PacketWriter out(request.begin()+request.position(),request.available()); // 3 for future type and size
		out.clear(3);

		if(type==0x10) {

			out.write8(content.read8());
			UInt32 idFlow = content.read7BitValue();out.write7BitValue(idFlow);
			UInt32 stage = content.read7BitValue();out.write7BitValue(stage);

			if(idFlow==0x02 && stage==0x01) {
				if(!_isPeer) {
				
					/// Replace NetConnection infos

					out.writeRaw(content.current(),14);content.next(14);

					// first string
					string tmp;
					content.readString16(tmp);out.writeString16(tmp);

					AMFWriter writer(out);
					writer.amf0Preference=true;
					AMFReader reader(content);
					writer.writeNumber(reader.readNumber()); // double
					
					AMFSimpleObject obj;
					reader.readSimpleObject(obj);
					
					/// Replace tcUrl
					if(obj.has("tcUrl"))
						obj.setString("tcUrl",_queryUrl);
					
					writer.writeSimpleObject(obj);

				} else {

					out.writeRaw(content.current(),3);content.next(3);
					UInt16 netGroupHeader = content.read16();out.write16(netGroupHeader);
					if(netGroupHeader==0x4752) {
						out.writeRaw(content.current(),71);content.next(71);
						
						Entities<Group>::Iterator it;
						for(it = _invoker.groups.begin();it!=_invoker.groups.end();++it) {
	
							Group& group = *it->second;						
			
							Group::Iterator itP;
							for(itP=group.begin();itP!=group.end();++itP) {
								if((**itP)==_target.id) {
									UInt8 result1[AES_KEY_SIZE];
									UInt8 result2[AES_KEY_SIZE];
									HMAC(EVP_sha256(),_sharedSecret,KEY_SIZE,&_targetNonce[0],_targetNonce.size(),result1,NULL);
									HMAC(EVP_sha256(),group.id,ID_SIZE,result1,AES_KEY_SIZE,result2,NULL);
									out.writeRaw(result2,AES_KEY_SIZE);content.next(AES_KEY_SIZE);
									out.writeRaw(content.current(),4);content.next(4);
									out.writeRaw(_target.peerId,ID_SIZE);content.next(ID_SIZE);
									break;
								}
							}
							if(itP!=group.end())
								break;

						}
						if(it==_invoker.groups.end())
							ERROR("Handshake NetGroup packet between peers without corresponding Group");
						
					}
				}
			}

		}  else if(type == 0x4C) {
			 kill();
		}  else if(type == 0x51) {
			//printf("%s\n",Util::FormatHex(content.current(),content.available()).c_str());
		}
		out.writeRaw(content.current(),content.available());

		packet.next(size);

		if(out.length()>=3) {
			request<<type;
			size = out.length()-3;
			request.write16(size);request.next(size);
		}


		type = packet.available()>0 ? packet.read8() : 0xFF;
	}

	if(request.length()>pos)
		sendToTarget();
}
示例#21
0
	RTMFPPacket(const PoolBuffers& poolBuffers,PacketReader& fragment) : fragments(1),_pMessage(NULL),_pBuffer(poolBuffers,fragment.available()) {
		if(_pBuffer->size()>0)
			memcpy(_pBuffer->data(),fragment.current(),_pBuffer->size());
	}
示例#22
0
文件: Flow.cpp 项目: jacobdam/Cumulus
void Flow::messageHandler(UInt32 stage,PacketReader& message,UInt8 flags) {
	if(_completed)
		return;

	if(stage<=_stage) {
		DEBUG("Stage %u on flow %u has already been received",stage,id);
		return;
	}
	_stage = stage;

	PacketReader* pMessage(NULL);
	if(flags&MESSAGE_WITH_BEFOREPART){
		if(_sizeBuffer==0) {
			ERROR("A received message tells to have a 'afterpart' and nevertheless partbuffer is empty");
			return;
		}
		
		UInt8* pOldBuffer = _pBuffer;
		_pBuffer = new UInt8[_sizeBuffer + message.available()]();
		memcpy(_pBuffer,pOldBuffer,_sizeBuffer);
		memcpy(_pBuffer+_sizeBuffer,message.current(),message.available());
		_sizeBuffer += message.available();
		delete [] pOldBuffer;

		if(flags&MESSAGE_WITH_AFTERPART)
			return;

		pMessage = new PacketReader(_pBuffer,_sizeBuffer);
	} else if(flags&MESSAGE_WITH_AFTERPART) {
		if(_sizeBuffer>0) {
			ERROR("A received message tells to have not 'beforepart' and nevertheless partbuffer exists");
			delete [] _pBuffer;
			_sizeBuffer=0;
		}
		_sizeBuffer = message.available();
		_pBuffer = new UInt8[_sizeBuffer]();
		memcpy(_pBuffer,message.current(),_sizeBuffer);
		return;
	}
	if(!pMessage)
		pMessage = new PacketReader(message);

	UInt8 type = unpack(*pMessage);
	if(type!=EMPTY) {
		writer._callbackHandle = 0;
		string name;
		AMFReader amf(*pMessage);
		if(type==AMF_WITH_HANDLER || type==AMF) {
			amf.read(name);
			if(type==AMF_WITH_HANDLER) {
				writer._callbackHandle = amf.readNumber();
				amf.skipNull();
			}
		}

		// create code prefix
		writer._code.assign(_name);
		if(!name.empty()) {
			writer._code.append(".");
			writer._code.push_back(toupper(name[0]));
			if(name.size()>1)
				writer._code.append(&name[1]);
		}

		switch(type) {
			case AMF_WITH_HANDLER:
			case AMF:
				messageHandler(name,amf);
				break;
			case AUDIO:
				audioHandler(*pMessage);
				break;
			case VIDEO:
				videoHandler(*pMessage);
				break;
			default:
				rawHandler(type,*pMessage);
		}
	}

	delete pMessage;

	if(flags&MESSAGE_END)
		complete();

	if(_sizeBuffer>0) {
		delete [] _pBuffer;
		_sizeBuffer=0;
	}
}
示例#23
0
	void add(PacketReader& fragment) {
		_pBuffer->append(fragment.current(),fragment.available());
		++(UInt32&)fragments;
	}
示例#24
0
void RTMFPSession::packetHandler(PacketReader& packet) {

	_recvTimestamp.update();

	// Read packet
	UInt8 marker = packet.read8()|0xF0;
	
	_timeSent = packet.read16();

	// with time echo
	if(marker == 0xFD) {
		UInt16 time = RTMFP::TimeNow();
		UInt16 timeEcho = packet.read16();
		if(timeEcho>time) {
			if(timeEcho-time<30)
				time=0;
			else
				time += 0xFFFF-timeEcho;
			timeEcho = 0;
		}
		peer.setPing((time-timeEcho)*RTMFP_TIMESTAMP_SCALE);
	}
	else if(marker != 0xF9)
		WARN("RTMFPPacket marker unknown : ", Format<UInt8>("%02x",marker));


	// Variables for request (0x10 and 0x11)
	UInt8 flags;
	RTMFPFlow* pFlow=NULL;
	UInt64 stage=0;
	UInt64 deltaNAck=0;

	UInt8 type = packet.available()>0 ? packet.read8() : 0xFF;
	bool answer = false;

	// Can have nested queries
	while(type!=0xFF) {

		UInt16 size = packet.read16();

		PacketReader message(packet.current(),size);		

		switch(type) {
			case 0x0c :
				fail("failed on client side");
				break;

			case 0x4c :
				/// Session death!
				_failed = true; // to avoid the fail signal!!
				kill();
				return;

			/// KeepAlive
			case 0x01 :
				if(!peer.connected)
					fail("Timeout connection client");
				else
					writeMessage(0x41,0);
			case 0x41 :
				_timesKeepalive=0;
				break;

			case 0x5e : {
				// RTMFPFlow exception!
				UInt64 id = message.read7BitLongValue();
				
				RTMFPWriter* pRTMFPWriter = writer(id);
				if(pRTMFPWriter)
					pRTMFPWriter->fail("Writer rejected on session ",name());
				else
					WARN("RTMFPWriter ", id, " unfound for failed signal on session ", name());
				break;

			}
			case 0x18 :
				/// This response is sent when we answer with a Acknowledgment negative
				// It contains the id flow
				// I don't unsertand the usefulness...
				//pFlow = &flow(message.read8());
				//stage = pFlow->stageSnd();
				// For the moment, we considerate it like a exception
				fail("ack negative from server"); // send fail message immediatly
				break;

			case 0x51 : {
				/// Acknowledgment
				UInt64 id = message.read7BitLongValue();
				RTMFPWriter* pRTMFPWriter = writer(id);
				if(pRTMFPWriter)
					pRTMFPWriter->acknowledgment(message);
				else
					WARN("RTMFPWriter ",id," unfound for acknowledgment on session ",name());
				break;
			}
			/// Request
			// 0x10 normal request
			// 0x11 special request, in repeat case (following stage request)
			case 0x10 : {
				flags = message.read8();
				UInt64 idFlow = message.read7BitLongValue();
				stage = message.read7BitLongValue()-1;
				deltaNAck = message.read7BitLongValue()-1;
				
				if (_failed)
					break;

				map<UInt64,RTMFPFlow*>::const_iterator it = _flows.find(idFlow);
				pFlow = it==_flows.end() ? NULL : it->second;

				// Header part if present
				if(flags & MESSAGE_HEADER) {
					string signature;
					message.readString8(signature);

					if(!pFlow)
						pFlow = createFlow(idFlow,signature);

					if(message.read8()>0) {

						// Fullduplex header part
						if(message.read8()!=0x0A)
							WARN("Unknown fullduplex header part for the flow ",idFlow)
						else 
							message.read7BitLongValue(); // Fullduplex useless here! Because we are creating a new RTMFPFlow!

						// Useless header part 
						UInt8 length=message.read8();
						while(length>0 && message.available()) {
							WARN("Unknown message part on flow ",idFlow);
							message.next(length);
							length=message.read8();
						}
						if(length>0)
							ERROR("Bad header message part, finished before scheduled");
					}

				}
				
				if(!pFlow) {
					WARN("RTMFPFlow ",idFlow," unfound");
					((UInt64&)_pFlowNull->id) = idFlow;
					pFlow = _pFlowNull;
				}

			}	
			case 0x11 : {
				++stage;
				++deltaNAck;

				// has Header?
				if(type==0x11)
					flags = message.read8();

				// Process request
				if (pFlow)
					pFlow->fragmentHandler(stage, deltaNAck, message, flags);

				break;
			}
			default :
				ERROR("RTMFPMessage type '", Format<UInt8>("%02x", type), "' unknown");
		}

		// Next
		packet.next(size);
		type = packet.available()>0 ? packet.read8() : 0xFF;

		// Commit RTMFPFlow
		if(pFlow && type!= 0x11) {
			pFlow->commit();
			if(pFlow->consumed()) {
				_flows.erase(pFlow->id);
				delete pFlow;
			}
			pFlow=NULL;
		}
	}
示例#25
0
	RTMFPFragment(const PoolBuffers& poolBuffers,PacketReader& packet,UInt8 flags) : flags(flags),PoolBuffer(poolBuffers,packet.available()) {
		packet.read((*this)->size(),(*this)->data());
	}
示例#26
0
void RTMFPWriter::acknowledgment(PacketReader& packet) {

	UInt64 bufferSize = packet.read7BitLongValue(); // TODO use this value in reliability mechanism?
	
	if(bufferSize==0) {
		// In fact here, we should send a 0x18 message (with id flow),
		// but it can create a loop... We prefer the following behavior
		fail("Negative acknowledgment");
		return;
	}

	UInt64 stageAckPrec = _stageAck;
	UInt64 stageReaden = packet.read7BitLongValue();
	UInt64 stage = _stageAck+1;

	if(stageReaden>_stage) {
		ERROR("Acknowledgment received ",stageReaden," superior than the current sending stage ",_stage," on writer ",id);
		_stageAck = _stage;
	} else if(stageReaden<=_stageAck) {
		// already acked
		if(packet.available()==0)
			DEBUG("Acknowledgment ",stageReaden," obsolete on writer ",id);
	} else
		_stageAck = stageReaden;

	UInt64 maxStageRecv = stageReaden;
	UInt32 pos=packet.position();

	while(packet.available()>0)
		maxStageRecv += packet.read7BitLongValue()+packet.read7BitLongValue()+2;
	if(pos != packet.position()) {
		// TRACE(stageReaden,"..x"Util::FormatHex(reader.current(),reader.available()));
		packet.reset(pos);
	}

	UInt64 lostCount = 0;
	UInt64 lostStage = 0;
	bool repeated = false;
	bool header = true;
	bool stop=false;

	auto it=_messagesSent.begin();
	while(!stop && it!=_messagesSent.end()) {
		RTMFPMessage& message(**it);

		if(message.fragments.empty()) {
			CRITIC("RTMFPMessage ",(stage+1)," is bad formatted on fowWriter ",id);
			++it;
			continue;
		}

		map<UInt32,UInt64>::iterator itFrag=message.fragments.begin();
		while(message.fragments.end()!=itFrag) {
			
			// ACK
			if(_stageAck>=stage) {
				message.fragments.erase(message.fragments.begin());
				itFrag=message.fragments.begin();
				++_ackCount;
				++stage;
				continue;
			}

			// Read lost informations
			while(!stop) {
				if(lostCount==0) {
					if(packet.available()>0) {
						lostCount = packet.read7BitLongValue()+1;
						lostStage = stageReaden+1;
						stageReaden = lostStage+lostCount+packet.read7BitLongValue();
					} else {
						stop=true;
						break;
					}
				}
				// check the range
				if(lostStage>_stage) {
					// Not yet sent
					ERROR("Lost information received ",lostStage," have not been yet sent on writer ",id);
					stop=true;
				} else if(lostStage<=_stageAck) {
					// already acked
					--lostCount;
					++lostStage;
					continue;
				}
				break;
			}
			if(stop)
				break;
			
			// lostStage > 0 and lostCount > 0

			if(lostStage!=stage) {
				if(repeated) {
					++stage;
					++itFrag;
					header=true;
				} else // No repeated, it means that past lost packet was not repeatable, we can ack this intermediate received sequence
					_stageAck = stage;
				continue;
			}

			/// Repeat message asked!
			if(!message.repeatable) {
				if(repeated) {
					++itFrag;
					++stage;
					header=true;
				} else {
					INFO("RTMFPWriter ",id," : message ",stage," lost");
					--_ackCount;
					++_lostCount;
					_stageAck = stage;
				}
				--lostCount;
				++lostStage;
				continue;
			}

			repeated = true;
			// Don't repeate before that the receiver receives the itFrag->second sending stage
			if(itFrag->second >= maxStageRecv) {
				++stage;
				header=true;
				--lostCount;
				++lostStage;
				++itFrag;
				continue;
			}

			// Repeat message

			DEBUG("RTMFPWriter ",id," : stage ",stage," repeated");
			UInt32 fragment(itFrag->first);
			itFrag->second = _stage; // Save actual stage sending to wait that the receiver gets it before to retry
			UInt32 contentSize = message.size() - fragment; // available
			++itFrag;

			// Compute flags
			UInt8 flags = 0;
			if(fragment>0)
				flags |= MESSAGE_WITH_BEFOREPART; // fragmented
			if(itFrag!=message.fragments.end()) {
				flags |= MESSAGE_WITH_AFTERPART;
				contentSize = itFrag->first - fragment;
			}

			UInt32 size = contentSize+4;
			UInt32 availableToWrite(_band.availableToWrite());
			if(!header && size>availableToWrite) {
				_band.flush();
				header=true;
			}

			if(header)
				size+=headerSize(stage);

			if(size>availableToWrite)
				_band.flush();

			// Write packet
			size-=3;  // type + timestamp removed, before the "writeMessage"
			flush(_band.writeMessage(header ? 0x10 : 0x11,(UInt16)size)
				,stage,flags,header,message,fragment,contentSize);
			header=false;
			--lostCount;
			++lostStage;
			++stage;
		}

		if(message.fragments.empty()) {
			if(message.repeatable)
				--_repeatable;
			if(_ackCount || _lostCount) {
				_qos.add(_lostCount / (_lostCount + _ackCount));
				_ackCount=_lostCount=0;
			}
			
			delete *it;
			it=_messagesSent.erase(it);
		} else
			++it;
	
	}

	if(lostCount>0 && packet.available()>0)
		ERROR("Some lost information received have not been yet sent on writer ",id);


	// rest messages repeatable?
	if(_repeatable==0)
		_trigger.stop();
	else if(_stageAck>stageAckPrec || repeated)
		_trigger.reset();
}
示例#27
0
void Flow::rawHandler(UInt8 type,PacketReader& data) {
	ERROR("Raw message %s unknown for flow %llu",Util::FormatHex(data.current(),data.available()).c_str(),id);
}