"Fossies" - the Fresh Open Source Software Archive 
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "thread.cc" see the
Fossies "Dox" file reference documentation.
1 /*
2 * xstress - xk0derz SMTP Stress Tester
3 *
4 * (c) Amit Singh amit@xkoder.com
5 * http://xkoder.com
6 *
7 * This software and related files are licensed under GNU GPL version 2
8 * Please visit the following webpage for more details
9 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10 */
11 #include "common.h"
12 #include "thread.h"
13 #include "logger.h"
14
15 Thread::Thread(void)
16 {
17 ulLastTS = 0;
18 uiTimeoutCounter = 0;
19 id = -1;
20 iOkay = true;
21 uiMailsToSend = 1;
22 uiReportCnt = 0;
23
24 uiMailsSend = 0;
25 uiNotSent = 0;
26
27 configObj = NULL;
28 iSockFd = -1;
29 uiEventToPoll = POLLOUT;
30 logger.setThreadId(id);
31
32 }
33
34 Thread::Thread(int _id, int _mailsToSend, Config *_configObj)
35 {
36 initThread(_id, _mailsToSend, _configObj);
37 }
38
39 int Thread::getid()
40 {
41 return id;
42 }
43
44 void Thread::initThread(int _id, int _mailsToSend, Config *_configObj)
45 {
46 uiReportCnt = 0;
47
48 ulLastTS = 0;
49 uiTimeoutCounter = 0;
50 id = _id;
51 logger.setThreadId(id);
52
53 uiEventToPoll = POLLOUT;
54 iOkay = true;
55 uiMailsToSend = _mailsToSend;
56
57 uiMailsSend = 0;
58 uiNotSent = 0;
59
60 configObj = _configObj;
61 iSockFd = -1;
62
63
64 createSocket();
65 //initMailObj();
66 //mailObj.iSock = iSockFd;
67 }
68
69 void Thread::createSocket()
70 {
71 if(iSockFd>=0) { iOkay = false; return; }
72
73 iSockFd = socket(AF_INET, SOCK_STREAM, 6);
74
75 if(iSockFd<0){ iOkay = false; return; }
76
77 fcntl(iSockFd, F_SETFL, O_NONBLOCK);
78
79 mailObj.resetAuth();
80 initMailObj();
81 }
82
83 void Thread::closeSocket()
84 {
85 if(iSockFd>=0)
86 {
87 mailObj.disconnect();
88 close(iSockFd);
89 iSockFd = -1;
90 }
91
92 }
93
94 void Thread::initMailObj()
95 {
96 iOkay = true;
97 mailObj.iSock = iSockFd;
98 mailObj.reset();
99 mailObj.setServer(configObj->sServerIP, configObj->uiServerPort);
100 mailObj.setAuthInfo(configObj->sUsername, configObj->sPassword, configObj->sAuthType);
101 mailObj.setMailInfo(configObj->getTo(),
102 configObj->getFrom(),
103 configObj->getSubject(),
104 configObj->getBody(),
105 configObj->getAttachment());
106 }
107
108 int Thread::okay()
109 {
110 return iOkay;
111 }
112
113 void Thread::process()
114 {
115 int rv;
116 pollfd fds[1];
117 fds[0].fd = iSockFd;
118 fds[0].events = uiEventToPoll;
119
120
121 //cout << "events = " << uiEventToPoll << " POLLIN,POLLOUT,POLLERR,POLLHUP " << POLLIN <<"," << POLLOUT << "," << POLLERR << "," << POLLHUP << " CurrState=" << mailObj.state() <<endl;
122
123 rv = poll(fds, 1, 1000);
124
125 //cout << "revents = " << fds[0].revents << " POLLIN,POLLOUT " << POLLIN <<"," << POLLOUT <<endl;
126
127 if(rv==1 && (fds[0].revents == POLLHUP || fds[0].revents == POLLNVAL))
128 {
129 ulLastTS = time(NULL);
130 logger.log("Received POLLHUP or POLLNVAL, restarting thread.");
131
132 uiEventToPoll = POLLOUT;
133
134 closeSocket();
135 createSocket();
136 //initMailObj();
137
138 return;
139 }
140
141
142 if(rv==1 && ((fds[0].revents & POLLIN) || (fds[0].revents & POLLOUT)))
143 {
144 ulLastTS = time(NULL);
145
146 if(mailObj.state()==FINISHED)
147 {
148 uiMailsSend++;
149 uiReportCnt++;
150
151 if(uiMailsSend>=0xFFFFFFFF)
152 {
153 char cBuf[200];
154 sprintf(cBuf,"Sent %ld mails, reseting counter to Zero.",0xFFFFFFFF);
155 logger.log(cBuf);
156 uiMailsSend=0;
157 }
158 // Get another TO/FROM/BODY/ATTACH
159 initMailObj();
160 uiEventToPoll = POLLOUT;
161 return;
162 }
163
164 if((fds[0].revents & POLLIN)==POLLIN)
165 {
166 uiEventToPoll = POLLOUT;
167 if(mailObj.changeState(READ_READY)==ERR_IO)
168 {
169 logger.log("Mail server didn't understand command OR invalid TO/FROM address.");
170 closeSocket();
171 createSocket();
172 //initMailObj();
173 }
174
175 //return;
176 }
177
178
179 if((fds[0].revents & POLLOUT)==POLLOUT || mailObj.state()==MAIL)
180 {
181
182 mailObj.changeState(WRITE_READY);
183
184 if(mailObj.state()==MAIL) uiEventToPoll = POLLOUT;
185 else uiEventToPoll = POLLIN;
186
187 if(mailObj.state()!=FINISHED)
188 {
189 if((rv = mailObj.run(0))!=0)
190 {
191 if(rv == ERR_CONNECT)
192 logger.log("Error connecting to mail server");
193 if(rv == ERR_INVALID_SOCKET)
194 logger.log("Error Invalid Socket");
195 }
196
197 if(mailObj.state()==FINISHED)
198 {
199 mailObj.changeState(READ_READY);
200 }
201 }
202
203 }
204
205 }
206
207 //cout << "Elapsed Time: " << (time(NULL)-ulLastTS) << endl;
208
209 if((time(NULL)-ulLastTS)>configObj->uiTimeout)
210 {
211 ulLastTS = 0;
212 //uiTimeoutCounter++;
213
214 {
215 if(configObj->uiLogTimeout) logger.log("Timeout!");
216 uiMailsSend++;
217 uiNotSent++;
218 uiReportCnt++;
219
220 if(uiMailsSend>=0xFFFFFFFF)
221 {
222 char cBuf[200];
223 sprintf(cBuf,"Sent %ld mails, reseting counter to Zero.",0xFFFFFFFF);
224 logger.log(cBuf);
225 uiMailsSend = 0;
226 }
227 if(uiMailsSend>=0xFFFFFFFF)
228 {
229 char cBuf[200];
230 sprintf(cBuf,"Failed sending %ld mails, reseting counter to Zero.",0xFFFFFFFF);
231 logger.log(cBuf);
232 uiNotSent=0;
233 }
234
235 uiTimeoutCounter = configObj->uiTimeout;
236 closeSocket();
237 createSocket();
238
239 //initMailObj();
240
241 uiEventToPoll = POLLOUT;
242 }
243 }
244
245 if(configObj->uiReportAfter!=0 && uiReportCnt>=configObj->uiReportAfter)
246 {
247 uiReportCnt=0;
248 reportStatus();
249 }
250 }
251
252 void Thread::stop(int iSig)
253 {
254 uiMailsToSend=1;
255 uiMailsSend=1;
256 }
257
258 int Thread::finished()
259 {
260 if(uiMailsToSend==0) return false;
261
262 if(uiMailsSend == uiMailsToSend) return true;
263 else return false;
264 }
265
266 void Thread::writeStatus()
267 {
268 char cBuffer[1024];
269 sprintf(cBuffer, "Total Mails to send: %ld, Mails Sent: %ld, Mails failed: %ld", uiMailsToSend,
270 uiMailsSend-uiNotSent, uiNotSent);
271 string sBuf = cBuffer;
272 logger.log(sBuf);
273 }
274
275 void Thread::reportStatus()
276 {
277 char cBuffer[1024];
278 sprintf(cBuffer, "T: %ld, S: %ld, F: %ld", uiMailsToSend,
279 uiMailsSend-uiNotSent, uiNotSent);
280 cout << "Thread: "<< logger.getThreadId() << ":: "<< cBuffer << endl;
281 }
282
283 Thread::~Thread()
284 {
285 writeStatus();
286 closeSocket();
287 }