0.95.12 develop 1, a lot of systems calls changed to universal IPv4/IPv6 functions

This commit is contained in:
Michiel Broek
2011-01-29 13:03:22 +01:00
parent 20e7a332c9
commit 8460ee977d
15 changed files with 419 additions and 318 deletions

View File

@@ -1,11 +1,10 @@
/*****************************************************************************
*
* $Id: binkp.c,v 1.135 2007/08/26 14:02:28 mbse Exp $
* Purpose .................: Fidonet binkp protocol
* Binkp protocol copyright : Dima Maloff.
*
*****************************************************************************
* Copyright (C) 1997-2007
* Copyright (C) 1997-2011
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
@@ -72,7 +71,7 @@ extern char *tempinbound;
extern char *ttystat[];
extern int Loaded;
extern pid_t mypid;
extern struct sockaddr_in peeraddr;
extern struct sockaddr_in peeraddr4;
extern int most_debug;
extern int laststat;
extern int crashme;
@@ -693,7 +692,7 @@ SM_STATE(WaitConn)
SM_ERROR;
}
if (!CFG.NoMD5 && ((bp.MD_Challenge = MD_getChallenge(NULL, &peeraddr)) != NULL)) {
if (!CFG.NoMD5 && ((bp.MD_Challenge = MD_getChallenge(NULL, &peeraddr4)) != NULL)) {
/*
* Answering site MUST send CRAM message as very first M_NUL
*/

View File

@@ -1,10 +1,9 @@
/*****************************************************************************
*
* $Id: opentcp.c,v 1.27 2006/07/17 18:54:16 mbse Exp $
* Purpose ...............: Fidonet mailer
*
*****************************************************************************
* Copyright (C) 1997-2005
* Copyright (C) 1997-2011
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
@@ -59,26 +58,32 @@ static int tcp_is_open = FALSE;
/* opentcp() was rewritten by Martin Junius */
int opentcp(char *name)
/*
* Parameter may be:
* host.example.com
* host.example.com:portnumber
* host.example.com:portname
*/
int opentcp(char *servname)
{
struct servent *se;
struct hostent *he;
struct sockaddr_in server;
int a1, a2, a3, a4, GotPort = FALSE;
char *errmsg, *portname;
short portnum;
int rc, GotPort = FALSE;
char *portname, *ipver = NULL, servport[20], ipstr[INET6_ADDRSTRLEN];
u_int16_t portnum;
struct addrinfo hints, *res=NULL, *p;
Syslog('+', "Open TCP connection to \"%s\"", MBSE_SS(name));
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
Syslog('+', "Open TCP connection to \"%s\"", MBSE_SS(servname));
tcp_is_open = FALSE;
server.sin_family = AF_INET;
/*
* Get port number from name argument if there is a : part
*/
if ((portname = strchr(name,':'))) {
if ((portname = strchr(servname,':'))) {
*portname++='\0';
if ((portnum = atoi(portname))) {
server.sin_port=htons(portnum);
@@ -112,23 +117,16 @@ int opentcp(char *name)
default: server.sin_port = htons(FIDOPORT);
}
}
snprintf(servport, 19, "%d", ntohs(server.sin_port));
/*
* Get IP address for the hostname
* Lookup hostname and return list of IPv4 and or IPv6 addresses.
*/
if (sscanf(name,"%d.%d.%d.%d",&a1,&a2,&a3,&a4) == 4)
server.sin_addr.s_addr = inet_addr(name);
else if ((he = gethostbyname(name)))
memcpy(&server.sin_addr,he->h_addr,he->h_length);
else {
switch (h_errno) {
case HOST_NOT_FOUND: errmsg = (char *)"Authoritative: Host not found"; break;
case TRY_AGAIN: errmsg = (char *)"Non-Authoritive: Host not found"; break;
case NO_RECOVERY: errmsg = (char *)"Non recoverable errors"; break;
case NO_ADDRESS: errmsg = (char *)"Host has no IP address"; break;
default: errmsg = (char *)"Unknown error"; break;
}
Syslog('+', "No IP address for %s: %s\n", name, errmsg);
if ((rc = getaddrinfo(servname, servport, &hints, &res))) {
if (rc == EAI_SYSTEM)
WriteError("opentcp: getaddrinfo() failed");
else
Syslog('+', "Host not found --> %s\n", gai_strerror(rc));
return -1;
}
@@ -142,29 +140,68 @@ int opentcp(char *name)
close(0);
close(1);
if ((fd = socket(AF_INET,SOCK_STREAM,0)) != 0) {
WriteError("$Cannot create socket (got %d, expected 0)", fd);
open("/dev/null",O_RDONLY);
open("/dev/null",O_WRONLY);
return -1;
/*
* In case a node has a A and AAAA dns entry, we now have a list of
* possible connections to make, we try them until we succeed.
* Most likely, the first one is ok.
* Nice that this also works for clustered hosts, not that we will
* find any in fidonet, but .....
*/
for (p = res; p != NULL; p = p->ai_next) {
void *addr;
rc = 0;
if (p->ai_family == AF_INET) {
struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
addr = &(ipv4->sin_addr);
ipver = (char *)"IPv4";
} else {
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
addr = &(ipv6->sin6_addr);
ipver = (char *)"IPv6";
}
inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
Syslog('+', "Trying %s %s port %s", ipver, ipstr, servport);
if ((fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) != 0) {
if (fd > 0)
WriteError("Cannot create socket (got %d, expected 0)", fd);
else
WriteError("$Cannot create socket");
rc = -1;
} else {
if (dup(fd) != 1) {
WriteError("$Cannot dup socket");
rc = -1;
} else {
clearerr(stdin);
clearerr(stdout);
if (connect(fd, p->ai_addr, p->ai_addrlen) == -1) {
Syslog('+', "$Cannot connect %s port %s", ipstr, servport);
close(fd+1); /* close duped socket */
close(fd); /* close this socket */
rc = -1;
} else {
/*
* Connected, leave this loop
*/
break;
}
}
}
}
if (dup(fd) != 1) {
WriteError("$Cannot dup socket");
open("/dev/null",O_WRONLY);
return -1;
}
clearerr(stdin);
clearerr(stdout);
if (connect(fd,(struct sockaddr *)&server,sizeof(server)) == -1) {
Syslog('+', "$Cannot connect %s",inet_ntoa(server.sin_addr));
if (rc == -1) {
open("/dev/null", O_RDONLY);
open("/dev/null", O_WRONLY);
freeaddrinfo(res);
return -1;
}
f_flags=0;
Syslog('+', "Established %s/TCP connection with %s, port %d",
Syslog('+', "Established %s/TCP %s connection with %s, port %s",
(tcp_mode == TCPMODE_IFC) ? "IFC":(tcp_mode == TCPMODE_ITN) ?"ITN":(tcp_mode == TCPMODE_IBN) ? "IBN":"Unknown",
inet_ntoa(server.sin_addr), (int)ntohs(server.sin_port));
ipver, ipstr, servport);
freeaddrinfo(res);
c_start = time(NULL);
carrier = TRUE;
tcp_is_open = TRUE;
@@ -181,7 +218,7 @@ void closetcp(void)
if (!tcp_is_open)
return;
shutdown(fd, 2);
shutdown(fd, SHUT_RDWR);
signal(SIGHUP, SIG_IGN);
signal(SIGPIPE, SIG_IGN);

View File

@@ -1,10 +1,9 @@
/*****************************************************************************
*
* $Id: session.c,v 1.37 2007/10/14 13:15:34 mbse Exp $
* Purpose ...............: Fidonet mailer
*
*****************************************************************************
* Copyright (C) 1997-2007
* Copyright (C) 1997-2011
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
@@ -63,7 +62,8 @@ int session_state = STATE_BAD;
static char *data=NULL;
struct sockaddr_in peeraddr;
struct sockaddr_in peeraddr4;
struct sockaddr_in6 peeraddr6;
char *typestr(int);
@@ -103,6 +103,17 @@ void geoiplookup(GeoIP* gi, char *hostname, int i)
Syslog('+', "GeoIP location: %s, %s %s\n", country_name, country_code, country_continent);
}
}
if (GEOIP_COUNTRY_EDITION_V6 == i) {
country_id = GeoIP_id_by_name_v6(gi, hostname);
country_code = GeoIP_country_code[country_id];
country_name = GeoIP_country_name[country_id];
country_continent = GeoIP_country_continent[country_id];
if (country_code == NULL) {
Syslog('+', "%s: IP Address not found\n", GeoIPDBDescription[i]);
} else {
Syslog('+', "GeoIP location: %s, %s %s\n", country_name, country_code, country_continent);
}
}
}
#endif
@@ -111,12 +122,12 @@ void geoiplookup(GeoIP* gi, char *hostname, int i)
int session(faddr *a, node *nl, int role, int tp, char *dt)
{
int rc = MBERR_OK;
socklen_t addrlen = sizeof(struct sockaddr_in);
socklen_t addrlen = sizeof(struct sockaddr_in6);
fa_list *tmpl;
int Fdo = -1, input_pipe[2], output_pipe[2];
pid_t ipid, opid;
char str[INET6_ADDRSTRLEN];
#ifdef HAVE_GEOIP_H
char *hostname;
GeoIP *gi;
#endif
@@ -124,18 +135,26 @@ int session(faddr *a, node *nl, int role, int tp, char *dt)
session_type = tp;
nlent = nl;
if (getpeername(0,(struct sockaddr*)&peeraddr,&addrlen) == 0) {
Syslog('s', "TCP connection: len=%d, family=%hd, port=%hu, addr=%s",
addrlen,peeraddr.sin_family, peeraddr.sin_port, inet_ntoa(peeraddr.sin_addr));
if (getpeername(0,(struct sockaddr *)&peeraddr6, &addrlen) == 0) {
/*
* Copy IPv4 part into the IPv6 structure. There has to be a better way
* to deal with mixed incoming sockets ???
*/
memcpy(&peeraddr4, &peeraddr6, sizeof(struct sockaddr_in));
if ((peeraddr6.sin6_family == AF_INET6) && (inet_ntop(AF_INET6, &peeraddr6.sin6_addr, str, sizeof(str)))) {
Syslog('s', "IPv6 TCP connection: len=%d, port=%hu, addr=%s", addrlen, ntohs(peeraddr6.sin6_port), str);
} else if ((peeraddr4.sin_family == AF_INET) && (inet_ntop(AF_INET, &peeraddr4.sin_addr, str, sizeof(str)))) {
Syslog('s', "IPv4 TCP connection: len=%d, port=%hu, addr=%s", addrlen, ntohs(peeraddr4.sin_port), str);
}
if (role == 0) {
if (tcp_mode == TCPMODE_IBN) {
Syslog('+', "Incoming IBN/TCP connection from %s", inet_ntoa(peeraddr.sin_addr));
Syslog('+', "Incoming IBN/TCP connection from %s", str);
IsDoing("Incoming IBN/TCP");
} else if (tcp_mode == TCPMODE_IFC) {
Syslog('+', "Incoming IFC/TCP connection from %s", inet_ntoa(peeraddr.sin_addr));
Syslog('+', "Incoming IFC/TCP connection from %s", str);
IsDoing("Incoming IFC/TCP");
} else if (tcp_mode == TCPMODE_ITN) {
Syslog('+', "Incoming ITN/TCP connection from %s", inet_ntoa(peeraddr.sin_addr));
Syslog('+', "Incoming ITN/TCP connection from %s", str);
IsDoing("Incoming ITN/TCP");
} else if (tcp_mode == TCPMODE_NONE) {
WriteError("Unknown TCP connection, parameter missing");
@@ -145,13 +164,21 @@ int session(faddr *a, node *nl, int role, int tp, char *dt)
session_flags |= SESSION_TCP;
#ifdef HAVE_GEOIP_H
hostname = inet_ntoa(peeraddr.sin_addr);
_GeoIP_setup_dbfilename();
if (GeoIP_db_avail(GEOIP_COUNTRY_EDITION)) {
if ((gi = GeoIP_open_type(GEOIP_COUNTRY_EDITION, GEOIP_STANDARD)) != NULL) {
geoiplookup(gi, hostname, GEOIP_COUNTRY_EDITION);
if (peeraddr6.sin6_family == AF_INET6) {
if (GeoIP_db_avail(GEOIP_COUNTRY_EDITION_V6)) {
if ((gi = GeoIP_open_type(GEOIP_COUNTRY_EDITION_V6, GEOIP_STANDARD)) != NULL) {
geoiplookup(gi, str, GEOIP_COUNTRY_EDITION_V6);
}
GeoIP_delete(gi);
}
} else if (peeraddr6.sin6_family == AF_INET) {
if (GeoIP_db_avail(GEOIP_COUNTRY_EDITION)) {
if ((gi = GeoIP_open_type(GEOIP_COUNTRY_EDITION, GEOIP_STANDARD)) != NULL) {
geoiplookup(gi, str, GEOIP_COUNTRY_EDITION);
}
GeoIP_delete(gi);
}
GeoIP_delete(gi);
}
#endif
@@ -163,7 +190,6 @@ int session(faddr *a, node *nl, int role, int tp, char *dt)
* since it's now on stadin and stdout.
*/
Fdo = dup(0);
Syslog('s', "session: new socket %d", Fdo);
/*
* Close stdin and stdout so that when we create the pipes to