... | ... |
@@ -8,7 +8,7 @@ |
8 | 8 |
VERSION = 0 |
9 | 9 |
PATCHLEVEL = 8 |
10 | 10 |
SUBLEVEL = 7 |
11 |
-EXTRAVERSION = -6-ipv6 |
|
11 |
+EXTRAVERSION = -7-srv |
|
12 | 12 |
|
13 | 13 |
RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) |
14 | 14 |
OS = $(shell uname -s) |
... | ... |
@@ -373,7 +373,7 @@ YACC=bison |
373 | 373 |
YACC_FLAGS=-d -b cfg |
374 | 374 |
# on linux and freebsd keep it empty (e.g. LIBS= ) |
375 | 375 |
# on solaris add -lxnet (e.g. LIBS= -lxnet) |
376 |
-LIBS=-lfl -ldl |
|
376 |
+LIBS=-lfl -ldl -lresolv |
|
377 | 377 |
|
378 | 378 |
|
379 | 379 |
#os specific stuff |
... | ... |
@@ -54,9 +54,12 @@ |
54 | 54 |
#define CRLF "\r\n" |
55 | 55 |
#define CRLF_LEN 2 |
56 | 56 |
|
57 |
-#define RECEIVED ";received=" |
|
57 |
+#define RECEIVED ";received=" |
|
58 | 58 |
#define RECEIVED_LEN 10 |
59 | 59 |
|
60 |
+#define SRV_PREFIX "_sip._udp." |
|
61 |
+#define SRV_PREFIX_LEN 10 |
|
62 |
+ |
|
60 | 63 |
/*used only if PKG_MALLOC is defined*/ |
61 | 64 |
#define PKG_MEM_POOL_SIZE 1024*1024 |
62 | 65 |
|
... | ... |
@@ -161,7 +161,8 @@ int update_sock_struct_from_via( union sockaddr_union* to, |
161 | 161 |
if (via->host.s[via->host.len]){ |
162 | 162 |
host_copy=pkg_malloc( via->host.len+1 ); |
163 | 163 |
if (!host_copy) { |
164 |
- LOG(L_NOTICE, "ERROR: update_sock_struct_from_via: not enough memory\n"); |
|
164 |
+ LOG(L_NOTICE, "ERROR: update_sock_struct_from_via:" |
|
165 |
+ " not enough memory\n"); |
|
165 | 166 |
return -1; |
166 | 167 |
} |
167 | 168 |
memcpy(host_copy, via->host.s, via->host.len ); |
... | ... |
@@ -6,6 +6,7 @@ |
6 | 6 |
*/ |
7 | 7 |
|
8 | 8 |
|
9 |
+#include "config.h" |
|
9 | 10 |
#include "proxy.h" |
10 | 11 |
#include "error.h" |
11 | 12 |
#include "dprint.h" |
... | ... |
@@ -158,15 +159,21 @@ error: |
158 | 159 |
|
159 | 160 |
|
160 | 161 |
|
161 |
-/* same as add_proxy, but it doesn't add the proxy to the list*/ |
|
162 |
+/* same as add_proxy, but it doesn't add the proxy to the list |
|
163 |
+ * uses also SRV if possible (quick hack) */ |
|
164 |
+ |
|
162 | 165 |
struct proxy_l* mk_proxy(char* name, unsigned short port) |
163 | 166 |
{ |
164 | 167 |
struct proxy_l* p; |
165 | 168 |
struct hostent* he; |
169 |
+ struct rdata* head; |
|
170 |
+ struct rdata* l; |
|
171 |
+ struct srv_rdata* srv; |
|
172 |
+ static char tmp[MAX_DNS_NAME]; /* tmp buff. for SRV lookups*/ |
|
173 |
+ int len; |
|
166 | 174 |
#ifdef DNS_IP_HACK |
167 | 175 |
int err; |
168 | 176 |
unsigned int ip; |
169 |
- int len; |
|
170 | 177 |
#endif |
171 | 178 |
|
172 | 179 |
p=(struct proxy_l*) malloc(sizeof(struct proxy_l)); |
... | ... |
@@ -177,7 +184,7 @@ struct proxy_l* mk_proxy(char* name, unsigned short port) |
177 | 184 |
} |
178 | 185 |
memset(p,0,sizeof(struct proxy_l)); |
179 | 186 |
p->name=name; |
180 |
- p->port=port; |
|
187 |
+ p->port=port?port:SIP_PORT; |
|
181 | 188 |
#ifdef DNS_IP_HACK |
182 | 189 |
/* fast ipv4 string to address conversion*/ |
183 | 190 |
len=strlen(name); |
... | ... |
@@ -219,6 +226,37 @@ struct proxy_l* mk_proxy(char* name, unsigned short port) |
219 | 226 |
#endif |
220 | 227 |
/* fail over to normal lookup */ |
221 | 228 |
|
229 |
+ /* try SRV if no port specified (draft-ietf-sip-srv-06) */ |
|
230 |
+ if (port==0){ |
|
231 |
+ len=strlen(name); |
|
232 |
+ if ((len+SRV_PREFIX_LEN+1)>MAX_DNS_NAME){ |
|
233 |
+ LOG(L_WARN, "WARNING: domain name too long (%d), unable" |
|
234 |
+ " to perform SRV lookup\n", len); |
|
235 |
+ }else{ |
|
236 |
+ memcpy(tmp, SRV_PREFIX, SRV_PREFIX_LEN); |
|
237 |
+ memcpy(tmp+SRV_PREFIX_LEN, name, len+1); /*include the ending 0*/ |
|
238 |
+ |
|
239 |
+ head=get_record(tmp, T_SRV); |
|
240 |
+ for(l=head; l; l=l->next){ |
|
241 |
+ if (l->type!=T_SRV) continue; /*should never happen*/ |
|
242 |
+ srv=(struct srv_rdata*) l->rdata; |
|
243 |
+ if (srv==0){ |
|
244 |
+ LOG(L_CRIT, "mk_proxy: BUG: null rdata\n"); |
|
245 |
+ free_rdata_list(head); |
|
246 |
+ break; |
|
247 |
+ } |
|
248 |
+ he=resolvehost(srv->name); |
|
249 |
+ if (he!=0){ |
|
250 |
+ DBG("mk_proxy: SRV(%s) = %s:%d\n", |
|
251 |
+ tmp, srv->name, srv->port); |
|
252 |
+ p->port=srv->port; |
|
253 |
+ free_rdata_list(head); /*clean up*/ |
|
254 |
+ goto copy_he; |
|
255 |
+ } |
|
256 |
+ } |
|
257 |
+ DBG(" not SRV record found for %s\n", name); |
|
258 |
+ } |
|
259 |
+ } |
|
222 | 260 |
he=resolvehost(name); |
223 | 261 |
if (he==0){ |
224 | 262 |
ser_error=E_BAD_ADDRESS; |
... | ... |
@@ -227,6 +265,7 @@ struct proxy_l* mk_proxy(char* name, unsigned short port) |
227 | 265 |
free(p); |
228 | 266 |
goto error; |
229 | 267 |
} |
268 |
+copy_he: |
|
230 | 269 |
if (hostent_cpy(&(p->host), he)!=0){ |
231 | 270 |
free(p); |
232 | 271 |
goto error; |
233 | 272 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,306 @@ |
1 |
+/* $Id$*/ |
|
2 |
+ |
|
3 |
+/* #include <arpa/nameser.h> -- included from resolve.h*/ |
|
4 |
+#include <netinet/in.h> |
|
5 |
+#include <resolv.h> |
|
6 |
+#include <string.h> |
|
7 |
+ |
|
8 |
+#include "resolve.h" |
|
9 |
+#include "dprint.h" |
|
10 |
+#include "mem/mem.h" |
|
11 |
+ |
|
12 |
+ |
|
13 |
+ |
|
14 |
+/* mallocs for local stuff */ |
|
15 |
+#define local_malloc pkg_malloc |
|
16 |
+#define local_free pkg_free |
|
17 |
+ |
|
18 |
+ |
|
19 |
+ |
|
20 |
+ /* skips over a domain name in a dns message |
|
21 |
+ * (it can be a sequence of labels ending in \0, a pointer or |
|
22 |
+ * a sequence of labels ending in a pointer -- see rfc1035 |
|
23 |
+ * returns pointer after the domain name or null on error*/ |
|
24 |
+unsigned char* dns_skipname(unsigned char* p, unsigned char* end) |
|
25 |
+{ |
|
26 |
+ while(p<end){ |
|
27 |
+ /* check if \0 (root label length) */ |
|
28 |
+ if (*p==0){ |
|
29 |
+ p+=1; |
|
30 |
+ break; |
|
31 |
+ } |
|
32 |
+ /* check if we found a pointer */ |
|
33 |
+ if (((*p)&0xc0)==0xc0){ |
|
34 |
+ /* if pointer skip over it (2 bytes) & we found the end */ |
|
35 |
+ p+=2; |
|
36 |
+ break; |
|
37 |
+ } |
|
38 |
+ /* normal label */ |
|
39 |
+ p+=*p+1; |
|
40 |
+ } |
|
41 |
+ return (p>end)?0:p; |
|
42 |
+} |
|
43 |
+ |
|
44 |
+ |
|
45 |
+ |
|
46 |
+/* parses the srv record into a srv_rdata structure |
|
47 |
+ * msg - pointer to the dns message |
|
48 |
+ * end - pointer to the end of the message |
|
49 |
+ * rdata - pointer to the rdata part of the srv answer |
|
50 |
+ * returns 0 on error, or a dyn. alloc'ed srv_rdata structure */ |
|
51 |
+/* SRV rdata format: |
|
52 |
+ * 111111 |
|
53 |
+ * 0123456789012345 |
|
54 |
+ * +----------------+ |
|
55 |
+ * | priority | |
|
56 |
+ * |----------------| |
|
57 |
+ * | weight | |
|
58 |
+ * |----------------| |
|
59 |
+ * | port number | |
|
60 |
+ * |----------------| |
|
61 |
+ * | | |
|
62 |
+ * ~ name ~ |
|
63 |
+ * | | |
|
64 |
+ * +----------------+ |
|
65 |
+ */ |
|
66 |
+struct srv_rdata* dns_srv_parser( unsigned char* msg, unsigned char* end, |
|
67 |
+ unsigned char* rdata) |
|
68 |
+{ |
|
69 |
+ struct srv_rdata* srv; |
|
70 |
+ int len; |
|
71 |
+ |
|
72 |
+ srv=0; |
|
73 |
+ if ((rdata+6)>end) goto error; |
|
74 |
+ srv=(struct srv_rdata*)local_malloc(sizeof(struct srv_rdata)); |
|
75 |
+ if (srv==0){ |
|
76 |
+ LOG(L_ERR, "ERROR: dns_srv_parser: outof memory\n"); |
|
77 |
+ goto error; |
|
78 |
+ } |
|
79 |
+ |
|
80 |
+ memcpy((void*)&srv->priority, rdata, 2); |
|
81 |
+ memcpy((void*)&srv->weight, rdata+2, 2); |
|
82 |
+ memcpy((void*)&srv->port, rdata+4, 2); |
|
83 |
+ rdata+=6; |
|
84 |
+ srv->priority=ntohs(srv->priority); |
|
85 |
+ srv->weight=ntohs(srv->weight); |
|
86 |
+ srv->port=ntohs(srv->port); |
|
87 |
+ if ((len=dn_expand(msg, end, rdata, srv->name, MAX_DNS_NAME))==-1) |
|
88 |
+ goto error; |
|
89 |
+ /* add terminatng 0 ? */ |
|
90 |
+ return srv; |
|
91 |
+error: |
|
92 |
+ if (srv) local_free(srv); |
|
93 |
+ return 0; |
|
94 |
+} |
|
95 |
+ |
|
96 |
+ |
|
97 |
+ |
|
98 |
+/* parses an A record rdata into an a_rdata structure |
|
99 |
+ * returns 0 on error or a dyn. alloc'ed a_rdata struct |
|
100 |
+ */ |
|
101 |
+struct a_rdata* dns_a_parser(unsigned char* rdata, unsigned char* end) |
|
102 |
+{ |
|
103 |
+ struct a_rdata* a; |
|
104 |
+ |
|
105 |
+ if (rdata+4>end) goto error; |
|
106 |
+ a=(struct a_rdata*)local_malloc(sizeof(struct a_rdata)); |
|
107 |
+ if (a==0){ |
|
108 |
+ LOG(L_ERR, "ERROR: dns_a_parser: out of memory\n"); |
|
109 |
+ goto error; |
|
110 |
+ } |
|
111 |
+ memcpy(a->ip, rdata, 4); |
|
112 |
+ return a; |
|
113 |
+error: |
|
114 |
+ return 0; |
|
115 |
+} |
|
116 |
+ |
|
117 |
+ |
|
118 |
+ |
|
119 |
+/* parses an AAAA (ipv6) record rdata into an aaaa_rdata structure |
|
120 |
+ * returns 0 on error or a dyn. alloc'ed aaaa_rdata struct */ |
|
121 |
+struct aaaa_rdata* dns_aaaa_parser(unsigned char* rdata, unsigned char* end) |
|
122 |
+{ |
|
123 |
+ struct aaaa_rdata* aaaa; |
|
124 |
+ |
|
125 |
+ if (rdata+16>end) goto error; |
|
126 |
+ aaaa=(struct aaaa_rdata*)local_malloc(sizeof(struct aaaa_rdata)); |
|
127 |
+ if (aaaa==0){ |
|
128 |
+ LOG(L_ERR, "ERROR: dns_aaaa_parser: out of memory\n"); |
|
129 |
+ goto error; |
|
130 |
+ } |
|
131 |
+ memcpy(aaaa->ip6, rdata, 16); |
|
132 |
+ return aaaa; |
|
133 |
+error: |
|
134 |
+ return 0; |
|
135 |
+} |
|
136 |
+ |
|
137 |
+ |
|
138 |
+ |
|
139 |
+/* frees completely a struct rdata list */ |
|
140 |
+void free_rdata_list(struct rdata* head) |
|
141 |
+{ |
|
142 |
+ struct rdata* l; |
|
143 |
+ for(l=head; l; l=l->next){ |
|
144 |
+ /* free the parsed rdata*/ |
|
145 |
+ if (l->rdata) local_free(l->rdata); |
|
146 |
+ local_free(l); |
|
147 |
+ } |
|
148 |
+} |
|
149 |
+ |
|
150 |
+ |
|
151 |
+ |
|
152 |
+/* gets the DNS records for name:type |
|
153 |
+ * returns a dyn. alloc'ed struct rdata linked list with the parsed responses |
|
154 |
+ * or 0 on error |
|
155 |
+ * see rfc1035 for the query/response format */ |
|
156 |
+struct rdata* get_record(char* name, int type) |
|
157 |
+{ |
|
158 |
+ int size; |
|
159 |
+ int qno, answers_no; |
|
160 |
+ int r,i; |
|
161 |
+ int ans_len; |
|
162 |
+ static union dns_query buff; |
|
163 |
+ unsigned char* p; |
|
164 |
+ unsigned char* t; |
|
165 |
+ unsigned char* end; |
|
166 |
+ static unsigned char answer[ANS_SIZE]; |
|
167 |
+ unsigned short rtype, class, rdlength; |
|
168 |
+ unsigned int ttl; |
|
169 |
+ struct rdata* head; |
|
170 |
+ struct rdata** crt; |
|
171 |
+ struct rdata* rd; |
|
172 |
+ struct srv_rdata* srv_rd; |
|
173 |
+ struct srv_rdata* crt_srv; |
|
174 |
+ |
|
175 |
+ |
|
176 |
+ |
|
177 |
+ head=rd=0; |
|
178 |
+ crt=&head; |
|
179 |
+ size=res_search(name, C_IN, type, buff.buff, sizeof(buff)); |
|
180 |
+ if (size<0) goto error; |
|
181 |
+ else if (size > sizeof(buff)) size=sizeof(buff); |
|
182 |
+ |
|
183 |
+ p=buff.buff+DNS_HDR_SIZE; |
|
184 |
+ end=buff.buff+size; |
|
185 |
+ if (p>end) goto error_boundary; |
|
186 |
+ qno=ntohs((unsigned short)buff.hdr.qdcount); |
|
187 |
+ |
|
188 |
+ for (r=0; r<qno; r++){ |
|
189 |
+ /* skip the name of the question */ |
|
190 |
+ if ((p=dns_skipname(p, end))==0) goto error; |
|
191 |
+ p+=2+2; /* skip QCODE & QCLASS */ |
|
192 |
+ #if 0 |
|
193 |
+ for (;(p<end && (*p)); p++); |
|
194 |
+ p+=1+2+2; /* skip the ending '\0, QCODE and QCLASS */ |
|
195 |
+ #endif |
|
196 |
+ if (p>end) goto error; |
|
197 |
+ }; |
|
198 |
+ answers_no=ntohs((unsigned short)buff.hdr.ancount); |
|
199 |
+ ans_len=ANS_SIZE; |
|
200 |
+ t=answer; |
|
201 |
+ for (r=0; (r<answers_no) && (p<end); r++){ |
|
202 |
+ /* ignore it the default domain name */ |
|
203 |
+ if ((p=dns_skipname(p, end))==0) goto error; |
|
204 |
+ /* |
|
205 |
+ skip=dn_expand(buff.buff, end, p, t, ans_len); |
|
206 |
+ p+=skip; |
|
207 |
+ */ |
|
208 |
+ /* check if enough space is left fot type, class, ttl & size */ |
|
209 |
+ if ((p+2+2+4+2)>end) goto error_boundary; |
|
210 |
+ /* get type */ |
|
211 |
+ memcpy((void*) &rtype, (void*)p, 2); |
|
212 |
+ rtype=ntohs(rtype); |
|
213 |
+ p+=2; |
|
214 |
+ /* get class */ |
|
215 |
+ memcpy((void*) &class, (void*)p, 2); |
|
216 |
+ class=ntohs(class); |
|
217 |
+ p+=2; |
|
218 |
+ /* get ttl*/ |
|
219 |
+ memcpy((void*) &ttl, (void*)p, 4); |
|
220 |
+ ttl=ntohl(ttl); |
|
221 |
+ p+=4; |
|
222 |
+ /* get size */ |
|
223 |
+ memcpy((void*)&rdlength, (void*)p, 2); |
|
224 |
+ rdlength=ntohs(rdlength); |
|
225 |
+ p+=2; |
|
226 |
+ /* check for type */ |
|
227 |
+ if (rtype!=type){ |
|
228 |
+ LOG(L_WARN, "WARNING: get_record: wrong type in answer\n"); |
|
229 |
+ p+=rdlength; |
|
230 |
+ continue; |
|
231 |
+ } |
|
232 |
+ /* expand the "type" record (rdata)*/ |
|
233 |
+ /* print it */ |
|
234 |
+ /* |
|
235 |
+ printf("\ntype=%d class= %d, ttl= %d, rdlength= %d\n", |
|
236 |
+ rtype, class, ttl, rdlength); |
|
237 |
+ for (i=0;i<rdlength;i++){ |
|
238 |
+ printf("%x ", *(p+i)); |
|
239 |
+ } |
|
240 |
+ printf("\n"); |
|
241 |
+ */ |
|
242 |
+ rd=(struct rdata*) local_malloc(sizeof(struct rdata)); |
|
243 |
+ if (rd==0){ |
|
244 |
+ LOG(L_ERR, "ERROR: get_record: out of memory\n"); |
|
245 |
+ goto error; |
|
246 |
+ } |
|
247 |
+ rd->type=rtype; |
|
248 |
+ rd->class=class; |
|
249 |
+ rd->ttl=ttl; |
|
250 |
+ switch(type){ |
|
251 |
+ case T_SRV: |
|
252 |
+ srv_rd= dns_srv_parser(buff.buff, end, p); |
|
253 |
+ rd->rdata=(void*)srv_rd; |
|
254 |
+ if (srv_rd==0) goto error_parse; |
|
255 |
+ |
|
256 |
+ /* insert sorted into the list |
|
257 |
+ * crt reused */ |
|
258 |
+ for (crt=&head; *crt; crt= &((*crt)->next)){ |
|
259 |
+ crt_srv=(struct srv_rdata*)(*crt)->rdata; |
|
260 |
+ if ((srv_rd->priority < crt_srv->priority) || |
|
261 |
+ ( (srv_rd->priority == crt_srv->priority) && |
|
262 |
+ (srv_rd->weight > crt_srv->weight) ) ){ |
|
263 |
+ /* insert here */ |
|
264 |
+ break; |
|
265 |
+ } |
|
266 |
+ } |
|
267 |
+ /* insert here */ |
|
268 |
+ rd->next=*crt; |
|
269 |
+ *crt=rd; |
|
270 |
+ |
|
271 |
+ break; |
|
272 |
+ case T_A: |
|
273 |
+ rd->rdata=(void*) dns_a_parser(p,end); |
|
274 |
+ if (rd->rdata==0) goto error_parse; |
|
275 |
+ *crt=rd; /* crt points to the last "next" or the list head*/ |
|
276 |
+ crt=&(rd->next); |
|
277 |
+ break; |
|
278 |
+ case T_AAAA: |
|
279 |
+ rd->rdata=(void*) dns_aaaa_parser(p,end); |
|
280 |
+ if (rd->rdata==0) goto error_parse; |
|
281 |
+ *crt=rd; |
|
282 |
+ crt=&(rd->next); |
|
283 |
+ break; |
|
284 |
+ default: |
|
285 |
+ LOG(L_ERR, "BUG: get_record: unknown type %d\n", type); |
|
286 |
+ rd->rdata=0; |
|
287 |
+ goto error; |
|
288 |
+ } |
|
289 |
+ |
|
290 |
+ p+=rdlength; |
|
291 |
+ |
|
292 |
+ } |
|
293 |
+ return head; |
|
294 |
+error_boundary: |
|
295 |
+ LOG(L_ERR, "ERROR: get_record: end of query buff reached\n"); |
|
296 |
+ return 0; |
|
297 |
+error_parse: |
|
298 |
+ LOG(L_ERR, "ERROR: get_record: rdata parse error \n"); |
|
299 |
+ if (rd) local_free(rd); /* rd->rdata=0 & rd is not linked yet into |
|
300 |
+ the list */ |
|
301 |
+error: |
|
302 |
+ LOG(L_ERR, "ERROR: get_record \n"); |
|
303 |
+ if (head) free_rdata_list(head); |
|
304 |
+ return 0; |
|
305 |
+} |
|
306 |
+ |
... | ... |
@@ -9,14 +9,60 @@ |
9 | 9 |
#define resolve_h |
10 | 10 |
|
11 | 11 |
#include <netdb.h> |
12 |
+#include <arpa/nameser.h> |
|
12 | 13 |
|
13 |
-#include "ip_addr.h" |
|
14 | 14 |
|
15 |
+#define MAX_QUERY_SIZE 8192 |
|
16 |
+#define ANS_SIZE 8192 |
|
17 |
+#define DNS_HDR_SIZE 12 |
|
18 |
+#define MAX_DNS_NAME 256 |
|
15 | 19 |
|
16 |
-/* gethostbyname wrappers |
|
17 |
- * use this, someday htey will use a local cache */ |
|
18 | 20 |
|
19 | 21 |
|
22 |
+/* query union*/ |
|
23 |
+union dns_query{ |
|
24 |
+ HEADER hdr; |
|
25 |
+ unsigned char buff[MAX_QUERY_SIZE]; |
|
26 |
+}; |
|
27 |
+ |
|
28 |
+ |
|
29 |
+/* rdata struct*/ |
|
30 |
+struct rdata { |
|
31 |
+ unsigned short type; |
|
32 |
+ unsigned short class; |
|
33 |
+ unsigned int ttl; |
|
34 |
+ void* rdata; |
|
35 |
+ struct rdata* next; |
|
36 |
+}; |
|
37 |
+ |
|
38 |
+ |
|
39 |
+/* srv rec. struct*/ |
|
40 |
+struct srv_rdata { |
|
41 |
+ unsigned short priority; |
|
42 |
+ unsigned short weight; |
|
43 |
+ unsigned short port; |
|
44 |
+ unsigned int name_len; |
|
45 |
+ char name[MAX_DNS_NAME]; |
|
46 |
+}; |
|
47 |
+ |
|
48 |
+ |
|
49 |
+/* A rec. struct */ |
|
50 |
+struct a_rdata { |
|
51 |
+ unsigned char ip[4]; |
|
52 |
+}; |
|
53 |
+ |
|
54 |
+struct aaaa_rdata { |
|
55 |
+ unsigned char ip6[16]; |
|
56 |
+}; |
|
57 |
+ |
|
58 |
+ |
|
59 |
+ |
|
60 |
+struct rdata* get_record(char* name, int type); |
|
61 |
+void free_rdata_list(struct rdata* head); |
|
62 |
+ |
|
63 |
+ |
|
64 |
+/* gethostbyname wrappers |
|
65 |
+ * use this, someday htey will use a local cache */ |
|
20 | 66 |
|
21 | 67 |
static inline struct hostent* resolvehost(const char* name) |
22 | 68 |
{ |
23 | 69 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,150 @@ |
1 |
+/* |
|
2 |
+ * $Id$ |
|
3 |
+ * |
|
4 |
+ * tests for ../resolver.c |
|
5 |
+ */ |
|
6 |
+ |
|
7 |
+#include <stdio.h> |
|
8 |
+#include <stdlib.h> |
|
9 |
+#include <errno.h> |
|
10 |
+#include <string.h> |
|
11 |
+#include <unistd.h> |
|
12 |
+ |
|
13 |
+#include "../resolve.h" |
|
14 |
+ |
|
15 |
+/* symbols needed by dprint */ |
|
16 |
+int log_stderr=1; |
|
17 |
+int debug=0; |
|
18 |
+int pids[1]; |
|
19 |
+int process_no=0; |
|
20 |
+ |
|
21 |
+ |
|
22 |
+static char* id="$Id$"; |
|
23 |
+static char* version="dns_query 0.1"; |
|
24 |
+static char* help_msg="\ |
|
25 |
+Usage: dns_query [-t type] [-hV] -n host\n\ |
|
26 |
+Options:\n\ |
|
27 |
+ -n host host name\n\ |
|
28 |
+ -t type query type (default A)\n\ |
|
29 |
+ -V version number\n\ |
|
30 |
+ -h this help message\n\ |
|
31 |
+"; |
|
32 |
+ |
|
33 |
+ |
|
34 |
+int main(int argc, char** argv) |
|
35 |
+{ |
|
36 |
+ char c; |
|
37 |
+ char* name; |
|
38 |
+ char* type_str; |
|
39 |
+ int type; |
|
40 |
+ int r; |
|
41 |
+ struct rdata* head; |
|
42 |
+ struct rdata* l; |
|
43 |
+ struct srv_rdata* srv; |
|
44 |
+ struct a_rdata* ip; |
|
45 |
+ |
|
46 |
+ name=type_str=0; |
|
47 |
+ |
|
48 |
+ opterr=0; |
|
49 |
+ while ((c=getopt(argc, argv, "n:t:hV"))!=-1){ |
|
50 |
+ switch(c){ |
|
51 |
+ case 'n': |
|
52 |
+ name=optarg; |
|
53 |
+ break; |
|
54 |
+ case 't': |
|
55 |
+ type_str=optarg; |
|
56 |
+ break; |
|
57 |
+ case 'V': |
|
58 |
+ printf("version: %s\n", version); |
|
59 |
+ printf("%s\n", id); |
|
60 |
+ exit(0); |
|
61 |
+ break; |
|
62 |
+ case 'h': |
|
63 |
+ printf("version: %s\n", version); |
|
64 |
+ printf("%s", help_msg); |
|
65 |
+ exit(0); |
|
66 |
+ break; |
|
67 |
+ case '?': |
|
68 |
+ if (isprint(optopt)) |
|
69 |
+ fprintf(stderr, "Unknown option `-%c�\n", optopt); |
|
70 |
+ else |
|
71 |
+ fprintf(stderr, "Unknown character `\\x%x�\n", optopt); |
|
72 |
+ goto error; |
|
73 |
+ case ':': |
|
74 |
+ fprintf(stderr, "Option `-%c� requires an argument.\n", |
|
75 |
+ optopt); |
|
76 |
+ goto error; |
|
77 |
+ break; |
|
78 |
+ default: |
|
79 |
+ abort(); |
|
80 |
+ } |
|
81 |
+ } |
|
82 |
+ |
|
83 |
+ if (name==0){ |
|
84 |
+ fprintf(stderr, "Missing domain name (-n name)\n"); |
|
85 |
+ goto error; |
|
86 |
+ } |
|
87 |
+ type=T_A; |
|
88 |
+ if (type_str){ |
|
89 |
+ if (strcasecmp(type_str, "A")==0) type=T_A; |
|
90 |
+ else if (strcasecmp(type_str, "NS")==0) type=T_NS; |
|
91 |
+ else if (strcasecmp(type_str, "MD")==0) type=T_MD; |
|
92 |
+ else if (strcasecmp(type_str, "MF")==0) type=T_MF; |
|
93 |
+ else if (strcasecmp(type_str, "CNAME")==0) type=T_CNAME; |
|
94 |
+ else if (strcasecmp(type_str, "SOA")==0) type=T_SOA; |
|
95 |
+ else if (strcasecmp(type_str, "PTR")==0) type=T_PTR; |
|
96 |
+ else if (strcasecmp(type_str, "HINFO")==0) type=T_HINFO; |
|
97 |
+ else if (strcasecmp(type_str, "MINFO")==0) type=T_MINFO; |
|
98 |
+ else if (strcasecmp(type_str, "MX")==0) type=T_MX; |
|
99 |
+ else if (strcasecmp(type_str, "TXT")==0) type=T_TXT; |
|
100 |
+ else if (strcasecmp(type_str, "AAAA")==0) type=T_AAAA; |
|
101 |
+ else if (strcasecmp(type_str, "SRV")==0) type=T_SRV; |
|
102 |
+ else if (strcasecmp(type_str, "NAPTR")==0) type=T_NAPTR; |
|
103 |
+ else if (strcasecmp(type_str, "AXFR")==0) type=T_AXFR; |
|
104 |
+ else{ |
|
105 |
+ fprintf(stderr, "Unknown query type %s\n", type_str); |
|
106 |
+ goto error; |
|
107 |
+ } |
|
108 |
+ } |
|
109 |
+ printf("calling get_record...\n"); |
|
110 |
+ head=get_record(name, type); |
|
111 |
+ if (head==0) printf("no answer\n"); |
|
112 |
+ else{ |
|
113 |
+ printf("records:\n"); |
|
114 |
+ for(l=head; l; l=l->next){ |
|
115 |
+ switch(l->type){ |
|
116 |
+ case T_SRV: |
|
117 |
+ srv=(struct srv_rdata*)l->rdata; |
|
118 |
+ printf("SRV type= %d class=%d ttl=%d\n", |
|
119 |
+ l->type, l->class, l->ttl); |
|
120 |
+ printf(" prio= %d weight=%d port=%d\n", |
|
121 |
+ srv->priority, srv->weight, srv->port); |
|
122 |
+ printf(" name= [%s]\n", srv->name); |
|
123 |
+ break; |
|
124 |
+ case T_A: |
|
125 |
+ ip=(struct a_rdata*)l->rdata; |
|
126 |
+ printf("A type= %d class=%d ttl=%d\n", |
|
127 |
+ l->type, l->class, l->ttl); |
|
128 |
+ printf(" ip= %d.%d.%d.%d\n", |
|
129 |
+ ip->ip[0], ip->ip[1], ip->ip[2], ip->ip[3]); |
|
130 |
+ break; |
|
131 |
+ case T_AAAA: |
|
132 |
+ printf("AAAA type= %d class=%d ttl=%d\n", |
|
133 |
+ l->type, l->class, l->ttl); |
|
134 |
+ printf(" ip6= "); |
|
135 |
+ for(r=0;r<16;r++) |
|
136 |
+ printf("%x ", ((struct aaaa_rdata*)l->rdata)->ip6[r]); |
|
137 |
+ printf("\n"); |
|
138 |
+ break; |
|
139 |
+ default: |
|
140 |
+ printf("UNKN type= %d class=%d ttl=%d\n", |
|
141 |
+ l->type, l->class, l->ttl); |
|
142 |
+ printf(" rdata=%p\n", l->rdata); |
|
143 |
+ } |
|
144 |
+ } |
|
145 |
+ } |
|
146 |
+ printf("done\n"); |
|
147 |
+ exit(0); |
|
148 |
+error: |
|
149 |
+ exit(-1); |
|
150 |
+} |
0 | 151 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,23 @@ |
1 |
+INVITE sip:andrei@iptel.org SIP/2.0 |
|
2 |
+Via: SIP/2.0/UDP dorian.fokus.gmd.de |
|
3 |
+From: "GMD FOKUS iptlab" <sip:jiri@iptel.org>;tag=b96b0300ed30f1286-2f5d |
|
4 |
+Call-ID: b96b0300-88d30f-66da-63aa@195.37.78.190 |
|
5 |
+CSeq: 101 INVITE |
|
6 |
+Expires: 180 |
|
7 |
+Max-Forwards: 0 |
|
8 |
+User-Agent: Cisco-SIP-IP-Phone/2 |
|
9 |
+Accept: application/sdp |
|
10 |
+Contact: sip:jiri@195.37.78.190:5060 |
|
11 |
+Content-Type: application/sdp |
|
12 |
+Content-Length: 225 |
|
13 |
+ |
|
14 |
+ |
|
15 |
+v=0 |
|
16 |
+o=CiscoSystemsSIP-IPPhone-UserAgent 14474 8233 IN IP4 195.37.78.190 |
|
17 |
+s=SIP Call |
|
18 |
+c=IN IP4 195.37.78.190 |
|
19 |
+t=0 0 |
|
20 |
+m=audio 18456 RTP/AVP 0 8 18 101 |
|
21 |
+a=rtpmap:0 pcmu/8000 |
|
22 |
+a=rtpmap:101 telephone-event/8000 |
|
23 |
+a=fmtp:101 0-11 |
... | ... |
@@ -8,7 +8,7 @@ |
8 | 8 |
debug=9 # debug level (cmd line: -dddddddddd) |
9 | 9 |
#fork=yes # (cmd. line: -D) |
10 | 10 |
fork=yes |
11 |
-#fork=no |
|
11 |
+fork=no |
|
12 | 12 |
log_stderror=yes # (cmd line: -E) |
13 | 13 |
#log_stderror=no # (cmd line: -E) |
14 | 14 |
|
... | ... |
@@ -26,7 +26,6 @@ loop_checks=0 |
26 | 26 |
# for more info: sip_router -h |
27 | 27 |
|
28 | 28 |
#modules |
29 |
-loadmodule "modules/tm/tm.so" |
|
30 | 29 |
|
31 | 30 |
|
32 | 31 |
route{ |