📄 lastcommonroutefinder.cpp
字号:
Sleep(1000);
if(m_enabled == false)
enabled = false;
// trying other ping method
useUdp = !useUdp;
}
}
if(pingStatus.success == true && pingStatus.status == IP_TTL_EXPIRED_TRANSIT) {
if(curHost == 0)
curHost = pingStatus.destinationAddress;
atLeastOnePingSucceded = true;
lastSuccedingPingAddress = curAddress;
lastDestinationAddress = pingStatus.destinationAddress;
} else {
// failed to ping this host for some reason.
// Or we reached the actual host we are pinging. We don't want that, since it is too close.
// Remove it.
IN_ADDR stDestAddr;
stDestAddr.s_addr = curAddress;
if(pingStatus.success == true && pingStatus.status == IP_SUCCESS) {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Host was too close! Removing this host. (TTL: %i IP: %s status: %i). Removing this host and restarting host collection."), ttl, ipstr(stDestAddr), pingStatus.status);
hostsToTraceRoute.RemoveAt(lastPos);
//failed = true;
} else if(pingStatus.success == true && pingStatus.status == IP_DEST_HOST_UNREACHABLE) {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Host unreacheable! (TTL: %i IP: %s status: %i). Removing this host. Status info follows."), ttl, ipstr(stDestAddr), pingStatus.status);
pinger.PIcmpErr(pingStatus.status);
hostsToTraceRoute.RemoveAt(lastPos);
} else if(pingStatus.success == true) {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Unknown ping status! (TTL: %i IP: %s status: %i). Reason follows. Changing ping method to see if it helps."), ttl, ipstr(stDestAddr), pingStatus.status);
pinger.PIcmpErr(pingStatus.status);
useUdp = !useUdp;
} else {
if(pingStatus.error == IP_REQ_TIMED_OUT) {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Timeout when pinging a host! (TTL: %i IP: %s Error: %i). Keeping host. Error info follows."), ttl, ipstr(stDestAddr), pingStatus.error);
pinger.PIcmpErr(pingStatus.error);
if(hostsToTraceRouteCounter > 2 && lastSuccedingPingAddress == 0) {
// several pings have timed out on this ttl. Probably we can't ping on this ttl at all
failedThisTtl = true;
}
} else {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Unknown pinging error! (TTL: %i IP: %s status: %i). Reason follows. Changing ping method to see if it helps."), ttl, ipstr(stDestAddr), pingStatus.error);
pinger.PIcmpErr(pingStatus.error);
useUdp = !useUdp;
}
}
if(hostsToTraceRoute.GetSize() <= 8) {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: To few hosts to traceroute left. Restarting host colletion."));
failed = true;
}
}
}
if(failed == false) {
if(curHost != 0 && lastDestinationAddress != 0) {
if(lastDestinationAddress == curHost) {
IN_ADDR stDestAddr;
stDestAddr.s_addr = curHost;
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Host at TTL %i: %s"), ttl, ipstr(stDestAddr));
lastCommonHost = curHost;
lastCommonTTL = ttl;
} else /*if(lastSuccedingPingAddress != 0)*/ {
foundLastCommonHost = true;
hostToPing = lastSuccedingPingAddress;
CString hostToPingString = ipstr(hostToPing);
if(lastCommonHost != 0) {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Found differing host at TTL %i: %s. This will be the host to ping."), ttl, hostToPingString);
} else {
CString lastCommonHostString = ipstr(lastDestinationAddress);
lastCommonHost = lastDestinationAddress;
lastCommonTTL = ttl;
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Found differing host at TTL %i, but last ttl couldn't be pinged so we don't know last common host. Taking a chance and using first differing ip as last commonhost. Host to ping: %s. Faked LastCommonHost: %s"), ttl, hostToPingString, lastCommonHostString);
}
}
} else {
if(ttl < 4) {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Could perform no ping at all at TTL %i. Trying next ttl."), ttl);
} else {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Could perform no ping at all at TTL %i. Giving up."), ttl);
}
lastCommonHost = 0;
}
}
}
if(foundLastCommonHost == false && traceRouteTries >= 3) {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Tracerouting failed several times. Waiting a few minutes before trying again."));
SetUpload(maxUpload);
pingLocker.Lock();
m_state = _T("Waiting...");
pingLocker.Unlock();
prefsEvent->Lock(3*60*1000);
pingLocker.Lock();
m_state = _T("Preparing...");
pingLocker.Unlock();
}
if(m_enabled == false) {
enabled = false;
}
}
if(enabled) {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Done tracerouting. Evaluating results."));
if(foundLastCommonHost == true) {
IN_ADDR stLastCommonHostAddr;
stLastCommonHostAddr.s_addr = lastCommonHost;
// log result
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Found last common host. LastCommonHost: %s @ TTL: %i"), ipstr(stLastCommonHostAddr), lastCommonTTL);
IN_ADDR stHostToPingAddr;
stHostToPingAddr.s_addr = hostToPing;
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Found last common host. HostToPing: %s"), ipstr(stHostToPingAddr));
} else {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Tracerouting failed too many times. Disabling Upload SpeedSense."));
enabled = false;
pingLocker.Lock();
m_state = _T("Error.");
pingLocker.Unlock();
// PENDING: this may not be thread safe
thePrefs.SetDynUpEnabled(false);
}
}
}
if(m_enabled == false) {
enabled = false;
}
if(doRun && enabled) {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Finding a start value for lowest ping..."));
}
// PENDING:
prefsLocker.Lock();
uint64 lowestInitialPingAllowed = m_LowestInitialPingAllowed;
prefsLocker.Unlock();
uint32 initial_ping = _I32_MAX;
bool foundWorkingPingMethod = false;
// finding lowest ping
for(int initialPingCounter = 0; doRun && enabled && initialPingCounter < 10; initialPingCounter++) {
Sleep(200);
PingStatus pingStatus = pinger.Ping(hostToPing, lastCommonTTL, true, useUdp);
if (pingStatus.success && pingStatus.status == IP_TTL_EXPIRED_TRANSIT) {
foundWorkingPingMethod = true;
if(pingStatus.delay > 0 && pingStatus.delay < initial_ping) {
initial_ping = max(pingStatus.delay, lowestInitialPingAllowed);
}
} else {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: %s-Ping #%i failed. Reason follows"), useUdp?_T("UDP"):_T("ICMP"), initialPingCounter);
pinger.PIcmpErr(pingStatus.error);
// trying other ping method
if(!pingStatus.success && !foundWorkingPingMethod) {
useUdp = !useUdp;
}
}
if(m_enabled == false) {
enabled = false;
}
}
// Set the upload to a good starting point
SetUpload(startUpload);
Sleep(SEC2MS(1));
DWORD initTime = ::GetTickCount();
// if all pings returned 0, initial_ping will not have been changed from default value.
// then set initial_ping to lowestInitialPingAllowed
if(initial_ping == _I32_MAX)
initial_ping = lowestInitialPingAllowed;
uint32 upload = 0;
hasSucceededAtLeastOnce = true;
if(doRun && enabled) {
if(initial_ping > lowestInitialPingAllowed) {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Lowest ping: %i ms"), initial_ping);
} else {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Lowest ping: %i ms. (Filtered lower values. Lowest ping is never allowed to go under %i ms)"), initial_ping, lowestInitialPingAllowed);
}
prefsLocker.Lock();
upload = m_CurUpload;
if(upload < minUpload) {
upload = minUpload;
}
if(upload > maxUpload) {
upload = maxUpload;
}
prefsLocker.Unlock();
}
if(m_enabled == false) {
enabled = false;
}
if(doRun && enabled) {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Done with preparations. Starting control of upload speed."));
}
pingLocker.Lock();
m_state = _T("");
pingLocker.Unlock();
// There may be several reasons to start over with tracerouting again.
// Currently we only restart if we get an unexpected ip back from the
// ping at the set TTL.
bool restart = false;
DWORD lastLoopTick = ::GetTickCount();
DWORD lastUploadReset = 0;
while(doRun && enabled && restart == false) {
DWORD ticksBetweenPings = 1000;
if(upload > 0) {
// ping packages being 64 bytes, this should use 1% of bandwidth (one hundredth of bw).
ticksBetweenPings = (64*100*1000)/upload;
if(ticksBetweenPings < 125) {
// never ping more than 8 packages a second
ticksBetweenPings = 125;
} else if(ticksBetweenPings > 1000) {
ticksBetweenPings = 1000;
}
}
DWORD curTick = ::GetTickCount();
DWORD timeSinceLastLoop = curTick-lastLoopTick;
if(timeSinceLastLoop < ticksBetweenPings) {
//theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Sleeping %i ms, timeSinceLastLoop %i ms ticksBetweenPings %i ms"), ticksBetweenPings-timeSinceLastLoop, timeSinceLastLoop, ticksBetweenPings);
Sleep(ticksBetweenPings-timeSinceLastLoop);
}
lastLoopTick = curTick;
prefsLocker.Lock();
double pingTolerance = m_pingTolerance;
uint32 pingToleranceMilliseconds = m_iPingToleranceMilliseconds;
bool useMillisecondPingTolerance = m_bUseMillisecondPingTolerance;
uint32 goingUpDivider = m_goingUpDivider;
uint32 goingDownDivider = m_goingDownDivider;
uint32 numberOfPingsForAverage = m_iNumberOfPingsForAverage;
lowestInitialPingAllowed = m_LowestInitialPingAllowed; // PENDING
prefsLocker.Unlock();
DWORD tempTick = ::GetTickCount();
if(tempTick - initTime < SEC2MS(60)) {
goingUpDivider = 1;
goingDownDivider = 1;
} else if(tempTick - initTime < SEC2MS(61)) {
lastUploadReset = tempTick;
prefsLocker.Lock();
upload = m_CurUpload;
prefsLocker.Unlock();
}
uint32 soll_ping = initial_ping*pingTolerance;
// EastShare START - Add by TAHO, USS limit
if ( useMillisecondPingTolerance ) {
soll_ping = pingToleranceMilliseconds;
} else {
soll_ping = initial_ping*pingTolerance; // ZZ, USS
}
// EastShare END - Add by TAHO, USS limit
uint32 raw_ping = soll_ping; // this value will cause the upload speed not to change at all.
bool pingFailure = false;
for(uint64 pingTries = 0; doRun && enabled && (pingTries == 0 || pingFailure) && pingTries < 60; pingTries++) {
if(m_enabled == false) {
enabled = false;
}
// ping the host to ping
PingStatus pingStatus = pinger.Ping(hostToPing, lastCommonTTL, false, useUdp);
if(pingStatus.success && pingStatus.status == IP_TTL_EXPIRED_TRANSIT) {
if(pingStatus.destinationAddress != lastCommonHost) {
// something has changed about the topology! We got another ip back from this ttl than expected.
// Do the tracerouting again to figure out new topology
CString lastCommonHostAddressString = ipstr(lastCommonHost);
CString destinationAddressString = ipstr(pingStatus.destinationAddress);
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Network topology has changed. TTL: %i Expected ip: %s Got ip: %s Will do a new traceroute."), lastCommonTTL, lastCommonHostAddressString, destinationAddressString);
restart = true;
}
raw_ping = (uint32)pingStatus.delay;
if(pingFailure) {
// only several pings in row should fails, the total doesn't count, so reset for each successful ping
pingFailure = false;
//theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Ping #%i successful. Continuing."), pingTries);
}
} else {
raw_ping = soll_ping*3+initial_ping*3; // this value will cause the upload speed be lowered.
pingFailure = true;
if(m_enabled == false) {
enabled = false;
} else if(pingTries > 3) {
prefsEvent->Lock(1000);
}
//theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: %s-Ping #%i failed. Reason follows"), useUdp?_T("UDP"):_T("ICMP"), pingTries);
//pinger.PIcmpErr(pingStatus.error);
}
if(m_enabled == false) {
enabled = false;
}
}
if(pingFailure) {
if(enabled) {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: No response to pings for a long time. Restarting..."));
}
restart = true;
}
if(restart == false) {
if(raw_ping > 0 && raw_ping < initial_ping && initial_ping > lowestInitialPingAllowed) {
theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: New lowest ping: %i ms. Old: %i ms"), max(raw_ping,lowestInitialPingAllowed), initial_ping);
initial_ping = max(raw_ping, lowestInitialPingAllowed);
}
pingDelaysTotal += raw_ping;
pingDelays.AddTail(raw_ping);
while(!pingDelays.IsEmpty() && (uint32)pingDelays.GetCount() > numberOfPingsForAverage) {
uint32 pingDelay = pingDelays.RemoveHead();
pingDelaysTotal -= pingDelay;
}
uint32 normalized_ping = 0;
if((pingDelaysTotal/pingDelays.GetCount()) > initial_ping) {
normalized_ping = (pingDelaysTotal/pingDelays.GetCount()) - initial_ping;
}
pingLocker.Lock();
m_pingAverage = pingDelaysTotal/pingDelays.GetCount();
m_lowestPing = initial_ping;
pingLocker.Unlock();
// Calculate Waiting Time
sint64 hping = (soll_ping - (sint64)normalized_ping);
// Calculate change of upload speed
if(hping < 0) {
// lower the speed
sint64 ulDiff = hping*1024*10 / (sint64)(goingDownDivider*initial_ping);
acceptNewClient = false;
//theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Down! Ping cur %i ms. Ave %I64i ms %i values. New Upload %i + %I64i = %I64i"), raw_ping, pingDelaysTotal/pingDelays.GetCount(), pingDelays.GetCount(), upload, ulDiff, upload+ulDiff);
// prevent underflow
if(upload > -ulDiff) {
upload += ulDiff;
} else {
upload = 0;
}
} else if(hping > 0) {
// raise the speed
uint64 ulDiff = hping*1024*10 / (uint64)(goingUpDivider*initial_ping);
acceptNewClient = true;
//theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Up! Ping cur %i ms. Ave %I64i ms %i values. New Upload %i + %I64i = %I64i"), raw_ping, pingDelaysTotal/pingDelays.GetCount(), pingDelays.GetCount(), upload, ulDiff, upload+ulDiff);
// prevent overflow
if(_I32_MAX-upload > ulDiff) {
upload += ulDiff;
} else {
upload = _I32_MAX;
}
}
prefsLocker.Lock();
if (upload < minUpload) {
upload = minUpload;
acceptNewClient = true;
}
if (upload > maxUpload) {
upload = maxUpload;
}
prefsLocker.Unlock();
SetUpload(upload);
if(m_enabled == false) {
enabled = false;
}
}
}
}
}
// Signal that we have ended.
threadEndedEvent->SetEvent();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -