#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "const.h" #include "parsage.h" #include "tools.h" #ifdef ENABLE_MODULE #include "modules/modules.h" #endif void *client (void *arg); int prochain_client = 0; unsigned long time_s; int main (int argc, char *argv[]) { struct sockaddr_in csin; struct sockaddr_in6 csin6; int i; // pthread_attr_t t_attr; #ifdef ENABLE_MODULE int a, b; #endif char *liste_options = "p:m:dh6"; //liste des options int option; unsigned short try; int port = DEFAULT_PORT; short ipv6_enable = 0; while ((option = getopt (argc, argv, liste_options)) != -1) { switch (option) { case 'p': port = atoi (optarg); break; #ifdef ENABLE_MODULE case 'm': a = 0; b = 0; for (i = 0; i < MAX_MODULES && a != -1; i++) { /*s_all_module.s_module[i] = malloc (sizeof (struct struct_module)); if(s_all_module.s_module[i] == NULL) { printf("Erreur d'allocation memoire !\n"); SignalQuit(1); } */ memset (s_all_module.s_module[i].name, 0, MAX_BUFFER); for (a = 0; a < MAX_BUFFER; a++) { if (optarg[b] == ',') { #ifdef DEBUG // printf ("\tmod : %s...\n",s_module[i]->name); #endif b++; break; } else if (optarg[b] == '\0') { #ifdef DEBUG // printf ("\tmod : %s...\n",s_module[i]->name); #endif a = -1; break; } s_all_module.s_module[i].name[a] = optarg[b]; b++; } s_all_module.s_module[i].num = i; } b = i; // pour savoir le nombre de modules chargés break; #else case 'm': printf ("Desole, le programme n'a pas ete compile avec le support des modules !\n"); break; #endif case 'd': break; case 'h': printf ("Aide ...\n"); printf ("\t-h : affiche l'aide\n"); printf ("\t-p : specifie le port d'ecoute\n"); printf ("\t-m ,,..., : specifie les modules a charger\n"); exit (0); break; case '6': ipv6_enable = 1; break; case '?': return 1; } } signal (SIGTERM, SignalQuit); signal (SIGINT, SignalQuit); /* chargement des modules */ #ifdef ENABLE_MODULE if (LoadAllModule (&s_all_module, b) != 0) { printf ("\nErreur lors du chargement du module\n"); SignalQuit (1); } #endif /* lancement du serveur */ if(ipv6_enable == 1) { serveur_sock = socket (AF_INET6, SOCK_STREAM, 0); csin6.sin6_addr = in6addr_any; csin6.sin6_family = AF_INET6; csin6.sin6_port = htons (port); if (bind (serveur_sock, (struct sockaddr *) &csin6, sizeof (csin6)) == -1) { perror ("bind6"); SignalQuit (1); } } else { serveur_sock = socket (AF_INET, SOCK_STREAM, 0); csin.sin_addr.s_addr = INADDR_ANY; csin.sin_family = AF_INET; csin.sin_port = htons (port); if (bind (serveur_sock, (struct sockaddr *) &csin, sizeof (csin)) == -1) { perror ("bind"); SignalQuit (1); } perror ("bind"); } listen (serveur_sock, MAX_CLIENT); printf ("Port : %d\n", port); // pthread_attr_init (&t_attr); // pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED); //thread detaché par defaut i = 0; try = 0; while (1) { if (prochain_client == (MAX_CLIENT + 1)) { printf ("Nombre de clients maximal atteint, recherche des places libres...\n"); for (i = 0; i <= MAX_CLIENT; i++) { if (s_client[i] == NULL) { printf ("La place %d est libre\n", i); prochain_client = i; break; } } if (i >= MAX_CLIENT) { printf ("Plus de places...\n"); sleep (WAITING_BEFORE_REQUEST_PLACE); // a modifier try ++; if(try >= MAX_TRY_RECONNECT) { sleep(WAITING_IF_NO_PLACE); try = 0; } } } else { s_client[prochain_client] = malloc (sizeof (struct struct_client)); //allocation if (s_client[prochain_client] == NULL) { printf ("Erreur d'allocation memoire !\n"); SignalQuit (1); } s_client[prochain_client]->sinsize = sizeof (s_client[prochain_client]->client_csin); if ((s_client[prochain_client]->sock = accept (serveur_sock, (struct sockaddr *) &s_client[prochain_client]-> client_csin, &s_client[prochain_client]->sinsize)) == -1) { printf ("Erreur lors de la creation de la socket\n"); free (s_client[prochain_client]); s_client[prochain_client] = NULL; } else { printf ("Client connecte %d!\n", prochain_client); if(s_client[prochain_client] != NULL) { s_client[prochain_client]->numero = prochain_client; pthread_create (&s_client[prochain_client]->t_client, NULL, client, (void *) prochain_client); prochain_client++; } } } } } void * client (void *arg) { int num = (int) arg; char reception[MAX_BUFFER_LARGE]; signal (SIGPIPE, BrokenPipe); pthread_detach(s_client[num]->t_client); printf ("Thread client numero : %d\n", num); s_client[num]->error = 0; s_client[num]->first = 0; s_client[num]->host_old[0] = '\0'; /* calcul de la taille de l'url du proxy (necessaire pour parser l'host) */ s_client[num]->PROXY_URL_SIZE = (strlen (PROXY_URL) + strlen (itoa (DEFAULT_PORT, 10)) + 1); while (s_client[num]->error == 0) { memset (reception, 0, MAX_BUFFER_LARGE); fcntl (s_client[num]->csock, !O_NONBLOCK); fcntl (s_client[num]->sock, !O_NONBLOCK); recv(s_client[num]->sock, &reception, MAX_BUFFER_LARGE, 0); fcntl (s_client[num]->csock, O_NONBLOCK); fcntl (s_client[num]->sock, O_NONBLOCK); /* parsage des données */ if (ParseGet (reception, s_client[num]->get, &s_client[num]->protocole) == 0) break; if (ParseHost (reception, s_client[num]->host, &s_client[num]->PROXY_URL_SIZE) == 0) break; if (ParseUserAgent (reception, s_client[num]->user_agent) == 0) break; if (ParseConnection (reception, s_client[num]->keep_alive) == 0) { memset (s_client[num]->keep_alive, 0, strlen (s_client[num]->keep_alive)); strcpy (s_client[num]->keep_alive, "Close"); } if (ParseKeepAlive (reception, &s_client[num]->timeout) == 0) { s_client[num]->timeout = DEFAULT_TIMEOUT; } if ((s_client[num]->first == 0) || (strcmp (s_client[num]->host, s_client[num]->host_old) != 0)) { if (Connexion (&s_client[num]->csock, 80, s_client[num]) == 0) { EnvoiClientErreur (s_client[num]); break; } } if (EnvoiRequeteServeur (s_client[num]) == 0 || s_client[num]->error == 1) break; if (RecvSendRequeteServeurHeader (s_client[num]) == 0 || s_client[num]->error == 1) break; if (RecvSendRequeteServeur (s_client[num]) == 0 || s_client[num]->error == 1) break; if (strcmp (s_client[num]->keep_alive, "Close") == 0) break; else { s_client[num]->first = 1; //pour ne pas refaire la connexion au serveur memset (s_client[num]->host_old, 0, MAX_BUFFER); strcpy (s_client[num]->host_old, s_client[num]->host); } // s_client[num]->error = 1; } close (s_client[num]->csock); close (s_client[num]->sock); free (s_client[num]); s_client[num] = NULL; printf ("Fin du thread %d\n", num); pthread_exit (0); }