/* sockunion_connect returns -1 : error occured 0 : connect success 1 : connect is in progress */ enum connect_result sockunion_connect (int fd, union sockunion *peersu, unsigned short port, unsigned int ifindex) { int ret; int val = 1; union sockunion su; //inet_ntop(AF_INET, &sin.sin_addr, buf, 256); //fprintf(stderr, "convert from dstip %s address to union address success\n", buf); memcpy(&su, peersu, sizeof(union sockunion)); printf ( "try connect to %s:%d fd %d : %s",sockunion_log ( &su ), ntohs(port), fd, strerror ( errno ) ); /* Call connect function. */ ret = connect(fd, (struct sockaddr *) &su, sockunion_sizeof(&su)); val = 0; /* added by fanky 2004 0601 */ /* Immediate success */ if (ret == 0) { ret = ioctl(fd, FIONBIO, &val); return connect_success; } /* If connect is in progress then return 1 else it's real error. */ if (ret < 0) { if (errno != EINPROGRESS) { printf ( "can't connect to %s fd %d : %s", sockunion_log ( &su ), fd, strerror ( errno ) ); return connect_error; } } return connect_in_progress; }
/* Performs a non-blocking connect(). */ enum connect_result sockunion_connect(int fd, const union sockunion *peersu, unsigned short port, ifindex_t ifindex) { int ret; union sockunion su; memcpy(&su, peersu, sizeof(union sockunion)); switch (su.sa.sa_family) { case AF_INET: su.sin.sin_port = port; break; case AF_INET6: su.sin6.sin6_port = port; #ifdef KAME if (IN6_IS_ADDR_LINKLOCAL(&su.sin6.sin6_addr) && ifindex) { su.sin6.sin6_scope_id = ifindex; SET_IN6_LINKLOCAL_IFINDEX(su.sin6.sin6_addr, ifindex); } #endif /* KAME */ break; } /* Call connect function. */ ret = connect(fd, (struct sockaddr *)&su, sockunion_sizeof(&su)); /* Immediate success */ if (ret == 0) return connect_success; /* If connect is in progress then return 1 else it's real error. */ if (ret < 0) { if (errno != EINPROGRESS) { char str[SU_ADDRSTRLEN]; zlog_info("can't connect to %s fd %d : %s", sockunion_log(&su, str, sizeof str), fd, safe_strerror(errno)); return connect_error; } } return connect_in_progress; }
/* sockunion_connect returns -1 : error occured 0 : connect success 1 : connect is in progress */ enum connect_result sockunion_connect (int fd, union sockunion *peersu, unsigned short port, unsigned int ifindex) { int ret; int val; union sockunion su; memcpy (&su, peersu, sizeof (union sockunion)); switch (su.sa.sa_family) { case AF_INET: su.sin.sin_port = port; break; #ifdef HAVE_IPV6 case AF_INET6: su.sin6.sin6_port = port; #ifdef KAME if (IN6_IS_ADDR_LINKLOCAL(&su.sin6.sin6_addr) && ifindex) { #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID /* su.sin6.sin6_scope_id = ifindex; */ #ifdef MUSICA su.sin6.sin6_scope_id = ifindex; #endif #endif /* HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID */ #ifndef MUSICA SET_IN6_LINKLOCAL_IFINDEX (su.sin6.sin6_addr, ifindex); #endif } #endif /* KAME */ break; #endif /* HAVE_IPV6 */ } /* Make socket non-block. */ val = fcntl (fd, F_GETFL, 0); fcntl (fd, F_SETFL, val|O_NONBLOCK); /* Call connect function. */ ret = connect (fd, (struct sockaddr *) &su, sockunion_sizeof (&su)); /* Immediate success */ if (ret == 0) { fcntl (fd, F_SETFL, val); return connect_success; } /* If connect is in progress then return 1 else it's real error. */ if (ret < 0) { if (errno != EINPROGRESS) { char str[SU_ADDRSTRLEN]; zlog_info ("can't connect to %s fd %d : %s", sockunion_log (&su, str, sizeof str), fd, safe_strerror (errno)); return connect_error; } } fcntl (fd, F_SETFL, val); return connect_in_progress; }
/* sockunion_connect returns -1 : error occured 0 : connect success 1 : connect is in progress */ enum connect_result sockunion_connect (int fd, union sockunion *peersu, unsigned short port, unsigned int ifindex) { int ret; int val; union sockunion su; int ret2=0; memcpy (&su, peersu, sizeof (union sockunion)); switch (su.sa.sa_family) { case AF_INET: su.sin.sin_port = port; break; #ifdef HAVE_IPV6 case AF_INET6: su.sin6.sin6_port = port; #ifdef KAME if (IN6_IS_ADDR_LINKLOCAL(&su.sin6.sin6_addr) && ifindex) { #ifdef HAVE_SIN6_SCOPE_ID /* su.sin6.sin6_scope_id = ifindex; */ #ifdef MUSICA su.sin6.sin6_scope_id = ifindex; #endif #endif /* HAVE_SIN6_SCOPE_ID */ #ifndef MUSICA SET_IN6_LINKLOCAL_IFINDEX (su.sin6.sin6_addr, ifindex); #endif } #endif /* KAME */ break; #endif /* HAVE_IPV6 */ } /* Make socket non-block. */ val = fcntl (fd, F_GETFL, 0); /*CID 10316 (#1 of 3): Unchecked return value from library (CHECKED_RETURN) 3. check_return: Calling function "fcntl(fd, 4, val | 0x80)" without checking return value. This library function may fail and return an error code. Add check return value.*/ /*fcntl (fd, F_SETFL, val|O_NONBLOCK);*/ ret = fcntl (fd, F_SETFL, val|O_NONBLOCK); if(ret < 0) zlog_warn("%s: line %d, fcntl failed : %s .\n",__func__,__LINE__,safe_strerror(errno)); /* Call connect function. */ ret = connect (fd, (struct sockaddr *) &su, sockunion_sizeof (&su)); /* Immediate success */ if (ret == 0) { /*CID 10316 (#2 of 3): Unchecked return value from library (CHECKED_RETURN) 4. check_return: Calling function "fcntl(fd, 4, val)" without checking return value. This library function may fail and return an error code. Change , add check return value.*/ /*fcntl (fd, F_SETFL, val);*/ ret2 = fcntl (fd, F_SETFL, val); if(ret < 0) zlog_warn("%s: line %d, fcntl failed : %s .\n",__func__,__LINE__,safe_strerror(errno)); return connect_success; } /* If connect is in progress then return 1 else it's real error. */ if (ret < 0) { if (errno != EINPROGRESS) { char *log_str = sockunion_log (&su); zlog_info ("can't connect to %s fd %d : %s", log_str, fd, safe_strerror (errno)); free(log_str); return connect_error; } } /*CID 10316 (#3 of 3): Unchecked return value from library (CHECKED_RETURN) 6. check_return: Calling function "fcntl(fd, 4, val)" without checking return value. This library function may fail and return an error code. Add check return value.*/ /*fcntl (fd, F_SETFL, val);*/ ret2 = fcntl (fd, F_SETFL, val); if(ret < 0) zlog_warn("%s: line %d, fcntl failed : %s .\n",__func__,__LINE__,safe_strerror(errno)); return connect_in_progress; }