[Dnsmasq-discuss] Is field 'arraypos' missing in struct serv_addr4?

Simon Kelley simon at thekelleys.org.uk
Wed Jun 16 08:56:10 UTC 2021


On 16/06/2021 02:40, Xingcong Li wrote:
> I reviewed this commit:
> 
> commit 1c9f136b57456278ad7aae62b8bae01f01383e1c
> Author: Simon Kelley <simon at thekelleys.org.uk
> <mailto:simon at thekelleys.org.uk>>
> Date:   Tue Jun 15 22:07:59 2021 +0100
> Man page update, lease times can be given in days or weeks.
> 
> And  found the structure 'server_addr4*' was casted from to 'server*'
> 
> // domain-match.c
> /* servers need the location in the array to find all the whole
> set of equivalent servers from a pointer to a single one. */
> for (count = 0; count < daemon->serverarraysz; count++)
>   if (!(daemon->serverarray[count]->flags & SERV_LITERAL_ADDRESS))
>     daemon->serverarray[count]->arrayposn = count;
> 
> But the type server_addr4 has no field 'arraypos'.
> 
> // dnsmasq.h
> /* First three fields must match struct server in next three
> definitions.. */
> struct serv_addr4 {
>   int flags;
>   char *domain;
>   struct server *next;
>   struct in_addr addr;
> };
> 
> Does server_addr4 miss the field 'arraypos'?
> 
> Regards,
> Xingcong Li
> 

Good question, but it's not a problem. All members of serverarray are
copied into it in the code above, from daemon->servers and
daemon->local_domains.

The pointers from daemon->servers are the full struct server, and have
the flags & SERV_LITERAL_ADDRESS set to zero.

The pointers from daemon->local_domains are serv_addr4, serv_addr6 or
serv_local and have flags & SERV_LITERAL_ADDRESS set to one. (They also
have other flag bits which distinguish between the three possible unions.

So the

if (!(daemon->serverarray[count]->flags & SERV_LITERAL_ADDRESS))

line saves the code from writing outside the structure if it's a serv_addr4.

Looking at the code in src/option.c around line 2630 should demonstrate
this.


Update: there _is_ a problem! I took my own advice and looked at the
option.c code.

server=/example.com/#

generates a struct serv_local on the ->local_domains list, which doesn't
have SERV_LITERAL_ADDRESS set. Instead it's marked by SERV_USE_RESOLV,
so the test should be

if (!(daemon->serverarray[count]->flags & (SERV_LITERAL_ADDRESS |
SERV_USE_RESOLV)

I'll fix that now.

Many thanks for your efforts in reviewing this: we just proved yet again
that there's no such thing as a dumb question!

PS. the code in add_update_server() gets this right.

Cheers,

Simon.



More information about the Dnsmasq-discuss mailing list