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

Contents of /vendor/pxys2-2.1.0/pxyscand/src/PXScanManager.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: 5480 byte(s)
- Imported pxys2-2.1.0

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: PXScanManager.cc,v 1.4 2004/01/16 18:05:37 mbuna Exp $"
20
21 #include "PXScanManager.h"
22 #include "PXScan.h"
23 #include "PXConfig.h"
24
25 #include <iostream>
26 #include <cassert>
27 #include <cstring>
28
29 using std::clog;
30 using std::endl;
31 using std::deque;
32 using std::queue;
33 using std::ios;
34
35 int PXScanManager::sNeededFDs = 0;
36
37 PXScanManager::PXScanManager(PXConfig *inConfig)
38 : PXRepeater(inConfig->scanner.target_check), // Setup the target check timer
39 mConfig(inConfig), mLastTargetCheck(0), mIPScanCount(0), mRunScanCount(0)
40 {
41 mRunScanMax = mConfig->scanner.maxscans;
42 assert(mRunScanMax > 0);
43
44 if (mConfig->scanner.log_agent && *mConfig->scanner.log_agent)
45 {
46 mFAgent.open(mConfig->scanner.log_agent, ios::out | ios::app);
47 if (!mFAgent.is_open())
48 clog << "Cannot open agent log file: " << mConfig->scanner.log_agent
49 << endl;
50 }
51
52 // The scan manager handles target assignment. Because socks4, http proxy,
53 // and other proxy checks need to specify a target host, we want to be sure
54 // it's up. So this class regularly tries a (direct) connection.
55 // Interval delay is configurable but shouldn't be too low to avoid unwanted
56 // DoS. However, it's only a connection and then we close immediately...
57
58 // Check first time
59 mScanTarget.port = -1;
60 mScanTargets = mConfig->scanner.targets; // copy targets
61 mScanTargetIterator = mScanTargets.begin();
62 this->TargetCheck();
63 }
64
65 PXScanManager::~PXScanManager()
66 {
67 }
68
69 void
70 PXScanManager::Rehash()
71 {
72 peak_timer_configure(mRepeaterTimer, 10, mConfig->scanner.target_check);
73 }
74
75 bool
76 PXScanManager::AddScan(PXScan *inScan)
77 {
78 if (sNeededFDs == 0)
79 sNeededFDs = inScan->GetMaxNeededFDs();
80
81 if (mScanTarget.port < 0)
82 return false;
83
84 mMutex.Lock();
85 if (mRunScanCount + sNeededFDs <= mRunScanMax)
86 {
87 mIPScanCount++;
88 mRunScanCount += sNeededFDs;
89 mMutex.Unlock();
90 inScan->Start();
91 }
92 else
93 {
94 // Queue needed
95 inScan->mStatus = PXScan::PXSCAN_QUEUED;
96 mScanQ.push(inScan);
97 mMutex.Unlock();
98 }
99 return true;
100 }
101
102 void
103 PXScanManager::ScanCompleted(PXScan *inScan)
104 {
105 mMutex.Lock();
106 if (mScanQ.size() > 0)
107 {
108 PXScan *queuedScan = mScanQ.front();
109 mScanQ.pop();
110 mMutex.Unlock();
111
112 queuedScan->Start();
113 }
114 else
115 {
116 // If we don't launch another scan, we need to decrease these values.
117 mIPScanCount--;
118 mRunScanCount -= sNeededFDs;
119 mMutex.Unlock();
120 }
121 }
122
123 void
124 PXScanManager::TargetCheck()
125 {
126 peak_stream s;
127 int timeout;
128
129 sockaddr_in sin;
130 memset(&sin, 0, sizeof(struct sockaddr_in));
131 sin.sin_family = AF_INET;
132 sin.sin_addr = mScanTargetIterator->address;
133 sin.sin_port = htons((uint16_t)mScanTargetIterator->port);
134
135 s = peak_stream_socket_create((struct sockaddr *)&sin, sizeof(sin),
136 PEAK_STREAM_OPT_DEFAULT,
137 TCEventCallback,
138 this);
139
140 if (!s)
141 return;
142
143 if (mConfig->HasSourcePool())
144 {
145 sockaddr_in local_sin;
146 memset(&local_sin, 0, sizeof(local_sin));
147 local_sin.sin_family = AF_INET;
148 local_sin.sin_addr = mConfig->GetOneFromSourcePool();
149 local_sin.sin_port = htons(0);
150 peak_stream_set_address(s, (sockaddr*)&local_sin, sizeof(local_sin));
151 }
152
153 timeout = mConfig->scanner.timeout / 2;
154 if (timeout < 1) // bah
155 timeout = 1;
156
157 peak_stream_set_timeout(s, timeout);
158 if (peak_stream_connect(s) == -1)
159 {
160 peak_release(s);
161 this->TargetCheckNext();
162 return;
163 }
164 peak_stream_schedule(s, peak_task_self());
165 }
166
167 void
168 PXScanManager::TargetCheckNext()
169 {
170 // try next target
171 mScanTargetIterator++;
172
173 if (mScanTargetIterator != mScanTargets.end())
174 this->TargetCheck();
175 else
176 this->Rehash(); // retry in a few from the beginning
177 }
178
179 void
180 PXScanManager::RepeaterFire()
181 {
182 peak_task_exclusivity();
183 mScanTargets.clear();
184 mScanTargets = mConfig->scanner.targets; // copy targets
185 mScanTargetIterator = mScanTargets.begin();
186
187 this->TargetCheck();
188 }
189
190 void
191 PXScanManager::TCEvent(peak_stream s, int type)
192 {
193 switch (type)
194 {
195 case PEAK_STREAM_EVT_OPEN:
196 /* ok ! */
197 mScanTarget = *mScanTargetIterator; // copy
198 mLastTargetCheck = peak_time();
199 peak_release(s);
200 break;
201 case PEAK_STREAM_EVT_END:
202 case PEAK_STREAM_EVT_ERROR:
203 case PEAK_STREAM_EVT_TIMEDOUT:
204 peak_release(s);
205 this->TargetCheckNext();
206 break;
207 }
208 }
209
210 void
211 PXScanManager::TCEventCallback(peak_stream s, int type, void *context)
212 {
213 PXScanManager *me = reinterpret_cast<PXScanManager*>(context);
214 me->TCEvent(s, type);
215 }
216

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