Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2001-2003 FhG Fokus |
3 | | * |
4 | | * This file is part of opensips, a free SIP server. |
5 | | * |
6 | | * opensips is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU General Public License as published by |
8 | | * the Free Software Foundation; either version 2 of the License, or |
9 | | * (at your option) any later version |
10 | | * |
11 | | * opensips is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program; if not, write to the Free Software |
18 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 | | * |
20 | | * History: |
21 | | * -------- |
22 | | * 2003-04-12 support for resolving ipv6 address references added (andrei) |
23 | | * 2004-07-28 darwin needs nameser_compat.h (andrei) |
24 | | * 2007-01-25 support for DNS failover added (bogdan) |
25 | | */ |
26 | | |
27 | | /*! |
28 | | * \file |
29 | | * \brief DNS resolver related functions |
30 | | */ |
31 | | |
32 | | |
33 | | #ifndef __resolve_h |
34 | | #define __resolve_h |
35 | | |
36 | | #include <sys/types.h> |
37 | | #include <sys/socket.h> |
38 | | #include <netdb.h> |
39 | | #include <arpa/nameser.h> |
40 | | |
41 | | #ifdef __OS_darwin |
42 | | #include <arpa/nameser_compat.h> |
43 | | #endif |
44 | | |
45 | | #include "mem/shm_mem.h" |
46 | | #include "ip_addr.h" |
47 | | #include "proxy.h" |
48 | | |
49 | | #ifndef MAXHOSTNAMELEN |
50 | | #define MAXHOSTNAMELEN 64 |
51 | | #endif |
52 | | |
53 | | |
54 | | #define MAX_QUERY_SIZE 8192 |
55 | | #define ANS_SIZE 8192 |
56 | 0 | #define DNS_HDR_SIZE 12 |
57 | 0 | #define MAX_DNS_NAME 256 |
58 | | #define MAX_DNS_STRING 255 |
59 | | |
60 | | /*! \brief this is not official yet */ |
61 | 0 | #define T_EBL 65300 |
62 | | |
63 | | typedef void* (fetch_dns_cache_f)(char *name,int r_type,int name_len); |
64 | | typedef int (put_dns_cache_f)(char *name,int r_type,void *record,int rdata_len, |
65 | | int failure,int ttl); |
66 | | |
67 | | extern fetch_dns_cache_f *dnscache_fetch_func; |
68 | | extern put_dns_cache_f *dnscache_put_func; |
69 | | |
70 | | /*! \brief query union*/ |
71 | | union dns_query{ |
72 | | HEADER hdr; |
73 | | unsigned char buff[MAX_QUERY_SIZE]; |
74 | | }; |
75 | | |
76 | | |
77 | | /*! \brief rdata struct*/ |
78 | | struct rdata { |
79 | | unsigned short type; |
80 | | unsigned short class; |
81 | | unsigned int ttl; |
82 | | void* rdata; |
83 | | struct rdata* next; |
84 | | }; |
85 | | |
86 | | |
87 | | /*! \brief srv rec. struct*/ |
88 | | struct srv_rdata { |
89 | | unsigned short priority; |
90 | | unsigned short weight; |
91 | | unsigned short running_sum; |
92 | | unsigned short port; |
93 | | unsigned int name_len; |
94 | | char name[MAX_DNS_NAME]; |
95 | | }; |
96 | | |
97 | | /*! \brief naptr rec. struct*/ |
98 | | struct naptr_rdata { |
99 | | unsigned short order; |
100 | | unsigned short pref; |
101 | | unsigned int flags_len; |
102 | | char flags[MAX_DNS_STRING]; |
103 | | unsigned int services_len; |
104 | | char services[MAX_DNS_STRING]; |
105 | | unsigned int regexp_len; |
106 | | char regexp[MAX_DNS_STRING]; |
107 | | unsigned int repl_len; /* not currently used */ |
108 | | char repl[MAX_DNS_NAME]; |
109 | | }; |
110 | | |
111 | | |
112 | | /*! \brief A rec. struct */ |
113 | | struct a_rdata { |
114 | | unsigned char ip[4]; |
115 | | }; |
116 | | |
117 | | struct aaaa_rdata { |
118 | | unsigned char ip6[16]; |
119 | | }; |
120 | | |
121 | | /*! \brief cname rec. struct*/ |
122 | | struct cname_rdata { |
123 | | char name[MAX_DNS_NAME]; |
124 | | }; |
125 | | |
126 | | /*! \brief txt rec. struct |
127 | | \note This is not strictly correct as TXT records *could* contain multiple strings. */ |
128 | | struct txt_rdata { |
129 | | char txt[MAX_DNS_NAME]; |
130 | | }; |
131 | | |
132 | | /*! \brief EBL rec. struct |
133 | | \note This is an experimental RR for infrastructure ENUM */ |
134 | | struct ebl_rdata { |
135 | | unsigned char position; |
136 | | unsigned int separator_len; |
137 | | char separator[MAX_DNS_NAME]; |
138 | | unsigned int apex_len; |
139 | | char apex[MAX_DNS_NAME]; |
140 | | }; |
141 | | |
142 | | /*! \brief DNS failover related structures */ |
143 | | struct dns_node { |
144 | | unsigned short type; |
145 | | unsigned short size; |
146 | | unsigned short idx; |
147 | | unsigned short no; |
148 | | struct dns_val *vals; |
149 | | struct dns_node *kids; |
150 | | }; |
151 | | |
152 | | |
153 | | struct rdata* get_record(char* name, int type); |
154 | | void free_rdata_list(struct rdata* head); |
155 | | |
156 | | |
157 | | extern int dns_try_ipv6; |
158 | | extern int dns_try_naptr; |
159 | | |
160 | | |
161 | | #define get_naptr(_rdata) \ |
162 | 0 | ( ((struct naptr_rdata*)(_rdata)->rdata) ) |
163 | | |
164 | | #define get_srv(_rdata) \ |
165 | 0 | ( ((struct srv_rdata*)(_rdata)->rdata) ) |
166 | | |
167 | | |
168 | | int check_ip_address(struct ip_addr* ip, str *name, |
169 | | unsigned short port, unsigned short proto, int resolver); |
170 | | |
171 | | struct hostent* sip_resolvehost(str* name, unsigned short* port, |
172 | | unsigned short *proto, int is_sips, struct dns_node **dn); |
173 | | |
174 | | struct hostent* resolvehost(char* name, int no_ip_test); |
175 | | |
176 | | struct hostent* rev_resolvehost(struct ip_addr *ip); |
177 | | |
178 | | /*! \brief free the DNS resolver state machine */ |
179 | | void free_dns_res( struct proxy_l *p ); |
180 | | |
181 | | /*! \brief make a perfect copy of a resolver state machine */ |
182 | | struct dns_node *dns_res_copy(struct dns_node *s); |
183 | | |
184 | | /*! \brief taked the next destination from a resolver state machine */ |
185 | | int get_next_su(struct proxy_l *p, union sockaddr_union* su, int add_to_bl); |
186 | | |
187 | | |
188 | | int resolv_init(); |
189 | | |
190 | | int resolv_blacklist_init(); |
191 | | |
192 | | |
193 | | |
194 | | static inline struct proxy_l* shm_clone_proxy(struct proxy_l *sp, |
195 | | unsigned int move_dn) |
196 | 0 | { |
197 | 0 | struct proxy_l *dp; |
198 | 0 |
|
199 | 0 | dp = (struct proxy_l*)shm_malloc(sizeof(struct proxy_l)); |
200 | 0 | if (dp==NULL) { |
201 | 0 | LM_ERR("no more shm memory\n"); |
202 | 0 | return 0; |
203 | 0 | } |
204 | 0 | memset( dp , 0 , sizeof(struct proxy_l)); |
205 | 0 |
|
206 | 0 | dp->port = sp->port; |
207 | 0 | dp->proto = sp->proto; |
208 | 0 | dp->addr_idx = sp->addr_idx; |
209 | 0 | dp->flags = PROXY_SHM_FLAG; |
210 | 0 |
|
211 | 0 | /* clone the hostent */ |
212 | 0 | if (hostent_shm_cpy( &dp->host, &sp->host)!=0) |
213 | 0 | goto error0; |
214 | 0 |
|
215 | 0 | /* clone the dns resolver */ |
216 | 0 | if (sp->dn) { |
217 | 0 | if (move_dn) { |
218 | 0 | dp->dn = sp->dn; |
219 | 0 | sp->dn = 0; |
220 | 0 | } else { |
221 | 0 | dp->dn = dns_res_copy(sp->dn); |
222 | 0 | if (dp->dn==NULL) |
223 | 0 | goto error1; |
224 | 0 | } |
225 | 0 | } |
226 | 0 |
|
227 | 0 | return dp; |
228 | 0 | error1: |
229 | 0 | free_shm_hostent(&dp->host); |
230 | 0 | error0: |
231 | 0 | shm_free(dp); |
232 | 0 | return 0; |
233 | 0 | } Unexecuted instantiation: route.c:shm_clone_proxy Unexecuted instantiation: socket_info.c:shm_clone_proxy Unexecuted instantiation: receive.c:shm_clone_proxy Unexecuted instantiation: forward.c:shm_clone_proxy Unexecuted instantiation: resolve.c:shm_clone_proxy Unexecuted instantiation: transformations.c:shm_clone_proxy Unexecuted instantiation: msg_translator.c:shm_clone_proxy Unexecuted instantiation: cfg.tab.c:shm_clone_proxy Unexecuted instantiation: proxy.c:shm_clone_proxy Unexecuted instantiation: core_cmds.c:shm_clone_proxy |
234 | | |
235 | | |
236 | | |
237 | | #endif |