00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef __resolve_h
00036 #define __resolve_h
00037
00038 #include <sys/types.h>
00039 #include <sys/socket.h>
00040 #include <netdb.h>
00041 #include <arpa/nameser.h>
00042
00043 #ifdef __OS_darwin
00044 #include <arpa/nameser_compat.h>
00045 #endif
00046
00047 #include "ip_addr.h"
00048 #include "proxy.h"
00049
00050
00051 #define MAX_QUERY_SIZE 8192
00052 #define ANS_SIZE 8192
00053 #define DNS_HDR_SIZE 12
00054 #define MAX_DNS_NAME 256
00055 #define MAX_DNS_STRING 255
00056
00057
00058 #define T_EBL 65300
00059
00060
00061 union dns_query{
00062 HEADER hdr;
00063 unsigned char buff[MAX_QUERY_SIZE];
00064 };
00065
00066
00067
00068 struct rdata {
00069 unsigned short type;
00070 unsigned short class;
00071 unsigned int ttl;
00072 void* rdata;
00073 struct rdata* next;
00074 };
00075
00076
00077
00078 struct srv_rdata {
00079 unsigned short priority;
00080 unsigned short weight;
00081 unsigned short running_sum;
00082 unsigned short port;
00083 unsigned int name_len;
00084 char name[MAX_DNS_NAME];
00085 };
00086
00087
00088 struct naptr_rdata {
00089 unsigned short order;
00090 unsigned short pref;
00091 unsigned int flags_len;
00092 char flags[MAX_DNS_STRING];
00093 unsigned int services_len;
00094 char services[MAX_DNS_STRING];
00095 unsigned int regexp_len;
00096 char regexp[MAX_DNS_STRING];
00097 unsigned int repl_len;
00098 char repl[MAX_DNS_NAME];
00099 };
00100
00101
00102
00103 struct a_rdata {
00104 unsigned char ip[4];
00105 };
00106
00107 struct aaaa_rdata {
00108 unsigned char ip6[16];
00109 };
00110
00111
00112 struct cname_rdata {
00113 char name[MAX_DNS_NAME];
00114 };
00115
00116
00117
00118 struct txt_rdata {
00119 char txt[MAX_DNS_NAME];
00120 };
00121
00122
00123
00124 struct ebl_rdata {
00125 unsigned char position;
00126 unsigned int separator_len;
00127 char separator[MAX_DNS_NAME];
00128 unsigned int apex_len;
00129 char apex[MAX_DNS_NAME];
00130 };
00131
00132
00133 struct dns_node {
00134 unsigned short type;
00135 unsigned short size;
00136 unsigned short idx;
00137 unsigned short no;
00138 struct dns_val *vals;
00139 struct dns_node *kids;
00140 };
00141
00142
00143 struct rdata* get_record(char* name, int type);
00144 void free_rdata_list(struct rdata* head);
00145
00146
00147 extern int dns_try_ipv6;
00148
00149
00150 #define rev_resolvehost(ip)\
00151 gethostbyaddr((char*)(ip)->u.addr, (ip)->len, (ip)->af);
00152
00153
00154
00155 #define HEX2I(c) \
00156 ( (((c)>='0') && ((c)<='9'))? (c)-'0' : \
00157 (((c)>='A') && ((c)<='F'))? ((c)-'A')+10 : \
00158 (((c)>='a') && ((c)<='f'))? ((c)-'a')+10 : -1 )
00159
00160
00161 #define get_naptr(_rdata) \
00162 ( ((struct naptr_rdata*)(_rdata)->rdata) )
00163
00164 #define get_srv(_rdata) \
00165 ( ((struct srv_rdata*)(_rdata)->rdata) )
00166
00167
00168
00169
00170
00171 static inline struct ip_addr* str2ip(str* st)
00172 {
00173 int i;
00174 unsigned char *limit;
00175 static struct ip_addr ip;
00176 unsigned char* s;
00177
00178 s=(unsigned char*)st->s;
00179
00180
00181 ip.u.addr32[0]=0;
00182 i=0;
00183 limit=(unsigned char*)(st->s + st->len);
00184
00185 for(;s<limit ;s++){
00186 if (*s=='.'){
00187 i++;
00188 if (i>3) goto error_dots;
00189 }else if ( (*s <= '9' ) && (*s >= '0') ){
00190 ip.u.addr[i]=ip.u.addr[i]*10+*s-'0';
00191 }else{
00192
00193 goto error_char;
00194 }
00195 }
00196 if (i<3) goto error_dots;
00197 ip.af=AF_INET;
00198 ip.len=4;
00199
00200 return &ip;
00201 error_dots:
00202 LM_DBG("too %s dots in [%.*s]\n", (i>3)?"many":"few",
00203 st->len, st->s);
00204 return 0;
00205 error_char:
00206
00207
00208
00209 return 0;
00210 }
00211
00212
00213
00214
00215
00216 static inline struct ip_addr* str2ip6(str* st)
00217 {
00218 int i, idx1, rest, no_colons, double_colon, hex;
00219 static struct ip_addr ip;
00220 unsigned short *addr_start, *addr;
00221 unsigned short addr_end[8];
00222 unsigned char *limit, *s;
00223
00224
00225 if ((st->len) && (st->s[0]=='[')){
00226
00227 if (st->s[st->len-1]!=']') goto error_char;
00228 s=(unsigned char*)(st->s+1);
00229 limit=(unsigned char*)(st->s+st->len-1);
00230 }else{
00231 s=(unsigned char*)st->s;
00232 limit=(unsigned char*)(st->s+st->len);
00233 }
00234 i=idx1=rest=0;
00235 double_colon=0;
00236 no_colons=0;
00237 ip.af=AF_INET6;
00238 ip.len=16;
00239 addr_start=ip.u.addr16;
00240 addr=addr_start;
00241 memset(addr_start, 0 , 8*sizeof(unsigned short));
00242 memset(addr_end, 0 , 8*sizeof(unsigned short));
00243 for (; s<limit; s++){
00244 if (*s==':'){
00245 no_colons++;
00246 if (no_colons>7) goto error_too_many_colons;
00247 if (double_colon){
00248 idx1=i;
00249 i=0;
00250 if (addr==addr_end) goto error_colons;
00251 addr=addr_end;
00252 }else{
00253 double_colon=1;
00254 addr[i]=htons(addr[i]);
00255 i++;
00256 }
00257 }else if ((hex=HEX2I(*s))>=0){
00258 addr[i]=addr[i]*16+hex;
00259 double_colon=0;
00260 }else{
00261
00262 goto error_char;
00263 }
00264 }
00265 if (!double_colon){
00266 addr[i]=htons(addr[i]);
00267 i++;
00268 }
00269
00270 if (addr==addr_end){
00271 rest=8-i-idx1;
00272 memcpy(addr_start+idx1+rest, addr_end, i*sizeof(unsigned short));
00273 }else{
00274
00275 if (no_colons<7) goto error_too_few_colons;
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285 return &ip;
00286
00287 error_too_many_colons:
00288 LM_DBG("too many colons in [%.*s]\n", st->len, st->s);
00289 return 0;
00290
00291 error_too_few_colons:
00292 LM_DBG("too few colons in [%.*s]\n", st->len, st->s);
00293 return 0;
00294
00295 error_colons:
00296 LM_DBG("too many double colons in [%.*s]\n", st->len, st->s);
00297 return 0;
00298
00299 error_char:
00300
00301
00302
00303 return 0;
00304 }
00305
00306
00307 struct hostent* sip_resolvehost(str* name, unsigned short* port,
00308 unsigned short *proto, int is_sips, struct dns_node **dn);
00309
00310
00311
00312
00313
00314
00315 static inline struct hostent* resolvehost(char* name, int no_ip_test)
00316 {
00317 static struct hostent* he=0;
00318 #ifdef HAVE_GETIPNODEBYNAME
00319 int err;
00320 static struct hostent* he2=0;
00321 #endif
00322 struct ip_addr* ip;
00323 str s;
00324
00325 if (!no_ip_test) {
00326 s.s = (char*)name;
00327 s.len = strlen(name);
00328
00329
00330 if ( ((ip=str2ip(&s))!=0)
00331 #ifdef USE_IPV6
00332 || ((ip=str2ip6(&s))!=0)
00333 #endif
00334 ){
00335
00336 return ip_addr2he(&s, ip);
00337 }
00338 }
00339
00340
00341 he=gethostbyname(name);
00342 #ifdef USE_IPV6
00343 if(he==0 && dns_try_ipv6){
00344
00345 #ifdef HAVE_GETHOSTBYNAME2
00346 he=gethostbyname2(name, AF_INET6);
00347 #elif defined HAVE_GETIPNODEBYNAME
00348
00349
00350
00351 if (he2) freehostent(he2);
00352 he=he2=getipnodebyname(name, AF_INET6, 0, &err);
00353 #else
00354 #error neither gethostbyname2 or getipnodebyname present
00355 #endif
00356 }
00357 #endif
00358 return he;
00359 }
00360
00361
00362
00363 void free_dns_res( struct proxy_l *p );
00364
00365
00366 struct dns_node *dns_res_copy(struct dns_node *s);
00367
00368
00369 int get_next_su(struct proxy_l *p, union sockaddr_union* su, int add_to_bl);
00370
00371
00372 int resolv_init(void);
00373
00374 int resolv_blacklist_init(void);
00375
00376
00377 #endif