|
|
|
@ -19,29 +19,50 @@
|
|
|
|
|
|
|
|
|
|
#define DEFAULT_PORT 60179 /* Birthday .. mother fucker :) */
|
|
|
|
|
|
|
|
|
|
struct addrinfo *ai = NULL;
|
|
|
|
|
|
|
|
|
|
static RETSIGTYPE tcpip_interrupt(int sig)
|
|
|
|
|
{
|
|
|
|
|
tty_abort = TRUE;
|
|
|
|
|
log("terminating on signal %d", sig);
|
|
|
|
|
(void)log("terminating on signal %d", sig);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static RETSIGTYPE tcpip_brokenpipe(int sig)
|
|
|
|
|
{
|
|
|
|
|
tty_abort = TRUE;
|
|
|
|
|
if( tty_online )
|
|
|
|
|
log("connection closed");
|
|
|
|
|
(void)log("connection closed");
|
|
|
|
|
else
|
|
|
|
|
log("terminating on signal %d", sig);
|
|
|
|
|
(void)log("terminating on signal %d", sig);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int tcpip_connect2(struct sockaddr_in server)
|
|
|
|
|
static int tcpip_connect2(struct addrinfo *ai)
|
|
|
|
|
{
|
|
|
|
|
int fd;
|
|
|
|
|
int fd = -1;
|
|
|
|
|
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
|
|
|
|
|
|
|
|
|
|
struct addrinfo *rai;
|
|
|
|
|
|
|
|
|
|
for (rai = ai; rai != NULL; rai = rai->ai_next)
|
|
|
|
|
{
|
|
|
|
|
if (getnameinfo(rai->ai_addr, rai->ai_addrlen, hbuf, sizeof(hbuf), sbuf,
|
|
|
|
|
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0)
|
|
|
|
|
DEB((D_INFO, "tcpip_connect2: trying host=%s, serv=%s", hbuf, sbuf));
|
|
|
|
|
|
|
|
|
|
DEB((D_INFO, "tcpip_connect2: trying \"%s\" at port %d",
|
|
|
|
|
inet_ntoa(server.sin_addr), (int)ntohs(server.sin_port)));
|
|
|
|
|
fd = socket (rai->ai_family, rai->ai_socktype, rai->ai_protocol);
|
|
|
|
|
|
|
|
|
|
if( (fd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
|
|
|
|
|
if ( fd == -1 )
|
|
|
|
|
{
|
|
|
|
|
DEB((D_INFO, "tcpip_connect2: socket error"));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else break;
|
|
|
|
|
|
|
|
|
|
hbuf[0]='\0';
|
|
|
|
|
sbuf[0]='\0';
|
|
|
|
|
}
|
|
|
|
|
DEB((D_INFO, "tcpip_connect2: socket success: %d", fd));
|
|
|
|
|
if (fd < 0 )
|
|
|
|
|
{
|
|
|
|
|
logerr("can't create socket");
|
|
|
|
|
return(1);
|
|
|
|
@ -84,9 +105,9 @@ static int tcpip_connect2(struct sockaddr_in server)
|
|
|
|
|
clearerr(stdout);
|
|
|
|
|
clearerr(stderr);
|
|
|
|
|
|
|
|
|
|
if( connect(0, (struct sockaddr*)&server, sizeof(server)) == -1 )
|
|
|
|
|
if( connect(0, rai->ai_addr, rai->ai_addrlen) == -1 )
|
|
|
|
|
{
|
|
|
|
|
logerr("can't connect to %s", inet_ntoa(server.sin_addr));
|
|
|
|
|
logerr("can't connect to %s", hbuf);
|
|
|
|
|
close(0);
|
|
|
|
|
close(1);
|
|
|
|
|
close(2);
|
|
|
|
@ -99,8 +120,7 @@ static int tcpip_connect2(struct sockaddr_in server)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
log("TCP/IP connect to %s on port %d",
|
|
|
|
|
inet_ntoa(server.sin_addr), (int)ntohs(server.sin_port));
|
|
|
|
|
(void)log("TCP/IP connect success to %s on service %s", hbuf, sbuf);
|
|
|
|
|
|
|
|
|
|
return(0);
|
|
|
|
|
}
|
|
|
|
@ -108,14 +128,23 @@ static int tcpip_connect2(struct sockaddr_in server)
|
|
|
|
|
int tcpip_connect(const char *hostname, e_tcpmode tcpmode)
|
|
|
|
|
{
|
|
|
|
|
int rc = 0;
|
|
|
|
|
struct hostent *he = NULL;
|
|
|
|
|
struct servent *se = NULL;
|
|
|
|
|
struct sockaddr_in server;
|
|
|
|
|
//struct hostent *he = NULL;
|
|
|
|
|
//struct servent *se = NULL;
|
|
|
|
|
//struct sockaddr_in server;
|
|
|
|
|
//struct sockaddr_storage server;
|
|
|
|
|
|
|
|
|
|
struct addrinfo *aisave = NULL;
|
|
|
|
|
struct addrinfo aihints;
|
|
|
|
|
int nameres = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
char *host = xstrcpy(hostname);
|
|
|
|
|
char *p = strrchr(host, ':');
|
|
|
|
|
const char *port = NULL;
|
|
|
|
|
|
|
|
|
|
server.sin_family = AF_INET;
|
|
|
|
|
|
|
|
|
|
// AF_INET - only IPv4
|
|
|
|
|
//server.sin_family = AF_INET;
|
|
|
|
|
|
|
|
|
|
if( p )
|
|
|
|
|
{ *p++ = '\0'; port = p; }
|
|
|
|
@ -126,15 +155,31 @@ int tcpip_connect(const char *hostname, e_tcpmode tcpmode)
|
|
|
|
|
else /* Can not rely on /etc/services - it is not well-known port */
|
|
|
|
|
port = "60179";
|
|
|
|
|
|
|
|
|
|
// Do not need it
|
|
|
|
|
/*
|
|
|
|
|
if( ISDEC(port) )
|
|
|
|
|
server.sin_port = htons(atoi(port));
|
|
|
|
|
else if( (se = getservbyname(port, "tcp")) )
|
|
|
|
|
server.sin_port = se->s_port;
|
|
|
|
|
else
|
|
|
|
|
{ log("invalid port or service name \"%s\"", port); rc = 1; }
|
|
|
|
|
|
|
|
|
|
if( rc == 0 )
|
|
|
|
|
*/
|
|
|
|
|
//if( rc == 0 )
|
|
|
|
|
//{
|
|
|
|
|
DEB((D_INFO, "tcpip_connect: port is %s", port));
|
|
|
|
|
memset( &aihints, 0, sizeof( aihints) );
|
|
|
|
|
aihints.ai_family = AF_UNSPEC;
|
|
|
|
|
//aihints.ai_socktype = SOCK_STREAM;
|
|
|
|
|
aihints.ai_protocol = IPPROTO_TCP;
|
|
|
|
|
|
|
|
|
|
nameres = getaddrinfo ( host, port, &aihints, &ai );
|
|
|
|
|
if ( nameres != 0 )
|
|
|
|
|
{
|
|
|
|
|
rc = 1;
|
|
|
|
|
log("Resolver error for host %s, port %s: \"%s\".", host, port, gai_strerror(nameres));
|
|
|
|
|
}
|
|
|
|
|
// GetHostByName works with IPv4 only and *deprecated*
|
|
|
|
|
/*
|
|
|
|
|
if( (he = gethostbyname(host)) )
|
|
|
|
|
{
|
|
|
|
|
memcpy(&server.sin_addr, he->h_addr, he->h_length);
|
|
|
|
@ -159,12 +204,19 @@ int tcpip_connect(const char *hostname, e_tcpmode tcpmode)
|
|
|
|
|
log("unknown error while resolving host \"%s\"", host);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} */
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
if( host ) { free(host); host = NULL; }
|
|
|
|
|
DEB((D_INFO, "tcpip_connect: resolver got result!"));
|
|
|
|
|
aisave = ai;
|
|
|
|
|
|
|
|
|
|
if (rc == 0 )
|
|
|
|
|
rc = tcpip_connect2(ai);
|
|
|
|
|
|
|
|
|
|
freeaddrinfo( aisave );
|
|
|
|
|
|
|
|
|
|
return rc ? rc : tcpip_connect2(server);
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int tcpip_init(void)
|
|
|
|
|