From 4414252976b8b37d0ec501355162df40a2803efe Mon Sep 17 00:00:00 2001 From: "Jean-Marc Pigeon (Delson)" Date: Sun, 14 Jul 2024 11:35:35 -0400 Subject: [PATCH] Improving unisoc.c (soc_getcontact) --- lib/gestcp.c | 22 ++++++++++ lib/modrec.c | 2 +- lib/unisoc.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/unisoc.h | 3 ++ 4 files changed, 146 insertions(+), 1 deletion(-) diff --git a/lib/gestcp.c b/lib/gestcp.c index 67db061..9db35fe 100644 --- a/lib/gestcp.c +++ b/lib/gestcp.c @@ -25,10 +25,32 @@ static _Bool modopen; //boolean module open/close PUBLIC CONTYP *tcp_getcontact(SOCTYP *binding) { +#define OPEP "gestcp.c:tcp_getcontact" + CONTYP *contact; +int phase; +_Bool proceed; contact=(CONTYP *)0; +phase=0; +proceed=true; +while (proceed==true) { + switch (phase){ + case 0 : //check for binding + if (binding==(SOCTYP *)0) { + (void) rou_alert(0,"%s binding pointer is NULL (Bug!?)",OPEP); + phase=999; //not going further + } + break; + case 1 : //waiting from contact + break; + default : //SAFE guard + break; + } + phase++; + } return contact; +#undef OPEP } /* ^L diff --git a/lib/modrec.c b/lib/modrec.c index e691a82..1b3c535 100644 --- a/lib/modrec.c +++ b/lib/modrec.c @@ -140,7 +140,7 @@ proceed=true; while (proceed==true) { switch (phase) { case 0 : //making sur the list is defined - if (bindings==(SOCTYP **)0) { + if (bindings==(SOCTYP **)0) { (void) rou_alert(0,"%s bindings list pointer is NULL (Bug!?)",OPEP); phase=999; //not going further } diff --git a/lib/unisoc.c b/lib/unisoc.c index c9affa2..4b5c6fb 100644 --- a/lib/unisoc.c +++ b/lib/unisoc.c @@ -33,6 +33,52 @@ static _Bool modopen; //module open/close status */ /********************************************************/ /* */ +/* Procedure to get the handle related to a remote */ +/* contact. */ +/* */ +/********************************************************/ +static int getcontact(SOCTYP *binding) + +{ +#define OPEP "unisoc.c:getcontac" +int contact; +socklen_t taille; +struct sockaddr addr; + +contact=-1; +taille=sizeof(addr); +if ((contact=accept(binding->handle,&addr,&taille))<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 */ + 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)); + } +return contact; +#undef OPEP +} +/* + +*/ +/********************************************************/ +/* */ /* Procedure to free memory used by a */ /* binding info. */ /* */ @@ -426,6 +472,80 @@ while (proceed==true) { ^L */ /********************************************************/ +/* */ +/* Procedure to wait for an incoming connecion */ +/* from a remote client. */ +/* return a socket handle or -1 if trouble. */ +/* */ +/********************************************************/ +PUBLIC int soc_listen(SOCTYP *binding) + +{ +#define OPEP "unisoc.c:soc_listen" + +int contact; +int phase; +_Bool proceed; + +contact=-2; +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 + fd_set reading; + struct timeval relax; + FD_ZERO(&reading); + FD_SET(binding->handle,&reading); + relax.tv_sec=1; //1 sec relax time + relax.tv_usec=0; + switch (select(binding->handle+1,&reading,(fd_set *)0,(fd_set *)0,&relax)) { + case -1 : //got a wrong return + switch (errno) { + case EINTR : //Received a signal, get out! fast! + phase=999; + break; + default : //Unexpected error? + (void) rou_core_dump("%, Unexpected select status (error=<%s>)", + OPEP,strerror(errno)); + break; //never reached + } + break; + case 0 : //normal time out. + phase--; //lets continue to wait for incoming + break; + default : //we got a contact + if ((contact=getcontact(binding))<0) + phase--; //not quick enough, lets continue to wait + break; + } + break; + default : //SAFE Guard + proceed=false; + break; + } + phase++; + } +return contact; +#undef OPEP +} +/* +^L +*/ +/********************************************************/ /* */ /* Procedure to "open/close" module and do */ /* homework purpose */ diff --git a/lib/unisoc.h b/lib/unisoc.h index bb42135..4f228fc 100644 --- a/lib/unisoc.h +++ b/lib/unisoc.h @@ -51,6 +51,9 @@ extern int soc_mullisten(SOCTYP **bindings); //procedure to close all sockets extern void soc_mulclose(SOCTYP **bindings); +//procedure to wait for a connection from a remote client +extern int soc_listen(SOCTYP *binding); + //homework to be done before starting/stopping module. extern int soc_modeunisoc(_Bool mode); -- 2.47.3