Skip to content

make the order of AFs in pcap_nametoaddrinfo() result deterministic #1574

@infrastation

Description

@infrastation

One of the causes of the CI failures in #1573 is this:

    accept_src_host_noeth_ipv4_ipv6_EN10MB_unopt_1: diff error
--- /tmp/libpcap_TESTrun_cwOV39f6/job000-expected.txt	2025-10-27 20:34:58.226969357 +0000
+++ /tmp/libpcap_TESTrun_cwOV39f6/job000-stdout.txt	2025-10-27 20:34:58.294970123 +0000
@@ -1,24 +1,24 @@
 (000) ldh      [12]
-(001) jeq      #0x800           jt 2	jf 4
-(002) ld       [26]
-(003) jeq      #0xa141e28       jt 22	jf 4
-(004) ldh      [12]
-(005) jeq      #0x806           jt 6	jf 8
-(006) ld       [28]
-(007) jeq      #0xa141e28       jt 22	jf 8
-(008) ldh      [12]
-(009) jeq      #0x8035          jt 10	jf 12
-(010) ld       [28]
-(011) jeq      #0xa141e28       jt 22	jf 12
-(012) ldh      [12]
-(013) jeq      #0x86dd          jt 14	jf 23
-(014) ld       [22]
-(015) jeq      #0xfd00a1b2      jt 16	jf 23
-(016) ld       [26]
-(017) jeq      #0xc3d40000      jt 18	jf 23
-(018) ld       [30]
-(019) jeq      #0x10203040      jt 20	jf 23
-(020) ld       [34]
-(021) jeq      #0x50607080      jt 22	jf 23
+(001) jeq      #0x86dd          jt 2	jf 10
+(002) ld       [22]
+(003) jeq      #0xfd00a1b2      jt 4	jf 10
+(004) ld       [26]
+(005) jeq      #0xc3d40000      jt 6	jf 10
+(006) ld       [30]
+(007) jeq      #0x10203040      jt 8	jf 10
+(008) ld       [34]
+(009) jeq      #0x50607080      jt 22	jf 10
+(010) ldh      [12]
+(011) jeq      #0x800           jt 12	jf 14
+(012) ld       [26]
+(013) jeq      #0xa141e28       jt 22	jf 14
+(014) ldh      [12]
+(015) jeq      #0x806           jt 16	jf 18
+(016) ld       [28]
+(017) jeq      #0xa141e28       jt 22	jf 18
+(018) ldh      [12]
+(019) jeq      #0x8035          jt 20	jf 23
+(020) ld       [28]
+(021) jeq      #0xa141e28       jt 22	jf 23
 (022) ret      #262144
 (023) ret      #0

The expected filter program matches IPv4 first, then ARP, then RARP, then IPv6. The actual filter program matches IPv6 first, then IPv4, then ARP, then RARP. This reproduces on two Linux hosts that are IPv6-only, which apparently affects the order of AFs in the result of pcap_nametoaddrinfo(), which for regular socket use purposes makes sense and looks consistent with the man page (arguably, a connect() call to an AF_INET on an IPv6-only host would fail, so in this case it makes sense to return AF_INET6 addresses first by default):

       service, getaddrinfo() returns one or  more  addrinfo  struc‐
       tures, each of which contains an Internet address that can be
       specified in a call to bind(2)  or  connect(2).   The  getad‐

Another reason why ai_family = AF_UNSPEC produces non-deterministic results is that on dual-stack Linux hosts the order of AFs is follows local runtime configuration in /etc/gai.conf.

However, in the use case of libpcap the addresses are not meant to interact with L3 protocols of the host's network stack, and it is desirable to keep any external effects on the filter program to the necessary minimum, so the solution seems to be processing one AF at a time in gen_host46_byname() instead of using pcap_nametoaddrinfo().

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions