TCP Socket - C Language
serverSSL.c
Vai alla documentazione di questo file.
00001 
00012 #include <stdio.h>
00013 #include <unistd.h>
00014 #include <signal.h>
00015 
00016 #include "pool.h"
00017 #include "commSSL.h"
00018 #include "errore.h"
00019 
00023 #define MAXSRVSLEEP 128
00024 
00026 volatile sig_atomic_t quitflag;
00027 
00029 void *client_comm(void * client_info);
00030 void gestore(int sig);
00031 
00033 int main(int argc,char* argv[]){
00034         int nsec;
00035         char * service = "12100"; 
00036         srvSkSSL * server = NULL; 
00037         cli_conn * client = NULL; 
00038         th_pool * pool;                   
00039         sigset_t poolset;                 
00040         sigset_t set;                     
00041         struct sigaction action;
00042         quitflag = 0;
00043 
00044         /* ========= Gestione dei segnali ========= */
00045         /* Blocco i segnali */
00046         if (sigfillset(&set) == -1){
00047         sys_err(__FILE__,__LINE__,"Server: error sigfillset");
00048         return EXIT_FAILURE;
00049         }
00050 
00051         if (pthread_sigmask(SIG_SETMASK, &set, NULL) != 0) {
00052                 sys_err(__FILE__,__LINE__,
00053                         "Server: pthread_sigmask error 'sigsetmask'");
00054                 return EXIT_FAILURE;
00055         }
00056 
00057         /* Installo il nuovo gestore */
00058         memset(&action, 0, sizeof(action));
00059         if (sigemptyset(&action.sa_mask) == -1){
00060         sys_err(__FILE__,__LINE__,"Server: error sigemptyset");
00061         return EXIT_FAILURE;
00062         }
00063 
00064         /* Ignoro il SIGPIPE */
00065         action.sa_handler = SIG_IGN;
00066         if (sigaction(SIGPIPE, &action, NULL) == -1) {
00067                 sys_err(__FILE__,__LINE__, "Server: sigaction error 'SIGPIPE'");
00068                 exit(EXIT_FAILURE);
00069         }
00070 
00071         action.sa_handler = gestore;
00072         action.sa_flags = 0;
00073 
00074         /* Definisco i segnali che voglio gestire */
00075         if (sigaction(SIGINT, &action, NULL) < 0){
00076                 sys_err(__FILE__,__LINE__,"Server: sigaction error 'SIGINT'");
00077                 return EXIT_FAILURE;
00078         }
00079 
00080         if (sigaction(SIGTERM, &action, NULL) < 0){
00081         sys_err(__FILE__,__LINE__,"Server: sigaction error 'SIGTERM'");
00082         return EXIT_FAILURE;;
00083         }
00084 
00085         /* Installo la nuova maschera dei segnali */
00086         if (pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL) != 0) {
00087                 sys_err(__FILE__,__LINE__,
00088                         "Server: pthread_sigmask error 'sigsetmask'");
00089                 return EXIT_FAILURE;
00090         }
00091 
00092         /* Questa maschera per il pool che ignora tutti i segnali */
00093         if (sigfillset(&poolset) == -1){
00094                 sys_err(__FILE__,__LINE__,"Server: error sigfillset");
00095                 exit(errno);
00096         }
00097 
00098         /* Creo una socket di comunicazione */
00099         if ((server = newSSLServerChannel(service)) == NULL){
00100                 sys_err(__FILE__,__LINE__,"Server: createServerChannel");
00101                 exit(errno);
00102         }
00103 
00104         /* Inizializzo un pool di thread di dimensione 5 e con
00105          * un numero massimo di job in attesa nella coda di 10 */
00106         pool = poolInit(5, 10, &poolset);
00107 
00108         while (!quitflag){
00109                 /* Pongo il server in attesa di nuove connessioni */
00110                 if ((client = acceptSSLConnection(server)) != NULL){
00111                         /* Sottomissione job al pool con riprova (lenta) */
00112                         for (nsec = 1; nsec<=MAXSRVSLEEP && poolDispatcher(pool, client_comm, client)==-5; nsec<<=1)
00113                                 if (nsec<=MAXSRVSLEEP/2) sleep(nsec);
00114                 }
00115                 /* TODO Manca la gestione degli errori */
00116         }
00117         /* Arresto il pool di threads e libero le risorse */
00118         poolDestroy(pool);
00119         /* Chiudo la socket di comunicazione */
00120         closeSSLServerSocket(server);
00121         unloadSSL();
00122         return 0;
00123 }
00124 
00125 void *client_comm(void * client_info){
00126         cli_conn * client = NULL;
00127         message_t msg;
00128         int recive_val = 1, sent_val = 1, quit = 0;
00129 
00130         client = (cli_conn *) client_info;
00131         msg.buffer = NULL;
00132 
00133         while ((recive_val>0) && (sent_val>0) && (quit!=1)){
00134                 /* Ricevo un messaggio */
00135                 if ((recive_val = receiveSSLMessage(client, &msg)) > 0){
00136                         /* Controllo il tipo di messaggio ricevuto */
00137                         switch(msg.type){
00138                                 case MSG_EXIT:
00139                                         quit = 1;
00140                                         msg.type = MSG_OK;
00141                                         msg.length = 0;
00142                                         if (msg.buffer){
00143                                                 free(msg.buffer);
00144                                                 msg.buffer=NULL;
00145                                         }
00146                                 break;
00147                                 case MSG_PRINT:
00148                                         msg.type = MSG_OK;
00149                                         msg.length = 0;
00150                                         if (msg.buffer){
00151                                                 printf ("Mgs: %s\n",msg.buffer);
00152                                                 free(msg.buffer);
00153                                                 msg.buffer = NULL;
00154                                         }
00155                                 break;
00156                         }
00157                         /* Invio il messaggio di risposta */
00158                         sent_val = sendSSLMessage(client, &msg);
00159                 }
00160         }
00161 
00162         printf("Server: Chiusura comunicazione con client\n");
00163         /* Chiudo la socket di comunicazione */
00164         closeSSLConnection(client);
00165         return 0;
00166 }
00167 
00175 void gestore(int sig) {
00176         switch (sig) {
00177                 case SIGTERM:
00178                         write(2, "server: signal 15 detected\n", 27);
00179                         quitflag = 1;
00180                 break;
00181                 case SIGINT:
00182                         write(2, "server: signal 2 detected\n", 26);
00183                         quitflag = 1;
00184                 break;
00185         }
00186 }