#endif
-static inline float CALC_DTIME(unsigned int lasttime, unsigned int curtime) {
+static inline float CALC_DTIME(u64 lasttime, u64 curtime)
+{
float value = ( curtime - lasttime) / 1000.0;
return MYMAX(MYMIN(value,0.1),0.0);
}
#define PING_TIMEOUT 5.0
+/* maximum number of retries for reliable packets */
+#define MAX_RELIABLE_RETRY 5
+
static u16 readPeerId(u8 *packetdata)
{
return readU16(&packetdata[4]);
delete this;
}
-void Peer::RTTStatistics(float rtt, std::string profiler_id,
+void Peer::RTTStatistics(float rtt, const std::string &profiler_id,
unsigned int num_samples) {
if (m_last_rtt > 0) {
m_rtt.jitter_avg = m_rtt.jitter_avg * (num_samples/(num_samples-1)) +
jitter * (1/num_samples);
- if (profiler_id != "")
- {
+ if (profiler_id != "") {
g_profiler->graphAdd(profiler_id + "_rtt", rtt);
g_profiler->graphAdd(profiler_id + "_jitter", jitter);
}
bool Peer::isTimedOut(float timeout)
{
MutexAutoLock lock(m_exclusive_access_mutex);
- u32 current_time = porting::getTimeMs();
+ u64 current_time = porting::getTimeMs();
float dtime = CALC_DTIME(m_last_timeout_check,current_time);
m_last_timeout_check = current_time;
u16 UDPPeer::getNextSplitSequenceNumber(u8 channel)
{
assert(channel < CHANNEL_COUNT); // Pre-condition
- return channels[channel].readNextIncomingSeqNum();
+ return channels[channel].readNextSplitSeqNum();
}
void UDPPeer::setNextSplitSequenceNumber(u8 channel, u16 seqnum)
LOG(dout_con<<m_connection->getDesc()
<<"ConnectionSend thread started"<<std::endl);
- u32 curtime = porting::getTimeMs();
- u32 lasttime = curtime;
+ u64 curtime = porting::getTimeMs();
+ u64 lasttime = curtime;
PROFILE(std::stringstream ThreadIdentifier);
PROFILE(ThreadIdentifier << "ConnectionSend: [" << m_connection->getDesc() << "]");
}
float resend_timeout = dynamic_cast<UDPPeer*>(&peer)->getResendTimeout();
+ bool retry_count_exceeded = false;
for(u16 i=0; i<CHANNEL_COUNT; i++)
{
std::list<BufferedPacket> timed_outs;
channel->UpdateBytesLost(k->data.getSize());
k->resend_count++;
+ if (k-> resend_count > MAX_RELIABLE_RETRY) {
+ retry_count_exceeded = true;
+ timeouted_peers.push_back(peer->id);
+ /* no need to check additional packets if a single one did timeout*/
+ break;
+ }
+
LOG(derr_con<<m_connection->getDesc()
<<"RE-SENDING timed-out RELIABLE to "
<< k->address.serializeString()
// do not handle rtt here as we can't decide if this packet was
// lost or really takes more time to transmit
}
+
+ if (retry_count_exceeded) {
+ break; /* no need to check other channels if we already did timeout */
+ }
+
channel->UpdateTimers(dtime,dynamic_cast<UDPPeer*>(&peer)->getLegacyPeer());
}
+ /* skip to next peer if we did timeout */
+ if (retry_count_exceeded)
+ continue;
+
/* send ping if necessary */
if (dynamic_cast<UDPPeer*>(&peer)->Ping(dtime,data)) {
LOG(dout_con<<m_connection->getDesc()
PROFILE(ThreadIdentifier << "ConnectionReceive: [" << m_connection->getDesc() << "]");
#ifdef DEBUG_CONNECTION_KBPS
- u32 curtime = porting::getTimeMs();
- u32 lasttime = curtime;
+ u64 curtime = porting::getTimeMs();
+ u64 lasttime = curtime;
float debug_print_timer = 0.0;
#endif
throw InvalidIncomingDataException("Channel doesn't exist");
}
- /* preserve original peer_id for later usage */
- u16 packet_peer_id = peer_id;
-
/* Try to identify peer by sender address (may happen on join) */
if (peer_id == PEER_ID_INEXISTENT) {
peer_id = m_connection->lookupPeer(sender);
+ // We do not have to remind the peer of its
+ // peer id as the CONTROLTYPE_SET_PEER_ID
+ // command was sent reliably.
}
/* The peer was not found in our lists. Add it. */
}
}
-
- /* mark peer as seen with id */
- if (!(packet_peer_id == PEER_ID_INEXISTENT))
- peer->setSentWithID();
-
peer->ResetTimeout();
Channel *channel = 0;
// only calculate rtt from straight sent packets
if (p.resend_count == 0) {
// Get round trip time
- unsigned int current_time = porting::getTimeMs();
+ u64 current_time = porting::getTimeMs();
// a overflow is quite unlikely but as it'd result in major
// rtt miscalculation we handle it here
for(; j != m_peers.end(); ++j)
{
Peer *peer = j->second;
- if (peer->isActive())
+ if (peer->isPendingDeletion())
continue;
Address tocheck;