197 lines
6.4 KiB
C
197 lines
6.4 KiB
C
#include "central-manager.h"
|
|
|
|
|
|
|
|
|
|
/*
|
|
*
|
|
* @history
|
|
* [0] Initialisation des variables
|
|
* [1] On démarre le SERVEUR d'écoute globale
|
|
* [2] Attente d'une demande de connection, puis création d'un THREAD
|
|
* [3] On attends la fin de tous les THREADS
|
|
* [4] On ferme la SOCKET d'écoute globale
|
|
*
|
|
*/
|
|
int main(int argc, char* argv[]){
|
|
/* [0] Initialisation des variables
|
|
==========================================================*/
|
|
int THREADABLE_SOCKET = -1; // contiendra le BUS DE COMMANDE utilisateur à envoyer à un THREAD
|
|
struct sockaddr_storage clientInfo; // contiendra les infos client
|
|
char repeat; // sert à sortir de la boucle
|
|
socklen_t len = sizeof(struct sockaddr_storage);
|
|
|
|
// retour de @DROP_SERVER
|
|
char* serverPort; // contiendra le port
|
|
int LISTENSOCK; // contiendra la socket d'écoute
|
|
|
|
|
|
/* [1] On démarre le SERVEUR d'écoute globale
|
|
==========================================================*/
|
|
serverPort = malloc(maxPortLen);
|
|
|
|
// attribution du port si dans les arguments
|
|
if( argc > 1 ) strcpy(serverPort, argv[1]);
|
|
|
|
DROP_SERVER(remoteHost, &serverPort, &LISTENSOCK);
|
|
printf("Port: %s\n", serverPort);
|
|
|
|
|
|
|
|
/* [2] Attente d'une demande de connection, puis création d'un THREAD
|
|
============================================================================*/
|
|
int index = -1;
|
|
while( 1 ){
|
|
/* 1. On initialise la SOCKET en attendant la connexion et le rang du "manager" inactif */
|
|
THREADABLE_SOCKET = -1;
|
|
index = -1;
|
|
|
|
/* 2. On attends une connection */
|
|
THREADABLE_SOCKET = accept(LISTENSOCK, (struct sockaddr *) &clientInfo, &len);
|
|
|
|
/* 3. On cherche un "manager" libre */
|
|
int i;
|
|
|
|
// si on trouve un "manager" inactif, on l'enregistre dans index
|
|
for( i = 0 ; i < maxListLen ; i++ )
|
|
if( activeManagers[i] == 0 ){ index = i; break; }
|
|
|
|
// si on a trouvé un "manager" libre
|
|
if( index != -1 ){
|
|
|
|
/* 4. On lance un thread pour le traitement de ce client */
|
|
pthread_create(&managers[index], NULL, manageConnection, (void*)(intptr_t) THREADABLE_SOCKET);
|
|
if( DEBUGMOD&THR ) printf("THREAD[%d] démarré\n", index);
|
|
|
|
/* 5. On signale que ce "manager" est maintenant actif */
|
|
activeManagers[index] = 1;
|
|
}else
|
|
if( DEBUGMOD&THR ) printf("Demande de thread refusée!\n");
|
|
}
|
|
|
|
|
|
/* [3] On attends la fin de tous les THREADS
|
|
==========================================================*/
|
|
int i;
|
|
for( i = 0 ; i < maxListLen ; i++ )
|
|
pthread_join(managers[i], NULL);
|
|
|
|
/* [4] On ferme la SOCKET d'écoute globale
|
|
==========================================================*/
|
|
printf("FERMETURE DE TOUTES LES CONNECTIONS!\n");
|
|
close(LISTENSOCK);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Gestion d'une connexion client
|
|
*
|
|
* @THREADABLE_SOCKET<void*> SOCKET de la connexion client
|
|
*
|
|
* @history
|
|
* [1] Initialisation des variables
|
|
* [2] Envoi de la séquence de bienvenue
|
|
* [3] Attente des données reçues et reception (CLIENT_FTP->PROXY)
|
|
* [4] Traitement de la requête client
|
|
* [5] Redirection de la requête vers le serveur FTP (PROXY->SERVER_FTP)
|
|
* [6] Traitement de la reponse du serveur FTP
|
|
* [7] Redirection de la réponse vers le client (PROXY->CLIENT_FTP)
|
|
* [8] On vide les buffers
|
|
* [9] Fermeture des connections (SOCKETS)
|
|
* [10] Arrêt du THREAD
|
|
* 1. On récupère le rang dans les "managers"
|
|
* 2. On met à jour "activeManagers"
|
|
* 3. On arrête le THREAD
|
|
*
|
|
*/
|
|
void* manageConnection(void* THREADABLE_SOCKET){
|
|
int USER_SOCKET = (intptr_t) THREADABLE_SOCKET; // BUS DE COMMANDE utilisateur
|
|
|
|
/* [1] Variables
|
|
============================================================================*/
|
|
// int USER_SOCKET = -1;
|
|
int FTP_SOCKET = -1; // contiendra le BUS DE COMMANDE FTP
|
|
int DUSER_SOCKET = -1; // contiendra le BUS DE DONNES utilisateur
|
|
int DFTP_SOCKET = -1; // contiendra le BUS DE DONNEES FTP
|
|
|
|
char* BUFFER; // contiendra le BUFFER
|
|
char* ftp_response; // contiendra le BUFFER de réponse du serveur FTP (commandes)
|
|
int nbReceived, nbSend; // contiendra les nb reçu && envoyé
|
|
BUFFER = malloc( maxBuffLen );
|
|
int error;
|
|
|
|
/* [2] Envoi de la séquence de bienvenue
|
|
============================================================================*/
|
|
swrite(&USER_SOCKET, WLCM_MSG);
|
|
|
|
/* BOUCLE DE COMMANDES */
|
|
while( USER_SOCKET != -1 ){
|
|
|
|
/* [3] On récupère les données reçues (+attente)
|
|
============================================================================*/
|
|
if( WAIT_SOCKET_UPDATE(&USER_SOCKET, BUFFER) == -1 ) break;
|
|
if( DEBUGMOD&CMD ) xPrint("C->P: %s\n", BUFFER);
|
|
|
|
|
|
/* [4] Traitement de la requête
|
|
============================================================================*/
|
|
error = MANAGE_REQUEST(BUFFER, &USER_SOCKET, &FTP_SOCKET, &DUSER_SOCKET, &DFTP_SOCKET);
|
|
|
|
// si on a pas la connection FTP (commande) initialisée, on quitte
|
|
if( error == -1 ) break;
|
|
|
|
|
|
/* [5] Redirection vers le serveur FTP
|
|
============================================================================*/
|
|
if( DEBUGMOD&CMD ) xPrint("P->F: %s\n\n", BUFFER);
|
|
CLIENT_SEND(&FTP_SOCKET, BUFFER, &BUFFER);
|
|
if( DEBUGMOD&CMD ) xPrint("F->P: %s\n", BUFFER);
|
|
|
|
/* [6] Traitement de la réponse (FTP)
|
|
============================================================================*/
|
|
MANAGE_RESPONSE(BUFFER, &USER_SOCKET, &FTP_SOCKET, &DUSER_SOCKET, &DFTP_SOCKET);
|
|
|
|
|
|
|
|
/* [7] Redirection vers le CLIENT
|
|
============================================================================*/
|
|
if( swrite(&USER_SOCKET, BUFFER) == -1 ) break;
|
|
if( DEBUGMOD&CMD ) xPrint("P->C: %s\n", BUFFER);
|
|
|
|
|
|
/* [8] On vide les buffers
|
|
============================================================================*/
|
|
memset(BUFFER, '\0', maxBuffLen); // on vide le buffer
|
|
memset(BUFFER, '\0', maxBuffLen);
|
|
}
|
|
|
|
/* [9] Fermeture des connections (SOCKETS)
|
|
============================================================================*/
|
|
printf("CLOSING CONNECTIONS\n");
|
|
close(USER_SOCKET);
|
|
close(FTP_SOCKET);
|
|
|
|
/* [10] Arrêt du THREAD
|
|
============================================================================*/
|
|
/* 1. On récupère le rang dans les "managers" */
|
|
int i, index = -1;
|
|
for( i = 0 ; i < maxListLen ; i++ )
|
|
if( managers[i] == pthread_self() ){ index = i; break; }
|
|
|
|
/* 2. On met à jour "activeManagers" */
|
|
if( index != -1 )
|
|
activeManagers[index] = 0;
|
|
|
|
/* 3. On arrête le THREAD */
|
|
if( DEBUGMOD&THR ) printf("THREAD[%d] libéré\n", index);
|
|
pthread_exit(NULL);
|
|
}
|