/[LeafOK_CVS]/innwebd/base_passive.cpp
ViewVC logotype

Annotation of /innwebd/base_passive.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (hide annotations)
Fri Apr 11 17:14:49 2008 UTC (17 years, 11 months ago) by sysadm
Branch: MAIN
CVS Tags: HEAD
Changes since 1.9: +14 -10 lines
Content type: text/x-c++src
Update copyright
Add extra log for exception

1 sysadm 1.1 /*******************************************************/
2     /* */
3 sysadm 1.4 /* LeafOK Innbbsd */
4 sysadm 1.1 /* */
5 sysadm 1.10 /* Copyright (C) LeafOK.com, 2003-2008 */
6 sysadm 1.1 /* */
7 sysadm 1.10 /* http://www.leafok.com */
8 sysadm 1.1 /* */
9     /*******************************************************/
10    
11     #include "StdAfx.h"
12     #include ".\base_passive.h"
13     #include ".\base_active.h"
14    
15     using namespace std;
16    
17 sysadm 1.3 // UINT base_passive::uThreadCount = 0;
18 sysadm 1.1
19     base_passive::base_passive(void)
20     {
21     }
22    
23     base_passive::~base_passive(void)
24     {
25     this->s_close();
26     this->db_close();
27     }
28    
29     int base_passive::s_connect(const char* hostaddr, unsigned int port)
30     {
31     SOCKADDR_IN sin;
32    
33     if (this->isConnected)
34     {
35     this->s_close();
36     }
37    
38     //Create a TCP/IP socket
39     if ((this->s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
40     {
41     syslog << logfile::log_head << "Cannot create socket" << endl;
42     return -1;
43     }
44    
45     //fill in sockaddr_in struct
46    
47     sin.sin_family = PF_INET;
48     sin.sin_port = htons(port);
49     sin.sin_addr.s_addr = (strlen(hostaddr) > 0 ? inet_addr(hostaddr) : INADDR_ANY);
50    
51     //bind the socket
52     if(bind(this->s, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
53     {
54     syslog << logfile::log_head << "Cannot bind" << endl;
55     return -1;
56     }
57    
58     if(listen(this->s,5) == SOCKET_ERROR)
59     {
60     syslog << logfile::log_head << "Cannot listen" << endl;
61     return -1;
62     }
63    
64     strcpy(this->hostaddr,hostaddr);
65     this->port = port;
66    
67     this->isConnected = true;
68    
69     return 0;
70     }
71    
72     int base_passive::s_close(void)
73     {
74     if (!this->isConnected)
75     return 0;
76    
77     if (closesocket(this->s) == SOCKET_ERROR)
78     {
79     syslog << logfile::log_head << "Close socket error" << endl;
80     }
81    
82     this->isConnected = false;
83    
84     return 0;
85     }
86    
87     int base_passive::work()
88     {
89     HANDLE hThreadCurrent;
90     ULONG ulThreadId;
91     base_passive* p;
92     SOCKADDR_IN sin;
93     int namelen;
94    
95     if (this->running)
96     return 1;
97    
98     if (this->load_priv() != 0)
99     return -1;
100    
101 sysadm 1.4 this->SetThreadPool(new thread_pool(MAX_CLIENT));
102 sysadm 1.3 if (this->p_ThreadPool->GetLastError() != 0)
103     {
104     return -1;
105     }
106    
107 sysadm 1.1 if (this->s_connect(this->w_address,this->w_port) == 0)
108     {
109     this->Startup();
110    
111     syslog << logfile::log_head << "Listen at port [" << this->w_port << "]" << endl;
112    
113     while(!this->IsShutdown())
114     {
115     if ((p = this->new_client()) == NULL)
116     {
117     syslog << logfile::log_head << "Assign new client failed" << endl;
118     continue;
119     }
120    
121 sysadm 1.3 p->SetParentThread(this);
122 sysadm 1.1 p->configure(this->innd_id,this->innd_name,this->innd_server,this->innd_uid,this->w_address,this->w_port,this->w_conn_str);
123    
124     this->running = true;
125    
126 sysadm 1.4 this->GetParentThread()->GetThreadPool()->SetThreadStatus(GetCurrentThreadId(),thread_pool::S_WAITING);
127 sysadm 1.3
128 sysadm 1.1 namelen = sizeof(sin);
129     if ((p->s = accept(this->s,(LPSOCKADDR)&sin,&namelen)) == INVALID_SOCKET)
130     {
131     syslog << logfile::log_head << "Socket accept failed (" << GetLastError() <<")" << endl;
132     this->unload_priv();
133     this->Shutdown();
134     this->running = false;
135     return -2;
136     }
137    
138     if (this->IsShutdown())
139     {
140     break;
141     }
142    
143 sysadm 1.7 this->GetParentThread()->GetThreadPool()->SetThreadStatus(GetCurrentThreadId(),thread_pool::S_WORKING);
144 sysadm 1.4
145 sysadm 1.1 strcpy(p->hostaddr,inet_ntoa(sin.sin_addr));
146     p->port = sin.sin_port;
147     p->isConnected = true;
148    
149     // strcpy(p->w_conn_str,this->w_conn_str);
150 sysadm 1.5
151 sysadm 1.1 if (this->get_priv(p)!=0)
152     {
153     p->s_send("502 Load access file failed.\r\n");
154     delete(p);
155     continue;
156     }
157    
158 sysadm 1.8 if (!p->check_priv())
159 sysadm 1.1 {
160     p->s_send("502 You are not in my access file.\r\n");
161     delete(p);
162     continue;
163     }
164 sysadm 1.3
165     // if (base_passive::uThreadCount < MAX_CLIENT)
166 sysadm 1.1 if (this->GetThreadPool()->GetThreadCount() < MAX_CLIENT)
167     {
168     if (hThreadCurrent = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)base_passive::AcceptThread,(LPVOID)p,0,&ulThreadId))
169 sysadm 1.6 {
170 sysadm 1.1 CloseHandle(hThreadCurrent);
171     syslog << logfile::log_head << "Create accept thread ... OK" << endl;
172     }
173     else
174     {
175     delete(p);
176     syslog << logfile::log_head << "Create accept thread ... Failed" << endl;
177     }
178     }
179     else
180     {
181     p->s_send("502 Too many connections\r\n");
182     delete(p);
183     }
184     }
185     delete(p);
186     Sleep(1000*5); // Wait several seconds for all threads to exit
187     }
188     this->s_close();
189    
190     this->unload_priv();
191    
192     this->running = false;
193    
194     return 0;
195     }
196    
197     DWORD base_passive::AcceptThread(LPVOID pParam)
198     {
199     base_passive* p;
200    
201     try
202     {
203 sysadm 1.3 p = (base_passive*)pParam;
204 sysadm 1.4
205     p->ulMainThreadId = GetCurrentThreadId();
206    
207 sysadm 1.8 syslog << logfile::log_head << "Accept connection from " << p->hostaddr
208     << ":" << p->port << endl;
209    
210 sysadm 1.3 if (p->GetParentThread()->GetThreadPool()->AddThread(GetCurrentThreadId(), CLOCKS_PER_SEC * 30) != 0)
211     {
212     syslog << logfile::log_head << "Register thread ... Failed" << endl;
213 sysadm 1.4 }
214 sysadm 1.3 p->GetParentThread()->GetThreadPool()->SetThreadStatus(GetCurrentThreadId(),thread_pool::S_WORKING);
215 sysadm 1.1
216     if (p->db_env_init() == 0)
217     {
218     p->Accept();
219     }
220     else
221     {
222     syslog << logfile::log_head << "DB_ENV_INIT failed" << endl;
223 sysadm 1.3 }
224 sysadm 1.4
225 sysadm 1.3 if (p->GetParentThread()->GetThreadPool()->RemoveThread(GetCurrentThreadId()) != 0)
226     {
227     syslog << logfile::log_head << "Unregister thread ... Failed" << endl;
228     }
229     // base_passive::uThreadCount--;
230 sysadm 1.1
231     delete(p);
232     syslog << logfile::log_head << "Delete accept thread ... OK" << endl;
233     }
234     catch(CException* e)
235     {
236 sysadm 1.10 char strErrMsg[1024];
237     e->GetErrorMessage(strErrMsg,1024);
238     syslog << logfile::log_head << "Error in AcceptThread() [" << strErrMsg << "]" << endl;
239 sysadm 1.1 e->Delete();
240     return -1;
241     }
242    
243     return 0;
244     }
245    
246     int base_passive::get_priv(base_passive* p)
247     {
248     try
249     {
250     //Default value
251     strcpy(p->access.ip,p->hostaddr);
252     p->access.control = false;
253 sysadm 1.8 p->access.get = false;
254 sysadm 1.1 p->access.post = false;
255     p->access.ihave = false;
256    
257     //Check access list
258     for (int i=1; i<this->access_array.GetCount(); i++)
259     {
260     if (strcmp(this->access_array[i]->ip,p->hostaddr) == 0)
261     {
262     p->access = *(this->access_array[i]);
263     break;
264     }
265     }
266     }
267     catch(CException* e)
268     {
269 sysadm 1.10 char strErrMsg[1024];
270     e->GetErrorMessage(strErrMsg,1024);
271     syslog << logfile::log_head << "Error in get_priv() [" << strErrMsg << "]" << endl;
272 sysadm 1.1 e->Delete();
273     return -1;
274     }
275    
276     return 0;
277     }
278    
279     int base_passive::load_priv(void)
280     {
281     CRecordset RS;
282     CString sql;
283     CDBVariant dbVar;
284     Access_STRUCT* p_access;
285    
286     try
287     {
288     if (this->db_open(this->w_conn_str) == 0)
289     {
290     RS.m_pDatabase = &(this->Db);
291     }
292     else
293     return -2;
294    
295     //Check access list
296     sql = "select * from innd_access where enable order by ip";
297     RS.Open(CRecordset::snapshot,sql,CRecordset::readOnly);
298     this->access_array.SetSize(RS.GetRecordCount());
299     while(!RS.IsEOF())
300     {
301     p_access = new Access_STRUCT();
302    
303     RS.GetFieldValue("ip",dbVar,SQL_C_CHAR);
304     strcpy(p_access->ip,*(dbVar.m_pstring));
305     RS.GetFieldValue("control",dbVar,SQL_C_SSHORT);
306     p_access->control = (dbVar.m_iVal!=0);
307     RS.GetFieldValue("get",dbVar,SQL_C_SSHORT);
308     p_access->get = (dbVar.m_iVal!=0);
309     RS.GetFieldValue("post",dbVar,SQL_C_SSHORT);
310     p_access->post = (dbVar.m_iVal!=0);
311     RS.GetFieldValue("ihave",dbVar,SQL_C_SSHORT);
312     p_access->ihave = (dbVar.m_iVal!=0);
313    
314     this->access_array.Add(p_access);
315     RS.MoveNext();
316     }
317     RS.Close();
318    
319     this->db_close();
320     }
321     catch(CException* e)
322     {
323 sysadm 1.10 char strErrMsg[1024];
324     e->GetErrorMessage(strErrMsg,1024);
325     syslog << logfile::log_head << "Error in load_priv() [" << strErrMsg << "]" << endl;
326 sysadm 1.1 e->Delete();
327     return -1;
328     }
329    
330     return 0;
331     }
332    
333     int base_passive::unload_priv(void)
334     {
335     Access_STRUCT* p_access;
336    
337     try
338     {
339     for (int i=1; i<this->access_array.GetCount();i++)
340     {
341     p_access = this->access_array[i];
342     delete (p_access);
343     }
344     this->access_array.RemoveAll();
345     }
346     catch(CException* e)
347     {
348 sysadm 1.10 char strErrMsg[1024];
349     e->GetErrorMessage(strErrMsg,1024);
350     syslog << logfile::log_head << "Error in unload_priv() [" << strErrMsg << "]" << endl;
351 sysadm 1.1 e->Delete();
352     return -1;
353     }
354    
355     return 0;
356     }
357    
358     int base_passive::w_call(void)
359     {
360     this->work();
361     return 0;
362     }
363 sysadm 1.8
364     bool base_passive::check_priv(void)
365     {
366     return this->access.get;
367     }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1