Repository navigation
Conversation
|
Caching of the DNS lookup in the new function is wrong. |
At least the output of the function was fixed (previously it was even missing), but caching should be really fixed. I'll check if |
|
Renamed |
|
It looks to me that |
This is a preparation for a next commit which will separate IP address from hostname in JSON output. Signed-off-by: Petr Vorel <[email protected]>
Previously hostname and IP were printed together in "host" key:
$ ./builddir/ping/ping -c1 -j seznam.cz
{"bytes": 64, "host": "www.seznam.cz (77.75.77.222)", "seq": 1,
"ttl": 55, "time": "11.0"}
{"host": "seznam.cz", "transmitted": 1, "received": 1, "duplicates":
0, "corrupted": 0, "errors": 0, "loss": 0, "time": 0, "rtt": {"min":
"11.015", "avg": "11.015", "max": "11.015", "mdev": "0.000"}}
Now output has new array "host", with "arg", "rdns" and "ip" keys,
replacing the original "host" key:
{"bytes": 64, "host": {"arg": "seznam.cz", "rdns": "www.seznam.cz",
"ip": "77.75.79.222"}, "seq": 1, "ttl": 55, "time": "10.5"}
{"transmitted": 1, "received": 1, "duplicates": 0, "corrupted": 0,
"errors": 0, "loss": 0, "time": 0, "rtt": {"min": "11.384", "avg":
"11.384", "max": "11.384", "mdev": "0.000"}}
* "arg" - original argv[1] parameter (destination).
* "rdns" - getaddrinfo() reverse DNS resolution (PTR lookup), NOTE: not
added if empty due calling ping with "-n"
* "ip" - IPv4 or IPv6
That required rewrite handling hostname and reverse IP resolution.
Previously were both hostname and IP address passed to
gather_statistics() in a single string. Now function have both as
separate parameters. That required adding new function set_rdns_ip().
TODO: Ideally construct_json_host() call would be in ping/ping_common.c,
but struct pr_addr is not visible in ping/ping_common.h even ping.h is
included or typedef used.
Fixes: iputils#609
Signed-off-by: Petr Vorel <[email protected]>
| * | ||
| * Return an ascii host address optionally with a hostname (separated). | ||
| */ | ||
| struct pr_addr _pr_addr_split(struct ping_rts *rts, void *sa, |
There was a problem hiding this comment.
Hm, it should probably be using pointer:
-struct pr_addr pr_addr_split(struct ping_rts *rts, void *sa,
+struct pr_addr *pr_addr_split(struct ping_rts *rts, void *sa,
socklen_t salen)There was a problem hiding this comment.
But changing it brings a core dump on certain use case:
$ r/ping/ping -c3 -i0.01 google.com -n -j
ninja -C builddir
ninja: Entering directory `builddir'
ninja: Jobserver mode detected: -j24 --jobserver-auth=fifo:/tmp/GMfifo877643
[17/17] Linking target ping/ping
Segmentation fault (core dumped) ./builddir/ping/ping -c3 -i0.01 google.com -n -j
Problem is in json_kv_str() having a garbage in json_packet->object and json_packet->size.
diff --git ping/ping.c ping/ping.c
index 7167ab7..ec80d4c 100644
--- ping/ping.c
+++ ping/ping.c
@@ -1794,7 +1794,7 @@ int ping4_parse_reply(struct ping_rts *rts, struct socket_st *sock,
*
* Return an ascii host address optionally with a hostname (separated).
*/
-struct pr_addr _pr_addr_split(struct ping_rts *rts, void *sa,
+struct pr_addr *_pr_addr_split(struct ping_rts *rts, void *sa,
socklen_t salen, int resolve_name)
{
static struct pr_addr out = {0};
@@ -1802,7 +1802,7 @@ struct pr_addr _pr_addr_split(struct ping_rts *rts, void *sa,
static socklen_t last_salen = 0;
if (salen == last_salen && !memcmp(sa, &last_sa, salen))
- return out;
+ return &out;
memcpy(&last_sa, sa, (last_salen = salen));
@@ -1814,7 +1814,7 @@ struct pr_addr _pr_addr_split(struct ping_rts *rts, void *sa,
rts->in_pr_addr = 0;
- return out;
+ return &out;
}
/*
@@ -1822,7 +1822,7 @@ struct pr_addr _pr_addr_split(struct ping_rts *rts, void *sa,
*
* Return an ascii host address with a hostname (separated).
*/
-struct pr_addr pr_addr_split(struct ping_rts *rts, void *sa,
+struct pr_addr *pr_addr_split(struct ping_rts *rts, void *sa,
socklen_t salen)
{
return _pr_addr_split(rts, sa, salen, 1);
@@ -1855,8 +1855,7 @@ char *pr_raw_addr(struct ping_rts *rts, void *sa, socklen_t salen)
*/
char *_pr_addr(struct ping_rts *rts, void *sa, socklen_t salen, int resolve_name)
{
- struct pr_addr out = _pr_addr_split(rts, sa, salen, resolve_name);
- return pr_addr_format(&out);
+ return pr_addr_format(_pr_addr_split(rts, sa, salen, resolve_name));
}
char *pr_addr_format(struct pr_addr *out)
diff --git ping/ping.h ping/ping.h
index a96f525..02e0403 100644
--- ping/ping.h
+++ ping/ping.h
@@ -422,7 +422,7 @@ struct pr_addr {
};
char *pr_addr(struct ping_rts *rts, void *sa, socklen_t salen);
-struct pr_addr pr_addr_split(struct ping_rts *rts, void *sa, socklen_t salen);
+struct pr_addr *pr_addr_split(struct ping_rts *rts, void *sa, socklen_t salen);
char *pr_raw_addr(struct ping_rts *rts, void *sa, socklen_t salen);
char *pr_addr_format(struct pr_addr *out);
@@ -440,7 +440,7 @@ extern void status(struct ping_rts *rts);
extern void common_options(int ch);
extern int gather_statistics(struct ping_rts *rts, uint8_t *icmph, int icmplen,
int cc, uint16_t seq, int hops,
- int csfailed, struct timeval *tv, struct pr_addr out,
+ int csfailed, struct timeval *tv, struct pr_addr *out,
void (*pr_reply)(struct ping_rts *rts, uint8_t *ptr, int cc), int multicast,
int wrong_source);
extern void print_timestamp(struct ping_rts *rts);
diff --git ping/ping_common.c ping/ping_common.c
index 751d1ec..87ca71a 100644
--- ping/ping_common.c
+++ ping/ping_common.c
@@ -748,7 +748,7 @@ int main_loop(struct ping_rts *rts, ping_func_set_st *fset, socket_st *sock,
int gather_statistics(struct ping_rts *rts, uint8_t *icmph, int icmplen,
int cc, uint16_t seq, int hops,
- int csfailed, struct timeval *tv, struct pr_addr out,
+ int csfailed, struct timeval *tv, struct pr_addr *out,
void (*pr_reply)(struct ping_rts *rts, uint8_t *icmph, int cc), int multicast,
int wrong_source)
{
@@ -838,9 +838,9 @@ restamp:
// TODO: move into ping/ping_output.c
if (rts->opt_json)
- construct_json_host(rts, out.name, out.addr);
+ construct_json_host(rts, out->name, out->addr);
else
- printf(_("from %s:"), pr_addr_format(&out));
+ printf(_("from %s:"), pr_addr_format(out));
if (pr_reply)
pr_reply(rts, icmph, cc);There was a problem hiding this comment.
If you use pointer you have to allocate the memory somewhere. What about adding these fields to struct ping_rts?
There was a problem hiding this comment.
Do you mean to add struct pr_addr to struct ping_rts? The problem is that we have kind of cache of the latest getnameinfo() result. Do you want to move this cache to struct ping_rts?
Probably the from (the destination) values should be done this way (calls in ping/ping6_common.c and ping/ping.c), but we need to keep pr_addr() available for other use because error handling in ping/ping.c uses it as well (it can get parameter of other hosts than the destination).
Also I don't even know how to trigger this error code path (it'd be great to be able to mock it).
There was a problem hiding this comment.
The cache should be probably part of struct pr_addr but I haven't finished reading the code yet.
| */ | ||
| struct pr_addr _pr_addr_split(struct ping_rts *rts, void *sa, | ||
| socklen_t salen, int resolve_name) | ||
| { |
There was a problem hiding this comment.
It's a bit unusual to return ~2kB of data in a return value. Is there a reason not to store the data in the ping_rts instead?
Previously hostname and IP were printed together in "host" key:
Now output has new array "host", with "arg", "cname" and "ip" keys, replacing the original "host" key:
arg- original argv[1] parameter (destination).cname- getaddrinfo() reverse DNS resolution (PTR lookup), NOTE: not added if empty due calling ping with-nip- IPv4 or IPv6That required rewrite handling hostname and reverse IP resolution. Previously were both hostname and IP address passed to gather_statistics() in a single string. Now function have both as separate parameters. That required adding new function set_cname_ip().
Fixes: #609
@iputils/maintainers @tacerus comments are welcome. I'm sure the implementation needs cleanup and better naming of functions and parameters.