libspf2  1.2.11
spf_dns_rr.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of either:
4  *
5  * a) The GNU Lesser General Public License as published by the Free
6  * Software Foundation; either version 2.1, or (at your option) any
7  * later version,
8  *
9  * OR
10  *
11  * b) The two-clause BSD license.
12  *
13  * These licenses can be found with the distribution in the file LICENSES
14  */
15 
16 
17 #include "spf_sys_config.h"
18 
19 #ifdef STDC_HEADERS
20 # include <stdio.h> /* stdin / stdout */
21 # include <stdlib.h> /* malloc / free */
22 #endif
23 
24 #ifdef HAVE_STRING_H
25 # include <string.h> /* strstr / strdup */
26 #else
27 # ifdef HAVE_STRINGS_H
28 # include <strings.h> /* strstr / strdup */
29 # endif
30 #endif
31 
32 #ifdef HAVE_NETDB_H
33 #include <netdb.h>
34 #endif
35 
36 #ifdef HAVE_ARPA_NAMESER_H
37 #include <arpa/nameser.h>
38 #endif
39 
40 
41 #include "spf.h"
42 #include "spf_dns.h"
43 #include "spf_internal.h"
44 #include "spf_dns_internal.h"
45 #include "spf_dns_rr.h"
46 
53 SPF_dns_rr_new_nxdomain(SPF_dns_server_t *spf_dns_server,
54  const char *domain)
55 {
56  return SPF_dns_rr_new_init(spf_dns_server,
57  domain, ns_t_any, 0, HOST_NOT_FOUND);
58 }
59 
61 SPF_dns_rr_new_init(SPF_dns_server_t *spf_dns_server,
62  const char *domain,
63  ns_type rr_type, int ttl,
64  SPF_dns_stat_t herrno)
65 {
66  SPF_dns_rr_t *spfrr;
67 
68  spfrr = SPF_dns_rr_new();
69  if (spfrr == NULL)
70  return spfrr;
71 
72  spfrr->source = spf_dns_server;
73  if (domain && (domain[0] != '\0')) {
74  spfrr->domain = strdup(domain);
75  if (spfrr->domain == NULL) {
76  SPF_dns_rr_free(spfrr);
77  return NULL;
78  }
79  spfrr->domain_buf_len = strlen(domain) + 1;
80  }
81  else {
82  spfrr->domain = NULL;
83  spfrr->domain_buf_len = 0;
84  }
85  spfrr->rr_type = rr_type;
86  spfrr->ttl = ttl;
87  spfrr->herrno = herrno;
88 
89  return spfrr;
90 }
91 
94 {
95  SPF_dns_rr_t *spfrr;
96 
97  spfrr = malloc(sizeof(SPF_dns_rr_t));
98  if (spfrr == NULL)
99  return spfrr;
100  memset(spfrr, 0, sizeof(SPF_dns_rr_t));
101 
102  spfrr->domain = NULL;
103  spfrr->domain_buf_len = 0;
104  spfrr->rr_type = ns_t_invalid;
105  spfrr->num_rr = 0;
106  spfrr->ttl = 0;
107  spfrr->utc_ttl = 0;
108  spfrr->herrno = HOST_NOT_FOUND;
109 
110  return spfrr;
111 }
112 
113 void
115 {
116  int i;
117 
118  if (spfrr->domain)
119  free(spfrr->domain);
120  if (spfrr->rr) {
121  for (i = 0; i < spfrr->rr_buf_num; i++)
122  if (spfrr->rr[i])
123  free(spfrr->rr[i]);
124  free(spfrr->rr);
125  }
126  if (spfrr->rr_buf_len)
127  free(spfrr->rr_buf_len);
128  if(spfrr->hook)
129  free(spfrr->hook);
130  free(spfrr);
131 }
132 
134 SPF_dns_rr_buf_realloc(SPF_dns_rr_t *spfrr, int idx, size_t len)
135 {
136  SPF_dns_rr_data_t **new_data;
137  size_t *new_buf_len;
138  int new_num;
139  void *new_rr;
140  int j;
141 
142  if (spfrr->rr_buf_num <= idx) {
143  /* allocate lots so we don't have to remalloc often */
144  new_num = spfrr->rr_buf_num + (idx + (idx >> 2) + 4 );
145 
146  new_data = realloc(spfrr->rr,
147  new_num * sizeof(*new_data));
148  if (new_data == NULL)
149  return SPF_E_NO_MEMORY;
150  spfrr->rr = new_data;
151 
152  new_buf_len = realloc(spfrr->rr_buf_len,
153  new_num * sizeof(*new_buf_len));
154  if (new_buf_len == NULL)
155  return SPF_E_NO_MEMORY;
156  spfrr->rr_buf_len = new_buf_len;
157 
158  for(j = spfrr->rr_buf_num; j < new_num; j++) {
159  spfrr->rr[j] = NULL;
160  spfrr->rr_buf_len[j] = 0;
161  }
162 
163  spfrr->rr_buf_num = new_num;
164  }
165 
166  if (len < sizeof(SPF_dns_rr_data_t))
167  len = sizeof(SPF_dns_rr_data_t);
168  if (spfrr->rr_buf_len[idx] >= len)
169  return SPF_E_SUCCESS;
170 
171  new_rr = realloc(spfrr->rr[idx], len);
172  if (new_rr == NULL)
173  return SPF_E_NO_MEMORY;
174  spfrr->rr[idx] = new_rr;
175  spfrr->rr_buf_len[idx] = len;
176 
177  return SPF_E_SUCCESS;
178 }
179 
180 
190 {
191  SPF_dns_rr_t *dst;
192  SPF_errcode_t err;
193  int i;
194 
195  SPF_ASSERT_NOTNULL(src);
196  SPF_ASSERT_NOTNULL(dstp);
197  dst = SPF_dns_rr_new_init(src->source,
198  src->domain, src->rr_type, src->ttl, src->herrno);
199  if (!dst) {
200  *dstp = NULL;
201  return SPF_E_NO_MEMORY;
202  }
203  *dstp = dst;
204 
205  dst->utc_ttl = src->utc_ttl;
206  dst->num_rr = src->num_rr;
207 
208 #define SPF_DNS_RR_REALLOC(d, i, s) do { \
209  err = SPF_dns_rr_buf_realloc(d, i, s); \
210  if (err) return err; \
211  } while(0)
212 
213  for (i = dst->num_rr - 1; i >= 0; i--) {
214  switch (dst->rr_type) {
215  case ns_t_a:
216  SPF_DNS_RR_REALLOC(dst, i, sizeof(SPF_dns_rr_data_t));
217  dst->rr[i]->a = src->rr[i]->a;
218  break;
219 
220  case ns_t_ptr:
221  SPF_DNS_RR_REALLOC(dst, i, strlen(src->rr[i]->ptr) + 1);
222  strcpy(dst->rr[i]->ptr, src->rr[i]->ptr);
223  break;
224 
225  case ns_t_mx:
226  SPF_DNS_RR_REALLOC(dst, i, strlen(src->rr[i]->mx) + 1);
227  strcpy(dst->rr[i]->mx, src->rr[i]->mx);
228  break;
229 
230  case ns_t_txt:
231  case ns_t_spf:
232  SPF_DNS_RR_REALLOC(dst, i, strlen(src->rr[i]->txt) + 1);
233  strcpy(dst->rr[i]->txt, src->rr[i]->txt);
234  break;
235 
236  case ns_t_aaaa:
237  SPF_DNS_RR_REALLOC(dst, i, sizeof(SPF_dns_rr_data_t));
238  dst->rr[i]->aaaa = src->rr[i]->aaaa;
239  break;
240 
241  default:
242  SPF_warningf("Attempt to dup unknown rr type %d",
243  dst->rr_type);
244  break;
245  }
246  }
247 
248  return SPF_E_SUCCESS;
249 }
SPF_dns_stat_t
int SPF_dns_stat_t
Definition: spf_dns.h:108
SPF_dns_rr_data_t::txt
char txt[1]
Definition: spf_dns_rr.h:36
ns_type
ns_type
Definition: arpa_nameser.h:300
SPF_dns_rr_t::rr_buf_len
size_t * rr_buf_len
Definition: spf_dns_rr.h:61
SPF_errcode_t
SPF_errcode_t
Definition: spf_response.h:119
ns_t_aaaa
@ ns_t_aaaa
Definition: arpa_nameser.h:329
SPF_dns_rr_dup
SPF_errcode_t SPF_dns_rr_dup(SPF_dns_rr_t **dstp, SPF_dns_rr_t *src)
Definition: spf_dns_rr.c:189
SPF_dns_rr_data_t::mx
char mx[1]
Definition: spf_dns_rr.h:35
ns_t_any
@ ns_t_any
Definition: arpa_nameser.h:350
ns_t_txt
@ ns_t_txt
Definition: arpa_nameser.h:317
spf.h
SPF_dns_rr_t
Definition: spf_dns_rr.h:51
ns_t_invalid
@ ns_t_invalid
Definition: arpa_nameser.h:301
SPF_dns_rr_data_t::ptr
char ptr[1]
Definition: spf_dns_rr.h:34
SPF_dns_rr_free
void SPF_dns_rr_free(SPF_dns_rr_t *spfrr)
Definition: spf_dns_rr.c:114
SPF_dns_rr_t::domain_buf_len
size_t domain_buf_len
Definition: spf_dns_rr.h:54
SPF_dns_rr_buf_realloc
SPF_errcode_t SPF_dns_rr_buf_realloc(SPF_dns_rr_t *spfrr, int idx, size_t len)
Definition: spf_dns_rr.c:134
SPF_dns_rr_t::domain
char * domain
Definition: spf_dns_rr.h:53
ns_t_ptr
@ ns_t_ptr
Definition: arpa_nameser.h:313
SPF_E_SUCCESS
@ SPF_E_SUCCESS
Definition: spf_response.h:120
SPF_warningf
#define SPF_warningf
Definition: spf_log.h:78
spf_dns_internal.h
ns_t_spf
#define ns_t_spf
Definition: spf_dns.h:89
spf_dns.h
SPF_dns_rr_t::num_rr
int num_rr
Definition: spf_dns_rr.h:59
spf_internal.h
SPF_dns_rr_data_t::a
struct in_addr a
Definition: spf_dns_rr.h:33
SPF_dns_rr_new_init
SPF_dns_rr_t * SPF_dns_rr_new_init(SPF_dns_server_t *spf_dns_server, const char *domain, ns_type rr_type, int ttl, SPF_dns_stat_t herrno)
Definition: spf_dns_rr.c:61
SPF_E_NO_MEMORY
@ SPF_E_NO_MEMORY
Definition: spf_response.h:121
SPF_dns_rr_t::utc_ttl
time_t utc_ttl
Definition: spf_dns_rr.h:65
ns_t_mx
@ ns_t_mx
Definition: arpa_nameser.h:316
SPF_dns_rr_t::source
SPF_dns_server_t * source
Definition: spf_dns_rr.h:70
SPF_dns_rr_t::rr
SPF_dns_rr_data_t ** rr
Definition: spf_dns_rr.h:60
spf_dns_rr.h
SPF_dns_rr_t::rr_type
ns_type rr_type
Definition: spf_dns_rr.h:56
NULL
#define NULL
Definition: spf_internal.h:28
SPF_ASSERT_NOTNULL
#define SPF_ASSERT_NOTNULL(x)
Definition: spf_log.h:118
HOST_NOT_FOUND
#define HOST_NOT_FOUND
Definition: spf_dns.h:103
SPF_dns_rr_t::rr_buf_num
int rr_buf_num
Definition: spf_dns_rr.h:62
SPF_dns_rr_data_t
Definition: spf_dns_rr.h:32
SPF_dns_rr_data_t::aaaa
struct in6_addr aaaa
Definition: spf_dns_rr.h:37
SPF_dns_rr_new_nxdomain
SPF_dns_rr_t * SPF_dns_rr_new_nxdomain(SPF_dns_server_t *spf_dns_server, const char *domain)
Definition: spf_dns_rr.c:53
SPF_DNS_RR_REALLOC
#define SPF_DNS_RR_REALLOC(d, i, s)
SPF_dns_rr_new
SPF_dns_rr_t * SPF_dns_rr_new()
Definition: spf_dns_rr.c:93
spf_sys_config.h
SPF_dns_rr_t::herrno
SPF_dns_stat_t herrno
Definition: spf_dns_rr.h:66
SPF_dns_rr_t::hook
void * hook
Definition: spf_dns_rr.h:69
SPF_dns_rr_t::ttl
time_t ttl
Definition: spf_dns_rr.h:64
ns_t_a
@ ns_t_a
Definition: arpa_nameser.h:302