1212#include <stdio.h>
1313#include <sys/ioctl.h>
1414#include <inttypes.h>
15+ #include <fcntl.h>
1516
1617#ifdef __linux__
1718#include <linux/ethtool.h>
@@ -142,12 +143,26 @@ static bool isIPv6AddressPreferred(const char* ifname, struct sockaddr_in6* addr
142143#define IN6_IS_ADDR_GLOBAL (a ) \
143144 ((((const uint32_t *) (a))[0] & htonl(0x70000000)) == htonl(0x20000000))
144145#endif
145- if (!IN6_IS_ADDR_GLOBAL (& addr -> sin6_addr ))
146+ #ifndef IN6_IS_ADDR_UNIQUE_LOCAL
147+ #define IN6_IS_ADDR_UNIQUE_LOCAL (a ) \
148+ ((((const uint32_t *) (a))[0] & htonl(0xfe000000)) == htonl(0xfc000000))
149+ #endif
150+ if (!IN6_IS_ADDR_GLOBAL (& addr -> sin6_addr ) && !IN6_IS_ADDR_UNIQUE_LOCAL (& addr -> sin6_addr ))
146151 return false;
147152
148153#ifdef SIOCGIFAFLAG_IN6
149154 static int sockfd = 0 ;
150- if (sockfd == 0 ) sockfd = socket (AF_INET6 , SOCK_DGRAM , 0 );
155+ if (sockfd == 0 )
156+ {
157+ sockfd = socket (AF_INET6 , SOCK_DGRAM
158+ #ifdef SOCK_CLOEXEC
159+ | SOCK_CLOEXEC
160+ #endif
161+ , 0 );
162+ #ifndef SOCK_CLOEXEC
163+ if (sockfd > 0 ) fcntl (sockfd , F_SETFD , FD_CLOEXEC );
164+ #endif
165+ }
151166 if (sockfd < 0 ) return true; // Give up
152167
153168 struct in6_ifreq ifr6 = {};
@@ -157,7 +172,7 @@ static bool isIPv6AddressPreferred(const char* ifname, struct sockaddr_in6* addr
157172 if (ioctl (sockfd , SIOCGIFAFLAG_IN6 , & ifr6 ) != 0 )
158173 return true;
159174
160- return !(ifr6 .ifr_ifru .ifru_flags6 & IN6_IFF_DEPRECATED ) && !( ifr6 . ifr_ifru . ifru_flags6 & IN6_IFF_TEMPORARY );
175+ return !(ifr6 .ifr_ifru .ifru_flags6 & ( IN6_IFF_DEPRECATED | IN6_IFF_TEMPORARY | IN6_IFF_TENTATIVE | IN6_IFF_DUPLICATED | IN6_IFF_OPTIMISTIC ) );
161176#elif __linux__
162177 FF_UNUSED (ifname );
163178
@@ -181,9 +196,8 @@ static bool isIPv6AddressPreferred(const char* ifname, struct sockaddr_in6* addr
181196 & entry -> s6_addr [8 ], & entry -> s6_addr [9 ], & entry -> s6_addr [10 ], & entry -> s6_addr [11 ],
182197 & entry -> s6_addr [12 ], & entry -> s6_addr [13 ], & entry -> s6_addr [14 ], & entry -> s6_addr [15 ],
183198 & flags ) != 17 ||
184- !IN6_IS_ADDR_GLOBAL (entry ) ||
185- (flags & IFA_F_DEPRECATED ) ||
186- (flags & IFA_F_TEMPORARY )
199+ (!IN6_IS_ADDR_GLOBAL (entry ) && !IN6_IS_ADDR_UNIQUE_LOCAL (entry )) ||
200+ (flags & (IFA_F_DEPRECATED | IFA_F_TEMPORARY | IFA_F_TENTATIVE | IFA_F_DADFAILED | IFA_F_OPTIMISTIC ))
187201 )
188202 -- addresses .length ;
189203 }
0 commit comments