2 Commits
Author SHA1 Message Date
fred 0dc02cb3e6 fix: add log 2026-07-12 14:22:04 +02:00
fred a7d4cadd1b Dynamic demon executing
Execute en mode demon si la fin du nom de l'exe est 'd'
2026-07-11 20:48:56 +02:00
+78 -40
View File
@@ -1,4 +1,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
@@ -12,6 +15,8 @@
/* compilation : gcc -o api api.c -Wall -lssl -lcrypto */
char * flog = NULL;
#define TRUE 1
#define FALSE 0
@@ -39,6 +44,34 @@ int mSignal; // indique si fin demandee par un signal (kill ou dmd arret depuis
long mNbFils; // > 0 si serveur
long mPid; // pid du process
// -----------------------------------------------------------
void trace(const char * fmt, ...)
{
va_list args;
va_start(args, fmt);
if(flog)
{
FILE * f = fopen(flog, "a+");
if(f)
{
fprintf(f, "%s%d%s", mServeur ? "Serveur " : "Cnx ", getpid(), ": ");
vfprintf(f, fmt, args);
fclose(f);
}
else
{
printf("%s%d%s", mServeur ? "Serveur " : "Cnx ", getpid(), ": ");
vprintf(fmt, args);
}
}
else
{
printf("%s%d%s", mServeur ? "Serveur " : "Cnx ", getpid(), ": ");
vprintf(fmt, args);
}
va_end(args);
}
// -----------------------------------------------------------
void libereSecu()
{
@@ -77,14 +110,14 @@ int secuSocket()
int cr;
if((mClientSsl = SSL_new(mSslCtx)) == NULL)
{
printf("Erreur SSL_new\n");
trace("Erreur SSL_new\n");
/* erreur gestion etat SSL */
libereSecu();
return FALSE;
}
if(!SSL_set_fd(mClientSsl, mSocket))
{
printf("Erreur SSL_set_fd\n");
trace("Erreur SSL_set_fd\n");
/* erreur assoc socket */
libereSecu();
return FALSE;
@@ -103,7 +136,7 @@ int secuSocket()
}
if(cr != 1)
{
printf("Erreur SSL_accept, code %d error %d\n", sslcr, errno);
trace("Erreur SSL_accept, code %d error %d\n", sslcr, errno);
libereSecu();
return FALSE;
}
@@ -119,7 +152,7 @@ int securise(char * certificat, char * privateKey, int socket)
{
if((mSslCtx = SSL_CTX_new(TLS_server_method())) == NULL)
{
printf("Erreur SSL_CTX_new\n");
trace("Erreur SSL_CTX_new\n");
libereSecu();
return FALSE;
}
@@ -133,19 +166,19 @@ int securise(char * certificat, char * privateKey, int socket)
/* */
if (SSL_CTX_use_certificate_file(mSslCtx, certificat, SSL_FILETYPE_PEM) <= 0)
{
printf("Erreur SSL_CTX_use_certificate_file\n");
trace("Erreur SSL_CTX_use_certificate_file\n");
libereSecu();
return FALSE;
}
if (SSL_CTX_use_PrivateKey_file(mSslCtx, privateKey, SSL_FILETYPE_PEM) <= 0)
{
printf("Erreur SSL_CTX_use_PrivateKey_file\n");
trace("Erreur SSL_CTX_use_PrivateKey_file\n");
libereSecu();
return FALSE;
}
if (!SSL_CTX_check_private_key(mSslCtx))
{
printf("Erreur SSL_CTX_check_private_key\n");
trace("Erreur SSL_CTX_check_private_key\n");
libereSecu();
return FALSE;
}
@@ -201,27 +234,27 @@ int creerServeur(long port)
/* mise en place de la socket serveur d'ecoute */
if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("Erreur creation socket\n");
trace("Erreur creation socket\n");
return FALSE; // erreur
}
ioctl(sock, FIONBIO, &arg); /* socket non bloquant (sys/ioctl.h) */
if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(int))) /* pour eliminer une erreur : permet de rouvrir des socket suite a fermeture avec des clients encore connectes */
{
printf("Erreur setsockopt SO_REUSEADDR\n");
trace("Erreur setsockopt SO_REUSEADDR\n");
/* erreur */
close(sock);
return FALSE;
}
if(setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void*)&buf, sizeof(buf)))
{
printf("Erreur setsockopt SO_RCVBUF\n");
trace("Erreur setsockopt SO_RCVBUF\n");
/* erreur */
close(sock);
return FALSE;
}
if(setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void*)&buf, sizeof(buf)))
{
printf("Erreur setsockopt SO_SNDBUF\n");
trace("Erreur setsockopt SO_SNDBUF\n");
/* erreur */
close(sock);
return FALSE;
@@ -231,21 +264,21 @@ int creerServeur(long port)
l_s.l_linger = 0; // les 2 valeurs provoquent un close avec retour immediat, sans traiter les donnees eventuelles en attente d'envoi et envoi RST au client s'il est connecte en TCP
if(setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&l_s, sizeof (l_s)))
{
printf("Erreur setsockopt SO_LINGER\n");
trace("Erreur setsockopt SO_LINGER\n");
/* erreur */
close(sock);
return FALSE;
}
if(bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
printf("Erreur bind, errno %d\n", errno);
trace("Erreur bind, errno %d\n", errno);
close(sock);
return FALSE;
}
else
if(listen(sock, 10) < 0)
{
printf("Erreur listen\n");
trace("Erreur listen\n");
close(sock);
return FALSE;
}
@@ -312,7 +345,7 @@ int lireConnexion(char * data)
int err = SSL_get_error(mClientSsl, nblu);
if(err == SSL_ERROR_ZERO_RETURN || err == SSL_ERROR_SYSCALL)
{
printf("Fermeture de la connexion par le client\n");
trace("Fermeture de la connexion par le client\n");
return FALSE;
}
@@ -423,7 +456,6 @@ void trt_connexion()
//Dynamic req, methode, uri, rep, tmp, fld;
//long meth, cr, nb;
int keepAlive;
printf("trt demande\n");
//
*data = 0;
keepAlive = TRUE;
@@ -431,36 +463,42 @@ void trt_connexion()
{
//tmp.let("GET;HEAD;POST");
//// lire les donnees entrantes sur la socket // pbm ici bloquant : sans doute pbm de longueur attendue !? a tester
//printf("debut boucle\n");
//trace("debut boucle\n");
if ( ! lireConnexion(data))
break; // fin du client
printf("lu:\n%s\n", data);
//if(strstr(data,"keep-alive") == NULL)
// keepAlive = FALSE;
trace("lu:\n%s\n", data);
if(strstr(data,"keep-alive") == NULL)
keepAlive = FALSE;
//
strcpy(data, "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nContent-Type:text/html\r\nContent-Length:35\r\n\r\n<html><h2>Hello World !</h2></html>");
printf("Reponse:\n%s\n", data);
trace("Reponse:\n%s\n", data);
ecrireConnexion(data);
*data = 0;
//// faire une attente passive ici (sinon consomme trop de CPU)
//printf("Attente fin boucle\n");
//while(attente(10) <= 0 && ! mFin) ;
//trace("Attente fin boucle\n");
while(attente(10) <= 0 && ! mFin) ;
//if ( ! lireConnexion(data))
// break;
//if(mFin)
break; // sortie sur signal
if(mFin)
break; // sortie sur signal
}
printf("fin cnx client\n");
trace("fin cnx client\n");
}
// ----------------------------------------------------------
int main(int argc, char *argv[])
{
if(argc != 4)
if(argc != 4 && argc != 5)
{
printf("Usage : %s <port> <certificat> <cleprivee>\n", argv[0]);
trace("Usage : %s <port> <certificat> <cleprivee> [<fichierlog>]\n", argv[0]);
exit(1);
}
int demon = (argv[0][strlen(argv[0]) - 1] == 'd');
if(argc == 5)
{
flog = argv[4];
remove(flog);
}
/* */
int port = atoi(argv[1]);
certificat = argv[2];
@@ -487,11 +525,11 @@ int main(int argc, char *argv[])
mSslCtx = NULL;
mClientSsl = NULL;
//
if(1)
if(demon)
{
if((mPid = fork()) != 0)
{
printf("Lancement en tache de fond du process pid %ld\n", mPid);
trace("Lancement en tache de fond du process pid %ld\n", mPid);
exit(0); /* sortie du pere */
}
mPid = getpid();
@@ -501,14 +539,14 @@ int main(int argc, char *argv[])
close(i);
}
//
printf("Demarrage serveur, port %d pid %d mode %d bits\n", port, getpid(), sizeof(long)==4?32:64);
trace("Demarrage serveur, port %d pid %d mode %d bits\n", port, getpid(), sizeof(long)==4?32:64);
/* initialisations internes openssl */
SSL_load_error_strings();
OpenSSL_add_ssl_algorithms();
// verification du contexte securise avant de continuer
if( ! securise(certificat, cleprivee, FALSE))
{
printf("Erreur lors de la mise en place du contexte securise SSL/TLS\n");
trace("Erreur lors de la mise en place du contexte securise SSL/TLS\n");
exit(4);
}
else
@@ -533,7 +571,7 @@ int main(int argc, char *argv[])
// dans le pere
mNbFils++;
signal(SIGCHLD, trt_sig); /* SIGCHLD : prevenu quand un process fils se termine */
printf("Connexion depuis ip %d.%d.%d.%d : creation process pid %ld\n", (ipClient >> 24) & 0xFF, (ipClient >> 16) & 0xFF, (ipClient >> 8) & 0xFF, (ipClient & 0xFF), pid_fils);
trace("Connexion depuis ip %d.%d.%d.%d : creation process pid %ld\n", (ipClient >> 24) & 0xFF, (ipClient >> 16) & 0xFF, (ipClient >> 8) & 0xFF, (ipClient & 0xFF), pid_fils);
arret(sock_fils, TRUE);
}
else if(pid_fils == 0)
@@ -542,7 +580,7 @@ int main(int argc, char *argv[])
mServeur = FALSE;
mNbFils = 0;
mPid = getpid();
printf("Connexion entrante pid %ld socket %d\n", mPid, sock_fils);
trace("Connexion entrante pid %ld socket %d\n", mPid, sock_fils);
close(mSocket); // le fils n'a pas besoin de la socket serveur mere
mSocket = sock_fils;
mSockServeur = 0;
@@ -552,7 +590,7 @@ int main(int argc, char *argv[])
if( ! securise(certificat, cleprivee, TRUE))
{
// erreur : handshake securise SSL/TLS ko avec le client
printf("Erreur de handshake securise SSL/TLS\n");
trace("Erreur de handshake securise SSL/TLS\n");
break;
}
//
@@ -561,26 +599,26 @@ int main(int argc, char *argv[])
break;
}
else
printf("Erreur de fork() creation fils - demande non traitee\n");
trace("Erreur de fork() creation fils - demande non traitee\n");
}
verifierFinFils();
}
else
printf("Attente... %d\n", mSocket);
trace("Attente... %d\n", mSocket);
}
// arret socket en cours
arret(mSocket, TRUE);
if(mServeur)
{
demandeArretFilsEtAttente();
printf("Arret du serveur\n");
trace("Arret du serveur\n");
}
else
printf("Arret du client\n");
trace("Arret du client\n");
}
else
{
printf("Erreur d'initialisation du socket serveur - ARRET\n");
trace("Erreur d'initialisation du socket serveur - ARRET\n");
}
return(0);
}