[in progress] udp redirection management
This commit is contained in:
parent
470eaf2610
commit
6c5aabae30
|
@ -12,12 +12,10 @@ lib/network/tcp/server.o: lib/header.h lib/network/tcp/server.h lib/network/tcp/
|
||||||
lib/network/udp/server.o: lib/header.h lib/network/udp/server.h lib/network/udp/server.c
|
lib/network/udp/server.o: lib/header.h lib/network/udp/server.h lib/network/udp/server.c
|
||||||
gcc $(CFLAGS) -c -o lib/network/udp/server.o lib/network/udp/server.c
|
gcc $(CFLAGS) -c -o lib/network/udp/server.o lib/network/udp/server.c
|
||||||
|
|
||||||
lib/network/format/serializer.o: lib/network/format/serializer.h lib/network/format/serializer.c
|
|
||||||
gcc $(CFLAGS) -c -o lib/network/format/serializer.o lib/network/format/serializer.c
|
|
||||||
|
|
||||||
# Compiles the SGCA
|
# Compiles the SGCA
|
||||||
boot: lib/network/tcp/server.o lib/network/udp/server.o lib/network/format/serializer.o central-manager.h central-manager.c
|
boot: lib/network/tcp/server.o lib/network/udp/server.o central-manager.h central-manager.c
|
||||||
gcc $(CFLAGS) -o boot lib/network/udp/server.o lib/network/tcp/server.o lib/network/format/serializer.o central-manager.c
|
gcc $(CFLAGS) -o boot lib/network/udp/server.o lib/network/tcp/server.o central-manager.c
|
||||||
|
|
||||||
|
|
||||||
# Run full compilation
|
# Run full compilation
|
||||||
|
|
|
@ -145,19 +145,22 @@ void* LISTEN_TCP(){
|
||||||
* [1] On démarre le SERVEUR UDP d'écoute globale
|
* [1] On démarre le SERVEUR UDP d'écoute globale
|
||||||
* [2] On attends un client
|
* [2] On attends un client
|
||||||
* [3] On gère la requête
|
* [3] On gère la requête
|
||||||
* [4] On envoie la réponse
|
* [4] On ouvre une socket client sur un nouveau port (si ok)
|
||||||
* [n] On ferme la SOCKET d'écoute UDP globale
|
* [5] On envoie la réponse
|
||||||
|
* [6] On démarre un thread de gestion avec timeout (en attente du client redirigé)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void* LISTEN_UDP(){
|
void* LISTEN_UDP(){
|
||||||
/* [0] Initialisation des variables
|
/* [0] Initialisation des variables
|
||||||
==========================================================*/
|
==========================================================*/
|
||||||
struct sockaddr_in clientInfo; // contiendra les infos client
|
int CLIENT_SOCKET; // contiendra la socket UDP à envoyer sur un THREAD
|
||||||
char client_ip[20]; // IP du client
|
struct sockaddr_in clientInfo; // contiendra les infos client
|
||||||
socklen_t len; // taille de la socket
|
char client_ip[20]; // IP du client
|
||||||
int read; // compteurs
|
socklen_t len; // taille de la socket
|
||||||
char request[MAX_BUF_LEN] = {0}; // buffer requête
|
int read; // compteurs
|
||||||
// char response[MAX_BUF_LEN] = {0}; // buffer réponse
|
char buffer[MAX_BUF_LEN]; // buffer requête
|
||||||
|
struct bind_header request; // requête parsée
|
||||||
|
int i, index; // compteurs
|
||||||
|
|
||||||
// retour de @DROP_UDP_SERVER
|
// retour de @DROP_UDP_SERVER
|
||||||
int SOCKET;
|
int SOCKET;
|
||||||
|
@ -183,16 +186,16 @@ void* LISTEN_UDP(){
|
||||||
============================================================================*/
|
============================================================================*/
|
||||||
while( 1 ){
|
while( 1 ){
|
||||||
|
|
||||||
/* 0. On vide les données */
|
/* 0. On initialise les SOCKET en attendant la connexion et le rang du "manager" inactif */
|
||||||
bzero(request, MAX_BUF_LEN);
|
CLIENT_SOCKET = -1;
|
||||||
bzero(&clientInfo, sizeof(struct sockaddr_in));
|
index = -1;
|
||||||
|
|
||||||
/* 1. On attends une connection UDP */
|
/* 1. On attends une connection UDP */
|
||||||
read = recvfrom(SOCKET, request, MAX_BUF_LEN, 0, (struct sockaddr*) &clientInfo, &len);
|
read = recvfrom(SOCKET, buffer, MAX_BUF_LEN, 0, (struct sockaddr*) &clientInfo, &len);
|
||||||
|
|
||||||
/* 2. Si erreur reception */
|
/* 2. Si erreur reception ou taille incorrecte */
|
||||||
if( read < 0 ){
|
if( read != sizeof(struct bind_header) ){
|
||||||
if( DEBUGMOD&BUF ) printf("\t\t[UDP] READ = %d\n", read);
|
if( DEBUGMOD&BUF ) printf("\t\t[UDP] READ('%s') = %d bytes (expected: %d)\n", buffer, read, (int) sizeof(struct bind_header));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,9 +204,31 @@ void* LISTEN_UDP(){
|
||||||
|
|
||||||
if( DEBUGMOD&SCK ) printf("\t[UDP] %s connecté\n", client_ip);
|
if( DEBUGMOD&SCK ) printf("\t[UDP] %s connecté\n", client_ip);
|
||||||
|
|
||||||
|
/* 3. On parse la requête*/
|
||||||
|
memcpy(&request, buffer, sizeof(struct bind_header));
|
||||||
|
|
||||||
/* 3. Gestion requête */
|
printf("\t\t\t[UDP] parsed:\n\t\t\t\tflag = %d\n\t\t\t\tport = %d\n", (int) request.flags, request.port);
|
||||||
printf("\t\tRequest(%d bytes) : '%s'\n", read, request);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 4. On cherche un "manager" libre (inactif) */
|
||||||
|
for( i = 0 ; i < MAX_UDP_THR ; i++ )
|
||||||
|
if( activeUDPManagers[i] == 0 ){ index = i; break; }
|
||||||
|
|
||||||
|
// si on a trouvé un "manager" libre
|
||||||
|
if( index != -1 ){
|
||||||
|
|
||||||
|
/* 5. On lance un thread pour le traitement de ce client */
|
||||||
|
pthread_create(&UDPManagers[index], NULL, manageTerminal, (void*)(intptr_t) CLIENT_SOCKET);
|
||||||
|
|
||||||
|
if( DEBUGMOD&THR ) printf("\tTHREAD[UDP][%d] démarré\n", index);
|
||||||
|
|
||||||
|
/* 6. On signale que ce "manager" est maintenant actif */
|
||||||
|
activeUDPManagers[index] = 1;
|
||||||
|
|
||||||
|
}else
|
||||||
|
if( DEBUGMOD&THR ) printf("\tAucun thread UDP libre!\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,3 +316,78 @@ void* managePlane(void* THREADABLE_SOCKET){
|
||||||
if( DEBUGMOD&THR ) printf("\t\tTHREAD[TCP][%d] libéré\n", index);
|
if( DEBUGMOD&THR ) printf("\t\tTHREAD[TCP][%d] libéré\n", index);
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Gestion d'une connexion TERMINAL
|
||||||
|
*
|
||||||
|
* @THREADABLE_SOCKET<void*> SOCKET de la connexion client
|
||||||
|
*
|
||||||
|
* @history
|
||||||
|
* [1] Initialisation des variables
|
||||||
|
* [2] Récupération de la requête
|
||||||
|
* [3] Traitement de la requête
|
||||||
|
* [4] Création de la réponse
|
||||||
|
* [5] Envoi de la réponse
|
||||||
|
* [6] On vide les buffers
|
||||||
|
* [7] Fermeture de la connection (SOCKET)
|
||||||
|
* [n] 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* manageTerminal(void* THREADABLE_SOCKET){
|
||||||
|
|
||||||
|
/* [1] Initialisation des variables
|
||||||
|
=========================================================*/
|
||||||
|
int read; // compteur
|
||||||
|
struct sockaddr_in clientInfo;
|
||||||
|
socklen_t len;
|
||||||
|
int TCP_SOCKET = (intptr_t) THREADABLE_SOCKET; // Socket client
|
||||||
|
char request[MAX_BUF_LEN]; // Requête
|
||||||
|
// char response[MAX_BUF_LEN]; // Réponse
|
||||||
|
|
||||||
|
do{
|
||||||
|
|
||||||
|
/* [2] Récupération de la requête
|
||||||
|
=========================================================*/
|
||||||
|
/* 1. On lit sur la socket */
|
||||||
|
read = recvfrom(TCP_SOCKET, request, MAX_BUF_LEN, 0, (struct sockaddr*) &clientInfo, &len);
|
||||||
|
|
||||||
|
/* 2. Si erreur reception */
|
||||||
|
if( read < 0 ){
|
||||||
|
if( DEBUGMOD&BUF ) printf("\t\t[TCP] READ = %d\n", read);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3. On désérialise la requête*/
|
||||||
|
|
||||||
|
|
||||||
|
printf("\t\tPLANE Request(%d bytes) : '%s'\n", read, request);
|
||||||
|
|
||||||
|
/* [3] Gestion de la requête
|
||||||
|
=========================================================*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}while( 0 );
|
||||||
|
|
||||||
|
/* [n] Arrêt du THREAD
|
||||||
|
============================================================================*/
|
||||||
|
/* 1. On récupère le rang dans les "managers" */
|
||||||
|
int i, index = -1;
|
||||||
|
for( i = 0 ; i < MAX_TCP_THR ; i++ )
|
||||||
|
if( TCPManagers[i] == pthread_self() ){ index = i; break; }
|
||||||
|
|
||||||
|
/* 2. On met à jour "activeManagers" */
|
||||||
|
if( index != -1 )
|
||||||
|
activeTCPManagers[index] = 0;
|
||||||
|
|
||||||
|
/* 3. On arrête le THREAD */
|
||||||
|
if( DEBUGMOD&THR ) printf("\t\tTHREAD[TCP][%d] libéré\n", index);
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
/* local dependencies */
|
/* local dependencies */
|
||||||
#include "lib/network/tcp/server.h"
|
#include "lib/network/tcp/server.h"
|
||||||
#include "lib/network/udp/server.h"
|
#include "lib/network/udp/server.h"
|
||||||
#include "lib/network/format/serializer.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* headers */
|
/* headers */
|
||||||
void* LISTEN_TCP();
|
void* LISTEN_TCP();
|
||||||
void* LISTEN_UDP();
|
void* LISTEN_UDP();
|
||||||
void* managePlane(void* THREADABLE_SOCKET);
|
void* managePlane(void* THREADABLE_SOCKET);
|
||||||
|
void* manageTerminal(void* THREADABLE_SOCKET);
|
||||||
// void* manageViewTerm(void* THREADABLE_SOCKET);
|
// void* manageViewTerm(void* THREADABLE_SOCKET);
|
||||||
// void* manageCtrlTerm(void* THREADABLE_SOCKET);
|
// void* manageCtrlTerm(void* THREADABLE_SOCKET);
|
||||||
|
|
||||||
|
@ -21,3 +21,7 @@ static pthread_t listenManagers[2]; // contiendra les THREADS d'éco
|
||||||
// VARIABLES THREADS CONNECTION TCP
|
// VARIABLES THREADS CONNECTION TCP
|
||||||
static pthread_t TCPManagers[MAX_TCP_THR]; // contiendra les THREADS TCP
|
static pthread_t TCPManagers[MAX_TCP_THR]; // contiendra les THREADS TCP
|
||||||
static int activeTCPManagers[MAX_TCP_THR] = {0}; // contiendra les THREADS TCP actifs
|
static int activeTCPManagers[MAX_TCP_THR] = {0}; // contiendra les THREADS TCP actifs
|
||||||
|
|
||||||
|
// VARIABLES THREADS CONNECTION UDP
|
||||||
|
static pthread_t UDPManagers[MAX_UDP_THR]; // contiendra les THREADS UDP
|
||||||
|
static int activeUDPManagers[MAX_UDP_THR] = {0}; // contiendra les THREADS UDP actifs
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef _DATA_H_
|
||||||
|
#define _DATA_H_
|
||||||
|
|
||||||
|
#define TERMREQ_FBK 0x01
|
||||||
|
#define TERMREQ_CAP 0x02
|
||||||
|
#define TERMREQ_SPD 0x04
|
||||||
|
#define TERMREQ_ALT 0x08
|
||||||
|
|
||||||
|
struct plane{
|
||||||
|
char code[6];
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int z;
|
||||||
|
int cap;
|
||||||
|
int speed;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct term_req{
|
||||||
|
char flags;
|
||||||
|
struct plane udpate;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define BINDHEAD_CTL 0x01
|
||||||
|
#define BINDHEAD_PRT 0x02
|
||||||
|
|
||||||
|
struct bind_header{
|
||||||
|
char flags;
|
||||||
|
unsigned short port;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -12,4 +12,4 @@
|
||||||
#define THR 0x10 // FILTRE pour THREADS
|
#define THR 0x10 // FILTRE pour THREADS
|
||||||
|
|
||||||
// possibilité de cumuler les DEBUGMODES
|
// possibilité de cumuler les DEBUGMODES
|
||||||
#define DEBUGMOD ( SOCKETS | THREADS ) // REVEALS + HEADER + THREADS
|
#define DEBUGMOD ( SOCKETS | THREADS | BUFFERS ) // REVEALS + HEADER + THREADS
|
|
@ -21,6 +21,7 @@
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "data.h"
|
||||||
|
|
||||||
/* vars */
|
/* vars */
|
||||||
#define SRV_HOST "localhost"
|
#define SRV_HOST "localhost"
|
||||||
|
@ -33,5 +34,4 @@
|
||||||
#define maxHostLen 64
|
#define maxHostLen 64
|
||||||
#define maxPortLen 6
|
#define maxPortLen 6
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -1,64 +0,0 @@
|
||||||
#include "serializer.h"
|
|
||||||
|
|
||||||
|
|
||||||
int parse_plane_request(const char* pIn, struct plane_request* pOut){
|
|
||||||
|
|
||||||
/* 1. Check buffer length */
|
|
||||||
if( strlen(pIn)*sizeof(char) != sizeof(struct plane_request) )
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* 2. Parse buffer */
|
|
||||||
memcpy(pOut, pIn, (size_t) sizeof(struct plane_request));
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int parse_viewterm_request(const char* pIn, struct vterm_request* pOut){
|
|
||||||
|
|
||||||
/* 1. Check buffer length */
|
|
||||||
if( strlen(pIn)*sizeof(char) != sizeof(struct vterm_request) )
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* 2. Parse buffer */
|
|
||||||
memcpy(pOut, pIn, sizeof(struct vterm_request));
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int parse_ctrlterm_request(const char* pIn, struct cterm_request* pOut){
|
|
||||||
|
|
||||||
/* 1. Check buffer length */
|
|
||||||
if( strlen(pIn)*sizeof(char) != sizeof(struct cterm_request) )
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* 2. Parse buffer */
|
|
||||||
memcpy(pOut, pIn, sizeof(struct cterm_request));
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int serialize_term_response(const struct term_response* pIn, char* pOut, const size_t pSize){
|
|
||||||
|
|
||||||
/* 1. Check buffer length */
|
|
||||||
if( sizeof(struct term_response) > pSize*sizeof(char) )
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* 2. Serialize response into buffer */
|
|
||||||
memcpy(pOut, pIn, sizeof(struct term_response));
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
#ifndef _LIB_NETWORK_FORMAT_SERIALIZER_H_
|
|
||||||
#define _LIB_NETWORK_FORMAT_SERIALIZER_H_
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "../../plane/plane.h"
|
|
||||||
|
|
||||||
struct plane_request{ // Plane Request
|
|
||||||
struct coord co;
|
|
||||||
struct control ct;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vterm_request{ // ViewTerminal Request
|
|
||||||
char flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct term_response{ // Terminal-s Response
|
|
||||||
char flags;
|
|
||||||
struct coord co;
|
|
||||||
struct control ct;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct cterm_request{ // ControlTerminal Request
|
|
||||||
char flags;
|
|
||||||
int z;
|
|
||||||
struct control ct;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Parse a plane request ('char*' to 'struct plane_request')
|
|
||||||
*
|
|
||||||
* @history
|
|
||||||
* [1] Check if buffer have correct size (according to destination struct)
|
|
||||||
* [2] Parse buffer to struct
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int parse_plane_request(const char* pIn, struct plane_request* pOut);
|
|
||||||
|
|
||||||
/* Parse a viewTerminal request ('char*' to 'struct vt_request')
|
|
||||||
*
|
|
||||||
* @history
|
|
||||||
* [1] Check if buffer have correct size (according to destination struct)
|
|
||||||
* [2] Parse buffer to struct
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int parse_viewterm_request(const char* pIn, struct vterm_request* pOut);
|
|
||||||
|
|
||||||
/* Parse a ctrlTerminal request ('char*' to 'struct ct_request')
|
|
||||||
*
|
|
||||||
* @history
|
|
||||||
* [1] Check if buffer have correct size (according to destination struct)
|
|
||||||
* [2] Parse buffer to struct
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int parse_ctrlterm_request(const char* pIn, struct cterm_request* pOut);
|
|
||||||
|
|
||||||
/* Serialize a Terminal response ('struct t_response' to 'char*')
|
|
||||||
*
|
|
||||||
* @history
|
|
||||||
* [1] Check if buffer have correct size (according to input struct)
|
|
||||||
* [2] Serialize struct into buffer
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int serialize_term_response(const struct term_response* pIn, char* pOut, const size_t pSize);
|
|
||||||
>>>>>>> d647392d99c86e94aa550f6cf0e7f284c4b226a3
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,307 +0,0 @@
|
||||||
#include "server.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int MANAGE_REQUEST(char* pRequest, int* USER_SOCKET, int* FTP_SOCKET, int* DUSER_SOCKET, int* DFTP_SOCKET){
|
|
||||||
if( DEBUGMOD&HDR ) printf("====== MANAGE_REQUEST(%s, %d, %d, %d, %d) ======\n\n", pRequest, *USER_SOCKET, *FTP_SOCKET, *DUSER_SOCKET, *DFTP_SOCKET);
|
|
||||||
|
|
||||||
|
|
||||||
char response[MAX_BUF_LEN]; // contiendra la réponse (2*taille buffer pour strcat(BUFLEN, BUFLEN))
|
|
||||||
int nbSend; // contiendra le nombre de données envoyées
|
|
||||||
char rCommand[5]; // contiendra les commandes (1ère partie)
|
|
||||||
char rContent[MAX_BUF_LEN]; // contiendra le contenu associé à la commande (2ème partie)
|
|
||||||
|
|
||||||
// on vide les buffers
|
|
||||||
memset(&rCommand, '\0', sizeof(rCommand));
|
|
||||||
memset(&rContent, '\0', sizeof(rContent));
|
|
||||||
memset(&response, '\0', sizeof(response));
|
|
||||||
|
|
||||||
|
|
||||||
/* [1] On découpe la requête en 2 parties
|
|
||||||
================================================*/
|
|
||||||
splitFtpRequest(pRequest, rCommand, rContent);
|
|
||||||
|
|
||||||
|
|
||||||
/* [2] Selection en fonction de @rCommand
|
|
||||||
================================================*/
|
|
||||||
|
|
||||||
/* (1) USER username@serveur => connection FTP (commande)
|
|
||||||
--------------------------------------------*/
|
|
||||||
if( strcmp(rCommand, "USER") == 0 && indexOf(rContent, '@') >= 0 ){
|
|
||||||
char userName[100] = {0};
|
|
||||||
char hostName[maxHostLen] = {0};
|
|
||||||
// pour l'envoi de la séquence d'initialisation
|
|
||||||
char* ftp_response; ftp_response = malloc(MAX_BUF_LEN);
|
|
||||||
memset(ftp_response, 0, MAX_BUF_LEN);
|
|
||||||
|
|
||||||
/* 1. On extrait @username et @hostname */
|
|
||||||
sscanf(rContent, "%[^@]@%s\r\n", userName, hostName);
|
|
||||||
|
|
||||||
if( DEBUGMOD&BUF ) printf("USERNAME [[%s]]\n", userName);
|
|
||||||
if( DEBUGMOD&BUF ) printf("HOSTNAME [[%s]]\n", hostName);
|
|
||||||
|
|
||||||
|
|
||||||
/* 2. On se connecte au serveur FTP (commandes) */
|
|
||||||
int error = CONNECT_CLIENT(hostName, FTP_PORT, FTP_SOCKET);
|
|
||||||
|
|
||||||
if( error == -1 || *FTP_SOCKET == -1 ){ // si erreur
|
|
||||||
printf("Impossible de se connecter au serveur (%s:%s)\n", hostName, FTP_PORT);
|
|
||||||
strcpy(pRequest, "421 ERREUR: impossible de se connecter au serveur!!\r\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( DEBUGMOD&SCK ) printf("FTP SOCKET CONNECTED AT %s:%s\n", hostName, FTP_PORT);
|
|
||||||
|
|
||||||
|
|
||||||
/* 3. On envoie la séquence d'initialisation */
|
|
||||||
CLIENT_SEND(FTP_SOCKET, "", &ftp_response);
|
|
||||||
|
|
||||||
if( DEBUGMOD&CMD ) xPrint("P->F: %s\n\n", "\r\n");
|
|
||||||
if( DEBUGMOD&CMD ) xPrint("F->P: %s\n", ftp_response);
|
|
||||||
|
|
||||||
|
|
||||||
/* 4. On envoie la requête USER au serveur FTP auquel on vient de se connecter */
|
|
||||||
char newRequest[MAX_BUF_LEN];
|
|
||||||
strcat(newRequest, "USER ");
|
|
||||||
strcat(newRequest, userName);
|
|
||||||
strcat(newRequest, "\r\n");
|
|
||||||
strcpy(response, "USER xdrm\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
else if( strcmp(rCommand, "USER") == 0 ) // si oubli serveur
|
|
||||||
strcpy(response, "421 'username@FTPserver' attendu\n");
|
|
||||||
|
|
||||||
/* (2) PORT a1,a2,a3,a4,p1,p2 => utilisateur (actif)
|
|
||||||
--------------------------------------------*/
|
|
||||||
else if( strcmp(rCommand, "PORT") == 0 ){
|
|
||||||
int a1, a2, a3, a4 = 0;
|
|
||||||
int p1, p2 = 0;
|
|
||||||
|
|
||||||
char serverHost[maxHostLen] = {0};
|
|
||||||
char serverPort[maxPortLen] = {0};
|
|
||||||
char BUFFER[MAX_BUF_LEN] = {0};
|
|
||||||
|
|
||||||
/* 1. On récupère l'ip et le port de la réponse */
|
|
||||||
sscanf(pRequest, "PORT %d,%d,%d,%d,%d,%d", &a1, &a2, &a3, &a4, &p1, &p2);
|
|
||||||
// on récupère l'adresse en <char*>
|
|
||||||
sprintf(serverHost, "%d.%d.%d.%d", a1, a2, a3, a4);
|
|
||||||
// on récupère le port en <char*>
|
|
||||||
sprintf(serverPort, "%d", p1*256+p2);
|
|
||||||
|
|
||||||
|
|
||||||
/* 2. On se connecte au client */
|
|
||||||
if( DEBUGMOD&SCK ) printf("CONNECTING TO CLIENT %s:%s\n", serverHost, serverPort);
|
|
||||||
CONNECT_CLIENT(serverHost, serverPort, DUSER_SOCKET);
|
|
||||||
if( DEBUGMOD&SCK ) printf("CONNECTED TO CLIENT %s:%s\n", serverHost, serverPort);
|
|
||||||
|
|
||||||
/* 3. Envoi de "PASV" car on veut être en mode passif entre le proxy et le serveur FTP */
|
|
||||||
strcpy(response, "PASV\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (n) Si aucun traitement on recopie la requête telquel
|
|
||||||
--------------------------------------------*/
|
|
||||||
else
|
|
||||||
strcpy(response, pRequest);
|
|
||||||
|
|
||||||
/* [3] Retour de la réponse
|
|
||||||
================================================*/
|
|
||||||
strcpy(pRequest, response);
|
|
||||||
printf("RESP: %s\n", pRequest);
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void MANAGE_RESPONSE(char* pAnswer, int* USER_SOCKET, int* FTP_SOCKET, int* DUSER_SOCKET, int* DFTP_SOCKET){
|
|
||||||
if( DEBUGMOD&HDR ) printf("====== MANAGE_RESPONSE(%s, %d, %d, %d, %d) ======\n\n", pAnswer, *USER_SOCKET, *FTP_SOCKET, *DUSER_SOCKET, *DFTP_SOCKET);
|
|
||||||
|
|
||||||
char response[MAX_BUF_LEN]; // contiendra la réponse
|
|
||||||
char ftpCodeStr[4]; // contiendra le code FTP (1ère partie)
|
|
||||||
char ftpText[MAX_BUF_LEN]; // contiendra le texte associé à la commande (2ème partie)
|
|
||||||
int ftpCode; // contiendra le code FTP en numérique
|
|
||||||
|
|
||||||
// on vide les buffers
|
|
||||||
memset(&ftpCodeStr, '\0', sizeof(ftpCode));
|
|
||||||
memset(&ftpText, '\0', sizeof(ftpText));
|
|
||||||
memset(&response, '\0', sizeof(response));
|
|
||||||
|
|
||||||
|
|
||||||
/* [1] On découpe la requête en 2 parties
|
|
||||||
================================================*/
|
|
||||||
splitFtpResponse(pAnswer, ftpCodeStr, ftpText);
|
|
||||||
|
|
||||||
// on met le code FTP en <int>
|
|
||||||
ftpCode = atoi( ftpCodeStr );
|
|
||||||
|
|
||||||
// mise à disposition de variables temporaires
|
|
||||||
int tmp[6] = {0};
|
|
||||||
char serverHost[maxHostLen];
|
|
||||||
char serverPort[maxPortLen];
|
|
||||||
char BUFFER[MAX_BUF_LEN] = {0};
|
|
||||||
|
|
||||||
/* [2] Selection en fonction de @ftpCode
|
|
||||||
================================================*/
|
|
||||||
switch(ftpCode){
|
|
||||||
/* (1) Demande d'username
|
|
||||||
--------------------------------------------*/
|
|
||||||
case 220:
|
|
||||||
strcpy(response, WLCM_MSG);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* (2) username OK -> demande MDP
|
|
||||||
--------------------------------------------*/
|
|
||||||
case 331:
|
|
||||||
strcpy(response, USER_MSG);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* (3) Bon mdp -> connection
|
|
||||||
--------------------------------------------*/
|
|
||||||
case 230:
|
|
||||||
strcpy(response, PASS_BON_MSG);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* (4) Mauvais mdp -> message erreur
|
|
||||||
--------------------------------------------*/
|
|
||||||
case 530:
|
|
||||||
strcpy(response, PASS_BAD_MSG);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* (5) Info SYST
|
|
||||||
--------------------------------------------*/
|
|
||||||
// case 215:
|
|
||||||
// strcpy(response, "bla\n");
|
|
||||||
// break;
|
|
||||||
|
|
||||||
|
|
||||||
/* (6) LOGOUT => EXIT
|
|
||||||
--------------------------------------------*/
|
|
||||||
case 221:
|
|
||||||
strcpy(response, EXIT_MSG);
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
/* (7) Mode passif => On lance les SOCKETS du BUS DE DONNEES
|
|
||||||
--------------------------------------------*/
|
|
||||||
case 227: // on lance la SOCKET FTP du BUS DE DONNEES
|
|
||||||
|
|
||||||
/* 1. On récupère l'ip et le port de la réponse */
|
|
||||||
sscanf(pAnswer, "227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)", &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
|
|
||||||
// on récupère l'adresse en <char*>
|
|
||||||
sprintf(serverHost, "%d.%d.%d.%d", tmp[0], tmp[1], tmp[2], tmp[3]);
|
|
||||||
// on récupère le port en <char*>
|
|
||||||
sprintf(serverPort, "%d", tmp[4]*256+tmp[5]);
|
|
||||||
|
|
||||||
/* 2. Connexion au serveur FTP */
|
|
||||||
if( DEBUGMOD&SCK ) printf("CONNECTING TO FTP %s:%s\n", serverHost, serverPort);
|
|
||||||
CONNECT_CLIENT(serverHost, serverPort, DFTP_SOCKET);
|
|
||||||
if( DEBUGMOD&SCK ) printf("CONNECTED TO FTP %s:%s\n", serverHost, serverPort);
|
|
||||||
|
|
||||||
/* 3. Envoi du message de code 200 */
|
|
||||||
strcpy(response, LIST_DAT_MSG);
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
/* (8) On lit la SOCKET FTP du BUS DE DONNEES
|
|
||||||
--------------------------------------------*/
|
|
||||||
case 150:
|
|
||||||
|
|
||||||
/* 1. Envoi au client de l'écoute de la réponse (associée) du BUS DE DONNEES */
|
|
||||||
// sread(FTP_SOCKET, BUFFER);
|
|
||||||
// if( DEBUGMOD&CMD ) xPrint("F->P: %s\n", BUFFER);
|
|
||||||
swrite(USER_SOCKET, READ_CON_MSG);
|
|
||||||
if( DEBUGMOD&CMD ) xPrint("P->C: %s\n", READ_CON_MSG);
|
|
||||||
|
|
||||||
|
|
||||||
/* 2. On lit la SOCKET FTP (BUS DE DONNEES) */
|
|
||||||
tmp[0] = WAIT_SOCKET_UPDATE(DFTP_SOCKET, BUFFER);
|
|
||||||
|
|
||||||
if( DEBUGMOD&DAT && tmp[0] == -1 ) printf("ERROR\n");
|
|
||||||
else if( DEBUGMOD&DAT ) xPrint("[BUS_IN]: %s\n", BUFFER);
|
|
||||||
|
|
||||||
|
|
||||||
/* 3. On redirige sur la SOCKET utilisateur (BUS DE DONNEES) */
|
|
||||||
tmp[1] = swrite(DUSER_SOCKET, BUFFER);
|
|
||||||
|
|
||||||
if( DEBUGMOD&DAT && tmp[1] == -1 ) printf("ERROR\n");
|
|
||||||
else if( DEBUGMOD&DAT ) xPrint("[BUS_OUT]: %s\n", BUFFER);
|
|
||||||
|
|
||||||
if( DEBUGMOD&DAT ) xPrint("BUS_FTP->BUS_CLIENT: %s\n", BUFFER);
|
|
||||||
|
|
||||||
|
|
||||||
/* 4. On ferme les SOCKETS du BUS DE DONNEES */
|
|
||||||
close(*DFTP_SOCKET);
|
|
||||||
if( DEBUGMOD&CMD ) printf("BUS_FTP fermé (%d)\n", *DFTP_SOCKET);
|
|
||||||
close(*DUSER_SOCKET);
|
|
||||||
if( DEBUGMOD&CMD ) printf("BUS_USER fermé (%d)\n", *DUSER_SOCKET);
|
|
||||||
|
|
||||||
|
|
||||||
// on vide les SOCKET FTP des 2 BUS
|
|
||||||
// WAIT_SOCKET_UPDATE(FTP_SOCKET, BUFFER); // command
|
|
||||||
// WAIT_SOCKET_UPDATE(DFTP_SOCKET, BUFFER); // données
|
|
||||||
// printf("")
|
|
||||||
|
|
||||||
/* 5. On vide le BUS DE COMMANDE du serveur FTP */
|
|
||||||
/* A. On définit un TIMEOUT (1 sec) */
|
|
||||||
setSocketTimeout(FTP_SOCKET, 0, 50);
|
|
||||||
|
|
||||||
/* B. On attends une réponse */
|
|
||||||
tmp[2] = sread(FTP_SOCKET, BUFFER);
|
|
||||||
|
|
||||||
/* C. On enlève le TIMEOUT (default) */
|
|
||||||
setSocketTimeout(FTP_SOCKET, SOCKET_TIMEOUT);
|
|
||||||
|
|
||||||
|
|
||||||
/* 6. On transmet le message de fin de la transaction (226) */
|
|
||||||
strcpy(response, STOP_DAT_MSG);
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
/* (9) Fin de transfert de données (fermeture SOCKETS du BUS DE DONNEES)
|
|
||||||
--------------------------------------------*/
|
|
||||||
case 226:
|
|
||||||
strcpy(response, "226 Fin de la transaction!\r\n");
|
|
||||||
close(*DUSER_SOCKET);
|
|
||||||
close(*DFTP_SOCKET);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* (n) Commande inconnue
|
|
||||||
--------------------------------------------*/
|
|
||||||
default:
|
|
||||||
strcpy(response, pAnswer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [3] Retour de la réponse
|
|
||||||
================================================*/
|
|
||||||
strcpy(pAnswer, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int WAIT_SOCKET_UPDATE(int* pSocket, char* pBuffer){
|
|
||||||
memset(pBuffer, 0, MAX_BUF_LEN); // on vide le buffer
|
|
||||||
|
|
||||||
int nbRead = 0;
|
|
||||||
|
|
||||||
do{
|
|
||||||
nbRead = sread(pSocket, pBuffer);
|
|
||||||
|
|
||||||
// si on est déconnecté, on renvoie une erreur
|
|
||||||
if( nbRead == -1 ){
|
|
||||||
printf("Client déconnecté!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}while( pBuffer[nbRead-1] != '\n' && pBuffer[nbRead-2] != '\r' );
|
|
||||||
|
|
||||||
|
|
||||||
// on retourne -1 si erreur, SINON 0
|
|
||||||
return nbRead;
|
|
||||||
}
|
|
|
@ -1,100 +0,0 @@
|
||||||
#include "server.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Gestion de la requête du client
|
|
||||||
* ==IN/OUT==
|
|
||||||
* @pBuffer<char*> Requête en question
|
|
||||||
* @USER_SOCKET<int*> Pointeur sur la SOCKET du BUS DE COMMANDES utilisateur
|
|
||||||
* @FTP_SOCKET<int*> Pointeur sur la SOCKET du BUS DE COMMANDES FTP
|
|
||||||
* @DUSER_SOCKET<int*> Pointeur sur la SOCKET du BUS DE DONNEES utilisateur
|
|
||||||
* @DFTP_SOCKET<int*> Pointeur sur la SOCKET du BUS DE DONNEES FTP
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @history
|
|
||||||
* [1] On découpe la requête en 2 parties (rCommand, rContent)
|
|
||||||
* [2] Selection en fonction de @rCommand
|
|
||||||
* (1) USER username@serveur => connection FTP (commande)
|
|
||||||
* 1. On extrait @username et @hostname
|
|
||||||
* 2. On se connecte au serveur FTP (commandes)
|
|
||||||
* 3. On envoie la séquence d'initialisation
|
|
||||||
* 4. On envoie la requête USER au serveur FTP auquel on vient de se connecter
|
|
||||||
*
|
|
||||||
* (2) PORT a1,a2,a3,a4,p1,p2 => utilisateur (actif)
|
|
||||||
* 1. On récupère l'ip et le port de la requête
|
|
||||||
* 2. On se connecte au client
|
|
||||||
* 3. Envoi de "PASV" car on veut être en mode passif entre le proxy et le serveur FTP
|
|
||||||
* (n) Si aucun traitement on recopie la requête telquel
|
|
||||||
*
|
|
||||||
* [3] Retour de la réponse
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int MANAGE_REQUEST(char* pRequest, int* USER_SOCKET, int* FTP_SOCKET, int* DUSER_SOCKET, int* DFTP_SOCKET);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Gestion de la réponse du serveur FTP et modification de la réponse
|
|
||||||
*
|
|
||||||
* @pAnswer<char**> Pointeur sur le buffer de réponse du serveur FTP
|
|
||||||
* @USER_SOCKET<int*> Pointeur sur la SOCKET du BUS DE COMMANDES utilisateur
|
|
||||||
* @FTP_SOCKET<int*> Pointeur sur la SOCKET du BUS DE COMMANDES FTP
|
|
||||||
* @DUSER_SOCKET<int*> Pointeur sur la SOCKET du BUS DE DONNEES utilisateur
|
|
||||||
* @DFTP_SOCKET<int*> Pointeur sur la SOCKET du BUS DE DONNEES FTP
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @history
|
|
||||||
* [1] On découpe la requête en 2 parties (ftpCode, ftpText)
|
|
||||||
* [2] Selection en fonction de @ftpCode
|
|
||||||
* (1) 220- Demande d'username
|
|
||||||
* (2) 331- username OK -> demande MDP
|
|
||||||
* (3) 230- Bon mdp -> connection
|
|
||||||
* (4) 530- Mauvais mdp -> message erreur
|
|
||||||
* (5) 215- Info SYST [COMMENTÉ]
|
|
||||||
* (6) 221- LOGOUT => EXIT (commande QUIT)
|
|
||||||
* (7) 227- Mode passif => On lance les SOCKETS du BUS DE DONNEES
|
|
||||||
* 1. On récupère l'ip et le port de la réponse
|
|
||||||
* 2. Connexion au serveur FTP
|
|
||||||
* 3. Envoi du message de code 200
|
|
||||||
*
|
|
||||||
* (8) 150- On lit la SOCKET FTP du BUS DE DONNEES
|
|
||||||
* 1. Envoi au client de l'écoute de la réponse (associée) du BUS DE DONNEES
|
|
||||||
* 2. On lit la SOCKET FTP (BUS DE DONNEES)
|
|
||||||
* 3. On redirige sur la SOCKET utilisateur (BUS DE DONNEES)
|
|
||||||
* 4. On ferme les SOCKETS du BUS DE DONNEES
|
|
||||||
* 5. On vide le BUS DE COMMANDE du serveur FTP
|
|
||||||
* A. On définit un TIMEOUT (1 sec
|
|
||||||
* B. On attends une réponse
|
|
||||||
* C. On enlève le TIMEOUT (default)
|
|
||||||
* 6. On transmet le message de fin de la transaction (226)
|
|
||||||
*
|
|
||||||
* (9) 226- Fin de transfert de données (fermeture SOCKETS du BUS DE DONNEES)
|
|
||||||
* (n) xxx- Commande inconnue
|
|
||||||
*
|
|
||||||
* [3] Retour de la réponse
|
|
||||||
*/
|
|
||||||
void MANAGE_RESPONSE(char* pAnswer, int* USER_SOCKET, int* FTP_SOCKET, int* DUSER_SOCKET, int* DFTP_SOCKET);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Attends une réponse du client
|
|
||||||
*
|
|
||||||
* @pSocket<int*> Pointeur sur la SOCKET en question
|
|
||||||
* @pBuffer<char*> Buffer qui contiendra la réponse
|
|
||||||
*
|
|
||||||
* @return nbRead<int> On retourne le nombre de char lus, sinon -1 si erreur
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @history
|
|
||||||
* [1] On read() tant qu'on a pas les symboles de fin "\r\n"
|
|
||||||
* [2] On écrit sur le BUFFER
|
|
||||||
* [3] Si une erreur se produit, on retourne -1
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int WAIT_CLIENT(int* pSocket, char* pBuffer);
|
|
Loading…
Reference in New Issue