0.95.12 develop 1, a lot of systems calls changed to universal IPv4/IPv6 functions
This commit is contained in:
@@ -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
|
||||
*/
|
||||
|
125
mbcico/opentcp.c
125
mbcico/opentcp.c
@@ -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);
|
||||
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user