From 5a79dd31ceabf672a2ca359916675676d4b9a82b Mon Sep 17 00:00:00 2001 From: "Jean-Marc Pigeon (Delson)" Date: Wed, 31 Jul 2024 20:41:35 -0400 Subject: [PATCH] Abale to start process contact process (no issue with TIME_WAIT) --- lib/modrec.c | 157 +++++++++++++++++++++++++++++++-------------------- lib/unisig.c | 2 +- 2 files changed, 96 insertions(+), 63 deletions(-) diff --git a/lib/modrec.c b/lib/modrec.c index dc62293..92168fe 100644 --- a/lib/modrec.c +++ b/lib/modrec.c @@ -28,14 +28,13 @@ static _Bool modopen; //boolean module open/close /* a remote TCP connection. */ /* */ /********************************************************/ -void docontact(SOCTYP *binding) +void docontact(SOCTYP *binding,int pos) { #define OPEP "modrec.c:contact" #define TESTL 4 CONTYP *contact; -pid_t child; int phase; _Bool proceed; @@ -45,24 +44,17 @@ proceed=true; while (proceed==true) { switch (phase) { case 0 : //display waiting contact - (void) prc_settitle("Waiting contact on %s:%s",binding->ip,binding->port); + (void) prc_settitle("Waiting contact (%02d/%02d) on %s:%s", + pos,binding->iteration,binding->ip,binding->port); break; case 1 : //do we have a contact - if ((contact=tcp_getcontact(binding))==(CONTYP *)0) { + if ((contact=tcp_getcontact(binding))==(CONTYP *)0) phase=999; //No contact! - } break; case 2 : //forking process printf("New client connected: %d\n",contact->channel); - if ((child=fork())!=(pid_t)0) { - (void) close(contact->channel); - (void) free(contact); - contact=(CONTYP *)0; - phase=999; //no need to go further - } break; case 3 : //do contact - (void) close(binding->handle); printf("Client channel=%d (pid=%d)\n",contact->channel,getpid()); for (int i=0;ichannel,"Remote pid=%d iter=%d/%d\n", @@ -74,7 +66,6 @@ while (proceed==true) { (void) rou_alert(0,"Contact IP/PORT=<%s/%s> Exiting", binding->ip,binding->port); contact=tcp_dropcontact(contact); - (void) exit(0); //exiting sub process break; default : //SAFE guard proceed=false; @@ -89,33 +80,83 @@ while (proceed==true) { */ /********************************************************/ /* */ -/* Procedure to dispatch sub process */ +/* Procedure to activate child process if necessary*/ /* */ /********************************************************/ -static void dispatching(SOCTYP *binding) +static void setready(SOCTYP *binding) { -#define OPEP "modrec.c:dispatching" +#define OPEP "modrec.c:setready" +pid_t *childs; +int maxretry; int phase; _Bool proceed; +childs=(pid_t *)calloc(binding->iteration,sizeof(pid_t)); +maxretry=5; phase=0; proceed=true; while (proceed==true) { + //(void) fprintf(stderr,"setready phase='%d'\n",phase); switch (phase) { - case 0 : //dispatched process still alive - (void) prc_nozombie(); + case 0 : //empty phase + break; + case 1 : //check need to dispatch a process + for (int i=0;iiteration;i++) { + (void) prc_nozombie(); + if (prc_checkprocess(childs[i])==true) + continue; + childs[i]=fork(); + switch (childs[i]) { + case -1 : //trouble trouble to fork? + childs[i]=(pid_t)0; + (void) sleep(1); //Weathering the storm + break; + case 0 : //Child process itself + (void) docontact(binding,i+1); + (void) exit(0); + break; + default : //Main process + (void) usleep(10000); + break; + } + } + if ((hangup==true)||(reload==true)) + phase=999; break; - case 1 : //dispating need process - (void) docontact(binding); //waiting, handling remote contact + case 2 : //Relax time + (void) sleep(5); + if ((hangup==false)&&(reload==false)) + phase=0; //lets continue to check childs break; default : //SAFE Guard + while (maxretry>0) { + int remain; + + remain=0; + for (int i=0;iiteration;i++) { + (void) prc_nozombie(); + if (childs[i]==(pid_t)0) + continue; + if (prc_checkprocess(childs[i])==false) { + childs[i]=(pid_t)0; + continue; + } + remain++; + (void) kill(childs[i],SIGTERM); + } + if (remain==0) + break; + (void) sleep(1); + maxretry--; + } proceed=false; break; } phase++; } +(void) free(childs); #undef OPEP } /* @@ -123,13 +164,13 @@ while (proceed==true) { */ /********************************************************/ /* */ -/* Procedure to activate child process if necessary*/ +/* Procedure to start a binding+waiting process */ /* */ /********************************************************/ -static void activate(SOCTYP **bindings) +PUBLIC void startwaiter(SOCTYP *binding,int offset) { -#define OPEP "modrec.c:activate" +#define OPEP "moderec.c:startwaiter" int phase; _Bool proceed; @@ -138,19 +179,28 @@ phase=0; proceed=true; while (proceed==true) { switch (phase) { - case 0 : //making sur the list is defined - if (bindings==(SOCTYP **)0) { - (void) rou_alert(0,"%s bindings list pointer is NULL (Bug!?)",OPEP); - phase=999; //not going further - } + case 0 : //Opening logs + (void) openlog(appname,LOG_NDELAY|LOG_PID,LOG_DAEMON); + (void) prc_settitle("Daemon Waiting on %s:%s (Num of channels='%02d')", + binding->ip,binding->port,binding->iteration); break; - case 1 : //check need to dispatch a process - while (*bindings!=(SOCTYP *)0) { - (void) dispatching(*bindings); - bindings++; + case 1 : //binding on channel + if (soc_openbinding(binding)==false) { + (void) rou_alert(0,"%s Aborting binding on <%s:%s> (config?)", + OPEP,binding->ip,binding->port); + phase=999; //no need to go further } break; + case 2 : //waiting + (void) rou_alert(0,"JMPDBG waiter starting"); + (void) setready(binding); + (void) rou_alert(0,"JMPDBG waiter exiting"); + break; + case 3 : //stop binding + (void) soc_closebinding(binding); + break; default : //SAFE Guard + (void) closelog(); proceed=false; break; } @@ -163,32 +213,6 @@ while (proceed==true) { */ /********************************************************/ /* */ -/* Procedure to start a binding+waiting process */ -/* */ -/********************************************************/ -PUBLIC pid_t startwaiter(SOCTYP *binding) - -{ -pid_t waiter; - -if ((waiter=fork())==(pid_t)0) { - (void) closelog(); - (void) openlog("Waiter",LOG_NDELAY|LOG_PID,LOG_DAEMON); - (void) prc_settitle("Daemon Waiting on %s:%s (Num of channels='%02d')", - binding->ip,binding->port,binding->iteration); - (void) rou_alert(0,"JMPDBG starting waiter"); - (void) sleep(20); - (void) rou_alert(0,"JMPDBG waiter exiting"); - (void) closelog(); - (void) exit(0); - } -return waiter; -} -/* - -*/ -/********************************************************/ -/* */ /* Waiting and handling smtp request */ /* */ /********************************************************/ @@ -205,15 +229,15 @@ _Bool proceed; maxretry=30; //5 seconds max retry bindings=(SOCTYP **)0; -bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.1","2525",1); -//bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.26","2626",1); +bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.1","2525",3); +bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.26","2626",1); phase=0; proceed=true; while (proceed==true) { switch (phase) { case 0 : //looping forever email receiving processes - (void) prc_settitle("Emlrec Daemon"); (void) rou_alert(0,LINE); + (void) prc_settitle("Emlrec Daemon"); (void) rou_alert(0,"Starting Emlrec daemon"); if (bindings==(SOCTYP **)0) { (void) rou_alert(0,"No bindings definition found!"); @@ -231,9 +255,18 @@ while (proceed==true) { break; case 2 : //starting restarting all waiter process for (SOCTYP **ptr=bindings;(*ptr)!=(SOCTYP *)0;ptr++) { + int offset; + + offset=random()%10; if ((*ptr)->waiter!=(pid_t)0) continue; - (*ptr)->waiter=startwaiter(*ptr); + (*ptr)->waiter=fork(); + if ((*ptr)->waiter==(pid_t)0) { + (void) closelog(); + (void) startwaiter(*ptr,offset); + (void) exit(0); + } + (void) usleep(10000); //avoid avalanche } break; case 3 : //relax time diff --git a/lib/unisig.c b/lib/unisig.c index 1f26107..1be9871 100644 --- a/lib/unisig.c +++ b/lib/unisig.c @@ -85,7 +85,7 @@ PUBLIC void sig_alrm(int sig) { #define OPEP "unisig.c:sig_alrm" -(void) rou_alert(9,"%s, signal <%s> received",OPEP,strsignal(sig)); +(void) rou_alert(10,"%s, signal <%s> received",OPEP,strsignal(sig)); switch (sig) { case SIGCHLD : -- 2.47.3