ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/vendor/pxys2-2.0.0/pxyscand/src/PXScan.cc
Revision: 3252
Committed: Wed Apr 2 20:41:43 2014 UTC (11 years, 4 months ago) by michael
Content type: text/x-c++src
File size: 7424 byte(s)
Log Message:
- Imported pxys2-2.0.0

File Contents

# Content
1 // Copyright (C) 2003, 2004 Stephane Thiell
2 //
3 // This file is part of pxyscand (from pxys)
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 //
19 #define RCSID "$Id: PXScan.cc,v 1.5 2004/01/10 14:32:29 mbuna Exp $"
20
21 #define SCAN_TIMING 1.0
22
23 #include "PXScan.h"
24 #include "PXScanManager.h"
25 #include "PXSession.h"
26
27 /* Module headers */
28 #include "PXMWingate.h"
29 #include "PXMSocks.h"
30 #include "PXMHttpProxy.h"
31 #include "PXMCrazyBandit.h"
32
33 #include <algorithm>
34 #include <cassert>
35 #include <peak/peak.h>
36
37 bool PXScan::sInitialized = false;
38
39 PXScan::PXScan(const opas_msg_query &inQuery, PXSession *inSession,
40 PXScanManager *inScanManager)
41 : mScanManager( inScanManager ), mStatus(0), mScanFlags(0)
42 {
43 size_t nmods = mScanManager->mConfig->scanner.modules.size();
44
45 // Optimize memory allocation.
46 mModules.reserve(nmods);
47
48 // Instantiate and register our scan modules
49 for (size_t i = 0; i < nmods; i++)
50 {
51 PXConfigModule *mod = &mScanManager->mConfig->scanner.modules[i];
52 switch (mod->id)
53 {
54 case CONFIG_MODULE_HTTP:
55 this->RegisterModule(new PXMHttpProxy(this, mod->port));
56 break;
57 case CONFIG_MODULE_WINGATE:
58 this->RegisterModule(new PXMWingate(this));
59 break;
60 case CONFIG_MODULE_SOCKS:
61 this->RegisterModule(new PXMSocks(this));
62 break;
63 case CONFIG_MODULE_CRAZYBANDIT:
64 this->RegisterModule(new PXMCrazyBandit(this));
65 break;
66 default:
67 abort();
68 }
69 }
70
71 if (sInitialized)
72 {
73 // Shuffle scans order; an idea of Jeb.
74 std::random_shuffle(mModules.begin(), mModules.end());
75 }
76 else
77 {
78 sInitialized = true;
79 this->InitModules();
80 }
81
82 // And now store our first query for this scan.
83 this->AppendQuery(inQuery, inSession);
84 }
85
86 PXScan::~PXScan()
87 {
88 assert(mScanTimer == NULL);
89
90 mScanManager->ScanCompleted(this);
91
92 // Free resources allocated by the scan modules.
93 for (int i = mModules.size(); i--; )
94 delete mModules[i];
95 }
96
97 void
98 PXScan::RegisterModule(PXScanModule *inScanModule)
99 {
100 /* We store instantiated modules in a vector. */
101 mModules.push_back(inScanModule);
102 }
103
104 void
105 PXScan::InitModules()
106 {
107 for (size_t i = 0; i < mModules.size(); i++)
108 mModules[i]->InitModule();
109 }
110
111 void
112 PXScan::SneakModule(const char *inShortName, uint16_t inPort,
113 uint32_t *inConnCountPtr, uint32_t *inProxyCountPtr) const
114 {
115 mScanManager->UseModule(new PXModuleInfo(inShortName,
116 inPort,
117 inConnCountPtr,
118 inProxyCountPtr));
119 }
120
121 void
122 PXScan::AppendQuery(const opas_msg_query &inQuery, PXSession *inSession)
123 {
124 PXScanQuery query = { inQuery, inSession };
125 mScanQueryList.push_back(query);
126 }
127
128 bool
129 PXScan::IsSessionReferenced(const PXSession *inSession)
130 {
131 list<PXScanQuery>::const_iterator i = mScanQueryList.begin();
132 for (; i != mScanQueryList.end(); i++)
133 if ((*i).session == inSession)
134 return true;
135 return false;
136 }
137
138 void
139 PXScan::Schedule()
140 {
141 if (!mScanManager->AddScan(this))
142 {
143 this->Error(1000);
144 this->Done();
145 }
146 }
147
148 void
149 PXScan::Start()
150 {
151 // Sanity check, no module is no fun.
152 assert(mModules.size() > 0);
153
154 // Initialize stuffs. Iterator points to first module.
155 mModuleIterator = mModules.begin();
156 mCompletedCount = 0;
157 mCompletedMax = mModules.size();
158 mLaunched = 0;
159 mStatus = PXSCAN_SCANNING;
160
161 // Prepare for next scan, with a little delay
162 //
163 mScanTimer = peak_timer_create(SCAN_TIMING, SCAN_TIMING, // repeat!
164 TimerCallback, this);
165 if (!mScanTimer)
166 abort();
167
168 peak_task_timer_add(peak_task_self(), mScanTimer);
169 peak_release(mScanTimer);
170
171 // Launch first scan type.
172 this->Launch();
173 }
174
175 void
176 PXScan::Launch()
177 {
178 if (mModuleIterator == mModules.end())
179 {
180 // All scan types are now launched.
181 mMutex.Lock();
182 this->TimerStop();
183 mMutex.Unlock();
184 return;
185 }
186
187 mMutex.Lock();
188 if (mStatus == PXSCAN_SCANNING)
189 {
190 // Normal way.
191 mLaunched++;
192 mMutex.Unlock();
193
194 if (!(*mModuleIterator)->StartScan())
195 {
196 this->Error(1000);
197 this->Completed(*mModuleIterator);
198 }
199 else
200 mModuleIterator++;
201 }
202 else
203 {
204 // A proxy has already been found or an error occured.
205 if (mCompletedCount == mLaunched)
206 {
207 // Special case: all launched modules have been completed!
208 this->TimerStop();
209 mMutex.Unlock();
210 // -serialized-
211 this->Done(); // We are done.
212 }
213 else
214 {
215 mCompletedMax = mLaunched; // Done at next module completion
216 this->TimerStop();
217 mMutex.Unlock();
218 }
219 }
220 }
221
222 void
223 PXScan::Completed(PXScanModule * /* inCompletedModule */)
224 {
225 mMutex.Lock();
226 assert(mCompletedCount < mCompletedMax);
227 if (++mCompletedCount == mCompletedMax)
228 {
229 this->TimerStop();
230 mMutex.Unlock();
231 // -serialized-
232 this->Done(); // We are done.
233 return;
234 }
235 mMutex.Unlock();
236 }
237
238 void
239 PXScan::Done()
240 {
241 if (mStatus == PXSCAN_SCANNING)
242 this->ProxyNotFound();
243
244 delete this;
245 }
246
247 void
248 PXScan::ProxyNotFound()
249 {
250 list<PXScanQuery>::iterator i = mScanQueryList.begin();
251 i->session->ScanCompletedNoProxy(i->query);
252
253 for (; i != mScanQueryList.end(); i++)
254 i->session->ScanResultNoProxy(i->query, false);
255 }
256
257 void
258 PXScan::ProxyFound(uint16_t inTypeOfProxy, uint16_t inPort,
259 const char *inDescr)
260 {
261 mMutex.Lock();
262 if (mStatus == PXSCAN_SCANNING)
263 {
264 mStatus = PXSCAN_PROXY_FOUND;
265
266 list<PXScanQuery>::iterator i = mScanQueryList.begin();
267 i->session->ScanCompletedProxy(i->query, inTypeOfProxy, inPort, inDescr);
268
269 for (; i != mScanQueryList.end(); i++)
270 i->session->ScanResultProxy(i->query, false, peak_time(),
271 inTypeOfProxy, inPort,
272 inDescr);
273 }
274 mMutex.Unlock();
275 }
276
277 void
278 PXScan::Error(int error)
279 {
280 mMutex.Lock();
281 if (mStatus == PXSCAN_SCANNING)
282 {
283 mStatus = PXSCAN_ERROR;
284
285 list<PXScanQuery>::iterator i = mScanQueryList.begin();
286 i->session->ScanCompletedWithError(i->query);
287
288 for (; i != mScanQueryList.end(); i++)
289 i->session->ScanResultError(i->query, error);
290 }
291 mMutex.Unlock();
292 }
293
294 void
295 PXScan::TimerStop()
296 {
297 if (mScanTimer)
298 {
299 peak_task_timer_remove(peak_task_self(), mScanTimer); /* auto release */
300 mScanTimer = NULL;
301 }
302 }
303
304 void
305 PXScan::TimerCallback(peak_timer ti, void *context)
306 {
307 PXScan *scan = reinterpret_cast<PXScan*>(context);
308
309 assert(scan->mScanTimer == NULL || ti == scan->mScanTimer);
310
311 scan->Launch();
312 }