{
// Chunk packets, containing the TYPE_SPLIT header
std::list<SharedBuffer<u8> > chunks;
-
+
u32 chunk_header_size = 7;
u32 maximum_data_size = chunksize_max - chunk_header_size;
u32 start = 0;
end = start + maximum_data_size - 1;
if(end > data.getSize() - 1)
end = data.getSize() - 1;
-
+
u32 payload_size = end - start + 1;
u32 packet_size = chunk_header_size + payload_size;
SharedBuffer<u8> chunk(packet_size);
-
+
writeU8(&chunk[0], TYPE_SPLIT);
writeU16(&chunk[1], seqnum);
// [3] u16 chunk_count is written at next stage
chunks.push_back(chunk);
chunk_count++;
-
+
start = end + 1;
chunk_num++;
}
sp->reliable = reliable;
m_buf[seqnum] = sp;
}
-
+
IncomingSplitPacket *sp = m_buf[seqnum];
-
+
// TODO: These errors should be thrown or something? Dunno.
if(chunk_count != sp->chunk_count)
LOG(derr_con<<"Connection: WARNING: chunk_count="<<chunk_count
// lag and the server re-sends stuff.
if(sp->chunks.find(chunk_num) != sp->chunks.end())
return SharedBuffer<u8>();
-
+
// Cut chunk data out of packet
u32 chunkdatasize = p.data.getSize() - headersize;
SharedBuffer<u8> chunkdata(chunkdatasize);
memcpy(*chunkdata, &(p.data[headersize]), chunkdatasize);
-
+
// Set chunk data in buffer
sp->chunks[chunk_num] = chunkdata;
-
+
// If not all chunks are received, return empty buffer
if(sp->allReceived() == false)
return SharedBuffer<u8>();
{
totalsize += i->second.getSize();
}
-
+
SharedBuffer<u8> fulldata(totalsize);
// Copy chunks to data buffer
next_outgoing_split_seqnum(SEQNUM_INITIAL),
current_packet_loss(0),
current_packet_too_late(0),
+ current_packet_successfull(0),
packet_loss_counter(0),
current_bytes_transfered(0),
current_bytes_received(0),
/* send non reliable packets */
sendPackets(dtime);
- END_DEBUG_EXCEPTION_HANDLER(derr_con);
+ END_DEBUG_EXCEPTION_HANDLER(errorstream);
}
PROFILE(g_profiler->remove(ThreadIdentifier.str()));
{
std::list<u16> peerIds = m_connection->getPeerIDs();
- if ((this->m_outgoing_queue.size() > 0) && (peerIds.size() > 0))
+ if (!m_outgoing_queue.empty() && !peerIds.empty())
return true;
for(std::list<u16>::iterator j = peerIds.begin();
(m_max_data_packets_per_iteration/numpeers));
channel->UpdatePacketLossCounter(timed_outs.size());
+ g_profiler->graphAdd("packets_lost", timed_outs.size());
m_iteration_packets_avaialble -= timed_outs.size();
u16 seqnum = readU16(&(k->data[BASE_HEADER_SIZE+1]));
channel->UpdateBytesLost(k->data.getSize());
+ k->resend_count++;
LOG(derr_con<<m_connection->getDesc()
<<"RE-SENDING timed-out RELIABLE to "
}
}
#endif
- END_DEBUG_EXCEPTION_HANDLER(derr_con);
+ END_DEBUG_EXCEPTION_HANDLER(errorstream);
}
PROFILE(g_profiler->remove(ThreadIdentifier.str()));
return NULL;
// infrastructure
unsigned int packet_maxsize = 1500;
SharedBuffer<u8> packetdata(packet_maxsize);
-
+
bool packet_queued = true;
unsigned int loop_count = 0;
LOG(derr_con<<m_connection->getDesc()
<<"Receive(): Invalid incoming packet, "
<<"size: " << received_size
- <<", protocol: " << readU32(&packetdata[0]) <<std::endl);
+ <<", protocol: "
+ << ((received_size >= 4) ? readU32(&packetdata[0]) : -1)
+ << std::endl);
continue;
}
u16 peer_id = readPeerId(*packetdata);
u8 channelnum = readChannel(*packetdata);
-
+
if(channelnum > CHANNEL_COUNT-1){
LOG(derr_con<<m_connection->getDesc()
<<"Receive(): Invalid channel "<<channelnum<<std::endl);
throw InvalidIncomingDataException("Channel doesn't exist");
}
-
+
/* preserve original peer_id for later usage */
u16 packet_peer_id = peer_id;
}
}
-
+
/* mark peer as seen with id */
if (!(packet_peer_id == PEER_ID_INEXISTENT))
peer->setSentWithID();
{
channel = &(dynamic_cast<UDPPeer*>(&peer)->channels[channelnum]);
}
-
+
if (channel != 0) {
channel->UpdateBytesReceived(received_size);
}
SharedBuffer<u8> strippeddata(received_size - BASE_HEADER_SIZE);
memcpy(*strippeddata, &packetdata[BASE_HEADER_SIZE],
strippeddata.getSize());
-
+
try{
// Process it (the result is some data with no headers made by us)
SharedBuffer<u8> resultdata = processPacket
(channel, strippeddata, peer_id, channelnum, false);
-
+
LOG(dout_con<<m_connection->getDesc()
<<" ProcessPacket from peer_id: " << peer_id
<< ",channel: " << (channelnum & 0xFF) << ", returned "
<< resultdata.getSize() << " bytes" <<std::endl);
-
+
ConnectionEvent e;
e.dataReceived(peer_id, resultdata);
m_connection->putEvent(e);
SharedBuffer<u8> ConnectionReceiveThread::processPacket(Channel *channel,
SharedBuffer<u8> packetdata, u16 peer_id, u8 channelnum, bool reliable)
{
- PeerHelper peer = m_connection->getPeer(peer_id);
+ PeerHelper peer = m_connection->getPeerNoEx(peer_id);
+
+ if (!peer) {
+ errorstream << "Peer not found (possible timeout)" << std::endl;
+ throw ProcessedSilentlyException("Peer not found (possible timeout)");
+ }
if(packetdata.getSize() < 1)
throw InvalidIncomingDataException("packetdata.getSize() < 1");
try{
BufferedPacket p =
channel->outgoing_reliables_sent.popSeqnum(seqnum);
- // Get round trip time
- unsigned int current_time = porting::getTimeMs();
- if (current_time > p.absolute_send_time)
- {
- float rtt = (current_time - p.absolute_send_time) / 1000.0;
+ // only calculate rtt from straight sent packets
+ if (p.resend_count == 0) {
+ // Get round trip time
+ unsigned int current_time = porting::getTimeMs();
- // Let peer calculate stuff according to it
- // (avg_rtt and resend_timeout)
- dynamic_cast<UDPPeer*>(&peer)->reportRTT(rtt);
- }
- else if (p.totaltime > 0)
- {
- float rtt = p.totaltime;
+ // a overflow is quite unlikely but as it'd result in major
+ // rtt miscalculation we handle it here
+ if (current_time > p.absolute_send_time)
+ {
+ float rtt = (current_time - p.absolute_send_time) / 1000.0;
+
+ // Let peer calculate stuff according to it
+ // (avg_rtt and resend_timeout)
+ dynamic_cast<UDPPeer*>(&peer)->reportRTT(rtt);
+ }
+ else if (p.totaltime > 0)
+ {
+ float rtt = p.totaltime;
- // Let peer calculate stuff according to it
- // (avg_rtt and resend_timeout)
- dynamic_cast<UDPPeer*>(&peer)->reportRTT(rtt);
+ // Let peer calculate stuff according to it
+ // (avg_rtt and resend_timeout)
+ dynamic_cast<UDPPeer*>(&peer)->reportRTT(rtt);
+ }
}
//put bytes for max bandwidth calculation
channel->UpdateBytesSent(p.data.getSize(),1);
// we already have this packet so this one was on wire at least
// the current timeout
- dynamic_cast<UDPPeer*>(&peer)->reportRTT(dynamic_cast<UDPPeer*>(&peer)->getResendTimeout());
+ // we don't know how long this packet was on wire don't do silly guessing
+ // dynamic_cast<UDPPeer*>(&peer)->reportRTT(dynamic_cast<UDPPeer*>(&peer)->getResendTimeout());
throw ProcessedSilentlyException("Retransmitting ack for old packet");
}
if(m_peers.size() != 1)
return false;
-
+
std::map<u16, Peer*>::iterator node = m_peers.find(PEER_ID_SERVER);
if(node == m_peers.end())
return false;
-
+
if(m_peer_id == PEER_ID_INEXISTENT)
return false;
}
} // namespace
-