static _Bool modopen; //boolean module open/close
/*
-\f
-*/
-/********************************************************/
-/* */
-/* Procedure to get the handle related to a remote */
-/* contact. */
-/* */
-/********************************************************/
-static int getcontact(SOCTYP *binding)
-
-{
-#define OPEP "gestcp.c:getcontact"
-int contact;
-socklen_t taille;
-struct sockaddr addr;
-
-taille=sizeof(addr);
-contact=accept(binding->handle,&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
*/
/********************************************************/
}
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;
}
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!
/* */
/********************************************************/
#include <sys/types.h>
-#include <sys/socket.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
int handle;
struct linger slg;
int reuse;
-int flags;
int phase;
_Bool proceed;
slg.l_onoff=true;
slg.l_linger=0; /*0 sec timeout on close*/
reuse=1;
-flags=0;
phase=0;
proceed=true;
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')",
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')",
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
return bindings;
}
/*
-\f
-*/
-/********************************************************/
-/* */
-/* 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
*/
/********************************************************/
/* 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;
}
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;
}
phase++;
}
-(void) soc_getlinger(soc,"exiting from soc_onelisten");
-return soc;
+return done;
#undef OPEP
}
/*
/* 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;
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));
/* 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;
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;
*/
/********************************************************/
/* */
-/* Procedure to close all socket within a socket */
-/* list. */
+/* Procedure to close all socket previously binded */
/* */
/********************************************************/
PUBLIC void soc_mulclose(SOCTYP **bindings)
break;
case 1 : //
while (*bindings!=(SOCTYP *)0) {
- (void) soc_oneclose(*bindings);
+ (void) soc_closebinding(*bindings);
bindings++;
}
break;
}
#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