Merge pull request #322 from commonism/cleanups

sockaddr related cleanups
This commit is contained in:
Roger Wolff 2019-10-10 11:54:15 +02:00 committed by GitHub
commit 3bb66792d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 91 additions and 216 deletions

View File

@ -55,6 +55,7 @@ mtr_SOURCES = ui/mtr.c ui/mtr.h \
ui/select.c ui/select.h \ ui/select.c ui/select.h \
ui/utils.c ui/utils.h \ ui/utils.c ui/utils.h \
packet/cmdparse.c packet/cmdparse.h \ packet/cmdparse.c packet/cmdparse.h \
packet/sockaddr.c packet/sockaddr.h \
ui/mtr-curses.h \ ui/mtr-curses.h \
img/mtr_icon.xpm \ img/mtr_icon.xpm \
ui/mtr-gtk.h ui/mtr-gtk.h

View File

@ -424,8 +424,7 @@ static void mtr_curses_hosts(
addr = net_addr(at); addr = net_addr(at);
mpls = net_mpls(at); mpls = net_mpls(at);
addrcmp_result = addrcmp( addrcmp_result = addrcmp(addr, &ctl->unspec_addr, ctl->af);
(void *) addr, (void *) &ctl->unspec_addr, ctl->af);
if (err == 0 && addrcmp_result != 0) { if (err == 0 && addrcmp_result != 0) {
name = dns_lookup(ctl, addr); name = dns_lookup(ctl, addr);
@ -475,11 +474,9 @@ static void mtr_curses_hosts(
for (i = 0; i < MAXPATH; i++) { for (i = 0; i < MAXPATH; i++) {
addrs = net_addrs(at, i); addrs = net_addrs(at, i);
mplss = net_mplss(at, i); mplss = net_mplss(at, i);
if (addrcmp((void *) addrs, (void *) addr, ctl->af) == 0) if (addrcmp(addrs, addr, ctl->af) == 0)
continue; continue;
if (addrcmp if (addrcmp(addrs, &ctl->unspec_addr,ctl->af) == 0)
((void *) addrs, (void *) &ctl->unspec_addr,
ctl->af) == 0)
break; break;
name = dns_lookup(ctl, addrs); name = dns_lookup(ctl, addrs);
@ -645,7 +642,7 @@ static void mtr_curses_graph(
} }
if (err == 0 if (err == 0
&& addrcmp((void *) addr, (void *) &ctl->unspec_addr, ctl->af)) { && addrcmp(addr, &ctl->unspec_addr, ctl->af)) {
if (!net_up(at)) { if (!net_up(at)) {
attron(A_BOLD); attron(A_BOLD);

View File

@ -41,6 +41,7 @@
#include "dns.h" #include "dns.h"
#include "net.h" #include "net.h"
#include "utils.h" #include "utils.h"
#include "packet/sockaddr.h"
struct dns_results { struct dns_results {
ip_t ip; ip_t ip;
@ -105,7 +106,7 @@ static struct dns_results *findip(
struct dns_results *t; struct dns_results *t;
for (t = results; t; t = t->next) { for (t = results; t; t = t->next) {
if (addrcmp((void *) ip, (void *) &t->ip, ctl->af) == 0) if (addrcmp(ip, &t->ip, ctl->af) == 0)
return t; return t;
} }
@ -117,22 +118,9 @@ static void set_sockaddr_ip(
struct sockaddr_storage *sa, struct sockaddr_storage *sa,
ip_t * ip) ip_t * ip)
{ {
struct sockaddr_in *sa_in;
struct sockaddr_in6 *sa_in6;
memset(sa, 0, sizeof(struct sockaddr_storage)); memset(sa, 0, sizeof(struct sockaddr_storage));
switch (ctl->af) { sa->ss_family = ctl->af;
case AF_INET: memcpy(sockaddr_addr_offset(sa), ip, sockaddr_addr_size(sa));
sa_in = (struct sockaddr_in *) sa;
sa_in->sin_family = ctl->af;
addrcpy((void *) &sa_in->sin_addr, (void *) ip, ctl->af);
break;
case AF_INET6:
sa_in6 = (struct sockaddr_in6 *) sa;
sa_in6->sin6_family = ctl->af;
addrcpy((void *) &sa_in6->sin6_addr, (void *) ip, ctl->af);
break;
}
} }
void dns_open( void dns_open(

View File

@ -507,7 +507,7 @@ static void update_tree_row(
char str[256] = "???", *name = str; char str[256] = "???", *name = str;
addr = net_addr(row); addr = net_addr(row);
if (addrcmp((void *) addr, (void *) &ctl->unspec_addr, ctl->af)) { if (addrcmp(addr, &ctl->unspec_addr, ctl->af)) {
if ((name = dns_lookup(ctl, addr))) { if ((name = dns_lookup(ctl, addr))) {
if (ctl->show_ips) { if (ctl->show_ips) {
snprintf(str, sizeof(str), "%s (%s)", name, snprintf(str, sizeof(str), "%s (%s)", name,

263
ui/net.c
View File

@ -39,17 +39,13 @@
#include "display.h" #include "display.h"
#include "dns.h" #include "dns.h"
#include "utils.h" #include "utils.h"
#include "packet/sockaddr.h"
#define MinSequence 33000 #define MinSequence 33000
#define MaxSequence 65536 #define MaxSequence 65536
static int packetsize; /* packet size used by ping */ static int packetsize; /* packet size used by ping */
static void sockaddrtop(
struct sockaddr *saddr,
char *strptr,
size_t len);
struct nethost { struct nethost {
ip_t addr; ip_t addr;
ip_t addrs[MAXPATH]; /* for multi paths byMin */ ip_t addrs[MAXPATH]; /* for multi paths byMin */
@ -88,26 +84,13 @@ static struct nethost host[MaxHost];
static struct sequence sequence[MaxSequence]; static struct sequence sequence[MaxSequence];
static struct packet_command_pipe_t packet_command_pipe; static struct packet_command_pipe_t packet_command_pipe;
#ifdef ENABLE_IPV6
static struct sockaddr_storage sourcesockaddr_struct; static struct sockaddr_storage sourcesockaddr_struct;
static struct sockaddr_storage remotesockaddr_struct; static struct sockaddr_storage remotesockaddr_struct;
static struct sockaddr_in6 *ssa6 =
(struct sockaddr_in6 *) &sourcesockaddr_struct;
static struct sockaddr_in6 *rsa6 =
(struct sockaddr_in6 *) &remotesockaddr_struct;
#else
static struct sockaddr_in sourcesockaddr_struct;
static struct sockaddr_in remotesockaddr_struct;
#endif
static struct sockaddr *sourcesockaddr = static struct sockaddr *sourcesockaddr =
(struct sockaddr *) &sourcesockaddr_struct; (struct sockaddr *) &sourcesockaddr_struct;
static struct sockaddr *remotesockaddr = static struct sockaddr *remotesockaddr =
(struct sockaddr *) &remotesockaddr_struct; (struct sockaddr *) &remotesockaddr_struct;
static struct sockaddr_in *ssa4 =
(struct sockaddr_in *) &sourcesockaddr_struct;
static struct sockaddr_in *rsa4 =
(struct sockaddr_in *) &remotesockaddr_struct;
static ip_t *sourceaddress; static ip_t *sourceaddress;
static ip_t *remoteaddress; static ip_t *remoteaddress;
@ -124,6 +107,14 @@ static char localaddr[INET_ADDRSTRLEN];
static int batch_at = 0; static int batch_at = 0;
static int numhosts = 10; static int numhosts = 10;
#define host_addr_cmp(index, other, af) \
addrcmp((void *) &(host[(index)].addr), (void *) (other), (af))
#define host_addrs_cmp(index, path, other, af) \
addrcmp((void *) &(host[(index)].addrs[path]), (void *) (other), (af))
/* return the number of microseconds to wait before sending the next /* return the number of microseconds to wait before sending the next
ping */ ping */
int calc_deltatime( int calc_deltatime(
@ -215,6 +206,7 @@ static int mark_sequence_complete(
Record the round trip time and address of the responding host. Record the round trip time and address of the responding host.
*/ */
static void net_process_ping( static void net_process_ping(
struct mtr_ctl *ctl, struct mtr_ctl *ctl,
int seq, int seq,
@ -232,94 +224,93 @@ static void net_process_ping(
#else #else
char addrcopy[sizeof(struct in_addr)]; char addrcopy[sizeof(struct in_addr)];
#endif #endif
struct nethost *nh = NULL;
addrcpy((void *) &addrcopy, (char *) addr, ctl->af); memcpy(&addrcopy, addr, sockaddr_addr_size(sourcesockaddr));
index = mark_sequence_complete(seq); index = mark_sequence_complete(seq);
if (index < 0) { if (index < 0) {
return; return;
} }
nh = &host[index];
nh->err = err;
host[index].err = err;
if (addrcmp((void *) &(host[index].addr),
(void *) &ctl->unspec_addr, ctl->af) == 0) { if (addrcmp(&nh->addr, &ctl->unspec_addr, ctl->af) == 0) {
/* should be out of if as addr can change */ /* should be out of if as addr can change */
addrcpy((void *) &(host[index].addr), addrcopy, ctl->af); memcpy(&nh->addr, addrcopy, sockaddr_addr_size(sourcesockaddr));
host[index].mpls = *mpls; nh->mpls = *mpls;
display_rawhost(ctl, index, (void *) &(host[index].addr)); display_rawhost(ctl, index, (void *) &(nh->addr));
/* multi paths */ /* multi paths */
addrcpy((void *) &(host[index].addrs[0]), addrcopy, ctl->af); memcpy(&nh->addrs[0], addrcopy, sockaddr_addr_size(sourcesockaddr));
host[index].mplss[0] = *mpls; nh->mplss[0] = *mpls;
} else { } else {
for (i = 0; i < MAXPATH;) { for (i = 0; i < MAXPATH;) {
if (addrcmp if (addrcmp(&nh->addrs[i], &addrcopy, ctl->af) == 0 ||
((void *) &(host[index].addrs[i]), (void *) &addrcopy, addrcmp(&nh->addrs[i], &ctl->unspec_addr, ctl->af) == 0) {
ctl->af) == 0
|| addrcmp((void *) &(host[index].addrs[i]),
(void *) &ctl->unspec_addr, ctl->af) == 0) {
break; break;
} }
i++; i++;
} }
if (addrcmp((void *) &(host[index].addrs[i]), addrcopy, ctl->af) != if (addrcmp(&nh->addrs[i], &addrcopy, ctl->af) != 0 && i < MAXPATH) {
0 && i < MAXPATH) { memcpy(&nh->addrs[i], addrcopy, sockaddr_addr_size(sourcesockaddr));
addrcpy((void *) &(host[index].addrs[i]), addrcopy, ctl->af);
host[index].mplss[i] = *mpls; nh->mplss[i] = *mpls;
display_rawhost(ctl, index, (void *) &(host[index].addrs[i])); display_rawhost(ctl, index, (void *) &(nh->addrs[i]));
} }
} }
host[index].jitter = totusec - host[index].last; nh->jitter = totusec - nh->last;
if (host[index].jitter < 0) { if (nh->jitter < 0) {
host[index].jitter = -host[index].jitter; nh->jitter = -nh->jitter;
} }
host[index].last = totusec; nh->last = totusec;
if (host[index].returned < 1) { if (nh->returned < 1) {
host[index].best = host[index].worst = host[index].gmean = totusec; nh->best = nh->worst = nh->gmean = totusec;
host[index].avg = host[index].ssd = 0; nh->avg = nh->ssd = 0;
host[index].jitter = host[index].jworst = host[index].jinta = 0; nh->jitter = nh->jworst = nh->jinta = 0;
} }
if (totusec < host[index].best) { if (totusec < nh->best) {
host[index].best = totusec; nh->best = totusec;
} }
if (totusec > host[index].worst) { if (totusec > nh->worst) {
host[index].worst = totusec; nh->worst = totusec;
} }
if (host[index].jitter > host[index].jworst) { if (nh->jitter > nh->jworst) {
host[index].jworst = host[index].jitter; nh->jworst = nh->jitter;
} }
host[index].returned++; nh->returned++;
oldavg = host[index].avg; oldavg = nh->avg;
host[index].avg += (totusec - oldavg + .0) / host[index].returned; nh->avg += (totusec - oldavg + .0) / nh->returned;
host[index].ssd += nh->ssd +=
(totusec - oldavg + .0) * (totusec - host[index].avg); (totusec - oldavg + .0) * (totusec - nh->avg);
oldjavg = host[index].javg; oldjavg = nh->javg;
host[index].javg += nh->javg +=
(host[index].jitter - oldjavg) / host[index].returned; (nh->jitter - oldjavg) / nh->returned;
/* below algorithm is from rfc1889, A.8 */ /* below algorithm is from rfc1889, A.8 */
host[index].jinta += nh->jinta +=
host[index].jitter - ((host[index].jinta + 8) >> 4); nh->jitter - ((nh->jinta + 8) >> 4);
if (host[index].returned > 1) { if (nh->returned > 1) {
host[index].gmean = nh->gmean =
pow((double) host[index].gmean, pow((double) nh->gmean,
(host[index].returned - 1.0) / host[index].returned) (nh->returned - 1.0) / nh->returned)
* pow((double) totusec, 1.0 / host[index].returned); * pow((double) totusec, 1.0 / nh->returned);
} }
host[index].sent = 0; nh->sent = 0;
host[index].up = 1; nh->up = 1;
host[index].transit = 0; nh->transit = 0;
net_save_return(index, sequence[seq].saved_seq, totusec); net_save_return(index, sequence[seq].saved_seq, totusec);
display_rawping(ctl, index, totusec, seq); display_rawping(ctl, index, totusec, seq);
@ -475,8 +466,7 @@ int net_max(
max = 0; max = 0;
for (at = 0; at < ctl->maxTTL; at++) { for (at = 0; at < ctl->maxTTL; at++) {
if (addrcmp((void *) &(host[at].addr), if (host_addr_cmp(at , remoteaddress, ctl->af) == 0) {
(void *) remoteaddress, ctl->af) == 0) {
return at + 1; return at + 1;
} else if (host[at].err != 0) { } else if (host[at].err != 0) {
/* /*
@ -485,8 +475,7 @@ int net_max(
final hop. final hop.
*/ */
return at + 1; return at + 1;
} else if (addrcmp((void *) &(host[at].addr), } else if (host_addr_cmp(at, &ctl->unspec_addr, ctl->af) != 0) {
(void *) &ctl->unspec_addr, ctl->af) != 0) {
max = at + 2; max = at + 2;
} }
} }
@ -575,9 +564,7 @@ int net_send_batch(
net_send_query(ctl, batch_at, abs(packetsize)); net_send_query(ctl, batch_at, abs(packetsize));
for (i = ctl->fstTTL - 1; i < batch_at; i++) { for (i = ctl->fstTTL - 1; i < batch_at; i++) {
if (addrcmp if (host_addr_cmp(i, &ctl->unspec_addr, ctl->af) == 0)
((void *) &(host[i].addr), (void *) &ctl->unspec_addr,
ctl->af) == 0)
n_unknown++; n_unknown++;
/* The second condition in the next "if" statement was added in mtr-0.56, /* The second condition in the next "if" statement was added in mtr-0.56,
@ -585,14 +572,12 @@ int net_send_batch(
hosts. Removed in 0.65. hosts. Removed in 0.65.
If the line proves necessary, it should at least NOT trigger that line If the line proves necessary, it should at least NOT trigger that line
when host[i].addr == 0 */ when host[i].addr == 0 */
if ((addrcmp((void *) &(host[i].addr), if (host_addr_cmp(i, remoteaddress, ctl->af) == 0)
(void *) remoteaddress, ctl->af) == 0))
n_unknown = MaxHost; /* Make sure we drop into "we should restart" */ n_unknown = MaxHost; /* Make sure we drop into "we should restart" */
} }
if ( /* success in reaching target */ if ( /* success in reaching target */
(addrcmp((void *) &(host[batch_at].addr), (host_addr_cmp(batch_at, remoteaddress, ctl->af) == 0) ||
(void *) remoteaddress, ctl->af) == 0) ||
/* fail in consecutive maxUnknown (firewall?) */ /* fail in consecutive maxUnknown (firewall?) */
(n_unknown > ctl->maxUnknown) || (n_unknown > ctl->maxUnknown) ||
/* or reach limit */ /* or reach limit */
@ -690,8 +675,6 @@ static void net_find_local_address(
int udp_socket; int udp_socket;
int addr_length; int addr_length;
struct sockaddr_storage remote_sockaddr; struct sockaddr_storage remote_sockaddr;
struct sockaddr_in *remote4;
struct sockaddr_in6 *remote6;
udp_socket = udp_socket =
socket(remotesockaddr->sa_family, SOCK_DGRAM, IPPROTO_UDP); socket(remotesockaddr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
@ -703,24 +686,11 @@ static void net_find_local_address(
We need to set the port to a non-zero value for the connect We need to set the port to a non-zero value for the connect
to succeed. to succeed.
*/ */
if (remotesockaddr->sa_family == AF_INET6) { memcpy(&remote_sockaddr, &remotesockaddr_struct, sockaddr_size(&remotesockaddr_struct));
#ifdef ENABLE_IPV6 *sockaddr_port_offset(&remote_sockaddr) = htons(1);
addr_length = sizeof(struct sockaddr_in6);
memcpy(&remote_sockaddr, rsa6, addr_length);
remote6 = (struct sockaddr_in6 *) &remote_sockaddr;
remote6->sin6_port = htons(1);
#endif
} else {
addr_length = sizeof(struct sockaddr_in);
memcpy(&remote_sockaddr, rsa4, addr_length);
remote4 = (struct sockaddr_in *) &remote_sockaddr;
remote4->sin_port = htons(1);
}
if (connect if (connect
(udp_socket, (struct sockaddr *) &remote_sockaddr, addr_length)) { (udp_socket, (struct sockaddr *) &remote_sockaddr, sockaddr_size(&remote_sockaddr))) {
#ifdef __linux__ #ifdef __linux__
/* Linux doesn't require source address, so we can support /* Linux doesn't require source address, so we can support
* a case when mtr is run against unreachable host (that can become * a case when mtr is run against unreachable host (that can become
@ -739,7 +709,7 @@ static void net_find_local_address(
error(EXIT_FAILURE, errno, "local address determination failed"); error(EXIT_FAILURE, errno, "local address determination failed");
} }
sockaddrtop(sourcesockaddr, localaddr, sizeof(localaddr)); inet_ntop(sourcesockaddr->sa_family, sockaddr_addr_offset(sourcesockaddr), localaddr, sizeof(localaddr));
close(udp_socket); close(udp_socket);
} }
@ -759,32 +729,18 @@ int net_open(
net_reset(ctl); net_reset(ctl);
remotesockaddr->sa_family = hostent->h_addrtype; remotesockaddr->sa_family = sourcesockaddr->sa_family = hostent->h_addrtype;
memcpy(sockaddr_addr_offset(remotesockaddr), hostent->h_addr, sockaddr_addr_size(remotesockaddr));
switch (hostent->h_addrtype) { sourceaddress = sockaddr_addr_offset(sourcesockaddr);
case AF_INET: remoteaddress = sockaddr_addr_offset(remotesockaddr);
addrcpy((void *) &(rsa4->sin_addr), hostent->h_addr, AF_INET);
sourceaddress = (ip_t *) & (ssa4->sin_addr);
remoteaddress = (ip_t *) & (rsa4->sin_addr);
break;
#ifdef ENABLE_IPV6
case AF_INET6:
addrcpy((void *) &(rsa6->sin6_addr), hostent->h_addr, AF_INET6);
sourceaddress = (ip_t *) & (ssa6->sin6_addr);
remoteaddress = (ip_t *) & (rsa6->sin6_addr);
break;
#endif
default:
error(EXIT_FAILURE, 0, "net_open bad address type");
}
if (ctl->InterfaceAddress) { if (ctl->InterfaceAddress) {
net_validate_interface_address(ctl->af, ctl->InterfaceAddress); net_validate_interface_address(ctl->af, ctl->InterfaceAddress);
} else if (ctl->InterfaceName) { } else if (ctl->InterfaceName) {
net_find_interface_address_from_name( net_find_interface_address_from_name(
&sourcesockaddr_struct, ctl->af, ctl->InterfaceName); &sourcesockaddr_struct, ctl->af, ctl->InterfaceName);
inet_ntop(sourcesockaddr->sa_family, sockaddr_addr_offset(sourcesockaddr), localaddr, sizeof(localaddr));
sockaddrtop(sourcesockaddr, localaddr, sizeof(localaddr));
} else { } else {
net_find_local_address(); net_find_local_address();
} }
@ -804,21 +760,8 @@ void net_reopen(
} }
remotesockaddr->sa_family = addr->h_addrtype; remotesockaddr->sa_family = addr->h_addrtype;
addrcpy((void *) remoteaddress, addr->h_addr, addr->h_addrtype); memcpy(remoteaddress, addr->h_addr, sockaddr_addr_size(remotesockaddr));
memcpy(sockaddr_addr_offset(remotesockaddr), addr->h_addr, sockaddr_addr_size(remotesockaddr));
switch (addr->h_addrtype) {
case AF_INET:
addrcpy((void *) &(rsa4->sin_addr), addr->h_addr, AF_INET);
break;
#ifdef ENABLE_IPV6
case AF_INET6:
addrcpy((void *) &(rsa6->sin6_addr), addr->h_addr, AF_INET6);
break;
#endif
default:
error(EXIT_FAILURE, 0, "net_reopen bad address type");
}
net_reset(ctl); net_reset(ctl);
net_send_batch(ctl); net_send_batch(ctl);
} }
@ -907,41 +850,10 @@ void net_save_return(
host[at].saved[idx] = ms; host[at].saved[idx] = ms;
} }
/* Similar to inet_ntop but uses a sockaddr as it's argument. */
static void sockaddrtop(
struct sockaddr *saddr,
char *strptr,
size_t len)
{
struct sockaddr_in *sa4;
#ifdef ENABLE_IPV6
struct sockaddr_in6 *sa6;
#endif
switch (saddr->sa_family) {
case AF_INET:
sa4 = (struct sockaddr_in *) saddr;
xstrncpy(strptr, inet_ntoa(sa4->sin_addr), len - 1);
strptr[len - 1] = '\0';
return;
#ifdef ENABLE_IPV6
case AF_INET6:
sa6 = (struct sockaddr_in6 *) saddr;
inet_ntop(sa6->sin6_family, &(sa6->sin6_addr), strptr, len);
return;
#endif
default:
error(0, 0, "sockaddrtop unknown address type");
strptr[0] = '\0';
return;
}
}
/* Address comparison. */ /* Address comparison. */
int addrcmp( int addrcmp(
char *a, void *a,
char *b, void *b,
int family) int family)
{ {
int rc = -1; int rc = -1;
@ -960,25 +872,6 @@ int addrcmp(
return rc; return rc;
} }
/* Address copy. */
void addrcpy(
char *a,
char *b,
int family)
{
switch (family) {
case AF_INET:
memcpy(a, b, sizeof(struct in_addr));
break;
#ifdef ENABLE_IPV6
case AF_INET6:
memcpy(a, b, sizeof(struct in6_addr));
break;
#endif
}
}
/* for GTK frontend */ /* for GTK frontend */
void net_harvest_fds( void net_harvest_fds(
struct mtr_ctl *ctl) struct mtr_ctl *ctl)

View File

@ -117,12 +117,8 @@ extern void net_save_return(
int ms); int ms);
extern int addrcmp( extern int addrcmp(
char *a, void *a,
char *b, void *b,
int af);
extern void addrcpy(
char *a,
char *b,
int af); int af);
extern void net_add_fds( extern void net_add_fds(

View File

@ -92,7 +92,7 @@ void split_redraw(
*/ */
for (at = 0; at < max; at++) { for (at = 0; at < max; at++) {
addr = net_addr(at); addr = net_addr(at);
if (addrcmp((void *) addr, (void *) &ctl->unspec_addr, ctl->af)) { if (addrcmp(addr, &ctl->unspec_addr, ctl->af)) {
char str[256], *name; char str[256], *name;
if (!(name = dns_lookup(ctl, addr))) if (!(name = dns_lookup(ctl, addr)))
name = strlongip(ctl, addr); name = strlongip(ctl, addr);