spf_dns_rr.c

Go to the documentation of this file.
00001 /* 
00002  * This program is free software; you can redistribute it and/or modify
00003  * it under the terms of either:
00004  * 
00005  *   a) The GNU Lesser General Public License as published by the Free
00006  *      Software Foundation; either version 2.1, or (at your option) any
00007  *      later version, 
00008  * 
00009  *   OR
00010  * 
00011  *   b) The two-clause BSD license.
00012  *
00013  * These licenses can be found with the distribution in the file LICENSES
00014  */
00015 
00016 
00017 #include "spf_sys_config.h"
00018 
00019 #ifdef STDC_HEADERS
00020 # include <stdio.h>        /* stdin / stdout */
00021 # include <stdlib.h>       /* malloc / free */
00022 #endif
00023 
00024 #ifdef HAVE_STRING_H
00025 # include <string.h>       /* strstr / strdup */
00026 #else
00027 # ifdef HAVE_STRINGS_H
00028 #  include <strings.h>       /* strstr / strdup */
00029 # endif
00030 #endif
00031 
00032 #ifdef HAVE_NETDB_H
00033 #include <netdb.h>
00034 #endif
00035 
00036 #ifdef HAVE_ARPA_NAMESER_H
00037 #include <arpa/nameser.h>
00038 #endif
00039 
00040 
00041 #include "spf.h"
00042 #include "spf_dns.h"
00043 #include "spf_internal.h"
00044 #include "spf_dns_internal.h"
00045 #include "spf_dns_rr.h"
00046 
00052 SPF_dns_rr_t *
00053 SPF_dns_rr_new_nxdomain(SPF_dns_server_t *spf_dns_server,
00054                                 const char *domain)
00055 {
00056         return SPF_dns_rr_new_init(spf_dns_server,
00057                                         domain, ns_t_any, 0, HOST_NOT_FOUND);
00058 }
00059 
00060 SPF_dns_rr_t *
00061 SPF_dns_rr_new_init(SPF_dns_server_t *spf_dns_server,
00062                                 const char *domain,
00063                                 ns_type rr_type, int ttl,
00064                                 SPF_dns_stat_t herrno)
00065 {
00066     SPF_dns_rr_t        *spfrr;
00067 
00068     spfrr = SPF_dns_rr_new();
00069     if (spfrr == NULL)
00070                 return spfrr;
00071 
00072     spfrr->source = spf_dns_server;
00073         if (domain && (domain[0] != '\0')) {
00074                 spfrr->domain = strdup(domain);
00075                 if (spfrr->domain == NULL) {
00076                         SPF_dns_rr_free(spfrr);
00077                         return NULL;
00078                 }
00079                 spfrr->domain_buf_len = strlen(domain) + 1;
00080         }
00081         else {
00082                 spfrr->domain = NULL;
00083                 spfrr->domain_buf_len = 0;
00084         }
00085     spfrr->rr_type = rr_type;
00086     spfrr->ttl = ttl;
00087     spfrr->herrno = herrno;
00088 
00089     return spfrr;
00090 }
00091 
00092 SPF_dns_rr_t *
00093 SPF_dns_rr_new()
00094 {
00095     SPF_dns_rr_t        *spfrr;
00096 
00097     spfrr = malloc(sizeof(SPF_dns_rr_t));
00098     if (spfrr == NULL)
00099                 return spfrr;
00100         memset(spfrr, 0, sizeof(SPF_dns_rr_t));
00101 
00102         spfrr->domain = NULL;
00103         spfrr->domain_buf_len = 0;
00104         spfrr->rr_type = ns_t_invalid;
00105         spfrr->num_rr = 0;
00106         spfrr->ttl = 0;
00107         spfrr->utc_ttl = 0;
00108         spfrr->herrno = HOST_NOT_FOUND;
00109 
00110     return spfrr;
00111 }
00112 
00113 void
00114 SPF_dns_rr_free(SPF_dns_rr_t *spfrr)
00115 {
00116         int      i;
00117 
00118         if (spfrr->domain)
00119                 free(spfrr->domain);
00120         if (spfrr->rr) {
00121                 for (i = 0; i < spfrr->rr_buf_num; i++)
00122                         if (spfrr->rr[i])
00123                                 free(spfrr->rr[i]);
00124                 free(spfrr->rr);
00125         }
00126         if (spfrr->rr_buf_len)
00127                 free(spfrr->rr_buf_len);
00128         if(spfrr->hook)
00129                 free(spfrr->hook);
00130         free(spfrr);
00131 }
00132 
00133 SPF_errcode_t
00134 SPF_dns_rr_buf_realloc(SPF_dns_rr_t *spfrr, int idx, size_t len)
00135 {
00136         SPF_dns_rr_data_t       **new_data;
00137         size_t                           *new_buf_len;
00138         int                                       new_num;
00139         void                             *new_rr;
00140         int                                       j;
00141         
00142         if (spfrr->rr_buf_num <= idx) {
00143                 /* allocate lots so we don't have to remalloc often */
00144                 new_num = spfrr->rr_buf_num + (idx + (idx >> 2) + 4 );
00145 
00146                 new_data = realloc(spfrr->rr,
00147                                                 new_num * sizeof(*new_data));
00148                 if (new_data == NULL)
00149                         return SPF_E_NO_MEMORY;
00150                 spfrr->rr = new_data;
00151                 
00152                 new_buf_len = realloc(spfrr->rr_buf_len,
00153                                            new_num * sizeof(*new_buf_len));
00154                 if (new_buf_len == NULL)
00155                         return SPF_E_NO_MEMORY;
00156                 spfrr->rr_buf_len = new_buf_len;
00157                 
00158                 for(j = spfrr->rr_buf_num; j < new_num; j++) {
00159                         spfrr->rr[j] = NULL;
00160                         spfrr->rr_buf_len[j] = 0;
00161                 }
00162 
00163                 spfrr->rr_buf_num = new_num;
00164         }
00165 
00166     if (len < sizeof(SPF_dns_rr_data_t))
00167                 len = sizeof(SPF_dns_rr_data_t);
00168     if (spfrr->rr_buf_len[idx] >= len)
00169                 return SPF_E_SUCCESS;
00170 
00171         new_rr = realloc(spfrr->rr[idx], len);
00172     if (new_rr == NULL)
00173                 return SPF_E_NO_MEMORY;
00174     spfrr->rr[idx] = new_rr;
00175     spfrr->rr_buf_len[idx] = len;
00176 
00177     return SPF_E_SUCCESS;
00178 }
00179 
00180 
00188 SPF_errcode_t
00189 SPF_dns_rr_dup(SPF_dns_rr_t **dstp, SPF_dns_rr_t *src)
00190 {
00191         SPF_dns_rr_t    *dst;
00192     SPF_errcode_t       err;
00193     int                 i;
00194 
00195         SPF_ASSERT_NOTNULL(src);
00196         SPF_ASSERT_NOTNULL(dstp);
00197         dst = SPF_dns_rr_new_init(src->source,
00198                                         src->domain, src->rr_type, src->ttl, src->herrno);
00199         if (!dst) {
00200                 *dstp = NULL;
00201                 return SPF_E_NO_MEMORY;
00202         }
00203         *dstp = dst;
00204 
00205     dst->utc_ttl = src->utc_ttl;
00206     dst->num_rr  = src->num_rr;
00207 
00208 #define SPF_DNS_RR_REALLOC(d, i, s) do { \
00209                         err = SPF_dns_rr_buf_realloc(d, i, s); \
00210                         if (err) return err; \
00211                 } while(0)
00212 
00213     for (i = dst->num_rr - 1; i >= 0; i--) {
00214                 switch (dst->rr_type) {
00215                         case ns_t_a:
00216                                 SPF_DNS_RR_REALLOC(dst, i, sizeof(SPF_dns_rr_data_t));
00217                                 dst->rr[i]->a = src->rr[i]->a;
00218                                 break;
00219                                 
00220                         case ns_t_ptr:
00221                                 SPF_DNS_RR_REALLOC(dst, i, strlen(src->rr[i]->ptr) + 1);
00222                                 strcpy(dst->rr[i]->ptr, src->rr[i]->ptr);
00223                                 break;
00224                                 
00225                         case ns_t_mx:
00226                                 SPF_DNS_RR_REALLOC(dst, i, strlen(src->rr[i]->mx) + 1);
00227                                 strcpy(dst->rr[i]->mx, src->rr[i]->mx);
00228                                 break;
00229                                 
00230                         case ns_t_txt:
00231                         case ns_t_spf:
00232                                 SPF_DNS_RR_REALLOC(dst, i, strlen(src->rr[i]->txt) + 1);
00233                                 strcpy(dst->rr[i]->txt, src->rr[i]->txt);
00234                                 break;
00235                                 
00236                         case ns_t_aaaa:
00237                                 SPF_DNS_RR_REALLOC(dst, i, sizeof(SPF_dns_rr_data_t));
00238                                 dst->rr[i]->aaaa = src->rr[i]->aaaa;
00239                                 break;
00240                                 
00241                         default:
00242                                 SPF_warningf("Attempt to dup unknown rr type %d",
00243                                                                 dst->rr_type);
00244                                 break;
00245                 }
00246         }
00247 
00248     return SPF_E_SUCCESS;
00249 }

Generated on Tue Nov 4 13:27:39 2008 for libspf2 by  doxygen 1.5.4