ffead.server.doc
CHServer.cpp
1 /*
2  Copyright 2009-2012, Sumeet Chhetri
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 */
16 /*
17  * CHServer.cpp
18  *
19  * Created on: Aug 25, 2009
20  * Author: sumeet
21  */
22 
23 #include "CHServer.h"
24 
25 
26 CHServer::CHServer()
27 {}
28 
29 CHServer::~CHServer() {
30  // TODO Auto-generated destructor stub
31 }
32 //SharedData* SharedData::shared_instance = NULL;
33 string servd, serverCntrlFileNm;
34 static bool isSSLEnabled = false,isThreadprq = false,processforcekilled = false,processgendone = false,sessatserv = false,isCompileEnabled = false;
35 static long sessionTimeout;
36 static int thrdpsiz/*,shmid*/;
37 static SSL_CTX *ctx;
38 static char *ciphers=0;
39 map<int,pid_t> pds;
40 static pid_t parid;
41 void *dlib = NULL, *ddlib = NULL;
42 typedef map<string,string> sessionMap;
43 static Mutex m_mutex,p_mutex;
44 ConfigurationData configurationData;
45 
46 Logger logger;
47 
48 void sigchld_handler(int s)
49 {
50  while(waitpid(-1, NULL, WNOHANG) > 0);
51 }
52 
53 // get sockaddr, IPv4 or IPv6:
54 void *get_in_addr(struct sockaddr *sa)
55 {
56  if (sa->sa_family == AF_INET) {
57  return &(((struct sockaddr_in*)sa)->sin_addr);
58  }
59  return &(((struct sockaddr_in6*)sa)->sin6_addr);
60 }
61 
62 
63 int send_connection(int fd,int descriptor)
64 {
65  struct msghdr msg;
66  struct iovec iov [1];
67  int n;
68 
69  /* need to send some data otherwise client can't distinguish between
70  * EOF and "just sending a file descriptor"
71  */
72  iov [0].iov_base = (void *)"x";
73  iov [0].iov_len = 1;
74 
75  /* not relevant for connected sockets */
76  msg.msg_name = NULL;
77  msg.msg_namelen = 0;
78  msg.msg_iov = iov;
79  msg.msg_iovlen = 1;
80  msg.msg_flags = 0;
81 
82  msg.msg_control = NULL;
83  msg.msg_controllen = 0;
84 
85  /* put the descriptor in the ancillary data */
86  {
87  /* using a union to ensure its correctly aligned */
88  union
89  {
90  struct cmsghdr cmsg;
91  char control [CMSG_SPACE (sizeof (int))];
92  } msg_control;
93  struct cmsghdr *cmsg;
94 
95  msg.msg_control = &msg_control;
96  msg.msg_controllen = sizeof (msg_control);
97 
98  cmsg = CMSG_FIRSTHDR (&msg);
99 
100  cmsg->cmsg_len = CMSG_LEN (sizeof (int));
101  cmsg->cmsg_level = SOL_SOCKET;
102  cmsg->cmsg_type = SCM_RIGHTS;
103 
104  *((int *) CMSG_DATA (cmsg)) = descriptor;
105  }
106 
107  if((n= sendmsg(fd, &msg, 0)) < 0 )
108  {
109  perror("sendmsg()");
110  exit(1);
111  }
112  close(descriptor);
113  return n;
114 }
115 
116 int receive_fd(int fd)
117 {
118  union
119  {
120  struct cmsghdr cmsg;
121  char control [CMSG_SPACE (sizeof (int))];
122  } msg_control;
123 
124  struct msghdr msg;
125  struct iovec iov [1];
126  struct cmsghdr *cmsg;
127  char buf [192];
128  int n;
129 
130  iov [0].iov_base = buf;
131  iov [0].iov_len = sizeof (buf);
132 
133  /* not relevant for connected sockets */
134  msg.msg_name = NULL;
135  msg.msg_namelen = 0;
136  msg.msg_iov = iov;
137  msg.msg_iovlen = 1;
138  msg.msg_control = &msg_control;
139  msg.msg_controllen = sizeof (msg_control);
140  msg.msg_flags = 0;
141 
142  n = recvmsg (fd, &msg, 0);
143  if(n == 1)
144  {
145  for (cmsg = CMSG_FIRSTHDR (&msg); cmsg; cmsg = CMSG_NXTHDR (&msg, cmsg))
146  {
147  int descriptor;
148 
149  if (cmsg->cmsg_len != CMSG_LEN (sizeof (int)) ||
150  cmsg->cmsg_level != SOL_SOCKET ||
151  cmsg->cmsg_type != SCM_RIGHTS)
152  continue;
153 
154  descriptor = *((int *) CMSG_DATA (cmsg));
155  return descriptor;
156  }
157  }
158  return -1;
159 }
160 
161 void signalSIGSEGV(int dummy)
162 {
163  signal(SIGSEGV,signalSIGSEGV);
164  string filename;
165  stringstream ss;
166  ss << servd;
167  ss << getpid();
168  ss >> filename;
169  filename.append(".cntrl");
170  remove(filename.c_str());
171  string tempo;
172  /*void * array[25];
173  int nSize = backtrace(array, 25);
174  char ** symbols = backtrace_symbols(array, nSize);
175  string tempo;
176  for (int i = 0; i < nSize; i++)
177  {
178  tempo = symbols[i];
179  tempo += "\n";
180  }
181  free(symbols);*/
182  logger << "Segmentation fault occurred for process" << getpid() << "\n" << tempo << endl;
183  abort();
184 }
185 void signalSIGCHLD(int dummy)
186 {
187  signal(SIGCHLD,signalSIGCHLD);
188  string filename;
189  stringstream ss;
190  ss << servd;
191  ss << getpid();
192  ss >> filename;
193  filename.append(".cntrl");
194  remove(filename.c_str());
195  string tempo;
196  /*void * array[25];
197  int nSize = backtrace(array, 25);
198  char ** symbols = backtrace_symbols(array, nSize);
199  string tempo;
200  for (int i = 0; i < nSize; i++)
201  {
202  tempo = symbols[i];
203  tempo += "\n";
204  }
205  free(symbols);*/
206  logger << "Child process got killed " << getpid() << "\n" << tempo << endl;
207  abort();
208 }
209 void signalSIGABRT(int dummy)
210 {
211  signal(SIGABRT,signalSIGABRT);
212  string filename;
213  stringstream ss;
214  ss << servd;
215  ss << getpid();
216  ss >> filename;
217  filename.append(".cntrl");
218  remove(filename.c_str());
219  string tempo;
220  /*void * array[25];
221  int nSize = backtrace(array, 25);
222  char ** symbols = backtrace_symbols(array, nSize);
223  string tempo;
224  for (int i = 0; i < nSize; i++)
225  {
226  tempo = symbols[i];
227  tempo += "\n";
228  }
229  free(symbols);*/
230  logger << "Abort signal occurred for process" << getpid() << "\n" << tempo << endl;
231  abort();
232 }
233 void signalSIGTERM(int dummy)
234 {
235  signal(SIGKILL,signalSIGTERM);
236  string filename;
237  stringstream ss;
238  ss << servd;
239  ss << getpid();
240  ss >> filename;
241  filename.append(".cntrl");
242  remove(filename.c_str());
243  string tempo;
244  /*void * array[25];
245  int nSize = backtrace(array, 25);
246  char ** symbols = backtrace_symbols(array, nSize);
247  string tempo;
248  for (int i = 0; i < nSize; i++)
249  {
250  tempo = symbols[i];
251  tempo += "\n";
252  }
253  free(symbols);*/
254  logger << "Termination signal occurred for process" << getpid() << "\n" << tempo << endl;
255  abort();
256 }
257 
258 void signalSIGKILL(int dummy)
259 {
260  signal(SIGKILL,signalSIGKILL);
261  string filename;
262  stringstream ss;
263  ss << servd;
264  ss << getpid();
265  ss >> filename;
266  filename.append(".cntrl");
267  remove(filename.c_str());
268  string tempo;
269  /*void * array[25];
270  int nSize = backtrace(array, 25);
271  char ** symbols = backtrace_symbols(array, nSize);
272  string tempo;
273  for (int i = 0; i < nSize; i++)
274  {
275  tempo = symbols[i];
276  tempo += "\n";
277  }
278  free(symbols);*/
279  logger << "Kill signal occurred for process" << getpid() << "\n" << tempo << endl;
280  abort();
281 }
282 
283 void signalSIGINT(int dummy)
284 {
285  signal(SIGINT,signalSIGINT);
286  string filename;
287  stringstream ss;
288  ss << servd;
289  ss << getpid();
290  ss >> filename;
291  filename.append(".cntrl");
292  remove(filename.c_str());
293  string tempo;
294  /*void * array[25];
295  int nSize = backtrace(array, 25);
296  char ** symbols = backtrace_symbols(array, nSize);
297  string tempo;
298  for (int i = 0; i < nSize; i++)
299  {
300  tempo = symbols[i];
301  tempo += "\n";
302  }
303  free(symbols);*/
304  logger << "Interrupt signal occurred for process" << getpid() << "\n" << tempo << endl;
305  abort();
306 }
307 
308 void signalSIGFPE(int dummy)
309 {
310  signal(SIGFPE,signalSIGFPE);
311  string filename;
312  stringstream ss;
313  ss << servd;
314  ss << getpid();
315  ss >> filename;
316  filename.append(".cntrl");
317  remove(filename.c_str());
318  string tempo;
319  /*void * array[25];
320  int nSize = backtrace(array, 25);
321  char ** symbols = backtrace_symbols(array, nSize);
322  string tempo;
323  for (int i = 0; i < nSize; i++)
324  {
325  tempo = symbols[i];
326  tempo += "\n";
327  }
328  free(symbols);*/
329  logger << "Floating point Exception occurred for process" << getpid() << "\n" << tempo << endl;
330  abort();
331 }
332 void signalSIGPIPE(int dummy)
333 {
334  signal(SIGPIPE,signalSIGPIPE);
335  /*string filename;
336  stringstream ss;
337  ss << servd;
338  ss << getpid();
339  ss >> filename;
340  filename.append(".cntrl");
341  remove(filename.c_str());*/
342  string tempo;
343  /*void * array[25];
344  int nSize = backtrace(array, 25);
345  char ** symbols = backtrace_symbols(array, nSize);
346  string tempo;
347  for (int i = 0; i < nSize; i++)
348  {
349  tempo = symbols[i];
350  tempo += "\n";
351  }
352  free(symbols);*/
353  logger << "Broken pipe ignore it" << getpid() << "\n" << tempo << endl;
354  abort();
355 }
356 
357 void signalSIGILL(int dummy)
358 {
359  signal(SIGILL,signalSIGILL);
360  string filename;
361  stringstream ss;
362  ss << servd;
363  ss << getpid();
364  ss >> filename;
365  filename.append(".cntrl");
366  remove(filename.c_str());
367  string tempo;
368  /*void * array[25];
369  int nSize = backtrace(array, 25);
370  char ** symbols = backtrace_symbols(array, nSize);
371  string tempo;
372  for (int i = 0; i < nSize; i++)
373  {
374  tempo = symbols[i];
375  tempo += "\n";
376  }
377  free(symbols);*/
378  logger << "Floating point Exception occurred for process" << getpid() << "\n" << tempo << endl;
379  abort();
380 }
381 
382 void* service(void* arg)
383 {
384  logger << "service method " << endl;
385  ServiceTask *task = (ServiceTask*)arg;
386  task->run();
387  delete task;
388  return NULL;
389 }
390 
391 pid_t createChildProcess(string serverRootDirectory,int sp[],int sockfd)
392 {
393  pid_t pid;
394  if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sp) == -1)
395  {
396  perror("socketpair");
397  exit(1);
398  }
399  if((pid=fork())==0)
400  {
401  SSLHandler sSLHandler;
402  dlib = dlopen(Constants::INTER_LIB_FILE.c_str(), RTLD_NOW);
403  //logger << endl <<dlib << endl;
404  if(dlib==NULL)
405  {
406  logger << dlerror() << endl;
407  logger.info("Could not load Library");
408  exit(0);
409  }
410  else
411  logger.info("Library loaded successfully");
412 
413  ddlib = dlopen(Constants::DINTER_LIB_FILE.c_str(), RTLD_NOW);
414  //logger << endl <<dlib << endl;
415  if(ddlib==NULL)
416  {
417  logger << dlerror() << endl;
418  logger.info("Could not load dynamic Library");
419  exit(0);
420  }
421  else
422  logger.info("Dynamic Library loaded successfully");
423  if(isSSLEnabled)
424  {
425  /*HTTPS related*/
426  //client_auth=CLIENT_AUTH_REQUIRE;
427  /* Build our SSL context*/
428  ctx = sSLHandler.initialize_ctx((char*)configurationData.key_file.c_str(),(char*)configurationData.sec_password.c_str(),
429  configurationData.ca_list);
430  sSLHandler.load_dh_params(ctx,(char*)configurationData.dh_file.c_str());
431 
432  SSL_CTX_set_session_id_context(ctx,
433  (const unsigned char*)&SSLHandler::s_server_session_id_context,
434  sizeof SSLHandler::s_server_session_id_context);
435 
436  /* Set our cipher list */
437  if(ciphers){
438  SSL_CTX_set_cipher_list(ctx,ciphers);
439  }
440  /*if(configurationData.client_auth==2)
441  SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);
442  else if(configurationData.client_auth==1)
443  SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,0);*/
444  }
445  servd = serverRootDirectory;
446  string filename;
447  stringstream ss;
448  ss << serverRootDirectory;
449  ss << getpid();
450  ss >> filename;
451  filename.append(".cntrl");
452  logger << ("generated file " + filename) << endl;
453  ofstream cntrlfile;
454  cntrlfile.open(filename.c_str());
455  cntrlfile << "Process Running" << endl;
456  cntrlfile.close();
457 
458  close(sockfd);
459 
460  SelEpolKqEvPrt selEpolKqEvPrtHandler;
461  selEpolKqEvPrtHandler.initialize(sp[1]);
462  ThreadPool pool;
463  if(!isThreadprq)
464  {
465  pool.init(thrdpsiz,30,true);
466  }
467  PropFileReader pread;
468  propMap params = pread.getProperties(serverRootDirectory+"resources/security.prop");
469 
470  //logger << params.size() <<endl;
471 
472  ofstream serverCntrlFile;
473  serverCntrlFile.open(serverCntrlFileNm.c_str());
474  while(serverCntrlFile.is_open())
475  {
476  serverCntrlFile.close();
477 
478  int nfds = selEpolKqEvPrtHandler.getEvents();
479  if (nfds == -1)
480  {
481  perror("poller wait child process");
482  logger << "\n----------poller child process----" << endl;
483  }
484  else
485  {
486  int fd = receive_fd(sp[1]);
487  selEpolKqEvPrtHandler.reRegisterServerSock();
488  fcntl(fd, F_SETFL,O_SYNC);
489 
490  char buf[10];
491  int err;
492  if((err=recv(fd,buf,10,MSG_PEEK))==0)
493  {
494  close(fd);
495  logger << "Socket conn closed before being serviced" << endl;
496  continue;
497  }
498 
499  if(isThreadprq)
500  {
501  ServiceTask *task = new ServiceTask(fd,serverRootDirectory,&params,
502  isSSLEnabled, ctx, sSLHandler, configurationData, dlib, ddlib);
503  Thread pthread(&service, task);
504  pthread.execute();
505  }
506  else
507  {
508  ServiceTask *task = new ServiceTask(fd,serverRootDirectory,&params,
509  isSSLEnabled, ctx, sSLHandler, configurationData, dlib, ddlib);
510  task->setCleanUp(true);
511  pool.execute(*task);
512  }
513  }
514  serverCntrlFile.open(serverCntrlFileNm.c_str());
515  }
516  }
517  return pid;
518 }
519 
520 
521 
522 /*pid_t createChildMonitProcess(int sp[])
523 {
524  pid_t pid;
525  if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sp) == -1)
526  {
527  perror("socketpair");
528  exit(1);
529  }
530  if((pid=fork())==0)
531  {
532  map<string,bool> stat;
533  while(1)
534  {
535  char buf[10];
536  if(read(sp[1], buf, sizeof buf) < 0)
537  {
538  string temp = buf;
539  strVec tempv;
540  StringUtil::split(tempv, temp, ":");
541  if(tempv.size()==2)
542  {
543  if(tempv.at(0)=="R")
544  {
545  string h = "0";
546  if(stat[tempv.at(1)])
547  h = "1";
548  write(sp[0], h.c_str() , sizeof(h));
549  }
550  else if(tempv.at(0)=="W")
551  {
552  stat[tempv.at(1)] = false;
553  }
554  }
555  }
556  }
557  }
558  return pid;
559 }*/
560 
561 
562 void* dynamic_page_monitor(void* arg)
563 {
564  string serverRootDirectory = *(string*)arg;
565  struct stat statbuf;
566  strVec dcpsss = configurationData.dcpsss;
567  strVec tpes = configurationData.tpes;
568  strVec dcspstpes = dcpsss;
569  dcspstpes.insert(dcspstpes.end(), tpes.begin(), tpes.end());
570  map<string,long> statsinf;
571  for(int i=0;i<(int)dcspstpes.size();i++)
572  {
573  stat(dcspstpes.at(i).c_str(), &statbuf);
574  time_t tm = statbuf.st_mtime;
575  long tim = (uintmax_t)tm;
576  statsinf[dcspstpes.at(i)] = tim;
577  }
578  while(true)
579  {
580  Thread::sSleep(5);
581  bool flag = false;
582  if(processgendone)
583  continue;
584  for(int i=0;i<(int)dcspstpes.size();i++)
585  {
586  stat(dcspstpes.at(i).c_str(), &statbuf);
587  time_t tm = statbuf.st_mtime;
588  long tim = (uintmax_t)tm;
589  if(tim!=statsinf[dcspstpes.at(i)])
590  {
591  string rtdcfpath = serverRootDirectory + "rtdcf/";
592  string respath = serverRootDirectory + "resources/";
593 
594  logger << "started generating dcp code" <<endl;
595  string ret = DCPGenerator::generateDCPAll(dcpsss);
596  AfcUtil::writeTofile(rtdcfpath+"DCPInterface.cpp",ret,true);
597  logger << "done generating dcp code" <<endl;
598  logger << "started generating template code" <<endl;
599  ret = TemplateGenerator::generateTempCdAll(tpes);
600  AfcUtil::writeTofile(rtdcfpath+"TemplateInterface.cpp",ret,true);
601  logger << "done generating template code" <<endl;
602 
603  string compres = respath+"rundyn_dinter.sh";
604  int i=system(compres.c_str());
605  if(!i)
606  {
607  logger << "regenerating intermediate code-----Done" << endl;
608  logger.info("Done generating intermediate code");
609  }
610  m_mutex.lock();
611  if(Constants::IS_FILE_DESC_PASSING_AVAIL)
612  {
613  map<int,pid_t>::iterator it;
614  for(it=pds.begin();it!=pds.end();it++)
615  {
616  kill(it->second,9);
617  }
618  }
619  else
620  {
621  if(ddlib!=NULL)
622  {
623  for (int var = 0; var < 100; ++var) {
624  if(dlclose(ddlib)!=0)
625  break;
626  }
627  }
628 
629  ddlib = dlopen(Constants::DINTER_LIB_FILE.c_str(), RTLD_NOW);
630  //logger << endl <<dlib << endl;
631  if(ddlib==NULL)
632  {
633  logger << dlerror() << endl;
634  logger.info("Could not re-load Dynamic Library");
635  }
636  else
637  logger.info("Dynamic Library re-loaded successfully");
638  }
639  m_mutex.unlock();
640  processforcekilled = true;
641  flag = true;
642  break;
643  }
644  }
645  if(flag)
646  {
647  for(int ii=0;ii<(int)dcspstpes.size();ii++)
648  {
649  stat(dcspstpes.at(ii).c_str(), &statbuf);
650  time_t tm = statbuf.st_mtime;
651  long tim = (uintmax_t)tm;
652  statsinf[dcspstpes.at(ii)] = tim;
653  }
654  }
655  }
656  return NULL;
657 }
658 
659 
660 int main(int argc, char* argv[])
661 {
662  parid = getpid();
663  signal(SIGSEGV,signalSIGSEGV);
664  signal(SIGFPE,signalSIGFPE);
665 
666  //signal(SIGILL,signalSIGILL);
667  signal(SIGPIPE,signalSIGPIPE);
668  int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
669  struct sockaddr_storage their_addr; // connector's address information
670  socklen_t sin_size;
671 
672  //int yes=1,rv;
673  int nfds,preForked=5;
674  string serverRootDirectory = argv[1];
675 
676  serverRootDirectory += "/";//serverRootDirectory = "/home/sumeet/server/";
677  string incpath = serverRootDirectory + "include/";
678  string rtdcfpath = serverRootDirectory + "rtdcf/";
679  string pubpath = serverRootDirectory + "public/";
680  string respath = serverRootDirectory + "resources/";
681  string webpath = serverRootDirectory + "web/";
682  string resourcePath = respath;
683 
684  servd = serverRootDirectory;
685  string logp = respath+"/log.prop";
686  Logger::init(logp);
687 
688  serverCntrlFileNm = serverRootDirectory + "ffead.cntrl";
689 
690  logger = Logger::getLogger("CHServer");
691 
692  PropFileReader pread;
693  propMap srprps = pread.getProperties(respath+"server.prop");
694  if(srprps["NUM_PROC"]!="")
695  {
696  try
697  {
698  preForked = CastUtil::lexical_cast<int>(srprps["NUM_PROC"]);
699  }
700  catch(...)
701  {
702  logger << "\nInvalid number for worker processes defined" << endl;
703  preForked = 5;
704  }
705  }
706  string sslEnabled = srprps["SSL_ENAB"];
707  if(sslEnabled=="true" || sslEnabled=="TRUE")
708  isSSLEnabled = true;
709  string thrdpreq = srprps["THRD_PREQ"];
710  if(thrdpreq=="true" || thrdpreq=="TRUE")
711  isThreadprq = true;
712  else
713  {
714  thrdpreq = srprps["THRD_PSIZ"];
715  if(thrdpreq=="")
716  thrdpsiz = 30;
717  else
718  {
719  try
720  {
721  thrdpsiz = CastUtil::lexical_cast<int>(thrdpreq);
722  }
723  catch(...)
724  {
725  logger << "\nInvalid thread pool size defined" << endl;
726  thrdpsiz = 30;
727  }
728  }
729  }
730  string compileEnabled = srprps["DEV_MODE"];
731  if(compileEnabled=="true" || compileEnabled=="TRUE")
732  isCompileEnabled = true;
733 
734  if(srprps["SCRIPT_ERRS"]=="true" || srprps["SCRIPT_ERRS"]=="TRUE")
735  {
736  Constants::SCRIPT_EXEC_SHOW_ERRS = true;
737  }
738  if(srprps["SESS_STATE"]=="server")
739  sessatserv = true;
740  if(srprps["SESS_TIME_OUT"]!="")
741  {
742  try {
743  sessionTimeout = CastUtil::lexical_cast<long>(srprps["SESS_TIME_OUT"]);
744  } catch (...) {
745  sessionTimeout = 3600;
746  logger << "\nInvalid session timeout value defined, defaulting to 1hour/3600sec" << endl;
747  }
748  }
749 
750  string PORT = srprps["PORT_NO"];
751  string IP_ADDRES = srprps["IP_ADDR"];
752  string IP_ADDRESS;
753 
754  if(IP_ADDRES!="")
755  IP_ADDRESS = IP_ADDRES + ":" + PORT;
756  else
757  IP_ADDRESS = "localhost:" + PORT;
758 
759  sockfd = Server::createListener(IP_ADDRES, PORT, false);
760 
761  strVec webdirs,webdirs1,pubfiles;
762  ConfigurationHandler::listi(webpath,"/",true,webdirs);
763  ConfigurationHandler::listi(webpath,"/",false,webdirs1);
764  ConfigurationHandler::listi(pubpath,".js",false,pubfiles);
765 
766 
767  strVec cmpnames;
768  try
769  {
770  configurationData = ConfigurationHandler::handle(webdirs, webdirs1, incpath, rtdcfpath, pubpath, respath, isSSLEnabled);
771  }
772  catch(XmlParseException p)
773  {
774  logger << p.getMessage() << endl;
775  }
776  catch(const char* msg)
777  {
778  logger << msg << endl;
779  }
780  configurationData.sessionTimeout = sessionTimeout;
781  configurationData.ip_address = IP_ADDRESS;
782  configurationData.sessatserv = sessatserv;
783  for(unsigned int var=0;var<pubfiles.size();var++)
784  {
785  configurationData.pubMap[pubfiles.at(var)] = "true";
786  }
787  bool libpresent = true;
788  void *dlibtemp = dlopen(Constants::INTER_LIB_FILE.c_str(), RTLD_NOW);
789  //logger << endl <<dlibtemp << endl;
790  if(dlibtemp==NULL)
791  {
792  libpresent = false;
793  logger << dlerror() << endl;
794  logger.info("Could not load Library");
795  }
796  else
797  dlclose(dlibtemp);
798  if(isCompileEnabled)
799  libpresent = false;
800 
801  configurationData.props = pread.getProperties(respath+"mime-types.prop");
802  configurationData.lprops = pread.getProperties(respath+"locale.prop");
803  string compres = respath+"rundyn.sh";
804  if(!libpresent)
805  {
806  string output = ScriptHandler::execute(compres, true);
807  logger << "Intermediate code generation task\n\n" << endl;
808  logger << output << endl;
809  }
810 
811  void* checkdlib = dlopen(Constants::INTER_LIB_FILE.c_str(), RTLD_NOW);
812  if(checkdlib==NULL)
813  {
814  logger << dlerror() << endl;
815  logger.info("Could not load Library");
816  exit(0);
817  }
818  else
819  {
820  dlclose(checkdlib);
821  logger.info("Library generated successfully");
822  }
823 
824  for (unsigned int var1 = 0;var1<configurationData.cmpnames.size();var1++)
825  {
826  string name = configurationData.cmpnames.at(var1);
827  StringUtil::replaceFirst(name,"Component_","");
828  ComponentHandler::registerComponent(name);
829  AppContext::registerComponent(name);
830  }
831  if(srprps["CMP_PORT"]=="")
832  {
833  srprps["CMP_PORT"] = "7001";
834  }
835  ComponentHandler::trigger(srprps["CMP_PORT"]);
836  if(srprps["MESS_PORT"]=="")
837  {
838  srprps["MESS_PORT"] = "7002";
839  }
840  MessageHandler::trigger(srprps["MESS_PORT"],resourcePath);
841  if(srprps["MI_PORT"]=="")
842  {
843  srprps["MI_PORT"] = "7003";
844  }
845  MethodInvoc::trigger(srprps["MI_PORT"]);
846 
847  //printf("server: waiting for connections...\n");
848  logger.info("Server: waiting for connections on port "+PORT);
849 
850  ofstream serverCntrlFile;
851  serverCntrlFile.open(serverCntrlFileNm.c_str());
852  serverCntrlFile << "Server Running" << endl;
853  serverCntrlFile.close();
854 
855  vector<string> files;
856  int sp[preForked][2];
857  ThreadPool *pool;
858  propMap params;
859  SSLHandler sSLHandler;
860  if(Constants::IS_FILE_DESC_PASSING_AVAIL)
861  {
862  for(int j=0;j<preForked;j++)
863  {
864  pid_t pid = createChildProcess(serverRootDirectory,sp[j],sockfd);
865  pds[j] = pid;
866  stringstream ss;
867  string filename;
868  ss << serverRootDirectory;
869  ss << pds[j];
870  ss >> filename;
871  filename.append(".cntrl");
872  files.push_back(filename);
873  }
874  }
875  else
876  {
877  propMap params = pread.getProperties(serverRootDirectory+"resources/security.prop");
878  SSLHandler sSLHandler;
879  if(isSSLEnabled)
880  {
881  /*HTTPS related*/
882  //client_auth=CLIENT_AUTH_REQUIRE;
883  /* Build our SSL context*/
884  ctx = sSLHandler.initialize_ctx((char*)configurationData.key_file.c_str(),(char*)configurationData.sec_password.c_str(),
885  configurationData.ca_list);
886  sSLHandler.load_dh_params(ctx,(char*)configurationData.dh_file.c_str());
887 
888  SSL_CTX_set_session_id_context(ctx,
889  (const unsigned char*)&SSLHandler::s_server_session_id_context,
890  sizeof SSLHandler::s_server_session_id_context);
891 
892  /* Set our cipher list */
893  if(ciphers){
894  SSL_CTX_set_cipher_list(ctx,ciphers);
895  }
896  /*if(configurationData.client_auth==2)
897  SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);
898  else if(configurationData.client_auth==1)
899  SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,0);*/
900  }
901  dlib = dlopen(Constants::INTER_LIB_FILE.c_str(), RTLD_NOW);
902  //logger << endl <<dlib << endl;
903  if(dlib==NULL)
904  {
905  logger << dlerror() << endl;
906  logger.info("Could not load Library");
907  exit(0);
908  }
909  else
910  logger.info("Library loaded successfully");
911  ddlib = dlopen(Constants::DINTER_LIB_FILE.c_str(), RTLD_NOW);
912  //logger << endl <<dlib << endl;
913  if(ddlib==NULL)
914  {
915  logger << dlerror() << endl;
916  logger.info("Could not load dynamic Library");
917  exit(0);
918  }
919  else
920  logger.info("Dynamic Library loaded successfully");
921  if(!isThreadprq)
922  {
923  pool = new ThreadPool(thrdpsiz,thrdpsiz+30,true);
924  pool->start();
925  }
926  }
927 
928  if(isCompileEnabled)
929  {
930  Thread pthread(&dynamic_page_monitor, &serverRootDirectory);
931  pthread.execute();
932  }
933 
934  SelEpolKqEvPrt selEpolKqEvPrtHandler;
935  selEpolKqEvPrtHandler.initialize(sockfd);
936  int childNo = 0;
937  /*if(fork()==0)
938  {
939  //start of hotdeployment process
940 
941  }*/
942 
943  serverCntrlFile.open(serverCntrlFileNm.c_str());
944  while(serverCntrlFile.is_open())
945  {
946  serverCntrlFile.close();
947 
948  if(childNo>=preForked)
949  childNo = 0;
950  nfds = selEpolKqEvPrtHandler.getEvents();
951  if (nfds == -1)
952  {
953  perror("poll_wait main process");
954  logger.info("Interruption Signal Received\n");
955  if(errno==EBADF)
956  logger << "\nInavlid fd" <<endl;
957  else if(errno==EFAULT)
958  logger << "\nThe memory area pointed to by events is not accessible" <<endl;
959  else if(errno==EINTR)
960  logger << "\ncall was interrupted by a signal handler before any of the requested events occurred" <<endl;
961  else if(errno==EINVAL)
962  logger << "not a poll file descriptor, or maxevents is less than or equal to zero" << endl;
963  else
964  logger << "\nnot an epoll file descriptor" <<endl;
965  }
966  processgendone = false;
967  if(processforcekilled)
968  {
969  if(Constants::IS_FILE_DESC_PASSING_AVAIL)
970  {
971  files.clear();
972  for(int j=0;j<preForked;j++)
973  {
974  pid_t pid = createChildProcess(serverRootDirectory,sp[j],sockfd);
975  pds[j] = pid;
976  stringstream ss;
977  string filename;
978  ss << serverRootDirectory;
979  ss << pds[j];
980  ss >> filename;
981  filename.append(".cntrl");
982  files.push_back(filename);
983  }
984  }
985  else
986  {
987  delete pool;
988  pool = new ThreadPool;
989  pool->init(thrdpsiz,thrdpsiz+30,true);
990  }
991  processforcekilled = false;
992  processgendone = true;
993  }
994  for(int n=0;n<nfds;n++)
995  {
996  if(childNo>=preForked)
997  childNo = 0;
998  int descriptor = selEpolKqEvPrtHandler.getDescriptor(n);
999  if (descriptor == sockfd)
1000  {
1001  new_fd = -1;
1002  sin_size = sizeof their_addr;
1003  new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
1004  if (new_fd == -1)
1005  {
1006  perror("accept");
1007  continue;
1008  }
1009  else
1010  {
1011  selEpolKqEvPrtHandler.reRegisterServerSock();
1012  selEpolKqEvPrtHandler.registerForEvent(new_fd);
1013  }
1014  }
1015  else if (descriptor != -1)
1016  {
1017  logger << ("got new connection " + CastUtil::lexical_cast<string>(descriptor)) << endl;
1018  selEpolKqEvPrtHandler.unRegisterForEvent(descriptor);
1019  if(Constants::IS_FILE_DESC_PASSING_AVAIL)
1020  {
1021  ifstream cntrlfile;
1022  cntrlfile.open(files.at(childNo).c_str());
1023  if(cntrlfile.is_open())
1024  {
1025  send_connection(sp[childNo][0], descriptor);
1026  string cno = CastUtil::lexical_cast<string>(childNo);
1027  childNo++;
1028  }
1029  else
1030  {
1031  int tcn = childNo;
1032  for(int o=0;o<preForked;o++)
1033  {
1034  ifstream cntrlfileT;
1035  cntrlfileT.open(files.at(o).c_str());
1036  if(cntrlfileT.is_open())
1037  {
1038  send_connection(sp[childNo][0], descriptor);
1039  string cno = CastUtil::lexical_cast<string>(o);
1040  childNo = o+1;
1041  cntrlfileT.close();
1042  break;
1043  }
1044  }
1045  close(sp[tcn][0]);
1046  close(sp[tcn][1]);
1047  logger << "Process got killed" << endl;
1048  pid_t pid = createChildProcess(serverRootDirectory,sp[tcn],sockfd);
1049  pds[tcn] = pid;
1050  stringstream ss;
1051  string filename;
1052  ss << serverRootDirectory;
1053  ss << pid;
1054  ss >> filename;
1055  filename.append(".cntrl");
1056  files[tcn] = filename;
1057  logger << "created a new Process" << endl;
1058  logger.info("Process got killed hence created a new Process\n");
1059  }
1060  cntrlfile.close();
1061  }
1062  else
1063  {
1064  fcntl(descriptor, F_SETFL,O_SYNC);
1065  if(isThreadprq)
1066  {
1067  ServiceTask *task = new ServiceTask(descriptor,serverRootDirectory,&params,
1068  isSSLEnabled, ctx, sSLHandler, configurationData, dlib, ddlib);
1069  Thread pthread(&service, task);
1070  pthread.execute();
1071  }
1072  else
1073  {
1074  ServiceTask *task = new ServiceTask(descriptor,serverRootDirectory,&params,
1075  isSSLEnabled, ctx, sSLHandler, configurationData, dlib, ddlib);
1076  task->setCleanUp(true);
1077  pool->execute(*task);
1078  }
1079  }
1080  }
1081  }
1082  serverCntrlFile.open(serverCntrlFileNm.c_str());
1083  }
1084  ComponentHandler::stop();
1085  MessageHandler::stop();
1086  MethodInvoc::stop();
1087 
1088  ConfigurationHandler::destroyCibernate();
1089  return 0;
1090 }
1091