00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "spf_sys_config.h"
00018
00019 #ifdef STDC_HEADERS
00020 # include <stdio.h>
00021 # include <stdlib.h>
00022 #endif
00023
00024 #ifdef HAVE_STRING_H
00025 # include <string.h>
00026 #else
00027 # ifdef HAVE_STRINGS_H
00028 # include <strings.h>
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
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 }