mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Fix problems with ipset or nftset and TCP DNS transport.
If DNS is happening over TCP, the query is handled by a forked process. Of ipset ot nftset is configured, this might include inserting addresses in the *sets. Before this update, that was done by the forked process using handles inherited from the parent "master" process. This is inherently racy. If the master process or another child process tries to do updates at the same time, the updates can clash and fail. To see this, you need a busy server doing lots of DNS queries over TCP, and ipset or nftset configured. Going forward, we use the already established pipe to send the updates from the child back to the master process, which serialises them.
This commit is contained in:
@@ -539,8 +539,10 @@ struct crec {
|
||||
|
||||
#define PIPE_OP_RR 1 /* Resource record */
|
||||
#define PIPE_OP_END 2 /* Cache entry complete: commit */
|
||||
#define PIPE_OP_RESULT 3 /* validation result. */
|
||||
#define PIPE_OP_RESULT 3 /* Validation result */
|
||||
#define PIPE_OP_STATS 4 /* Update parent's stats */
|
||||
#define PIPE_OP_IPSET 5 /* Update IPset */
|
||||
#define PIPE_OP_NFTSET 6 /* Update NFTset */
|
||||
|
||||
/* struct sockaddr is not large enough to hold any address,
|
||||
and specifically not big enough to hold an IPv6 address.
|
||||
@@ -1361,6 +1363,10 @@ int cache_recv_insert(time_t now, int fd);
|
||||
#ifdef HAVE_DNSSEC
|
||||
void cache_update_hwm(void);
|
||||
#endif
|
||||
#if defined(HAVE_IPSET) || defined(HAVE_NFTSET)
|
||||
void cache_send_ipset(unsigned char op, struct ipsets *sets,
|
||||
int flags, union all_addr *addr);
|
||||
#endif
|
||||
struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class,
|
||||
time_t now, unsigned long ttl, unsigned int flags);
|
||||
void cache_reload(void);
|
||||
|
||||
Reference in New Issue
Block a user