From: Jean-Marc Pigeon (Delson) Date: Wed, 31 Jul 2024 02:31:52 +0000 (-0400) Subject: Trying to work like "kleenes" with emlrec X-Git-Tag: tag-0.4~40 X-Git-Url: https://jmp-git.ovh.safe.ca/?a=commitdiff_plain;h=b1c2b81afbcf6baf92b61578fb03b95483fc2e51;p=jmp%2Fmailleur Trying to work like "kleenes" with emlrec --- diff --git a/kleenex/server.c b/kleenex/server.c index 8dd6a91..b94e359 100644 --- a/kleenex/server.c +++ b/kleenex/server.c @@ -8,7 +8,9 @@ #include #include #include +#include +#define MXCHILD 2 void receiveAndRespond(int handle) { @@ -16,8 +18,8 @@ void receiveAndRespond(int handle) printf("Start receiveAndRespond\n"); for (int i=0;i0); + printf("All %d channel used\n",MXCHILD); + continue; + } + for (int i=0;ihandle,&addr,&taille); -if (contact<0) { - switch (errno) { - case EAGAIN : - /*well process not quick enough the handle was already */ - /*accepted by another clement???. */ - break; - case EINVAL : /*no socket avail anymore */ - contact--; //There is NO main process anymore - break; - default : - (void) rou_alert(0,"%s Unexpected error on IP/PORT <%s/%s> errno=<%s>", - OPEP,binding->ip,binding->port,strerror(errno)); - break; - } - } -else { - int flags; - - if ((flags=fcntl(contact,F_GETFL,0))<0) - (void) rou_core_dump("%s Unable to get socket descripteur (error='%s')", - OPEP,strerror(errno)); - if ((flags=fcntl(contact,F_SETFL,flags|O_NONBLOCK|O_ASYNC))<0) - (void) rou_core_dump("%s Unable to set socket descripteur (error='%s')", - OPEP,strerror(errno)); - } -(void) rou_alert(0,"JMPDBG got contact channel='%d'",contact); -return contact; -#undef OPEP -} -/* -^L -*/ -/********************************************************/ -/* */ -/* Procedure to wait for an incoming connection */ -/* from a remote client. */ -/* return a socket handle or -1 if trouble. */ -/* */ -/********************************************************/ -static int waitlisten(SOCTYP *binding) - -{ -#define OPEP "gesttcp.c:waitlisten" - -int contact; -int phase; -_Bool proceed; - -contact=-1; -phase=0; -proceed=true; -while (proceed==true) { - switch (phase) { - case 0 : //checking if the point is ready; - if (binding==(SOCTYP *)0) { - (void) rou_alert(0,"%s binding pointer is NULL (Bug!?)",OPEP); - phase=999; //not going further - } - break; - case 1 : //checking if the handle is properly set - if (binding->handle<0) { - (void) rou_alert(0,"%s trouble with handle (handle value ='%d', Bug!?)", - OPEP,binding->handle); - phase=999; //not going further - } - break; - case 2 : //listening on the handle - (void) rou_alert(0,"JMPDBG contact handle ptr='%p'",&(binding->handle)); - (void) soc_getlinger(binding->handle,"waitlisten 1"); - (void) soc_setlinger(binding->handle); - (void) soc_getlinger(binding->handle,"waitlisten 2"); - break; - case 3 : //listening on the handle - fd_set reading; - struct timeval relax; - int status; - - FD_ZERO(&reading); - FD_SET(binding->handle,&reading); - relax.tv_sec=1; //1 sec relax time - relax.tv_usec=0; - status=select(binding->handle+1,&reading,(fd_set *)0,(fd_set *)0,&relax); - switch (status) { - case -1 : //got a wrong return - switch (errno) { - case EINTR : //Received a signal, get out! fast! - (void) fprintf(stderr,"JMPDBG pid='%05d select received a signal!\n", - getpid()); - phase=999; - break; - default : //Unexpected error? - (void) rou_core_dump("%s, Unexpected select status (error=<%s>)", - OPEP,strerror(errno)); - break; //never reached - } - break; - case 0 : //normal time out. - phase--; //lets continue to wait for incoming - if (prc_checkprocess(getppid())==false) { - (void) rou_alert(0,"%s parent process missing (daemon restart?)", - OPEP); - phase=999; //exiting - } - if ((hangup==true)||(reload==true)) - phase=999; //exiting - break; - default : //we got a contact - contact=getcontact(binding); - switch (contact) { - case -2 : //no handle anymore exiting - break; - case -1 : //not quick enough - phase--; //let continue to wait - (void) sleep(1); - break; - default : //we have a contact - break; - } - break; - } - break; - default : //SAFE Guard - proceed=false; - break; - } - phase++; - //(void) rou_alert(0,"JMPDB waitlisten contat='%d' phase='%d'",contact,phase); - } -return contact; -#undef OPEP -} -/* ^L */ /********************************************************/ @@ -223,7 +73,7 @@ while (proceed==true) { } break; case 1 : //waiting from contact - if ((contact->channel=waitlisten(binding))<0) { + if ((contact->channel=soc_accept(binding,&(contact->addr)))<0) { (void) rou_alert(0,"%s Unable to open contact",OPEP); (void) free(contact); contact=(CONTYP *)0; @@ -271,7 +121,6 @@ while (proceed==true) { } break; case 1 : //waiting from contact - (void) soc_getlinger(contact->channel,"before shutdown"); if (shutdown(contact->channel,SHUT_RDWR)<0) { switch (errno) { case ENOTCONN : //already disconnect by other side! diff --git a/lib/gestcp.h b/lib/gestcp.h index 9a1fd36..9ce9577 100644 --- a/lib/gestcp.h +++ b/lib/gestcp.h @@ -13,6 +13,7 @@ typedef struct { int channel; //xchang channle handle + SOCKADDR addr; //Remote address SOCTYP *binding;//extablised contact context }CONTYP; diff --git a/lib/modrec.c b/lib/modrec.c index 2f88e17..e8ad0ec 100644 --- a/lib/modrec.c +++ b/lib/modrec.c @@ -143,8 +143,6 @@ while (proceed==true) { break; case 1 : //check need to dispatch a process while (*bindings!=(SOCTYP *)0) { - (void) rou_alert(0,"JMPDBG handle ptr='%p'",&((*bindings)->handle)); - (void) soc_getlinger((*bindings)->handle,"before dispatching"); (void) dispatching(*bindings); bindings++; } @@ -255,7 +253,7 @@ while (proceed==true) { (void) rou_alert(0,"-------------JMPDBG---------------"); break; case 1 : //Opening ALL channels - if (soc_mullisten(bindings)==false) + if (soc_mulopen(bindings)==false) (void) rou_alert(0,"%s, Unable to open ALL socket (config?)",OPEP); break; case 2 : //Terminating all remaining process diff --git a/lib/unisoc.c b/lib/unisoc.c index abc8dcb..0e71de9 100644 --- a/lib/unisoc.c +++ b/lib/unisoc.c @@ -6,7 +6,6 @@ /* */ /********************************************************/ #include -#include #include #include #include @@ -68,7 +67,6 @@ static int bindhandle(struct addrinfo *ai,SOCTYP *binding) int handle; struct linger slg; int reuse; -int flags; int phase; _Bool proceed; @@ -76,7 +74,6 @@ handle=-1; slg.l_onoff=true; slg.l_linger=0; /*0 sec timeout on close*/ reuse=1; -flags=0; phase=0; proceed=true; while (proceed==true) { @@ -88,31 +85,15 @@ while (proceed==true) { phase=999; //trouble trouble } break; - case 1 : /*getting socket option */ - if ((flags=fcntl(handle,F_GETFL,0))<0) { - (void) rou_alert(0,"%s Unable to set socket descriptor " - "for <%s> (error='%s')", - OPEP,ai->ai_canonname,strerror(errno)); - phase=999; //trouble cleanup phase - } - break; - case 2 : //setting the socket working setting - if (fcntl(handle,F_SETFL,flags|O_NONBLOCK|O_ASYNC)<0) { - (void) rou_alert(0,"%s Unable to set socket in none " - "block mode for <%s> (error='%s')", - OPEP,ai->ai_canonname,strerror(errno)); - phase=999; //trouble cleanup phase - } - break; - case 3 : //setting socket option (address) + case 1 : //setting socket option (address) if (setsockopt(handle,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0) { (void) rou_alert(0,"%s Unable to get socket option " "SO_REUSEADDR for <%s> (error='%s')", OPEP,ai->ai_canonname,strerror(errno)); phase=999; //trouble cleanup phase - } + } break; - case 4 : //setting socket option (port) + case 2 : //setting socket option (port) if (setsockopt(handle,SOL_SOCKET,SO_REUSEPORT,&reuse,sizeof(reuse))<0) { (void) rou_alert(0,"%s Unable to get socket option " "SO_REUSEPORT for <%s> (error='%s')", @@ -120,7 +101,7 @@ while (proceed==true) { phase=999; //trouble cleanup phase } break; - case 5 : //SO_LINGER allow Connection reset by peer + case 3 : //SO_LINGER allow Connection reset by peer if (setsockopt(handle,SOL_SOCKET,SO_LINGER,&slg,sizeof(slg))<0) { (void) rou_alert(0,"%s Unable to set socket option " "SO_LINGER for <%s> (error='%s')", @@ -128,29 +109,17 @@ while (proceed==true) { phase=999; //trouble cleanup phase } break; - case 6 : //getting socket option - (void) soc_getlinger(handle,"before bind"); + case 4 : //getting socket option if (bind(handle,ai->ai_addr,ai->ai_addrlen)<0) { (void) rou_alert(0,"%s Unable to bind on IP/port <%s/%s> (error='%s')", OPEP,ai->ai_canonname,binding->port,strerror(errno)); phase=999; //trouble cleanup phase } break; - case 7 : /*preparing listen */ - (void) soc_getlinger(handle,"after bind"); - if (listen(handle,5)<0) { - (void) rou_alert(0,"%s Unable to listen on IP/port <%s/%s> (error='%s')", - OPEP,ai->ai_canonname,binding->port,strerror(errno)); - phase=999; //trouble cleanup phase - } - break; - case 8 : /*reporting listen */ - (void) soc_getlinger(handle,"after listen"); - (void) rou_alert(1,"Now Listening on IP/PORT <%s/%s>", - ai->ai_canonname,binding->port); - proceed=false; //evrything fine no need to go further + case 5 : //everythin is fine no need to go further + proceed=false; break; - default : //SAFE Guard + default : //SAFE Guard (in case of trouble) if (handle>=0) close(handle); handle=-1; //trouble trouble @@ -210,35 +179,6 @@ bindings=(SOCTYP **)rou_addlist((void **)bindings,(void *)bininf); return bindings; } /* - -*/ -/********************************************************/ -/* */ -/* Procedure to set set the linger mode on the */ -/* socket device. */ -/* return -1 if trouble. */ -/* */ -/********************************************************/ -PUBLIC int soc_setlinger(int socket) - -{ -#define OPEP "unisoc.c:soc_setlinger" - -int status; -struct linger slg; - -status=-1; -slg.l_onoff=true; -slg.l_linger=0; -status=setsockopt(socket,SOL_SOCKET,SO_LINGER,&slg,sizeof(slg)); -if (status<0) - (void) rou_alert(0,"%s Unable to set socket option " - "SO_LINGER for <%s> (error='%s' bug?)", - OPEP,strerror(errno)); -return status; -#undef OPEP -} -/* ^L */ /********************************************************/ @@ -247,18 +187,18 @@ return status; /* socket handle */ /* */ /********************************************************/ -PUBLIC int soc_onelisten(SOCTYP *binding) +PUBLIC _Bool soc_openbinding(SOCTYP *binding) { -#define OPEP "unisoc.c:soc_onelisten" +#define OPEP "unisoc.c:soc_openbinding" -int soc; +_Bool done; struct addrinfo hints; struct addrinfo *tobind; int phase; _Bool proceed; -soc=-1; +done=false; (void) memset(&hints,'\000',sizeof(hints)); hints.ai_family=PF_UNSPEC; hints.ai_flags=HINTFLG; @@ -290,9 +230,22 @@ while (proceed==true) { } break; case 3 : //binding socket - soc=bindhandle(tobind,binding); - (void) soc_getlinger(soc,"result from bindhandle"); - //(void) freeaddrinfo(tobind); JMPDBG ALARM + if ((binding->handle=bindhandle(tobind,binding))<0) + phase=999; //no need to go further + (void) freeaddrinfo(tobind); + break; + case 4 : //listening on socket + if (listen(binding->handle,binding->iteration)<0) { + (void) rou_alert(0,"%s, Unable to listen at address " + "IP:port '%s:%s' (error='%s')", + binding->ip,binding->port,strerror(errno)); + (void) close(binding->handle); + binding->handle=-1; + phase=999; //no need to go further + } + break; + case 5 : //listening on socket + done=true; break; default : //SAFE Guard proceed=false; @@ -300,8 +253,7 @@ while (proceed==true) { } phase++; } -(void) soc_getlinger(soc,"exiting from soc_onelisten"); -return soc; +return done; #undef OPEP } /* @@ -312,10 +264,10 @@ return soc; /* Procedure to unbind from one socket. */ /* */ /********************************************************/ -PUBLIC void soc_oneclose(SOCTYP *binding) +PUBLIC void soc_closebinding(SOCTYP *binding) { -#define OPEP "unisoc.c:soc_oneclose" +#define OPEP "unisoc.c:soc_closebinding" int phase; _Bool proceed; @@ -335,13 +287,7 @@ while (proceed==true) { phase=999; //yes, no need to go further } break; - case 2 : //check if time to retry binding - if (shutdown(binding->handle,SHUT_RDWR)<0) - (void) rou_alert(0,"%s Unable To shutdown socket (Bug!?, error=<%s>)", - OPEP,strerror(errno)); - - break; - case 3 : //closing the the socket + case 2 : //closing the the socket if (close(binding->handle)<0) (void) rou_alert(0,"%s Unable to close socket (Bug!?, error=<%s>)", OPEP,strerror(errno)); @@ -364,10 +310,10 @@ while (proceed==true) { /* true if all socket are open ready. */ /* */ /********************************************************/ -PUBLIC int soc_mullisten(SOCTYP **bindings) +PUBLIC _Bool soc_mulopen(SOCTYP **bindings) { -#define OPEP "unisoc.c:soc_mullisten" +#define OPEP "unisoc.c:soc_mulopen" _Bool ready; uid_t gid; @@ -399,17 +345,8 @@ while (proceed==true) { case 2 : //binding on all interface ready=true; while (*bindings!=(SOCTYP *)0) { - int soc; - - soc=soc_onelisten(*bindings); - (void) soc_getlinger(soc,"after onelisten"); - (*bindings)->handle=soc; - if ((*bindings)->handle<0) - ready=false; //Trouble? - else { - (void) rou_alert(0,"JMPDBG mullisten ptr='%p",&((*bindings)->handle)); - (void) soc_getlinger((*bindings)->handle,"mullisten"); - } + if (soc_openbinding(*bindings)==false) + ready=false; //Trouble? Unable to open channel bindings++; } break; @@ -429,8 +366,7 @@ return ready; */ /********************************************************/ /* */ -/* Procedure to close all socket within a socket */ -/* list. */ +/* Procedure to close all socket previously binded */ /* */ /********************************************************/ PUBLIC void soc_mulclose(SOCTYP **bindings) @@ -453,7 +389,7 @@ while (proceed==true) { break; case 1 : // while (*bindings!=(SOCTYP *)0) { - (void) soc_oneclose(*bindings); + (void) soc_closebinding(*bindings); bindings++; } break; @@ -465,19 +401,64 @@ while (proceed==true) { } #undef OPEP } -//temporary JMPDBG -void soc_getlinger(int socket,char *inf) +/* +^L +*/ +/********************************************************/ +/* */ +/* Procedure to wait an accept a connexion comming */ +/* from a remote client. */ +/* return the handle */ +/* */ +/********************************************************/ +PUBLIC int soc_accept(SOCTYP *binding,SOCKADDR *addr) { -socklen_t len; -struct linger slg; - -len=sizeof(struct linger); -if (getsockopt(socket,SOL_SOCKET,SO_LINGER,&slg,&len)<0) - (void) rou_alert(0,"JMPDBG LISTEN trouble (error='%s')",strerror(errno)); -(void) rou_alert(0,"JMPDBG [%s] get socket='%d' linger.onoff='%d', " - "timeout linger='%d' (len='%d')", - inf,socket,slg.l_onoff,slg.l_linger,len); +#define OPEP "unisoc.c:soc_accept" +int newhandle; +socklen_t taille; + +newhandle=-1; +taille=sizeof(struct sockaddr); +if ((newhandle=accept(binding->handle,addr,&taille))<0) { + if (errno==EAGAIN) + errno=EWOULDBLOCK; + switch (errno) { + case EWOULDBLOCK : + (void) rou_alert(0,"%s Socket on IP/PORT <%s/%s> is in no_block mode " + "(Bug?!, errno=<%s>)", + OPEP,binding->ip,binding->port,strerror(errno)); + break; + case EINVAL : + (void) rou_alert(0,"%s Socket on IP/PORT <%s/%s> not available " + "(Bug?!, errno=<%s>)", + OPEP,binding->ip,binding->port,strerror(errno)); + break; + case EINTR : + (void) rou_alert(0,"%s Socket on IP/PORT <%s/%s> got a signal " + "(errno=<%s>)", + OPEP,binding->ip,binding->port,strerror(errno)); + break; + default : + (void) rou_alert(0,"%s Unexpected error on IP/PORT <%s/%s> (errno=<%s>)", + OPEP,binding->ip,binding->port,strerror(errno)); + break; + } + } +else { + int flags; + + if ((flags=fcntl(newhandle,F_GETFL,0))<0) + (void) rou_core_dump("%s, Unable to get socket descripteur on " + "IP/PORT <%s/%s> (Bug? error=<%s>)", + OPEP,binding->ip,binding->port,strerror(errno)); + if ((flags=fcntl(newhandle,F_SETFL,flags|O_NONBLOCK|O_ASYNC))<0) + (void) rou_core_dump("%s, Unable to set socket descripteur on " + "IP/PORT <%s/%s> (Bug? error=<%s>)", + OPEP,binding->ip,binding->port,strerror(errno)); + } +return newhandle; +#undef OPEP } /* ^L diff --git a/lib/unisoc.h b/lib/unisoc.h index e9e9fa2..d4e3860 100644 --- a/lib/unisoc.h +++ b/lib/unisoc.h @@ -8,9 +8,13 @@ #ifndef UNISOC #define UNISOC +#include #include #include +//convenient adress structure +typedef struct sockaddr SOCKADDR; + //defining email protocol value. typedef enum { pro_smtp, //text SMTP protocol, in clear mode @@ -29,6 +33,7 @@ typedef struct { pid_t *childs; //all process connected to this handle }SOCTYP; + //procedure to free all memory used by a TCP socket //definition (once closed) extern SOCTYP **soc_freebindinf(SOCTYP **bindref); @@ -38,24 +43,20 @@ extern SOCTYP **soc_freebindinf(SOCTYP **bindref); extern SOCTYP **soc_mkbindinf(SOCTYP **bindings,PROTYP proto, const char *ip,const char *port,int iteration); -//Procedure to set the linger value on the socket handle -extern int soc_setlinger(int socket); - //procedure to open ONE socket and return handle to socket -extern int soc_onelisten(SOCTYP *binding); +extern _Bool soc_openbinding(SOCTYP *binding); //procedure to close ONE socket -extern void soc_oneclose(SOCTYP *binding); +extern void soc_closebinding(SOCTYP *binding); -//procedure to open multiple socket and return true if -//all socket are open -extern int soc_mullisten(SOCTYP **bindings); +//all socket are open in binding mode +extern _Bool soc_mulopen(SOCTYP **bindings); //procedure to close all sockets extern void soc_mulclose(SOCTYP **bindings); -//temporary JMPDBG -extern void soc_getlinger(int socket,char *inf); +//procedure to wait and accept remote connexion +extern int soc_accept(SOCTYP *binding,SOCKADDR *addr); //homework to be done before starting/stopping module. extern int soc_modeunisoc(_Bool mode);