CFriend::CFriend(CUpDownClient* client){ ASSERT ( client ); m_dwLastSeen = time(NULL); m_dwLastUsedIP = client->GetIP(); m_nLastUsedPort = client->GetUserPort(); m_dwLastChatted = 0; m_LinkedClient = NULL; m_friendSlot = false; SetLinkedClient(client); }
CFriend::CFriend(CUpDownClient* client){ ASSERT ( client ); m_dwLastSeen = time(NULL); m_dwLastUsedIP = client->GetIP(); m_nLastUsedPort = client->GetUserPort(); m_dwLastChatted = 0; m_LinkedClient = NULL; m_friendSlot = false; m_FriendConnectState = FCS_NONE; m_dwLastKadSearch = 0; md4clr(m_abyKadID); md4cpy(m_abyUserhash, client->GetUserHash()); SetLinkedClient(client); }
CUpDownClient* CFriend::GetClientForChatSession() { CUpDownClient* pResult; if (GetLinkedClient(true) != NULL) pResult = GetLinkedClient(false); else{ pResult = new CUpDownClient(0, m_nLastUsedPort, m_dwLastUsedIP, 0, 0, true); pResult->SetUserName(m_strName); pResult->SetUserHash(m_abyUserhash); theApp.clientlist->AddClient(pResult); SetLinkedClient(pResult); } pResult->SetChatState(MS_CHATTING); return pResult; };
void CFriend::UpdateFriendConnectionState(EFriendConnectReport eEvent) { /*#ifdef _DEBUG CString strDbg; strDbg.Format(_T("*** Debug: UpdateFriendConnectionState, Report: %u, CurrentState: %u \n"), eEvent, m_FriendConnectState); for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0;) m_liConnectionReport.GetNext(pos)->ReportConnectionProgress(GetLinkedClient(), strDbg, false); #endif*/ if (m_FriendConnectState == FCS_NONE || GetLinkedClient(true) == NULL){ // we aren't currently trying to build up a friendconnection, we shouldn't be called ASSERT( false ); return; } switch (eEvent){ case FCR_ESTABLISHED: case FCR_USERHASHVERIFIED: // connection established, userhash fits, check secureident if (GetLinkedClient()->HasPassedSecureIdent(true)) { // well here we are done, connecting worked out fine m_FriendConnectState = FCS_NONE; for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0;) m_liConnectionReport.GetNext(pos)->ConnectingResult(GetLinkedClient(), true); m_liConnectionReport.RemoveAll(); FindKadID(); // fetch the kadid of this friend if we don't have it already } else { ASSERT( eEvent != FCR_USERHASHVERIFIED ); // we connected, the userhash matches, now we wait for the authentification // nothing todo, just report about it for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0; m_liConnectionReport.GetNext(pos)){ m_liConnectionReport.GetAt(pos)->ReportConnectionProgress(GetLinkedClient(), _T(" ...") + GetResString(IDS_TREEOPTIONS_OK) + _T("\n"), true); m_liConnectionReport.GetAt(pos)->ReportConnectionProgress(GetLinkedClient(), _T("*** ") + CString(_T("Authenticating friend")) /*to stringlist*/, false); } if (m_FriendConnectState == FCS_CONNECTING) m_FriendConnectState = FCS_AUTH; else{ // client must have connected to use while we tried something else (like search for him an kad) ASSERT( false ); m_FriendConnectState = FCS_AUTH; } } break; case FCR_DISCONNECTED: // disconnected, lets see which state we were in if (m_FriendConnectState == FCS_CONNECTING || m_FriendConnectState == FCS_AUTH){ if (m_FriendConnectState == FCS_CONNECTING && Kademlia::CKademlia::IsRunning() && Kademlia::CKademlia::IsConnected() && !isnulmd4(m_abyKadID) && (m_dwLastKadSearch == 0 || ::GetTickCount() - m_dwLastKadSearch > MIN2MS(10))) { // connecting failed to the last known IP, now we search kad for an updated IP of our friend m_FriendConnectState = FCS_KADSEARCHING; m_dwLastKadSearch = ::GetTickCount(); for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0; m_liConnectionReport.GetNext(pos)){ m_liConnectionReport.GetAt(pos)->ReportConnectionProgress(GetLinkedClient(), _T(" ...") + GetResString(IDS_FAILED) + _T("\n"), true); m_liConnectionReport.GetAt(pos)->ReportConnectionProgress(GetLinkedClient(), _T("*** ") + GetResString(IDS_SEARCHINGFRIENDKAD), false); } Kademlia::CKademlia::FindIPByNodeID(*this, m_abyKadID); break; } m_FriendConnectState = FCS_NONE; for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0;) m_liConnectionReport.GetNext(pos)->ConnectingResult(GetLinkedClient(), false); m_liConnectionReport.RemoveAll(); } else // FCS_KADSEARCHING, shouldn't happen ASSERT( false ); break; case FCR_USERHASHFAILED:{ // the client we connected to, had a different userhash then we expected // drop the linked client object and create a new one, because we don't want to have anything todo // with this instance as it is not our friend which we try to connect to // the connection try counts as failed CUpDownClient* pOld = m_LinkedClient; SetLinkedClient(NULL); // removing old one GetClientForChatSession(); // creating new instance with the hash we search for m_LinkedClient->SetChatState(MS_CONNECTING); for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0;) // inform others about the change m_liConnectionReport.GetNext(pos)->ClientObjectChanged(pOld, GetLinkedClient()); pOld->SetChatState(MS_NONE); if (m_FriendConnectState == FCS_CONNECTING || m_FriendConnectState == FCS_AUTH){ ASSERT( m_FriendConnectState == FCS_AUTH ); // todo: kad here m_FriendConnectState = FCS_NONE; for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0;) m_liConnectionReport.GetNext(pos)->ConnectingResult(GetLinkedClient(), false); m_liConnectionReport.RemoveAll(); } else // FCS_KADSEARCHING, shouldn't happen ASSERT( false ); break; } case FCR_SECUREIDENTFAILED: // the client has the fitting userhash, but failed secureident - so we don't want to talk to him // we stop our search here in any case, multiple clientobjects with the same userhash would mess with other things // and its unlikely that we would find him on kad in this case too ASSERT( m_FriendConnectState == FCS_AUTH ); m_FriendConnectState = FCS_NONE; for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0;) m_liConnectionReport.GetNext(pos)->ConnectingResult(GetLinkedClient(), false); m_liConnectionReport.RemoveAll(); break; case FCR_DELETED: // mh, this should actually never happen i'm sure // todo: in any case, stop any connection tries, notify other etc m_FriendConnectState = FCS_NONE; for (POSITION pos = m_liConnectionReport.GetHeadPosition(); pos != 0;) m_liConnectionReport.GetNext(pos)->ConnectingResult(GetLinkedClient(), false); m_liConnectionReport.RemoveAll(); break; default: ASSERT( false ); } }