Explanation
We can determine the public IP address through DNS with dig
(the DNS lookup utility from BIND), this lets us try out both UDP (with the +notcp
option) and TCP (+tcp
option), leaving only ICMP behind. However, we can try sending all these queries to multiple independent destination IPv4 and IPv6 addresses, making it more likely that the load-balancing of the connection will take place, returning more unique responses.
It would appear that the positioning of the -4
and -6
options with dig
might also be handled differently depending on the order of the arguments — if positioned right after dig
before the @
specifier, then it's enforced as a hard requirement; if positioned past the @
specifier and/or as a final argument, then it's enforced as a soft requirement (IPv4 will be used if IPv6 connectivity is missing); the snippet below uses it as a soft requirement to avoid having to implement error-handling.
We can use GNU Parallel to mix-and-match several commands and options that are at stake here.
Solution
Here's the full solution:
parallel -kj16 dig -t txt o-o.myaddr.l.google.com +short \
::: @ns{1,2,3,4}.google.com ::: -4 -6 ::: +notcp +tcp
Here's the same snippet as a single line:
parallel -kj16 dig -t txt o-o.myaddr.l.google.com +short ::: @ns{1,2,3,4}.google.com ::: -4 -6 ::: +notcp +tcp
Here's the same snippet SO inline:
parallel -kj16 dig -t txt o-o.myaddr.l.google.com +short ::: @ns{1,2,3,4}.google.com ::: -4 -6 ::: +notcp +tcp
Testing
Here's a demonstration of what the above parallel
invocation would work to accomplish:
% parallel -k echo dig -t txt o-o.myaddr.l.google.com +short \
? ::: @ns{1,2,3,4}.google.com ::: -4 -6 ::: +notcp +tcp
dig -t txt o-o.myaddr.l.google.com +short @ns1.google.com -4 +notcp
dig -t txt o-o.myaddr.l.google.com +short @ns1.google.com -4 +tcp
dig -t txt o-o.myaddr.l.google.com +short @ns1.google.com -6 +notcp
dig -t txt o-o.myaddr.l.google.com +short @ns1.google.com -6 +tcp
dig -t txt o-o.myaddr.l.google.com +short @ns2.google.com -4 +notcp
dig -t txt o-o.myaddr.l.google.com +short @ns2.google.com -4 +tcp
dig -t txt o-o.myaddr.l.google.com +short @ns2.google.com -6 +notcp
dig -t txt o-o.myaddr.l.google.com +short @ns2.google.com -6 +tcp
dig -t txt o-o.myaddr.l.google.com +short @ns3.google.com -4 +notcp
dig -t txt o-o.myaddr.l.google.com +short @ns3.google.com -4 +tcp
dig -t txt o-o.myaddr.l.google.com +short @ns3.google.com -6 +notcp
dig -t txt o-o.myaddr.l.google.com +short @ns3.google.com -6 +tcp
dig -t txt o-o.myaddr.l.google.com +short @ns4.google.com -4 +notcp
dig -t txt o-o.myaddr.l.google.com +short @ns4.google.com -4 +tcp
dig -t txt o-o.myaddr.l.google.com +short @ns4.google.com -6 +notcp
dig -t txt o-o.myaddr.l.google.com +short @ns4.google.com -6 +tcp
%
P.S. More of GNU Parallel
To extend on our solution above, the following could be used to perform whois and rDNS lookups on all found addresses; note that for IPv6 lookups to work on BSDs and macOS, one might have to specify -a
for ARIN, -A
for APNIC or -r
for RIPE as an option to whois
:
parallel -kj16 dig -t txt o-o.myaddr.l.google.com +short ::: @ns{1,2,3,4}.google.com ::: -4 -6 ::: +notcp +tcp | sort -n | uniq | parallel -vk ::: "echo" "host" "whois -a" :::: /dev/stdin