Yahoo Groups archive

Milter-greylist

Index last updated: 2026-04-28 23:32 UTC

Message

Re: [milter-greylist] memory consumption

2010-02-18 by Johann E. Klasek

BTW, we had this strangeness on topic already back in Oct 2008, see
http://tech.groups.yahoo.com/group/milter-greylist/message/4805

The conclusion was that we need a autoconf rule that handles
res_ninit() existence in a proper way. My promise to provide
such a beast never came to reality ...
Well, I'll give them a 2nd try.

On Thu, Feb 18, 2010 at 11:40:07AM +0100, manu@... wrote:
[..]
> This means that any successful call to res_ninit() must have a
> corresponding res_ndestroy() call.
> 
> In dnsrbl_check_source, once res_ninit() is called, there is no way out
> of the function without executing res_ndestroy(). But the trick is that
> res_ninit() and res_ndestroy() may be macros in milter-greylist, so that
> we can cope with older BIND resolvers without having #ifdef's everywhere
> in our code.
> 
> In some situation,  milter-greylist can define res_ndestroy() as
> res_nclose(), and this is a problem, because at least in NetBSD's
> resolver, res_ndestroy() does free statp->_u._ext.ext  whereas
> res_nclose() does not.
> 
> Hence, here is the offending code in dnsrbl.c
> 
> #if (defined(res_ninit) || (__RES >= 19991006) )
> #define HAVE_RESN       1
> #ifndef res_ndestroy
> #define res_ndestroy(res)       res_nclose(res)   /* <--- XXXhereXXX */
> #endif
> #else   
> #define res_ninit(res) \
>         ((_res.options & RES_INIT) == 0 && res_init())
> #define res_nquery(res, req, class, type, ans, anslen)  \
>         res_query(req, class, type, ans, anslen)
> #define res_ndestroy(res)
> #endif  
> 
> The ifdef on res_ninit and res_ndestroy is an error, it will never be
> evaluated as true. Please try this instead, and tell us if you get the
> warning at compile time.

I'm not sure.
The origin in some 4.0 alpha version was

[..]
#ifdef res_ninit
#define HAVE_RESN     1
#ifndef res_ndestroy
#define res_ndestroy(res)     res_nclose(res)
[..]

This tried to discover if a threaded version of res_ninit() do exist. But
this works only in environments which implement a macro layer for res_n* calls.
This is trues at least for Linux, NetBSD (AFAIK) but this will never hold on
systems which has real library functions for this (like Solaris).
The __RES condition was only added as a simply hack to this work for systems
with a newer Bind resolver (for which we can asume that the thread-safe
variants do exist).


> 
> #if (__RES >= 19991006) )
> #define HAVE_RESN       1
> #else   
> #warn "no res_ninit!"
> #define res_ninit(res) \
>         ((_res.options & RES_INIT) == 0 && res_init())
> #define res_nquery(res, req, class, type, ans, anslen)  \
>         res_query(req, class, type, ans, anslen)
> #define res_ndestroy(res)
> #endif  
> 
> Handling the BIND versions where res_nclose() exists but not
> res_ndestroy() must be done by an autoconf test.

Maybe the check for __RES is sufficient (at least if we asume that
mostly Bind resolver are in use). But to get it really clean res_ninit()
should be also checked by autoconf ...

Johann E. K.

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.