Re: Re: core in libspf2 on SunOS 5.8

"Manish Raje" <[email protected]> Tue, 29 Jul 2008 19:57:47 +0530
Newsgroups gmane.mail.spam.spf.devel
Message-ID <[email protected]>
Hi

My earlier mail was in a wrong thread.
Replying to the correct one which was raised earlier and has the history of
the problem.

We ([email protected] and me) have worked around this issue by
modifying the spf code in "spf_dns_resolv.c". It would be great if you could
incorporate the changes in upcoming versions of SPF.

Changes attached.

Thanks,
Manish.

On 1/25/07, Julian Mehnle <[email protected]> wrote:
>
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
>
> Scott Kitterman wrote:
> > I doubt anyone is going to be able to help with SunOS 5.8 specific
> > issues (which I'm guessing your having) since it's unlikely they would
> > have access to a SunOS box.  I'd encourage you to continue trying to
> > understand the issue and work through it.
>
>
> ... and please do report back your findings here, so we may get the libspf2
> author to fix the issue!
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.6 (GNU/Linux)
>
> iD8DBQFFuKmwwL7PKlBZWjsRAie3AKDEGgAoQnyXW8wkCDM2JsCw+q9DMACbBL8C
> hPNA4h93G7EDmlSQ1ndlH1w=
> =Yq1W
> -----END PGP SIGNATURE-----
>
>
> -------
> To unsubscribe, change your address, or temporarily deactivate your
> subscription,
> please go to http://v2.listbox.com/member/?list_id=1007
>
changes_for_spf_dns_resolv.txt (text/plain, 9.6 KB)

+typedef struct dynamic_buffer
+{
+    size_t len;
+    u_char *respBuf;
+} dynamic_buffer_t;
 
 static inline SPF_dns_resolv_config_t *SPF_voidp2spfhook( void *hook ) 
     { return (SPF_dns_resolv_config_t *)hook; }
 static inline void *SPF_spfhook2voidp( SPF_dns_resolv_config_t *spfhook ) 
     { return (void *)spfhook; }
 
 
+#define INITIAL_SIZE 2048

-static SPF_dns_rr_t *SPF_dns_lookup_resolv( SPF_dns_config_t spfdcid, const
char *domain, ns_type rr_type, int should_cache )
+static void dynamic_buffer_init(dynamic_buffer_t *bufp)
+{
+    bufp->respBuf = (u_char *) malloc(sizeof(u_char) * INITIAL_SIZE);
+    if (!bufp->respBuf) {
+        bufp->len = -1;
+        return;
+    }
+
+    /* All went well. Set the initial size of buffer */
+    bufp->len = INITIAL_SIZE;
+}
+
+static void dynamic_buffer_free(dynamic_buffer_t *bufp)
+{
+    /* Get rid of dynamically allocated memory */
+    if (bufp->respBuf)
+    {
+        free(bufp->respBuf);
+        bufp->respBuf = NULL;
+    }
+}
+
+static u_char *dynamic_buffer_grow(dynamic_buffer_t *bufp, size_t sz)
+{
+    u_char *newBuf = (u_char *) realloc(bufp->respBuf, sz);
+
+    if (newBuf == NULL)
+        return NULL; /* leave (bufp->respBuf unchanged */
+
+    /* Record the newly allocated pointer in original struct pointer */
+    bufp->respBuf = newBuf;
+
+    /* Record the new buffer length */
+    bufp->len = sz;
+
+    return bufp->respBuf;
+}
+
+#define MAX_TRIES 3
+
+static SPF_dns_rr_t *SPF_dns_lookup_resolv_internal( SPF_dns_config_t spfdcid,
const char *domain, ns_type rr_type, int should_cache, dynamic_buffer_t *dynBuf )
 {
     SPF_dns_iconfig_t           *spfdic = SPF_dcid2spfdic( spfdcid );
     SPF_dns_resolv_config_t     *spfhook = SPF_voidp2spfhook( spfdic->hook );
     SPF_dns_rr_t *spfrr;
 
     int         err;
     int         i;
     int         nrec;
     int         cnt;
 
-    u_char      response[2048];
+    u_char      *response = dynBuf->respBuf;
+    int         max_try_ctr = 0;
 
     int         dns_len;
     
     ns_msg      ns_handle;
     ns_rr       rr;

@@ -142,19 +189,21 @@ Prev Next  static SPF_dns_rr_t *SPF_dns_lookup_reso
                    (rr_type == ns_t_any)   ? "ANY" :
                    "??" ),
                  rr_type );
 
     
+    for (max_try_ctr = 0; max_try_ctr < MAX_TRIES; max_try_ctr++) 
+    {
     /*
      * try resolving the name
      */
 #if HAVE_DECL_RES_NINIT
     dns_len = res_nquery( &spfhook->res_state, domain, ns_c_in, rr_type,
-                         response, sizeof( response ) );
+                             response, dynBuf->len );
 #else
     dns_len = res_query( domain, ns_c_in, rr_type,
-                         response, sizeof( response ) );
+                             response, dynBuf->len );
 #endif
 
     if ( dns_len < 0 )
     {
         if ( spfhook->debug )

@@ -165,13 +214,33 @@ Prev Next  static SPF_dns_rr_t *SPF_dns_lookup_reso
             return SPF_dcid2spfdic( spfdic->layer_below )->lookup(
spfdic->layer_below, domain, rr_type, should_cache );
 
         spfrr->herrno = SPF_h_errno;
         return spfrr;
     }
+        else if ( dns_len > dynBuf->len) 
+        {
+            if ( spfhook->debug )
+                SPF_debugf( "dns response length = %d, greater than buffer 
+                             size = %d", dns_len, dynBuf->len);
+
+            /* realloc the buffer to new size */
+            if ((response = dynamic_buffer_grow(dynBuf, dns_len)) == NULL) {
+                if ( spfhook->debug )
+                    SPF_debugf("realloc failed!");
+
+                return spfrr;
+            }
+
+            /* loop again with a new buffer of size = dns_len */
+        }
     else
+        {
+            /* Everything OK. Break out of the loop */
         spfrr->herrno = NETDB_SUCCESS;
-        
+            break;
+        }
+    } /* end for */
     
     err = ns_initparse( response, dns_len, &ns_handle );
 
     if ( err < 0 )                      /* 0 or -1 */
     {

@@ -246,11 +315,11 @@ Prev Next  static SPF_dns_rr_t *SPF_dns_lookup_reso
                             ip6_buf, sizeof( ip6_buf ) ));
                     break;
                 
                 case ns_t_ns:
                     err = ns_name_uncompress( response,
-                                              response + sizeof( response ),
+                                              response + dynBuf->len,
                                               rdata,
                                               name_buf, sizeof( name_buf ) );
                     if ( err < 0 )              /* 0 or -1 */
                     {
                         SPF_debugf( "ns_name_uncompress failed: err = %d  %s (%d)",

@@ -260,11 +329,11 @@ Prev Next  static SPF_dns_rr_t *SPF_dns_lookup_reso
                         SPF_debugf( "NS: %s", name_buf );
                     break;
                 
                 case ns_t_cname:
                     err = ns_name_uncompress( response,
-                                              response + sizeof( response ),
+                                              response + dynBuf->len,
                                               rdata,
                                               name_buf, sizeof( name_buf ) );
                     if ( err < 0 )              /* 0 or -1 */
                     {
                         SPF_debugf( "ns_name_uncompress failed: err = %d  %s (%d)",

@@ -275,11 +344,11 @@ Prev Next  static SPF_dns_rr_t *SPF_dns_lookup_reso
                     break;
                 
                 case ns_t_mx:
                     prio = ns_get16( rdata );
                     err = ns_name_uncompress( response,
-                                              response + sizeof( response ),
+                                              response + dynBuf->len,
                                               rdata + NS_INT16SZ,
                                               name_buf, sizeof( name_buf ) );
                     if ( err < 0 )              /* 0 or -1 */
                     {
                         SPF_debugf( "ns_name_uncompress failed: err = %d  %s (%d)",

@@ -295,11 +364,11 @@ Prev Next  static SPF_dns_rr_t *SPF_dns_lookup_reso
                             rdlen, rdlen-1, rdata+1 );
                     break;
                 
                 case ns_t_ptr:
                     err = ns_name_uncompress( response,
-                                              response + sizeof( response ),
+                                              response + dynBuf->len,
                                               rdata,
                                               name_buf, sizeof( name_buf ) );
                     if ( err < 0 )              /* 0 or -1 */
                     {
                         SPF_debugf( "ns_name_uncompress failed: err = %d  %s (%d)",

@@ -353,11 +422,11 @@ Prev Next  static SPF_dns_rr_t *SPF_dns_lookup_reso
                 /* FIXME:  are CNAMEs always sent with the real RR? */
                 break;
                 
             case ns_t_mx:
                 err = ns_name_uncompress( response,
-                                          response + sizeof( response ),
+                                          response + dynBuf->len,
                                           rdata + NS_INT16SZ,
                                           name_buf, sizeof( name_buf ) );
                 if ( err < 0 )          /* 0 or -1 */
                 {
                     if ( spfhook->debug > 1 )

@@ -405,11 +474,11 @@ Prev Next  static SPF_dns_rr_t *SPF_dns_lookup_reso
                 cnt++;
                 break;
                 
             case ns_t_ptr:
                 err = ns_name_uncompress( response,
-                                          response + sizeof( response ),
+                                          response + dynBuf->len,
                                           rdata,
                                           name_buf, sizeof( name_buf ) );
                 if ( err < 0 )          /* 0 or -1 */
                 {
                     if ( spfhook->debug > 1 )

@@ -438,10 +507,42 @@ Prev Next  static SPF_dns_rr_t *SPF_dns_lookup_reso
         spfhook->spfrr.herrno = NO_DATA;
 
     return spfrr;
 }
 
+static SPF_dns_rr_t *SPF_dns_lookup_resolv( SPF_dns_config_t spfdcid, const
char *domain, ns_type rr_type, int should_cache )
+{
+    SPF_dns_iconfig_t           *spfdic;
+    SPF_dns_resolv_config_t     *spfhook;
+    SPF_dns_rr_t                *ret_val;
+    dynamic_buffer_t            dynBuf;
+
+    /* Initialize the dynamic buffer within the structure */
+    dynamic_buffer_init(&dynBuf);
+
+    /* Initialization of dynBuf failed. Return error */
+    if (-1 == dynBuf.len)
+    {
+        spfdic = SPF_dcid2spfdic( spfdcid );
+        spfhook = SPF_voidp2spfhook( spfdic->hook );
+        ret_val = &spfhook->spfrr;
+        SPF_dns_reset_rr( ret_val );
+        ret_val->herrno = NO_RECOVERY;
+        ret_val->rr_type = rr_type;
+
+        return ret_val;
+    }
+
+    /* Query DNS and parse response */
+    ret_val = SPF_dns_lookup_resolv_internal(spfdcid, domain, rr_type,
should_cache, &dynBuf);
+
+    /* Free the dynamic buffer */
+    dynamic_buffer_free(&dynBuf);
+
+    return ret_val;
+    
+}
 
 SPF_dns_config_t SPF_dns_create_config_resolv2( SPF_dns_config_t layer_below,
int debug, int timeout, int retry )
 {
     SPF_dns_iconfig_t     *spfdic;
     SPF_dns_resolv_config_t *spfhook;



-------------------------------------------
Sender Policy Framework: http://www.openspf.org
Modify Your Subscription: http://www.listbox.com/member/
Archives: https://www.listbox.com/member/archive/1007/=now
RSS Feed: https://www.listbox.com/member/archive/rss/1007/
Powered by Listbox: http://www.listbox.com