1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2005-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net )
6 //
7 // Any parts of this program derived from the xMule, lMule or eMule project,
8 // or contributed by third-party developers are copyrighted by their
9 // respective authors.
10 //
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 //
25
26 #include "DeadSourceList.h"
27
28 #include <common/Macros.h>
29
30 #include "updownclient.h" // Needed for CUpDownClient
31
32 #define CLEANUPTIME MIN2MS(60)
33
34 #define BLOCKTIME (::GetTickCount() + (m_bGlobalList ? MIN2MS(30) : MIN2MS(45)))
35 #define BLOCKTIMEFW (::GetTickCount() + (m_bGlobalList ? MIN2MS(45) : MIN2MS(60)))
36
37 ///////////////////////////////////////////////////////////////////////////////////////
38 //// CDeadSource
39
40
CDeadSource(uint32 ID,uint16 Port,uint32 ServerIP,uint16 KadPort)41 CDeadSourceList::CDeadSource::CDeadSource(uint32 ID, uint16 Port, uint32 ServerIP, uint16 KadPort)
42 {
43 m_ID = ID;
44 m_Port = Port;
45 m_KadPort = KadPort;
46 m_ServerIP = ServerIP;
47 m_TimeStamp = 0;
48 }
49
50
SetTimeout(uint32 t)51 void CDeadSourceList::CDeadSource::SetTimeout( uint32 t )
52 {
53 m_TimeStamp = t;
54 }
55
56
GetTimeout() const57 uint32 CDeadSourceList::CDeadSource::GetTimeout() const
58 {
59 return m_TimeStamp;
60 }
61
62
operator ==(const CDeadSource & other) const63 bool CDeadSourceList::CDeadSource::operator==(const CDeadSource& other) const
64 {
65 if ( m_ID == other.m_ID ) {
66 if ( m_Port == other.m_Port || m_KadPort == other.m_KadPort ) {
67 if ( IsLowID( m_ID ) ) {
68 return m_ServerIP == other.m_ServerIP;
69 } else {
70 return true;
71 }
72 }
73 }
74
75 return false;
76 }
77
78
79 ///////////////////////////////////////////////////////////////////////////////////////
80 //// CDeadSourceList
81
CDeadSourceList(bool isGlobal)82 CDeadSourceList::CDeadSourceList(bool isGlobal)
83 {
84 m_dwLastCleanUp = ::GetTickCount();
85 m_bGlobalList = isGlobal;
86 }
87
88
GetDeadSourcesCount() const89 uint32 CDeadSourceList::GetDeadSourcesCount() const
90 {
91 return m_sources.size();
92 }
93
94
IsDeadSource(const CUpDownClient * client)95 bool CDeadSourceList::IsDeadSource(const CUpDownClient* client)
96 {
97 CDeadSource source(
98 client->GetUserIDHybrid(),
99 client->GetUserPort(),
100 client->GetServerIP(),
101 client->GetKadPort()
102 );
103
104
105 DeadSourcePair range = m_sources.equal_range( client->GetUserIDHybrid() );
106 for ( ; range.first != range.second; range.first++ ) {
107 if ( range.first->second == source ) {
108 // Check if the entry is still valid
109 if ( range.first->second.GetTimeout() > GetTickCount() ) {
110 return true;
111 }
112
113 // The source is no longer dead, so remove it to reduce the size of the list
114 m_sources.erase( range.first );
115 break;
116 }
117 }
118
119 return false;
120 }
121
122
AddDeadSource(const CUpDownClient * client)123 void CDeadSourceList::AddDeadSource( const CUpDownClient* client )
124 {
125 CDeadSource source(
126 client->GetUserIDHybrid(),
127 client->GetUserPort(),
128 client->GetServerIP(),
129 client->GetKadPort()
130 );
131
132 // Set the timeout for the new source
133 source.SetTimeout( client->HasLowID() ? BLOCKTIMEFW : BLOCKTIME );
134
135 // Check if the source is already listed
136 DeadSourcePair range = m_sources.equal_range( client->GetUserIDHybrid() );
137 for ( ; range.first != range.second; range.first++ ) {
138 if ( range.first->second == source ) {
139 range.first->second = source;
140 return;
141 }
142 }
143
144 m_sources.insert( DeadSourceMap::value_type( client->GetUserIDHybrid(), source ) );
145
146 // Check if we should cleanup the list. This is
147 // done to avoid a buildup of stale entries.
148 if ( GetTickCount() - m_dwLastCleanUp > CLEANUPTIME ) {
149 CleanUp();
150 }
151 }
152
153
CleanUp()154 void CDeadSourceList::CleanUp()
155 {
156 m_dwLastCleanUp = ::GetTickCount();
157
158 DeadSourceIterator it = m_sources.begin();
159 for ( ; it != m_sources.end(); ) {
160 DeadSourceIterator it1 = it++;
161 if ( it1->second.GetTimeout() < m_dwLastCleanUp ) {
162 m_sources.erase( it1 );
163 }
164 }
165 }
166 // File_checked_for_headers
167