/[svn]/vendor/pxys2-2.1.0/pxyscand/src/PXScan.cc
ViewVC logotype

Contents of /vendor/pxys2-2.1.0/pxyscand/src/PXScan.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3253 - (show annotations)
Wed Apr 2 20:46:18 2014 UTC (6 years, 11 months ago) by michael
File MIME type: text/x-c++src
File size: 7539 byte(s)
- Imported pxys2-2.1.0

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

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28