*/
/********************************************************/
/* */
+/* Procedure to clear and return socket status */
+/* return the errno. */
+/* */
+/********************************************************/
+static int checksockstat(int handle)
+
+{
+int status;
+socklen_t len;
+
+status=0;
+len=sizeof(status);
+if (getsockopt(handle,SOL_SOCKET,SO_ERROR,&status,&len)<0) {
+ status=errno;
+ }
+return status;
+}
+/*
+\f
+*/
+/********************************************************/
+/* */
/* Procedure to open plain incoming channel */
/* */
/********************************************************/
PUBLIC SOCPTR *soc_openfeedsock(PROTYP proto,const char *srcip,const char *ip,const char *port)
{
-#define OPEP "devsoc.c:soc_openfeedsoc"
+#define OPEP "devsoc.c:soc_openfeedsoc,"
+#define WAITCNT 10
SOCTYP *soc;
+int swait;
int status;
int handle;
int flags;
fd_set rset;
fd_set wset;
+struct timeval timeout;
struct addrinfo hints;
struct addrinfo *ai;
int phase;
_Bool proceed;
soc=(SOCTYP *)0;
+swait=WAITCNT;
status=0;
handle=0;
flags=0;
FD_ZERO(&rset);
FD_ZERO(&wset);
+timeout.tv_usec=0;;
+timeout.tv_sec=swait;
(void) memset(&hints,'\000',sizeof(hints));
hints.ai_family=PF_UNSPEC;
hints.ai_flags=HINTFLG;
phase=0;
proceed=true;
while (proceed==true) {
- //(void) rou_alert(0,"JMPDBG %s phase='%d'",OPEP,phase);
+ (void) rou_alert(0,"JMPDBG %s phase='%d'",OPEP,phase);
switch (phase) {
case 0 : //Do we have parameters
if ((ip==(const char *)0)||(port==(const char *)0)) {
}
}
break;
- case 4 : //connecting to remote
+ case 4 : //getting the socket status
+ if ((flags=fcntl(handle,F_GETFL,0))<0) {
+ (void) rou_core_dump("%s, Unable to get socket descripteur on "
+ "IP/PORT <%s/%s> (Bug? error=<%s>)",
+ OPEP,soc->ip,soc->port,strerror(errno));
+ phase=999; //never reached
+ }
+ break;
+ case 5 : //setting newhandle working mode
+ if ((flags=fcntl(handle,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,soc->ip,soc->port,strerror(errno));
+ phase=999; //never reached
+ }
+ break;
+ case 6 : //connecting to remote
+ FD_SET(handle,&rset); /*FD ready for select */
+ wset=rset;
if (connect(handle,ai->ai_addr,ai->ai_addrlen)<0) {
switch (errno) {
case EINPROGRESS : //its acceptable
}
}
break;
- case 5 : //getting newhandle flag
- if ((flags=fcntl(handle,F_GETFL,0))<0) {
- (void) rou_core_dump("%s, Unable to get socket descripteur on "
- "IP/PORT <%s/%s> (Bug? error=<%s>)",
- OPEP,soc->ip,soc->port,strerror(errno));
- phase=999; //never reached
+ case 7 : //Wait link established
+ switch (select(handle+1,&rset,&wset,(fd_set *)0,&timeout)) {
+ case -1 :
+ (void) rou_alert(1,"%s Unable to establish connection with '%s.%s' "
+ "(error=<%s>)",
+ OPEP,ip,port,strerror(errno));
+ (void) close(handle);
+ phase=999;
+ break;
+ case 0 :
+ (void) rou_alert(1,"%s Unable establish connection with <%s> "
+ "within %d sec",OPEP,ip,swait);
+ (void) close(handle);
+ phase=999;
+ break;
+ default : //Link established
+ break;
}
break;
- case 6 : //setting newhandle working mode
- if ((flags=fcntl(handle,F_SETFL,flags|O_NONBLOCK))<0) {
- (void) rou_core_dump("%s, Unable to set socket descripteur on "
- "IP/PORT <%s/%s> (Bug? error=<%s>)",
- OPEP,soc->ip,soc->port,strerror(errno));
- phase=999; //never reached
+ case 8 : //checking socket status
+ if ((status=checksockstat(handle))!=0) {
+ (void) rou_alert(0,"%s Unable establish socklink with <%s> (error=<%s>)",
+ OPEP,ip,strerror(status));
+ (void) close(handle);
+ phase=999;
}
break;
- case 7 : //socket is now ready
+ case 9 : //socket is now ready
soc=newsocket();
soc->proto=proto;
soc->connected=true;