2 * proxy list & assoc. functions
5 * Copyright (C) 2001-2003 FhG Fokus
7 * This file is part of Kamailio, a free SIP server.
9 * Kamailio is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version
14 * Kamailio is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 * \brief Kamailio core :: proxy list & assoc. functions
38 #include "mem/shm_mem.h"
42 #include <sys/socket.h>
53 struct proxy_l* proxies=0;
57 /* searches for the proxy named 'name', on port 'port' with
58 proto 'proto'; if proto==0 => proto wildcard (will match any proto)
59 returns: pointer to proxy_l on success or 0 if not found */
60 static struct proxy_l* find_proxy(str *name, unsigned short port, int proto)
63 for(t=proxies; t; t=t->next)
64 if (((t->name.len == name->len) &&
65 ((proto==PROTO_NONE)||(t->proto==proto))&&
66 (strncasecmp(t->name.s, name->s, name->len)==0)) &&
73 #define HOSTENT_CPY(dst, src, he_malloc, he_free) \
78 /* start copying the host entry.. */ \
80 len=strlen(src->h_name)+1; \
81 dst->h_name=(char*)he_malloc(sizeof(char) * len); \
82 if (dst->h_name) strncpy(dst->h_name,src->h_name, len); \
84 ser_error=ret=E_OUT_OF_MEM; \
88 /* copy h_aliases */ \
91 for (;src->h_aliases[len];len++); \
92 dst->h_aliases=(char**)he_malloc(sizeof(char*)*(len+1)); \
93 if (dst->h_aliases==0){ \
94 ser_error=ret=E_OUT_OF_MEM; \
95 he_free(dst->h_name); \
98 memset((void*)dst->h_aliases, 0, sizeof(char*) * (len+1) ); \
99 for (i=0;i<len;i++){ \
100 len2=strlen(src->h_aliases[i])+1; \
101 dst->h_aliases[i]=(char*)he_malloc(sizeof(char)*len2); \
102 if (dst->h_aliases==0){ \
103 ser_error=ret=E_OUT_OF_MEM; \
104 he_free(dst->h_name); \
105 for(r=0; r<i; r++) he_free(dst->h_aliases[r]); \
106 he_free(dst->h_aliases); \
109 strncpy(dst->h_aliases[i], src->h_aliases[i], len2); \
111 /* copy h_addr_list */ \
113 if (src->h_addr_list) \
114 for (;src->h_addr_list[len];len++); \
115 dst->h_addr_list=(char**)he_malloc(sizeof(char*)*(len+1)); \
116 if (dst->h_addr_list==0){ \
117 ser_error=ret=E_OUT_OF_MEM; \
118 he_free(dst->h_name); \
119 for(r=0; dst->h_aliases[r]; r++) \
120 he_free(dst->h_aliases[r]); \
121 he_free(dst->h_aliases[r]); \
122 he_free(dst->h_aliases); \
125 memset((void*)dst->h_addr_list, 0, sizeof(char*) * (len+1) ); \
126 for (i=0;i<len;i++){ \
127 dst->h_addr_list[i]= \
128 (char*)he_malloc(sizeof(char)*src->h_length); \
129 if (dst->h_addr_list[i]==0){ \
130 ser_error=ret=E_OUT_OF_MEM; \
131 he_free(dst->h_name); \
132 for(r=0; dst->h_aliases[r]; r++) \
133 he_free(dst->h_aliases[r]); \
134 he_free(dst->h_aliases[r]); \
135 he_free(dst->h_aliases); \
136 for (r=0; r<i;r++) he_free(dst->h_addr_list[r]); \
137 he_free(dst->h_addr_list); \
140 memcpy(dst->h_addr_list[i], src->h_addr_list[i], \
144 /* copy h_addr_type & length */ \
145 dst->h_addrtype=src->h_addrtype; \
146 dst->h_length=src->h_length; \
147 /*finished hostent copy */ \
153 #define FREE_HOSTENT(dst, he_free) \
156 if (dst->h_name) he_free(dst->h_name); \
157 if (dst->h_aliases){ \
158 for(r=0; dst->h_aliases[r]; r++) { \
159 he_free(dst->h_aliases[r]); \
161 he_free(dst->h_aliases); \
163 if (dst->h_addr_list){ \
164 for (r=0; dst->h_addr_list[r];r++) { \
165 he_free(dst->h_addr_list[r]); \
167 he_free(dst->h_addr_list); \
173 /* copies a hostent structure*, returns 0 on success, <0 on error*/
174 static int hostent_cpy(struct hostent *dst, struct hostent* src)
177 HOSTENT_CPY(dst, src, pkg_malloc, pkg_free);
179 LM_CRIT("memory allocation failure\n");
184 static int hostent_shm_cpy(struct hostent *dst, struct hostent* src)
187 HOSTENT_CPY(dst, src, shm_malloc, shm_free);
189 LM_CRIT("memory allocation failure\n");
194 void free_hostent(struct hostent* dst)
196 FREE_HOSTENT(dst, pkg_free);
199 void free_shm_hostent(struct hostent* dst)
201 FREE_HOSTENT(dst, shm_free);
206 struct proxy_l* add_proxy(str* name, unsigned short port, int proto)
210 if ((p=find_proxy(name, port, proto))!=0) return p;
211 if ((p=mk_proxy(name, port, proto))==0) goto error;
212 /* add p to the proxy list */
222 #define MK_PROXY(name, port, protocol, p_malloc, p_free, he_cpy) \
225 struct hostent* he; \
228 p=(struct proxy_l*) p_malloc(sizeof(struct proxy_l)); \
230 ser_error=E_OUT_OF_MEM; \
231 LM_ERR("memory allocation failure\n"); \
234 memset(p,0,sizeof(struct proxy_l)); \
238 LM_DBG("doing DNS lookup...\n"); \
240 he=sip_resolvehost(name, &(p->port), &proto); \
242 ser_error=E_BAD_ADDRESS; \
243 LM_CRIT("could not resolve hostname:" \
244 " \"%.*s\"\n", name->len, name->s); \
248 if (he_cpy(&(p->host), he)!=0){ \
260 /* same as add_proxy, but it doesn't add the proxy to the list
261 * uses also SRV if possible & port==0 (quick hack) */
263 struct proxy_l* mk_proxy(str* name, unsigned short port, int protocol)
265 MK_PROXY(name, port, protocol, pkg_malloc, pkg_free, hostent_cpy);
269 struct proxy_l* mk_shm_proxy(str* name, unsigned short port, int protocol)
271 MK_PROXY(name, port, protocol, shm_malloc, shm_free, hostent_shm_cpy);
276 /* same as mk_proxy, but get the host as an ip*/
277 struct proxy_l* mk_proxy_from_ip(struct ip_addr* ip, unsigned short port,
282 p=(struct proxy_l*) pkg_malloc(sizeof(struct proxy_l));
284 LM_CRIT("memory allocation failure\n");
287 memset(p,0,sizeof(struct proxy_l));
291 p->host.h_addrtype=ip->af;
292 p->host.h_length=ip->len;
293 p->host.h_addr_list=pkg_malloc(2*sizeof(char*));
294 if (p->host.h_addr_list==0) goto error;
295 p->host.h_addr_list[1]=0;
296 p->host.h_addr_list[0]=pkg_malloc(ip->len+1);
297 if (p->host.h_addr_list[0]==0){
298 pkg_free(p->host.h_addr_list);
302 memcpy(p->host.h_addr_list[0], ip->u.addr, ip->len);
303 p->host.h_addr_list[0][ip->len]=0;
314 void free_proxy(struct proxy_l* p)
316 if (p) free_hostent(&p->host);
320 void free_shm_proxy(struct proxy_l* p)
322 if (p) free_shm_hostent(&p->host);