From: Jean-Marc Pigeon (Delson) Date: Thu, 8 Aug 2024 12:45:13 +0000 (-0400) Subject: remote disconnected properly detected X-Git-Tag: tag-0.4~9 X-Git-Url: https://jmp-git.ovh.safe.ca/?a=commitdiff_plain;h=3fd96caebb4ef36398563728f62da026b5c18445;p=jmp%2Fmailleur remote disconnected properly detected --- diff --git a/lib/devsoc.c b/lib/devsoc.c index 3ca6620..efa201b 100644 --- a/lib/devsoc.c +++ b/lib/devsoc.c @@ -165,10 +165,10 @@ return newhandle; */ /********************************************************/ /* */ -/* Procedure to prepare plain incoming channel */ +/* Procedure to open plain incoming channel */ /* */ /********************************************************/ -static _Bool plainsoc(SOCTYP *soc) +static _Bool openplain(SOCTYP *soc) { #define OPEP "devsoc:plainsoc" @@ -187,9 +187,8 @@ proceed=true; while (proceed==true) { switch (phase) { case 0 : //First prepare a new socket - if ((newhandle=getnewhandle(soc))<0) { + if ((newhandle=getnewhandle(soc))<0) phase=999; //no newhandle troub trouble - } break; case 1 : //getting newhandle flag if ((flags=fcntl(newhandle,F_GETFL,0))<0) { @@ -225,6 +224,55 @@ return good; */ /********************************************************/ /* */ +/* Procedure to close plain incoming channel */ +/* */ +/********************************************************/ +static void closeplain(SOCTYP *soc) + +{ +#define OPEP "devsoc.c:closeplain" + +int phase; +_Bool proceed; + +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //shutting down the link + if (shutdown(soc->handle,SHUT_RDWR)<0) { + switch (errno) { + case ENOTCONN : //already disconnect by other side! + (void) rou_alert(0,"%s [%s:%s] Already disconnected (errno=<%s>)", + OPEP,soc->ip,soc->port,strerror(errno)); + break; + default : + (void) rou_alert(0,"%s unable to shutdown [%s:%s] (errno=<%s>)", + OPEP,soc->ip,soc->port,strerror(errno)); + break; + } + } + break; + case 1 : //closing connexion + if (close(soc->handle)<0) { + (void) rou_alert(0,"%s unable to close channel [%s:%s] properly " + "(errno=<%s>)", + OPEP,soc->ip,soc->port,strerror(errno)); + } + break; + default : //SAFE Guard + proceed=false; + break; + } + phase++; + } +#undef OPEP +} +/* + +*/ +/********************************************************/ +/* */ /* Procedure to wait and get a new handle */ /* */ /********************************************************/ @@ -246,9 +294,8 @@ while (proceed==true) { switch (phase) { case 0 : //First prepare a new socket newsoc=dupsocket(soc); - if (plainsoc(newsoc)==false) { - phase=999; //trouble trouble - } + if (openplain(newsoc)==false) + proceed=false; //received a termination signal break; case 1 : //wait for incoming connexion switch (newsoc->proto) { @@ -655,12 +702,10 @@ while (proceed==true) { phase=999; //No End Of Line yet break; case 3 : //duplicating carpile - (void) printf("JMPDBG carpil=<%s>\n",soc->carpile); *lineptr=calloc(soc->carin+1,sizeof(char)); *eol='\000'; (void) strcpy(*lineptr,soc->carpile); (void) strcat(*lineptr,soc->EOL); - (void) printf("JMPDBG *lineptr=<%s>\n",*lineptr); got=strlen(*lineptr); break; case 4 : //managing carpile @@ -717,16 +762,17 @@ return sent; /* socket. */ /* */ /********************************************************/ -PUBLIC void soc_receive(SOCPTR *socptr) +PUBLIC int soc_receive(SOCPTR *socptr) { #define OPEP "devsoc.c:soc_receive" +int got; SOCTYP *soc; +got=0; soc=(SOCTYP *)socptr; if (soc!=(SOCTYP *)0) { - int got; int limit; char *buffer; @@ -735,7 +781,6 @@ if (soc!=(SOCTYP *)0) { switch (soc->modtls) { case true : got=tls_read(soc->tls,buffer,limit); - (void) printf("JMPDBG tls_read got='%d'\n",got); break; case false : got=recv(soc->handle,buffer,limit,MSG_DONTWAIT); @@ -751,7 +796,7 @@ if (soc!=(SOCTYP *)0) { break; } break; - case 0 : //EOL? + case 0 : //Premature EOF? break; default : //we got some char from remote break; @@ -761,9 +806,9 @@ if (soc!=(SOCTYP *)0) { if (got>0) { //we have recived some character soc->carin+=got; //managing carpile soc->carpile[soc->carin]='\000'; - (void) printf("JMPDBG soc_receive carpile=<%s>\n",soc->carpile); } } +return got; #undef OPEP } /* @@ -906,28 +951,22 @@ while (proceed==true) { } break; case 1 : //shuting dow the TCP link - if (shutdown(soc->handle,SHUT_RDWR)<0) { - switch (errno) { - case ENOTCONN : //already disconnect by other side! - (void) rou_alert(0,"%s [%s:%s] Already disconnected (errno=<%s>)", - OPEP,soc->ip,soc->port,strerror(errno)); - break; - default : - (void) rou_alert(0,"%s unable to shutdown [%s:%s] (errno=<%s>)", - OPEP,soc->ip,soc->port,strerror(errno)); - break; - } + switch (soc->proto) { + case pro_smtp : //plain socket + case pro_starttls : //plain socket + STARTTLS + //nothing to do + break; + case pro_smtps : //set secure socket + soc->tls=tls_closetls(soc->tls); + break; + default : + (void) rou_alert(0,"%s Protocol '%d' unset (Bug?)", + OPEP,(int)(soc->proto)); + break; } break; case 2 : //closing connexion - if (close(soc->handle)<0) { - (void) rou_alert(0,"%s unable to close channel [%s:%s] properly " - "(errno=<%s>)", - OPEP,soc->ip,soc->port,strerror(errno)); - } - break; - case 3 : //freeing the SSL contaxt - soc->tls=tls_closetls(soc->tls); + (void) closeplain(soc); break; case 4 : //fee memory used by socket soc=freesocket(soc); diff --git a/lib/devsoc.h b/lib/devsoc.h index fbbc8fa..62cd75d 100644 --- a/lib/devsoc.h +++ b/lib/devsoc.h @@ -54,7 +54,7 @@ extern int soc_getnextline(SOCPTR *socptr,char **lineptr); extern int soc_writebuffer(SOCPTR *socptr,char *buffer,int tosend); //procedure to receive up to limit char from socket -extern void soc_receive(SOCPTR *socptr); +extern int soc_receive(SOCPTR *socptr); //procedure to wait and accept remote connexion extern SOCPTR *soc_accept(SOCPTR *socptr,int pos); diff --git a/lib/gestcp.c b/lib/gestcp.c index bd29a32..aecce9b 100644 --- a/lib/gestcp.c +++ b/lib/gestcp.c @@ -77,16 +77,21 @@ while (proceed==true) { phase=999; //we got a line. break; case 2 : //waiting for new character presence - switch (soc_waitforchar(contact->socptr,attend)) { + got=soc_waitforchar(contact->socptr,attend); + switch (got) { case -1 : //trouble? signal? if ((hangup==true)||(reload==true)) phase=999; //we got a real signal break; //no need to read line case 0 : //normal time out + phase=999; //no need to go further break; //no need to read line default : //char available - (void) soc_receive(contact->socptr); phase=0; //check for new line + if (soc_receive(contact->socptr)==0) { + got=0; + phase=999; //remote disconnected? + } break; } break; diff --git a/lib/modrec.c b/lib/modrec.c index 5e4b13a..2f26ae4 100644 --- a/lib/modrec.c +++ b/lib/modrec.c @@ -64,7 +64,7 @@ while (proceed==true) { attend.tv_nsec=0; (void) printf("attend %d seconds\n",(int)attend.tv_sec); got=tcp_getline(contact,&attend,&line); - if (got==0) { + if (got<=0) { (void) printf("remote timeout\n"); break; //remote disconnect } diff --git a/lib/subrou.c b/lib/subrou.c index 2110aeb..10e13b7 100644 --- a/lib/subrou.c +++ b/lib/subrou.c @@ -20,7 +20,7 @@ //version definition #define VERSION "0.3" -#define RELEASE "32" +#define RELEASE "33" //Public variables PUBLIC int debug=0; //debug level diff --git a/lib/unitls.c b/lib/unitls.c index 724468c..781595c 100644 --- a/lib/unitls.c +++ b/lib/unitls.c @@ -99,8 +99,7 @@ if (sslerror<=0) { break; case SSL_ERROR_SSL : (void) showerrorstack(info); - //detail=ERR_error_string(ERR_get_error(),(char *)0); - detail="Bigre"; + detail=ERR_error_string(ERR_get_error(),(char *)0); break; default : (void) rou_alert(0,"%s, caused by <%s> Unexpected ssl error='%d'", @@ -230,6 +229,8 @@ static TLSTYP *freetls(TLSTYP *tls) { if (tls!=(TLSTYP *)0) { + if (tls->ssl!=(SSL *)0) + (void) free(tls->ssl); if (tls->ctx!=(SSL_CTX *)0) (void) SSL_CTX_free(tls->ctx); (void) free(tls); @@ -391,7 +392,34 @@ return tls; PUBLIC TLSTYP *tls_closetls(TLSTYP *tls) { +#define OPEP "unitls.c:tls_closetls" + +int status; +int phase; +_Bool proceed; + +phase=0; +proceed=true; +while (proceed==true) { + switch (phase) { + case 0 : //Check if TLS is OK + if (tls==(TLSTYP *)0) { + (void) rou_core_dump("%s Unexpected NULL SSL (Bug?)",OPEP); + } + break; + case 1 : //set certificate + status=SSL_shutdown(tls->ssl); + (void) printf("JMPDBG ssl_shutdown status='%d'\n",status); + break; + default : //SAFE guard + tls=freetls(tls); + proceed=false; + break; + } + phase++; + } return tls; +#undef OPEP } /* ^L