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
00036
00037
00038 #include "config.h"
00039 #include "globals.h"
00040 #include "proxy.h"
00041 #include "error.h"
00042 #include "dprint.h"
00043 #include "mem/mem.h"
00044 #include "mem/shm_mem.h"
00045
00046 #include <string.h>
00047 #include <stdlib.h>
00048 #include <sys/socket.h>
00049
00050 #ifdef DNS_IP_HACK
00051 #include "ut.h"
00052 #endif
00053
00054 #include "resolve.h"
00055 #include "ip_addr.h"
00056 #include "globals.h"
00057
00058
00059
00060 struct proxy_l* proxies=0;
00061
00062
00063 int disable_dns_failover=0;
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 static struct proxy_l* find_proxy(str *name, unsigned short port, int proto)
00077 {
00078 struct proxy_l* t;
00079 for(t=proxies; t; t=t->next)
00080 if (((t->name.len == name->len) &&
00081 ((proto==PROTO_NONE)||(t->proto==proto))&&
00082 (strncasecmp(t->name.s, name->s, name->len)==0)) &&
00083 (t->port==port))
00084 break;
00085 return t;
00086 }
00087
00088
00089
00090
00091
00092
00093
00094
00095 int hostent_shm_cpy(struct hostent *dst, struct hostent* src)
00096 {
00097 int i;
00098 char *p;
00099
00100 for( i=0 ; src->h_addr_list[i] ; i++ );
00101
00102 dst->h_addr_list = (char**)shm_malloc
00103 (i * (src->h_length + sizeof(char*)) + sizeof(char*));
00104 if (dst->h_addr_list==NULL)
00105 return -1;
00106
00107 p = ((char*)dst->h_addr_list) + (i+1)*sizeof(char*);
00108 dst->h_addr_list[i] = 0;
00109
00110 for( i-- ; i>=0 ; i-- ) {
00111 dst->h_addr_list[i] = p;
00112 memcpy( dst->h_addr_list[i], src->h_addr_list[i], src->h_length );
00113 p += src->h_length;
00114 }
00115
00116 dst->h_addr = dst->h_addr_list[0];
00117 dst->h_addrtype = src->h_addrtype;
00118 dst->h_length = src->h_length;
00119 return 0;
00120 }
00121
00122
00123
00124
00125
00126
00127 void free_shm_hostent(struct hostent *dst)
00128 {
00129 if (dst->h_addr_list)
00130 shm_free(dst->h_addr_list);
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140 int hostent_cpy(struct hostent *dst, struct hostent* src)
00141 {
00142 unsigned int len,len2, i, r;
00143 int ret;
00144
00145
00146
00147 len=strlen(src->h_name)+1;
00148 dst->h_name=(char*)pkg_malloc(sizeof(char) * len);
00149 if (dst->h_name) strncpy(dst->h_name,src->h_name, len);
00150 else{
00151 ser_error=ret=E_OUT_OF_MEM;
00152 goto error;
00153 }
00154
00155
00156 len=0;
00157 if (src->h_aliases)
00158 for (;src->h_aliases[len];len++);
00159 dst->h_aliases=(char**)pkg_malloc(sizeof(char*)*(len+1));
00160 if (dst->h_aliases==0){
00161 ser_error=ret=E_OUT_OF_MEM;
00162 pkg_free(dst->h_name);
00163 goto error;
00164 }
00165 memset((void*)dst->h_aliases, 0, sizeof(char*) * (len+1) );
00166 for (i=0;i<len;i++){
00167 len2=strlen(src->h_aliases[i])+1;
00168 dst->h_aliases[i]=(char*)pkg_malloc(sizeof(char)*len2);
00169 if (dst->h_aliases==0){
00170 ser_error=ret=E_OUT_OF_MEM;
00171 pkg_free(dst->h_name);
00172 for(r=0; r<i; r++) pkg_free(dst->h_aliases[r]);
00173 pkg_free(dst->h_aliases);
00174 goto error;
00175 }
00176 strncpy(dst->h_aliases[i], src->h_aliases[i], len2);
00177 }
00178
00179 len=0;
00180 if (src->h_addr_list)
00181 for (;src->h_addr_list[len];len++);
00182 dst->h_addr_list=(char**)pkg_malloc(sizeof(char*)*(len+1));
00183 if (dst->h_addr_list==0){
00184 ser_error=ret=E_OUT_OF_MEM;
00185 pkg_free(dst->h_name);
00186 for(r=0; dst->h_aliases[r]; r++) pkg_free(dst->h_aliases[r]);
00187 pkg_free(dst->h_aliases[r]);
00188 pkg_free(dst->h_aliases);
00189 goto error;
00190 }
00191 memset((void*)dst->h_addr_list, 0, sizeof(char*) * (len+1) );
00192 for (i=0;i<len;i++){
00193 dst->h_addr_list[i]=(char*)pkg_malloc(sizeof(char)*src->h_length);
00194 if (dst->h_addr_list[i]==0){
00195 ser_error=ret=E_OUT_OF_MEM;
00196 pkg_free(dst->h_name);
00197 for(r=0; dst->h_aliases[r]; r++) pkg_free(dst->h_aliases[r]);
00198 pkg_free(dst->h_aliases[r]);
00199 pkg_free(dst->h_aliases);
00200 for (r=0; r<i;r++) pkg_free(dst->h_addr_list[r]);
00201 pkg_free(dst->h_addr_list);
00202 goto error;
00203 }
00204 memcpy(dst->h_addr_list[i], src->h_addr_list[i], src->h_length);
00205 }
00206
00207
00208 dst->h_addrtype=src->h_addrtype;
00209 dst->h_length=src->h_length;
00210
00211
00212 return 0;
00213
00214 error:
00215 LM_CRIT("pkg memory allocation failure\n");
00216 return ret;
00217 }
00218
00219
00220
00221
00222
00223
00224 void free_hostent(struct hostent *dst)
00225 {
00226 int r;
00227 if (dst->h_name) pkg_free(dst->h_name);
00228 if (dst->h_aliases){
00229 for(r=0; dst->h_aliases[r]; r++) {
00230 pkg_free(dst->h_aliases[r]);
00231 }
00232 pkg_free(dst->h_aliases);
00233 }
00234 if (dst->h_addr_list){
00235 for (r=0; dst->h_addr_list[r];r++) {
00236 pkg_free(dst->h_addr_list[r]);
00237 }
00238 pkg_free(dst->h_addr_list);
00239 }
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 struct proxy_l* add_proxy( str* name, unsigned short port,
00251 unsigned short proto)
00252 {
00253 struct proxy_l* p;
00254
00255 if ((p=find_proxy(name, port, proto))!=0) return p;
00256 if ((p=mk_proxy(name, port, proto, 0))==0) goto error;
00257
00258 p->next=proxies;
00259 proxies=p;
00260 return p;
00261
00262 error:
00263 return 0;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 struct proxy_l* mk_proxy(str* name, unsigned short port, unsigned short proto,
00280 int is_sips)
00281 {
00282 struct proxy_l* p;
00283 struct hostent* he;
00284
00285 p=(struct proxy_l*) pkg_malloc(sizeof(struct proxy_l));
00286 if (p==0){
00287 ser_error=E_OUT_OF_MEM;
00288 LM_CRIT("pkg memory allocation failure\n");
00289 goto error;
00290 }
00291 memset(p,0,sizeof(struct proxy_l));
00292 p->name=*name;
00293 p->port=port;
00294 p->proto=proto;
00295
00296 LM_DBG("doing DNS lookup...\n");
00297 he = sip_resolvehost(name, &(p->port), &p->proto, is_sips,
00298 disable_dns_failover?0:&p->dn );
00299 if (he==0){
00300 ser_error=E_BAD_ADDRESS;
00301 LM_CRIT("could not resolve hostname: \"%.*s\"\n", name->len, name->s);
00302 pkg_free(p);
00303 goto error;
00304 }
00305 if (hostent_cpy(&(p->host), he)!=0){
00306 free_dns_res( p );
00307 pkg_free(p);
00308 goto error;
00309 }
00310 return p;
00311 error:
00312 return 0;
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 struct proxy_l* mk_proxy_from_ip(struct ip_addr* ip, unsigned short port,
00328 unsigned short proto)
00329 {
00330 struct proxy_l* p;
00331
00332 p=(struct proxy_l*) pkg_malloc(sizeof(struct proxy_l));
00333 if (p==0){
00334 LM_CRIT("pkg memory allocation failure\n");
00335 goto error;
00336 }
00337 memset(p,0,sizeof(struct proxy_l));
00338
00339 p->port=port;
00340 p->proto=proto;
00341 p->host.h_addrtype=ip->af;
00342 p->host.h_length=ip->len;
00343 p->host.h_addr_list=pkg_malloc(2*sizeof(char*));
00344 if (p->host.h_addr_list==0) goto error;
00345 p->host.h_addr_list[1]=0;
00346 p->host.h_addr_list[0]=pkg_malloc(ip->len+1);
00347 if (p->host.h_addr_list[0]==0){
00348 pkg_free(p->host.h_addr_list);
00349 goto error;
00350 }
00351
00352 memcpy(p->host.h_addr_list[0], ip->u.addr, ip->len);
00353 p->host.h_addr_list[0][ip->len]=0;
00354
00355 return p;
00356
00357 error:
00358 return 0;
00359 }
00360
00361
00362
00363
00364
00365 void free_proxy(struct proxy_l* p)
00366 {
00367 if (p) {
00368 free_hostent(&p->host);
00369 free_dns_res( p );
00370 }
00371 }
00372
00373
00374
00375
00376
00377 void free_shm_proxy(struct proxy_l* p)
00378 {
00379 if (p) {
00380 free_shm_hostent(&p->host);
00381 free_dns_res(p);
00382 }
00383 }
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 struct proxy_l* mk_shm_proxy(str* name, unsigned short port, unsigned short proto,
00400 int is_sips)
00401 {
00402 struct proxy_l* p;
00403 struct hostent* he;
00404
00405 p=(struct proxy_l*) shm_malloc(sizeof(struct proxy_l));
00406 if (p==0){
00407 ser_error=E_OUT_OF_MEM;
00408 LM_CRIT("shm memory allocation failure\n");
00409 goto error;
00410 }
00411 memset(p,0,sizeof(struct proxy_l));
00412 p->name=*name;
00413 p->port=port;
00414 p->proto=proto;
00415
00416 LM_DBG("doing DNS lookup...\n");
00417 he = sip_resolvehost(name, &(p->port), &p->proto, is_sips,
00418 disable_dns_failover?0:&p->dn );
00419 if (he==0){
00420 ser_error=E_BAD_ADDRESS;
00421 LM_CRIT("could not resolve hostname: \"%.*s\"\n", name->len, name->s);
00422 shm_free(p);
00423 goto error;
00424 }
00425 if (hostent_shm_cpy(&(p->host), he)!=0){
00426 free_dns_res( p );
00427 shm_free(p);
00428 goto error;
00429 }
00430 return p;
00431 error:
00432 return 0;
00433 }