std::string CService::ToStringIPPort() const { if (IsIPv4() || IsTor() || IsInternal()) { return ToStringIP() + ":" + ToStringPort(); } else { return "[" + ToStringIP() + "]:" + ToStringPort(); } }
/** Calculates a metric for how reachable (*this) is from a given partner */ int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const { enum Reachability { REACH_UNREACHABLE, REACH_DEFAULT, REACH_TEREDO, REACH_IPV6_WEAK, REACH_IPV4, REACH_IPV6_STRONG, REACH_PRIVATE }; if (!IsRoutable() || IsInternal()) return REACH_UNREACHABLE; int ourNet = GetExtNetwork(this); int theirNet = GetExtNetwork(paddrPartner); bool fTunnel = IsRFC3964() || IsRFC6052() || IsRFC6145(); switch(theirNet) { case NET_IPV4: switch(ourNet) { default: return REACH_DEFAULT; case NET_IPV4: return REACH_IPV4; } case NET_IPV6: switch(ourNet) { default: return REACH_DEFAULT; case NET_TEREDO: return REACH_TEREDO; case NET_IPV4: return REACH_IPV4; case NET_IPV6: return fTunnel ? REACH_IPV6_WEAK : REACH_IPV6_STRONG; // only prefer giving our IPv6 address if it's not tunnelled } case NET_ONION: switch(ourNet) { default: return REACH_DEFAULT; case NET_IPV4: return REACH_IPV4; // Tor users can connect to IPv4 as well case NET_ONION: return REACH_PRIVATE; } case NET_TEREDO: switch(ourNet) { default: return REACH_DEFAULT; case NET_TEREDO: return REACH_TEREDO; case NET_IPV6: return REACH_IPV6_WEAK; case NET_IPV4: return REACH_IPV4; } case NET_UNKNOWN: case NET_UNROUTABLE: default: switch(ourNet) { default: return REACH_DEFAULT; case NET_TEREDO: return REACH_TEREDO; case NET_IPV6: return REACH_IPV6_WEAK; case NET_IPV4: return REACH_IPV4; case NET_ONION: return REACH_PRIVATE; // either from Tor, or don't care about our address } } }
enum Network CNetAddr::GetNetwork() const { if (IsInternal()) return NET_INTERNAL; if (!IsRoutable()) return NET_UNROUTABLE; if (IsIPv4()) return NET_IPV4; if (IsTor()) return NET_ONION; return NET_IPV6; }
bool CNetAddr::IsValid() const { // Cleanup 3-byte shifted addresses caused by garbage in size field // of addr messages from versions before 0.2.9 checksum. // Two consecutive addr messages look like this: // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26... // so if the first length field is garbled, it reads the second batch // of addr misaligned by 3 bytes. if (memcmp(ip, pchIPv4+3, sizeof(pchIPv4)-3) == 0) return false; // unspecified IPv6 address (::/128) unsigned char ipNone6[16] = {}; if (memcmp(ip, ipNone6, 16) == 0) return false; // documentation IPv6 address if (IsRFC3849()) return false; if (IsInternal()) return false; if (IsIPv4()) { // INADDR_NONE uint32_t ipNone = INADDR_NONE; if (memcmp(ip+12, &ipNone, 4) == 0) return false; // 0 ipNone = 0; if (memcmp(ip+12, &ipNone, 4) == 0) return false; } return true; }
void InfoModelManager::HandleData (QAbstractItemModel *model, int from, int to) { for (int i = from; i <= to; ++i) { const auto& idx = model->index (i, JobHolderColumn::JobProgress); if (IsInternal (idx)) continue; auto done = idx.data (ProcessState::Done).toLongLong (); auto total = idx.data (ProcessState::Total).toLongLong (); auto item = PIdx2Item_.value (idx); if (!item) { if (done != total) HandleRows (model, i, i); continue; } if (done == total) { PIdx2Item_.remove (idx); Model_->removeRow (item->row ()); continue; } while (done > 1000 && total > 1000) { done /= 10; total /= 10; } item->setData (static_cast<double> (done), InfoModel::Roles::Done); item->setData (static_cast<double> (total), InfoModel::Roles::Total); item->setData (model->index (i, JobHolderColumn::JobName).data ().toString (), InfoModel::Roles::Name); } }
std::string CNetAddr::ToStringIP() const { if (IsTor()) return EncodeBase32(&ip[6], 10) + ".onion"; if (IsInternal()) return EncodeBase32(ip + sizeof(g_internal_prefix), sizeof(ip) - sizeof(g_internal_prefix)) + ".internal"; CService serv(*this, 0); struct sockaddr_storage sockaddr; socklen_t socklen = sizeof(sockaddr); if (serv.GetSockAddr((struct sockaddr*)&sockaddr, &socklen)) { char name[1025] = ""; if (!getnameinfo((const struct sockaddr*)&sockaddr, socklen, name, sizeof(name), nullptr, 0, NI_NUMERICHOST)) return std::string(name); } if (IsIPv4()) return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); else return strprintf("%x:%x:%x:%x:%x:%x:%x:%x", GetByte(15) << 8 | GetByte(14), GetByte(13) << 8 | GetByte(12), GetByte(11) << 8 | GetByte(10), GetByte(9) << 8 | GetByte(8), GetByte(7) << 8 | GetByte(6), GetByte(5) << 8 | GetByte(4), GetByte(3) << 8 | GetByte(2), GetByte(1) << 8 | GetByte(0)); }
// // Return whether this URL corresponds to an internal object on this local // process. In this case, no Internet use is necessary. // bool FURL::IsLocalInternal() const { return IsInternal() && Host.Len()==0; }
bool CNetAddr::IsIPv6() const { return (!IsIPv4() && !IsTor() && !IsInternal()); }
// get canonical identifier of an address' group // no two connections will be attempted to addresses with the same group std::vector<unsigned char> CNetAddr::GetGroup() const { std::vector<unsigned char> vchRet; int nClass = NET_IPV6; int nStartByte = 0; int nBits = 16; // all local addresses belong to the same group if (IsLocal()) { nClass = 255; nBits = 0; } // all internal-usage addresses get their own group if (IsInternal()) { nClass = NET_INTERNAL; nStartByte = sizeof(g_internal_prefix); nBits = (sizeof(ip) - sizeof(g_internal_prefix)) * 8; } // all other unroutable addresses belong to the same group else if (!IsRoutable()) { nClass = NET_UNROUTABLE; nBits = 0; } // for IPv4 addresses, '1' + the 16 higher-order bits of the IP // includes mapped IPv4, SIIT translated IPv4, and the well-known prefix else if (IsIPv4() || IsRFC6145() || IsRFC6052()) { nClass = NET_IPV4; nStartByte = 12; } // for 6to4 tunnelled addresses, use the encapsulated IPv4 address else if (IsRFC3964()) { nClass = NET_IPV4; nStartByte = 2; } // for Teredo-tunnelled IPv6 addresses, use the encapsulated IPv4 address else if (IsRFC4380()) { vchRet.push_back(NET_IPV4); vchRet.push_back(GetByte(3) ^ 0xFF); vchRet.push_back(GetByte(2) ^ 0xFF); return vchRet; } else if (IsTor()) { nClass = NET_ONION; nStartByte = 6; nBits = 4; } // for he.net, use /36 groups else if (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x04 && GetByte(12) == 0x70) nBits = 36; // for the rest of the IPv6 network, use /32 groups else nBits = 32; vchRet.push_back(nClass); while (nBits >= 8) { vchRet.push_back(GetByte(15 - nStartByte)); nStartByte++; nBits -= 8; } if (nBits > 0) vchRet.push_back(GetByte(15 - nStartByte) | ((1 << (8 - nBits)) - 1)); return vchRet; }
bool CNetAddr::IsRoutable() const { return IsValid() && !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsLocal() || IsInternal()); }
const string& CEnumeratedTypeValues::GetInternalModuleName(void) const { return !IsInternal()? kEmptyStr: m_ModuleName; }
const string& CEnumeratedTypeValues::GetName(void) const { return IsInternal()? kEmptyStr: m_Name; }
const string& CTypeInfo::GetInternalModuleName(void) const { return !IsInternal()? kEmptyStr: m_ModuleName; }
const string& CTypeInfo::GetName(void) const { return IsInternal()? kEmptyStr: m_Name; }
DWORD CIM_Net::ProcessingServerEvents() { // HRESULT hr; DWORD res = 0; DWORD OperationComplet; DWORD ErrorCode = 0; DWORD ErrorType = 0; DWORD ErrorCount= 0; USES_CONVERSION; ::InterlockedIncrement(&m_OpenThreadCount); ::CoInitializeEx(NULL,COINIT_MULTITHREADED); /* NET_COMMAND_CHANNEL, NET_HISTORY_CHANNEL, NET_FILERECEIVE_CHANNEL, NET_FILESEND_CHANNEL, NET_EVENT_RECEIVER_CHANNEL */ MCTRACE(OBJECT_CREATE_DELETE,"CIM_Net::ProcessingServerEvents STARTED"); do { res = WaitForMultipleObjects(7,(const HANDLE *)(hCallBackEvents),FALSE,INFINITE); OperationComplet = res-WAIT_OBJECT_0; //================================================================== //Print state dump MCTRACE(OperationComplet+ 3, "CIM_Net::ProcessingServerEvents *State_dump_1*\r\n" "WaitForReconnect = %d;\r\n" "m_bWaitForDisconnect = %d;\r\n" "ErrorCount = %d;\r\n" "m_StartedChannelCount = %d\r\n", m_WaitForReconnect,m_bWaitForDisconnect,ErrorCount,m_StartedChannelCount); //=================================================================== // Must be destroied //6 == STOP if(OperationComplet == 6) { MCTRACE(OBJECT_CREATE_DELETE,"CIM_Net::ProcessingServerEvents STOPTED"); InterlockedDecrement(&m_OpenThreadCount); CoUninitialize(); return 0; } MCTRACE(OperationComplet+ 3,"CIM_Net::ProcessingServerEvents Operation Completed"); //=================================================================== // We have received new event //5 = new event if(OperationComplet == 5) { ErrorCount = 0; NewEventProcessing(); continue; } InterlockedDecrement(&m_StartedChannelCount); //Decrement Count Net Thread //=================================================================== //Preprocess any operation completed DWORD dwCommandHandle = 0; DWORD dwCommandType = 0; if(OperationComplet<4) { dwCommandHandle = m_CurrentHandles[OperationComplet]; dwCommandType = m_CurrentCommands[OperationComplet]; MCTRACE(OperationComplet+ 3, "CIM_Net::ProcessingServerEvents New Answer Command Handle = %d CommandType = %d", dwCommandHandle,dwCommandType); } //*************************************************************************** //Obtain error codes m_BaseNetManager.GetResultError((NET_CHANNEL_ENUM)OperationComplet, ErrorType,ErrorCode); MCTRACE(OperationComplet+ 3, "CIM_Net::ProcessingServerEvents New Answer Error Type= %d Code= %d", ErrorType,ErrorCode); //**************************************************************************** //Process errors //Что происходит если пришла ошибка когда //WaitForReconnect или m_bWaitForDisconnect true??? if(!m_WaitForReconnect && !m_bWaitForDisconnect) if(ErrorType != 0 || ErrorCode != 0) { MCTRACE(OperationComplet+ 3, "CIM_Net::ProcessingServerEvents error processing"); switch(ErrorType) { case etWININET://Ошибки связи case etSTATUS: MCTRACE(OperationComplet+ 3, "CIM_Net::ProcessingServerEvents etSTATUS or etSTATUS"); ErrorCount++; if(ErrorCount>3) //Отработка отключения (3 ошибки подряд) { MCTRACE(OperationComplet+ 3, "CIM_Net::ProcessingServerEvents ErrorCount > 3"); //Подготовка к отключению!!!!!!!!!!!!!!!!!!!!! m_bWaitForDisconnect = true; // m_DisErrorType = ErrorType; m_DisErrorCode = ErrorCode; LockSending(); m_BaseNetManager.StopAllOperations(); m_BaseNetManager.StopEventReceiver(); } else { MCTRACE(OperationComplet+ 3, "CIM_Net::ProcessingServerEvents ErrorCount <= 3"); // if command // try send again if(OperationComplet == NET_COMMAND_CHANNEL || OperationComplet == NET_HISTORY_CHANNEL) { UnlockSendingOperation((NET_CHANNEL_ENUM)OperationComplet); } else if(OperationComplet == NET_FILERECEIVE_CHANNEL || OperationComplet == NET_FILESEND_CHANNEL) { ErrorCount --; m_CommandQueue.DeleteCommand(dwCommandHandle); UnlockSendingOperation((NET_CHANNEL_ENUM)OperationComplet); while(!m_ParentSession->PostMessage(IM_ANSWER_ERROR,dwCommandHandle,MAKELONG(LOWORD(ErrorType),LOWORD(ErrorCode)))); } else if(OperationComplet == NET_EVENT_RECEIVER_CHANNEL) //5 == GET_EVENT { InterlockedIncrement(&m_StartedChannelCount); m_BaseNetManager.StartEventReceiver( OLE2T(m_ParentSession->m_SID), hCallBackEvents[NET_EVENT_RECEIVER_CHANNEL], hCallBackEvents[5]); } } break; //******************************************************** case etSERVER://Ошибки сервера MCTRACE(OperationComplet+ 3, "CIM_Net::ProcessingServerEvents etSERVER"); if(OperationComplet == opCommand && dwCommandType == cmLogOn) { MCTRACE(OperationComplet+ 3, "CIM_Net::ProcessingServerEvents command was LogOn"); m_bWaitForDisconnect = true; m_DisErrorType = ErrorType; m_DisErrorCode = ErrorCode; break; } else switch(ErrorCode) { case 112: MCTRACE(OperationComplet+ 3, "CIM_Net::ProcessingServerEvents 112 error"); LockSending(); m_BaseNetManager.StopAllOperations(); m_BaseNetManager.StopEventReceiver(); if(OperationComplet == opCommand && dwCommandType == cmLogOff) { m_DisErrorType = ErrorType; m_DisErrorCode = ErrorCode; m_bWaitForDisconnect = true; } else m_WaitForReconnect = true; break; //Any another server error default: MCTRACE(OperationComplet+ 3, "CIM_Net::ProcessingServerEvents Error Processing Serever Any another err"); if(dwCommandHandle != 0 && !IsInternal(dwCommandHandle)) { //????????????????????????????????????????? while(!m_ParentSession->PostMessage(IM_ANSWER_ERROR,dwCommandHandle,MAKELONG(LOWORD(ErrorType),LOWORD(ErrorCode)))); } else m_CommandQueue.DeleteCommand(dwCommandHandle); UnlockSendingOperation((NET_CHANNEL_ENUM)OperationComplet); break; } break; case etFILE: MCTRACE(OperationComplet+ 3, "CIM_Net::ProcessingServerEvents Error Processing Serever File err"); UnlockSendingOperation((NET_CHANNEL_ENUM)OperationComplet); if(dwCommandHandle != 0 && !IsInternal(dwCommandHandle)) { while(!m_ParentSession->PostMessage(IM_ANSWER_ERROR,dwCommandHandle,MAKELONG(LOWORD(ErrorType),LOWORD(ErrorCode)))); MCTRACE(2,"CIM_Net::CallBackThread Error Process Serever File err Send Message"); } break; case etCANCEL: MCTRACE(OperationComplet+ 3, "CIM_Net::ProcessingServerEvents Error Processing Serever Error Cancel"); ErrorCode = 0; UnlockSendingOperation((NET_CHANNEL_ENUM)OperationComplet); if(opCommand == OperationComplet && dwCommandType == cmLogOn) { m_DisErrorType = etCANCEL; m_DisErrorCode = ErrorCode; m_bWaitForDisconnect = true; break; } if(dwCommandHandle != 0 && !IsInternal(dwCommandHandle)) { while(!m_ParentSession->PostMessage(IM_ANSWER_ERROR,dwCommandHandle,MAKELONG(LOWORD(ErrorType),LOWORD(ErrorCode)))); MCTRACE(2,"CIM_Net::CallBackThread Error Process Serever Error Cancel Send Message"); } else m_CommandQueue.DeleteCommand(dwCommandHandle); break; default: break; } } else { ErrorCount = 0; MCTRACE(2,"CIM_Net::CallBackThread ErrorCount = 0"); } //************************************************************************** //If errors not found if(ErrorCode == 0 && ErrorType == 0) { ErrorCount = 0; CComPtr<IStream> pStream = NULL; CComPtr<IXMLDOMDocument> pDoc = NULL; CComPtr<IXMLDOMNode> pNode = NULL; pStream.Release(); m_BaseNetManager.GetResult((NET_CHANNEL_ENUM)OperationComplet,&pStream); m_CommandQueue.DeleteCommand(dwCommandHandle); //IMonitor implementation if(OperationComplet == NET_COMMAND_CHANNEL &&dwCommandType == cmMessage) { ::InterlockedIncrement(&g_MessageSend); } else if(OperationComplet == NET_COMMAND_CHANNEL &&dwCommandType == cmConfirmMessage) { ::InterlockedIncrement(&g_MessageReceveived); } else if(OperationComplet == NET_FILESEND_CHANNEL) { ::InterlockedIncrement(&g_FileSent); } else if(OperationComplet == NET_FILERECEIVE_CHANNEL) { ::InterlockedIncrement(&g_FileReceived); } //end IMonitor implementation if(pStream != NULL) XMLfromSream(&pDoc,pStream); if(pDoc != NULL) { if(S_OK == pDoc->get_firstChild(&pNode)) m_CommandQueue.AddAnswer(dwCommandHandle,dwCommandType,pNode); if(!IsInternal(dwCommandType)) while(!m_ParentSession->PostMessage(IM_ANSWER_BUFF,dwCommandHandle,dwCommandType)); } else if(!IsInternal(dwCommandType)) while(!m_ParentSession->PostMessage(IM_ANSWER_OK,dwCommandHandle,dwCommandType)); pNode.Release(); pDoc.Release(); if(opCommand == OperationComplet) switch(dwCommandType) { case cmLogOn: m_bWaitForDisconnect = FALSE; m_WaitForReconnect = FALSE; m_DisErrorCode = 0; m_DisErrorType = 0; //send StatusChanged message m_State = stConnected; while(!m_ParentSession->PostMessage(IM_CHANGE_STATE,stConnected,0)) Beep(100,100); //start event receiver InterlockedIncrement(&m_StartedChannelCount); m_BaseNetManager.StartEventReceiver( OLE2T(m_ParentSession->m_SID), hCallBackEvents[NET_EVENT_RECEIVER_CHANNEL], hCallBackEvents[5]); //add Load List command try { m_CommandQueue.x_LoadList(ltContact); } catch(...) {}; try { m_CommandQueue.x_LoadList(ltChats); } catch(...) {}; //unlock output commads UnlockSending(); break; case cmLogOff: MCTRACE(2,"CIM_Net::CallBackThread opCommand || opHistory new Answer LOGOFF"); m_bWaitForDisconnect = true; //lock output command LockSending(); //Stop any net activity m_BaseNetManager.StopAllOperations(); m_BaseNetManager.StopEventReceiver(); //Set disconnect errors m_DisErrorType = ErrorType; m_DisErrorCode = ErrorCode; //waiting all operation completed break; default: if(!m_bWaitForDisconnect && !m_WaitForReconnect) UnlockSendingOperation((NET_CHANNEL_ENUM)OperationComplet); break; } else if(!m_bWaitForDisconnect && !m_WaitForReconnect) UnlockSendingOperation((NET_CHANNEL_ENUM)OperationComplet); } //======================================================================== //All thread closed if(m_StartedChannelCount == 0) { if(m_bWaitForDisconnect) { MCTRACE(2,"CIM_Net::CallBackThread WaitForDisconnect"); m_State = stDisconnected; m_ParentSession->SendMessage(IM_CHANGE_STATE,stDisconnected,MAKELONG(m_DisErrorType,m_DisErrorCode)); ErrorCount = 0; m_bWaitForDisconnect = false; UnlockSendingOperation((NET_CHANNEL_ENUM)opCommand); } else if(m_WaitForReconnect) { MCTRACE(2,"CIM_Net::CallBackThread WaitForReconnect"); try { m_CommandQueue.x_LogOn_Inter(); } catch(...) {}; ErrorCount = 0; m_WaitForReconnect = FALSE; UnlockSendingOperation((NET_CHANNEL_ENUM)opCommand); } } MCTRACE(2,"CIM_Net::CallBackThread WaitForNew Event"); } while(!m_bMustBeDestroied); ::CoUninitialize(); ::InterlockedDecrement(&m_OpenThreadCount); MCTRACE(2,"CIM_Net::CallBackThread CLOSED"); return 0; }