Example #1
0
void FifoReadCallback::forwardMessage(const PacketHeader& header,
                                      std::unique_ptr<folly::IOBuf>&& buf) {
  auto data = buf->coalesce();
  CHECK(data.size() == header.packetSize()) << "Invalid header buffer size!";
  messageReady_(header.connectionId(), header.packetId(),
                std::move(from_), std::move(to_), data);
}
Example #2
0
void FifoReadCallback::feedParser(const PacketHeader& header,
                                  std::unique_ptr<folly::IOBuf>&& buf) {
  auto bodyBuf = buf->coalesce();
  CHECK(bodyBuf.size() == header.packetSize())
    << "Invalid header buffer size!";
  auto& parser = parserMap_.fetch(header.msgId()).parser();
  if (header.packetId() == 0) {
    parser.reset();
  }
  parser.parse(bodyBuf);
}
Example #3
0
void FifoReadCallback::forwardMessage(const PacketHeader& header,
                                      std::unique_ptr<folly::IOBuf> buf) {
  auto data = buf->coalesce();
  CHECK(data.size() == header.packetSize()) << "Invalid header buffer size!";
  if (typeId_ != 0) {
    messageReady_(header.connectionId(), header.packetId(),
                  std::move(from_), std::move(to_), typeId_, msgStartTime_,
                  data);
    typeId_ = 0;
  } else {
    VLOG(2) << "Type id is 0. Skipping message.";
  }
}
Example #4
0
Status ConnectionOut::sendPacketWithHeader(Packet& p, PacketHeader h){
	assert(&p != &buffer);

	do {
		size_t n = std::min(p.remaining(), NRG_MAX_PACKET_SIZE - PacketHeader::size);

		if(p.remaining() > NRG_MAX_PACKET_SIZE - PacketHeader::size){
			h.flags |= PKTFLAG_CONTINUED;
		}

		h.write(buffer.reset());
		buffer.writeArray(p.getPointer(), n);

		if(cc.transform) cc.transform->apply(buffer, buffer2.reset());

		Packet& sendme = cc.transform ? buffer2 : buffer;
		last_status = sock.sendPacket(sendme, remote_addr);
		if(!last_status){
			return last_status;
		}

		p.seek(n, SEEK_CUR);
		++h.frag_index;

	} while(p.remaining());

	return last_status = StatusOK();
}
Example #5
0
void Battlenet::Session::ReadHandler()
{
    BitStream stream(std::move(GetReadBuffer()));
    _crypt.DecryptRecv(stream.GetBuffer(), stream.GetSize());

    while (!stream.IsRead())
    {
        try
        {
            PacketHeader header;
            header.Opcode = stream.Read<uint32>(6);
            if (stream.Read<bool>(1))
                header.Channel = stream.Read<int32>(4);

            if (header.Channel != AUTHENTICATION && (header.Channel != CONNECTION || header.Opcode != Connection::CMSG_PING) && !_authed)
            {
                TC_LOG_DEBUG("session.packets", "%s Received not allowed %s. Client has not authed yet.", GetClientInfo().c_str(), header.ToString().c_str());
                CloseSocket();
                return;
            }

            if (ClientPacket* packet = sPacketManager.CreateClientPacket(header, stream))
            {
                if (sPacketManager.IsHandled(header))
                    TC_LOG_DEBUG("session.packets", "%s Received %s", GetClientInfo().c_str(), PacketToStringHelper(packet).c_str());

                packet->CallHandler(this);
                delete packet;
            }
            else if (sPacketManager.GetClientPacketName(header))
            {
                LogUnhandledPacket(header);
                break;
            }
            else
            {
                TC_LOG_DEBUG("session.packets", "%s Received unknown %s", GetClientInfo().c_str(), header.ToString().c_str());
                break;
            }

            stream.AlignToNextByte();
        }
        catch (BitStreamPositionException const& e)
        {
            TC_LOG_ERROR("session.packets", "%s Exception thrown during packet processing %s", GetClientInfo().c_str(), e.what());
            CloseSocket();
            return;
        }
    }

    GetReadBuffer().Resize(size_t(BufferSizes::Read));
    AsyncRead();
}
Example #6
0
// Reads a key data from a stream 
PIStream &Key::operator<<(PIStream &in)
{
	// Read packet header
	PacketHeader header;
	in >> header;
	if (!header.valid()) {
		throw "Invalid packet header";
	}
	if (header.type() != PacketHeader::TYPE_SECRET_KEY) {
		throw Utils::strprintf("Invalid packet type %d (not a secret key)", header.type());
	}
	uint32_t headerOff = in.pos();

	// Read public key
	in >> m_version;
	if (m_version < 2 || 4 < m_version) {
		throw Utils::strprintf("Unspported key version %d", m_version);
	}
	in >> m_time;
	if (m_version < 4) {
		in >> m_expire;
	}
Example #7
0
bool ConnectionIn::addPacket(Packet& p){
	PacketHeader h;

	if(cc.transform){
		if(!cc.transform->remove(p, buffer.reset())){
			return false; // removal of packet transformation failed.
		}
	}

	Packet& input = cc.transform ? buffer : p;

	if(!h.read(input) || h.version != 0){
		return false; // packet has invalid header / unknown version.
	}

	int packet_age = 0;

	if(packet_history.none()){ // first packet recieved
		cc.seq_num = h.seq_num;
		packet_history[0] = 1;
	} else {
		int16_t seq_dist = static_cast<int16_t>(h.seq_num - cc.seq_num);

		if(abs(seq_dist) >= NRG_CONN_PACKET_HISTORY){
			return true; // packet is out of history range.
		}

		// states need to know about retransmissons of the newest packet
		if(seq_dist < 0 && (h.flags & PKTFLAG_RETRANSMISSION)){
			return true;
		}

		if(seq_dist > 0){ // new packet
			packet_history <<= seq_dist;
			packet_history[0] = 1;
			cc.seq_num = h.seq_num;

			// update ages of reassembly fragments and remove them if they're too old.
			for(auto& i : reassembly_buf){
				if(i.age >= 0) i.age += seq_dist;
				if(i.age > (int)NRG_CONN_PACKET_HISTORY){
					i.age = -1;
					i.data.reset();
				}
			}
		} else {
			if(packet_history[-seq_dist]){ // already recieved this packet.
				return true;
			} else {
				packet_history[-seq_dist] = 1;
				packet_age = -seq_dist;
			}
		}
	}

	if((h.flags & PKTFLAG_FINISHED) && (cc.seq_num != h.seq_num)){
		return false; // packet claims end of stream, but there is a newer one...
	}

	new_packet = true;

	// reconstruct packets that were split into multiple fragments.
	if(h.frag_index > 0 || (h.flags & PKTFLAG_CONTINUED)){

		if(h.frag_index >= reassembly_buf.size()){
			return false;
		}

		ReassemblyInfo& frag = reassembly_buf[h.frag_index];

		if(frag.age >= 0 && packet_age > frag.age){
			new_packet = false;
		} else {
			frag.data.writeArray(input.getPointer(), input.remaining());
			frag.age = packet_age;
			frag.continued = h.flags & PKTFLAG_CONTINUED;

			// check if the newly added fragment completes a full packet.
			for(size_t i = 0; i < reassembly_buf.size(); ++i){
				NRG_DEBUG("Age calc: [%d, %d]\n", (int)i, reassembly_buf[i].age);
				if(reassembly_buf[i].age == -1
				|| (i > 0 && reassembly_buf[i].age != reassembly_buf[i-1].age - 1)){
					new_packet = false;
				}
				if(!reassembly_buf[i].continued) break;
			}
			NRG_DEBUG("Got fragment, idx: %d, continued?: %d, age: %d full?: %d\n",
				h.frag_index, h.flags & PKTFLAG_CONTINUED, packet_age, new_packet
			);
			// write all the fragments out if they do form a full packet.
			if(new_packet){
				latest.reset();

				int age_counter = reassembly_buf[0].age;
				for(auto& i : reassembly_buf){
					if(i.age != age_counter--) break;
					latest.writeArray(i.data.getBasePointer(), i.data.size());
					i.data.reset();
					i.age = -1;
				}
			}
		}
	} else {
		latest.reset().writeArray(input.getPointer(), input.remaining());
	}

	if(cc.seq_num > h.seq_num) h.flags |= PKTFLAG_OUT_OF_ORDER;
	latest_flags = static_cast<PacketFlags>(h.flags);

	return true;
}