34 #include <sys/socket.h>
35 #include <arpa/inet.h>
37 #include <netinet/in.h>
43 #include <sys/prctl.h>
52 #include <sys/types.h>
60 BOOL CtrlHandler( DWORD fdwCtrlType);
65 void *thread_fn(
void *inp_arg)
67 unsigned _stdcall thread_fn(
void *inp_arg)
70 int thread_no,plugin_init_state,iResult;
72 SOCKET clnt_sock,nfds;
76 fwork->rel_thread_sync_mutex();
80 plugin_p = (fwork->
factory[plugin_inp->get_plugin()])();
81 *plugin_p = *plugin_inp;
83 thread_no = plugin_p->get_thread_id();
84 fwork->plugin_read_conf_file(plugin_p,thread_no);
85 plugin_init_state = 1;
86 clnt_sock = (SOCKET) plugin_p->get_client_socket();
89 plugin_init_state = 0;
90 struct timeval timeout;
96 FD_SET (clnt_sock, &socks);
98 timeout.tv_sec = fwork->timeout_seconds;
100 iResult = select((
int)nfds+1, &socks, NULL, NULL, &timeout);
102 throw (
char *)
"97 Thread timeout.";
103 else if (iResult > 0 && FD_ISSET (clnt_sock, &socks))
109 throw (
char *)
"98 client disconnect.";
130 void *ssl_thread_fn(
void *inp_arg)
132 unsigned _stdcall ssl_thread_fn(
void *inp_arg)
135 int thread_no,plugin_init_state;
138 SOCKET clnt_sock,nfds;
143 fwork->rel_thread_sync_mutex();
147 plugin_p = (fwork->
factory[plugin_inp->get_plugin()])();
148 *plugin_p = *plugin_inp;
150 ssl = SSL_new(fwork->sslserver.get_ctx());
151 thread_no = plugin_p->get_thread_id();
152 fwork->plugin_read_conf_file(plugin_p,thread_no);
153 plugin_init_state = 1;
154 clnt_sock = (SOCKET) plugin_p->get_client_socket();
155 status = SSL_set_fd(ssl, clnt_sock);
157 throw (
char *)
"86 SSL_set_fd failed.";
158 if(fwork->get_verify_client())
159 SSL_set_verify(ssl,SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,NULL);
160 status = fwork->ssl_async_accept((SSL *)ssl);
162 throw (
char *)
"87 SSL_accept failed.";
165 plugin_init_state = 0;
166 struct timeval timeout;
172 FD_SET(clnt_sock, &socks);
174 timeout.tv_sec = fwork->timeout_seconds;
176 status = select((
int)nfds+1, &socks, NULL, NULL, &timeout);
179 else if (status > 0 && FD_ISSET (clnt_sock, &socks))
185 throw (
char *)
"89 client disconnect.";
211 unsigned int size,result;
212 char recvbuf[MAX_SZ];
213 int len,offset,ssl_response;
215 unsigned char sendbuf[MAX_SZ];
218 memset(sendbuf,0,MAX_SZ);
219 memset(recvbuf,0,MAX_SZ);
224 if(plugin_init_state == 0)
225 throw (
char *)
" 88 Can't inititalize plug-in.";
226 len = recv(SSL_get_fd(ssl), (
char*) recvbuf, MAX_SZ, MSG_PEEK);
228 throw (
char *)
" 89 client disconnected.";
237 len = fwork->ssl_async_read((SSL *)ssl, recvbuf, 8);
239 throw (
char *)
" 90 Invalid data received from client.";
245 size = get_data_size((
unsigned char *)recvbuf);
246 if(size > (
unsigned int) MAX_SZ-offset || size == 0)
248 len = fwork->ssl_async_read((SSL *)ssl, recvbuf, size);
250 throw (
char *)
" 90 Invalid data received from client.";
253 if(plugin_p->get_validate_plugin())
256 plugin_name = get_input_plugin_name(recvbuf);
257 offset += plugin_name.length();
258 if(plugin_name != plugin_p->get_plugin_name())
260 if(!plugin_p->find_plugin_alias(plugin_name))
263 plugin_p->add_plugin_alias(plugin_p->get_plugin_name());
265 plugin_p->set_plugin_name(plugin_name);
270 if(result == TERMINATE_SESSION)
272 add_size(sendbuf,size);
273 ssl_response = fwork->ssl_async_write((SSL *)ssl, (
char *)sendbuf, size+8);
275 throw (
char *)
" 93 SSL_write error.";
276 if(ssl_response == 0)
278 if(!print_source_hostname(clnt_sock,TLS_REQ,fwork,thread_no,plugin_p))
283 os <<
" Thr.ID:" << thread_no <<
" Plugin:" << plugin_p->get_plugin_name() << cp;
284 fwork->
log(LOG_LOW,LOG_LOW,os.str());
292 strcpy((
char *)sendbuf,
"92 Invalid plugin_name sent by client.");
294 strcpy((
char *)sendbuf,
"91 Invalid message.");
296 strcpy((
char *)sendbuf,
"00 Terminating..");
298 size = strlen((
char *)sendbuf);
299 add_size(sendbuf,size);
300 fwork->ssl_async_write((SSL *)ssl, (
char *)sendbuf, size+8);
309 struct sockaddr_storage peer;
310 struct sockaddr_in *s;
314 peer_len =
sizeof(sockaddr_storage);
315 if( (getpeername(clnt_sock, (sockaddr *)&peer,(socklen_t*) &peer_len)) != SOCKET_ERROR)
317 s = (sockaddr_in *) &peer;
318 os <<
" Thr.ID:" << thread_no <<
" Plugin:" << plugin_p->get_plugin_name() <<
" Request from: ";
319 os << inet_ntoa(s->sin_addr);
321 fwork->
log(LOG_LOW,LOG_LOW,os.str());
328 unsigned int size,result;
329 char recvbuf[MAX_SZ];
333 unsigned char sendbuf[MAX_SZ];
335 memset(sendbuf,0,MAX_SZ);
336 memset(recvbuf,0,MAX_SZ);
340 if(plugin_init_state == 0)
341 throw (
char *)
" 88 Can't inititalize plug-in.";
342 len = recv(clnt_sock, (
char*) recvbuf, MAX_SZ, MSG_PEEK);
344 throw (
char *)
" 89 client disconnected.";
345 len = read_socket((
unsigned char*) recvbuf,clnt_sock, 8);
347 throw (
char *)
" 90 1 Invalid data received from client.";
360 size = get_data_size((
unsigned char *)recvbuf);
361 if(size > (
unsigned int) MAX_SZ-offset || size == 0)
363 len = read_socket((
unsigned char*) recvbuf,clnt_sock, size);
365 throw (
char *)
" 90 2 Invalid data received from client.";
366 if(plugin_p->get_validate_plugin())
369 plugin_name = get_input_plugin_name(recvbuf);
370 offset += plugin_name.length();
371 if(plugin_name != plugin_p->get_plugin_name())
373 if(!plugin_p->find_plugin_alias(plugin_name))
376 plugin_p->add_plugin_alias(plugin_p->get_plugin_name());
378 plugin_p->set_plugin_name(plugin_name);
383 if(result == TERMINATE_SESSION)
385 add_size(sendbuf,size);
386 result = send(clnt_sock, (
char *)sendbuf,size+8,0);
388 throw (
char *)
" 00 Terminating..";
389 if(!print_source_hostname(clnt_sock,SOCKET_REQ,fwork,thread_no,plugin_p))
394 os <<
" Thr.ID:" << thread_no <<
" Plugin:" << plugin_p->get_plugin_name() << cp;
395 fwork->
log(LOG_LOW,LOG_LOW,os.str());
403 strcpy((
char *)sendbuf,
"92 Invalid plugin_name sent by client.");
405 strcpy((
char *)sendbuf,
"91 Invalid message.");
407 size = strlen((
char *)sendbuf);
408 add_size(sendbuf,size);
409 send(clnt_sock, (
char *)sendbuf,size+8,0);
421 len = strlen((
char *)sendbuf);
422 send(clnt_sock, (
char *)sendbuf, (
int)len, 0 );
426 os <<
" Thr.ID:" << thread_no <<
" Plugin:" << plugin_p->get_plugin_name() <<
" Quitting thread." << sendbuf;
427 fwork->
log(LOG_LOW,LOG_LOW,os.str());
428 fwork->socket_close(clnt_sock);
430 fwork->rel_thread_id(thread_no);
437 int len,ssl_response,status;
441 len = strlen((
char *)sendbuf);
442 status = recv(SSL_get_fd(ssl), (
char*) buf, 10, MSG_PEEK);
445 ssl_response = fwork->ssl_async_write((SSL *)ssl, (
char *)sendbuf, (
int)len);
448 while((SSL_shutdown(ssl)) == 0)
453 os <<
" Thr.ID:" << thread_no <<
" Plugin:" << plugin_p->get_plugin_name() <<
" Quitting thread." << sendbuf;
454 fwork->
log(LOG_LOW,LOG_LOW,os.str());
455 fwork->socket_close(SSL_get_fd(ssl));
456 SSL_free((SSL *)ssl);
460 fwork->rel_thread_id(thread_no);
466 int main(
int argc,
char* argv[])
468 VOID start_service(LPSTR* argv)
471 char pname[100],daemon_flag,cfile[MAX_SZ];
475 memset(cfile,0,MAX_SZ);
479 cout <<
"Usage: generic_server.exe <generic_server_name> <conf file>" << endl;
482 strncpy(cfile,argv[2],strlen(argv[2]));
484 daemon_flag = atoi(argv[3]);
485 strcpy(pname,argv[1]);
486 for(
int i = 0;i < argc; i++)
487 memset(argv[i],
' ',strlen(argv[i]));
488 strcpy(argv[0],pname);
489 prctl(PR_SET_NAME,(
unsigned long)pname,0,0,0);
492 istringstream iss(GetCommandLine());
496 strcpy(cfile,(
char *)tmp.c_str());
498 strcpy(cfile,(
char *)
"C:\\generic_server\\generic_server.conf");
499 strcpy(pname,argv[0]);
501 framework->set_conf_file(cfile);
502 framework->set_process_name(pname);
503 if(!framework->
init())
505 framework->
log(LOG_LOW,LOG_LOW,(
char *)
" FATAL error. Please check for configuration errors!.");
512 SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE);
514 framework->print_key_message();
530 cerr <<
"Unable to fork()..." << endl;
538 signal(SIGCHLD,SIG_IGN);
539 signal(SIGTSTP,SIG_IGN);
540 signal(SIGTTOU,SIG_IGN);
541 signal(SIGTTIN,SIG_IGN);
542 signal(SIGPIPE,SIG_IGN);
543 signal(SIGHUP,do_nothing);
544 signal(SIGTERM,sig_int);
556 case DLL_PROCESS_ATTACH:
561 case DLL_THREAD_ATTACH:
565 case DLL_THREAD_DETACH:
570 case DLL_PROCESS_DETACH:
579 void sig_int(
int sig_num)
582 vector <GENERIC_PLUGIN *>::iterator it;
585 os <<
" Thr.ID:MAIN thread. Signal received to terminate.. " << endl;
586 for(it = framework->get_start_iterator(); it != framework->get_end_iterator();it++)
588 map<string,bool>::iterator bootstrap_itr = framework->bootstrap_jobs.find((*it)->bootstrap_name());
590 if(bootstrap_itr != framework->bootstrap_jobs.end() && (*it)->bootstrap_name() !=
"")
592 os <<
"\tThr.ID:MAIN. Invoking bootstrap terminate: " << (*it)->bootstrap_name() <<
" on plug-in: " << (*it)->get_plugin_name() << endl;
593 if(!(*it)->bootstrap_terminate((*it)->bootstrap_name()))
595 os <<
"\tThr.ID:MAIN failed to terminate bootstrap: " << (*it)->bootstrap_name() <<
" on plug-in: " << (*it)->get_plugin_name() << endl;
597 framework->bootstrap_jobs.erase(bootstrap_itr);
599 if( (framework->check_enabled_plugin((*it)->get_plugin())) > 1)
600 it = framework->
v.erase(it);
603 os <<
"\tShutting down: " << *(*it) << endl;
604 (*it)->server_shutdown();
605 it = framework->
v.erase(it);
608 framework->
log(LOG_LOW,LOG_LOW,(
char *)os.str().c_str());
609 framework->close_log();
621 struct timeval timeout;
624 timeout.tv_usec = 20;
625 command_sock = fwork->
create_socket(fwork->get_command_port());
626 if(command_sock == 0)
632 nfds = init_sock_fds(&socks,command_sock);
633 readsock = select(nfds+1,&socks,NULL,NULL,0);
636 fwork->reload_conf_file();
641 if(chk_command_sock(&socks,command_sock))
643 chk_all_clients(&socks);
644 if(!fwork->syslog_flag)
650 unsigned int init_sock_fds(fd_set *socks,SOCKET command_sock)
655 for(fwork->itr = fwork->
v.begin(); fwork->itr != fwork->
v.end(); ++fwork->itr)
657 if(nfds < (*fwork->itr)->get_socket())
658 nfds = (
unsigned int)(*fwork->itr)->get_socket();
659 FD_SET((*fwork->itr)->get_socket(),socks);
661 FD_SET(command_sock,socks);
666 int chk_command_sock(fd_set *socks,SOCKET command_sock)
671 if(FD_ISSET(command_sock,socks))
673 clnt_sock = accept(command_sock,NULL,NULL);
676 shutdown(clnt_sock,2);
678 closesocket(clnt_sock);
682 fwork->reload_conf_file();
695 fwork->get_thread_sync_mutex();
696 pthread_attr_init(&attr);
697 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
699 if(generic_plugin->get_tls_flag())
702 fwork->get_thread_sync_mutex();
703 fwork->
thread_ids[new_slot].th = (HANDLE)_beginthreadex(NULL, 0, &ssl_thread_fn, (
void *)generic_plugin, 0, NULL );
705 pthread_create(&fwork->
thread_ids[new_slot].th,&attr,ssl_thread_fn, (
void *)generic_plugin);
711 fwork->get_thread_sync_mutex();
712 fwork->
thread_ids[new_slot].th = (HANDLE)_beginthreadex(NULL, 0, &thread_fn, (
void *)generic_plugin, 0, NULL );
714 pthread_create(&fwork->
thread_ids[new_slot].th,&attr,thread_fn, (
void *)generic_plugin);
718 pthread_attr_destroy(&attr);
720 fwork->close_thread_ids();
725 int chk_all_clients(fd_set *socks)
729 unsigned int len,new_slot;
731 char sendbuf[MAX_SZ];
733 memset(sendbuf,0,MAX_SZ);
734 for(fwork->itr = fwork->
v.begin(); fwork->itr != fwork->
v.end(); ++fwork->itr)
736 if(FD_ISSET((*fwork->itr)->get_socket(),socks))
738 clnt_sock = accept((*fwork->itr)->get_socket(),NULL,NULL);
741 fwork->setnonblocking(clnt_sock);
742 len = recv(clnt_sock, (
char*) sendbuf, 10, MSG_PEEK);
745 shutdown(clnt_sock,2);
746 fwork->
log(LOG_LOW,LOG_LOW,(
char *)
"85 client disconnected.");
749 if(fwork->
thread_ids.size() >= (
unsigned int) fwork->max_threads)
751 fwork->
log(LOG_LOW,LOG_LOW,(
char *)
"11 Too many threads running. Try later..");
752 shutdown(clnt_sock,2);
754 closesocket(clnt_sock);
761 fwork->close_thread_ids();
764 generic_plugin->set_client_socket(clnt_sock);
765 new_slot = fwork->get_thread_id();
766 generic_plugin->set_thread_id(new_slot);
775 BOOL CtrlHandler( DWORD fdwCtrlType )
777 switch( fdwCtrlType )
781 sig_int(fdwCtrlType);
783 case CTRL_BREAK_EVENT:
792 void do_nothing(
int sig_num)
797 unsigned int get_data_size(
unsigned char *recvbuf)
799 unsigned int size,plugin_signature;
801 plugin_signature = htonl(PLUGIN_SIGNATURE);
803 if(memcmp(recvbuf,(
char *)&plugin_signature,4))
805 memcpy(&size,recvbuf+4,4);
811 int add_size(
unsigned char *recvbuf,
unsigned int size)
814 unsigned int plugin_signature;
815 char buffer[MAX_SZ+8];
817 plugin_signature = htonl(PLUGIN_SIGNATURE);
820 memcpy(buffer,(
char *)&plugin_signature,4);
821 memcpy(buffer+4,&size,4);
822 memcpy(buffer+8,recvbuf,sav_size);
823 memcpy(recvbuf,buffer,sav_size+8);
828 string get_input_plugin_name(
char *buffer)
833 memcpy((
char *)&size,buffer,4);
835 plugin_name = string(buffer+4,size);
840 static int read_socket(
unsigned char *buffer,SOCKET sock,
int size)
843 struct timeval timeout;
849 memset(buffer,0,
sizeof(buffer));
850 memset(str,0,MAX_SZ);
851 while(bytes_recvd < size)
857 readsock = select((
int)sock+1,&socks,NULL,NULL,&timeout);
860 if(FD_ISSET(sock,&socks))
862 t = recv(sock,str,size, 0);
865 memcpy(buffer+bytes_recvd,str,t);
867 if(bytes_recvd >= size)
map< int, THREAD_INFO > thread_ids
Map to store all currently running threads.
int log(unsigned int, unsigned int, char *)
enables logging to framework managed log file.
static generic_server * pinstance
Pointer to singleton framework instance.
Singleton class to manage framework state and provide utility functions. This class stores master Vec...
static int terminate_ssl_client_session(SSL *ssl, generic_server *framework, GENERIC_PLUGIN *plugin_p, int thread_no, unsigned char *senduf)
int rollover_logs(void)
Rolls over log files, configured in Master configuation file.
static int terminate_client_session(SOCKET clnt_sock, generic_server *framework, GENERIC_PLUGIN *plugin_p, int thread_no, unsigned char *senduf)
This is a singleton class and provides framework functionality.
virtual int shutdown_plugin(void)
This component provides functionality that are common across plug-ins. Framework would instantiate an...
static int process_client_req(SOCKET clnt_sock, int plugin_init_state, GENERIC_PLUGIN *plugin_p, int thread_no, generic_server *framework)
static int process_data(void)
Main loop to 'select()' sockets from multiple clients.
This is the base class for all plugins. All plug-ins should derive from this class. This class has a bunch of virtual functions that all plug-in could/should implement. In addition to virtual functions, this class also provides a lot of utility functions for all plug-ins.
virtual int plugin_init(int thread_no)
static int launch_thread(GENERIC_PLUGIN *generic_plugin, unsigned int new_slot)
static int process_ssl_client_req(SOCKET clnt_sock, SSL *ssl, int plugin_init_state, GENERIC_PLUGIN *plugin_p, int thread_no, generic_server *framework)
SOCKET create_socket(int)
virtual int process_request(void *buffer, void *out_buff, unsigned int &size)
Master program that initiates GENERIC_SERVER, spawns a thread for each plug-in and runs message loop ...
vector< GENERIC_PLUGIN * > v
Vector to hold all plug-ins.
map< string, create_fp > factory
Map that has function pointers to 'create_instance()' factory method for all plug-in libraries...
Utility class for TLS. Please refer excellent documentation at: http://www.openssl.org/docs/ssl/ssl.html.
static generic_server * instance(void)
Instantiate tis singleton class only once and return pointer to instantiated object later on...