3a9f1f2f045275f33335e2aa28d74d7302f1c6ed
[sip-router] / modules / tm / ut.h
1 /*
2  * $Id$
3  *
4  * utilities
5  *
6  *
7  * Copyright (C) 2001-2003 FhG Fokus
8  *
9  * This file is part of ser, a free SIP server.
10  *
11  * ser is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version
15  *
16  * For a license to use the ser software under conditions
17  * other than those described here, or to purchase support for this
18  * software, please contact iptel.org by e-mail at the following addresses:
19  *    info@iptel.org
20  *
21  * ser is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License 
27  * along with this program; if not, write to the Free Software 
28  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29  *
30  * History:
31  * -------
32  *  2003-02-13  added proto to uri2proxy (andrei)
33  *  2003-04-09  uri2sock moved from uac.c (janakj)
34  *  2003-04-14  added get_proto to determine protocol from uri unless
35  *              specified explicitly (jiri)
36  *  2003-07-07  get_proto takes now two protos as arguments (andrei)
37  *              tls/sips support for get_proto & uri2proxy (andrei)
38  *  2006-04-13  added uri2dst(), simplified uri2sock() (andrei)
39  *  2006-08-11  dns failover support: uri2dst uses the dns cache and tries to 
40  *               get the first ip for which there is a send sock. (andrei)
41  */
42
43
44 #ifndef _TM_UT_H
45 #define _TM_UT_H
46
47
48 #include "../../proxy.h"
49 #include "../../str.h"
50 #include "../../parser/parse_uri.h"
51 #include "../../dprint.h"
52 #include "../../ut.h"
53 #include "../../ip_addr.h"
54 #include "../../error.h"
55 #include "../../forward.h"
56 #include "../../mem/mem.h"
57 #include "../../parser/msg_parser.h"
58 #include "../../resolve.h"
59 #ifdef USE_DNS_FAILOVER
60 #include "../../dns_cache.h"
61 #include "../../cfg_core.h" /* cfg_get(core, core_cfg, use_dns_failover) */
62 #endif
63
64
65 /*! Which header fields should be skipped */
66 #define tm_skip_hf(_hf) \
67         (((_hf)->type == HDR_FROM_T)  || \
68         ((_hf)->type == HDR_TO_T)     || \
69         ((_hf)->type == HDR_CALLID_T) || \
70         ((_hf)->type == HDR_CSEQ_T))
71
72
73 /* a forced_proto takes precedence if != PROTO_NONE */
74 inline static enum sip_protos get_proto(enum sip_protos force_proto,
75                                                                                 enum sip_protos proto)
76 {
77         /* calculate transport protocol */
78         switch(force_proto) {
79                 case PROTO_NONE: /* no protocol has been forced -- look at proto */
80                         switch(proto) {
81                                 case PROTO_NONE: /* leave it to dns */
82                                                 return PROTO_NONE;
83                                 case PROTO_UDP:/* transport specified explicitly */
84 #ifdef USE_TCP
85                                 case PROTO_TCP:
86                                 case PROTO_WS:
87 #endif
88 #ifdef USE_TLS
89                                 case PROTO_TLS:
90 #endif
91 #ifdef USE_SCTP
92                                 case PROTO_SCTP:
93 #endif
94                                                 return proto;
95                                 default:
96                                                 LOG(L_ERR, "ERROR: get_proto: unsupported transport:"
97                                                                 " %d\n", proto );
98                                                 return PROTO_NONE;
99                         }
100                 case PROTO_UDP: /* some protocol has been forced -- take it */
101 #ifdef USE_TCP
102                 case PROTO_TCP:
103                 case PROTO_WS:
104 #endif
105 #ifdef USE_TLS
106                 case PROTO_TLS:
107 #endif
108 #ifdef USE_SCTP
109                 case PROTO_SCTP:
110 #endif
111                         return force_proto;
112                 default:
113                         LOG(L_ERR, "ERROR: get_proto: unsupported forced protocol: "
114                                         "%d\n", force_proto);
115                         return PROTO_NONE;
116         }
117 }
118
119
120
121 /*
122  * Convert a URI into a proxy structure
123  */
124 inline static struct proxy_l *uri2proxy( str *uri, int proto )
125 {
126         struct sip_uri parsed_uri;
127         struct proxy_l *p;
128         enum sip_protos uri_proto;
129
130         if (parse_uri(uri->s, uri->len, &parsed_uri) < 0) {
131                 LOG(L_ERR, "ERROR: uri2proxy: bad_uri: %.*s\n",
132                     uri->len, uri->s );
133                 return 0;
134         }
135         
136         if (parsed_uri.type==SIPS_URI_T){
137                 if (parsed_uri.proto==PROTO_UDP) {
138                         LOG(L_ERR, "ERROR: uri2proxy: bad transport for sips uri: %d\n",
139                                         parsed_uri.proto);
140                         return 0;
141                 }else
142                         uri_proto=PROTO_TLS;
143         }else
144                 uri_proto=parsed_uri.proto;
145 #ifdef HONOR_MADDR
146         if (parsed_uri.maddr_val.s && parsed_uri.maddr_val.len) {
147                 p = mk_proxy(&parsed_uri.maddr_val, 
148                                           parsed_uri.port_no, 
149                                           get_proto(proto, uri_proto));
150                 if (p == 0) {
151                         LOG(L_ERR, "ERROR: uri2proxy: bad maddr param in URI <%.*s>\n",
152                                 uri->len, ZSW(uri->s));
153                         return 0;
154                 }
155         } else
156 #endif
157         p = mk_proxy(&parsed_uri.host, 
158                                   parsed_uri.port_no, 
159                                   get_proto(proto, uri_proto));
160         if (p == 0) {
161                 LOG(L_ERR, "ERROR: uri2proxy: bad host name in URI <%.*s>\n",
162                     uri->len, ZSW(uri->s));
163                 return 0;
164         }
165         
166         return p;
167 }
168
169
170
171 /*
172  * parse uri and return send related information
173  * params: uri - uri in string form
174  *         host - filled with the uri host part
175  *         port - filled with the uri port
176  *         proto - if != PROTO_NONE, this protocol will be forced over the
177  *                 uri_proto, otherwise the uri proto will be used 
178  *                 (value/return)
179  *         comp - compression (if used)
180  * returns 0 on success, < 0 on error
181  */
182 inline static int get_uri_send_info(str* uri, str* host, unsigned short* port,
183                                                                         char* proto, short* comp)
184 {
185         struct sip_uri parsed_uri;
186         enum sip_protos uri_proto;
187         
188         if (parse_uri(uri->s, uri->len, &parsed_uri) < 0) {
189                 LOG(L_ERR, "ERROR: get_uri_send_info: bad_uri: %.*s\n",
190                                         uri->len, uri->s );
191                 return -1;
192         }
193         
194         if (parsed_uri.type==SIPS_URI_T){
195                 if (parsed_uri.proto==PROTO_UDP) {
196                         LOG(L_ERR, "ERROR: get_uri_send_info: bad transport for"
197                                                 " sips uri: %d\n", parsed_uri.proto);
198                         return -1;
199                 }else
200                         uri_proto=PROTO_TLS;
201         }else
202                 uri_proto=parsed_uri.proto;
203         
204         *proto= get_proto(*proto, uri_proto);
205 #ifdef USE_COMP
206         *comp=parsed_uri.comp;
207 #endif
208 #ifdef HONOR_MADDR
209         if (parsed_uri.maddr_val.s && parsed_uri.maddr_val.len) {
210                 *host=parsed_uri.maddr_val;
211                 DBG("maddr dst: %.*s:%d\n", parsed_uri.maddr_val.len, 
212                                 parsed_uri.maddr_val.s, parsed_uri.port_no);
213         } else
214 #endif
215                 *host=parsed_uri.host;
216         *port=parsed_uri.port_no;
217         return 0;
218 }
219
220
221
222 /*
223  * Convert a URI into a dest_info structure.
224  * Same as uri2dst, but uses directly force_send_socket instead of msg.
225  * If the uri host resolves to multiple ips and dns_h!=0 the first ip for 
226  *  which a send socket is found will be used. If no send_socket are found,
227  *  the first ip is selected.
228  *
229  * params: dns_h - pointer to a valid dns_srv_handle structure (intialized!) or
230  *                 null. If null or use_dns_failover==0 normal dns lookup will
231  *                 be performed (no failover).
232  *         dst   - will be filled
233  *         force_send_sock - if 0 dst->send_sock will be set to the default 
234  *                 (see get_send_socket2()) 
235  *         sflags - send flags
236  *         uri   - uri in str form
237  *         proto - if != PROTO_NONE, this protocol will be forced over the
238  *                 uri_proto, otherwise the uri proto will be used if set or
239  *                 the proto obtained from the dns lookup
240  * returns 0 on error, dst on success
241  */
242 #ifdef USE_DNS_FAILOVER
243 inline static struct dest_info *uri2dst2(struct dns_srv_handle* dns_h,
244                                                                                 struct dest_info* dst,
245                                                                                 struct socket_info *force_send_socket,
246                                                                                 snd_flags_t sflags,
247                                                                                 str *uri, int proto )
248 #else
249 inline static struct dest_info *uri2dst2(struct dest_info* dst,
250                                                                                 struct socket_info *force_send_socket,
251                                                                                 snd_flags_t sflags,
252                                                                                 str *uri, int proto )
253 #endif
254 {
255         struct sip_uri parsed_uri;
256         enum sip_protos uri_proto;
257         str* host;
258 #ifdef USE_DNS_FAILOVER
259         int ip_found;
260         union sockaddr_union to;
261         int err;
262 #endif
263
264         if (parse_uri(uri->s, uri->len, &parsed_uri) < 0) {
265                 LOG(L_ERR, "ERROR: uri2dst: bad_uri: %.*s\n",
266                     uri->len, uri->s );
267                 return 0;
268         }
269         
270         if (parsed_uri.type==SIPS_URI_T){
271                 if (parsed_uri.proto==PROTO_UDP) {
272                         LOG(L_ERR, "ERROR: uri2dst: bad transport for sips uri: %d\n",
273                                         parsed_uri.proto);
274                         return 0;
275                 }else
276                         uri_proto=PROTO_TLS;
277         }else
278                 uri_proto=parsed_uri.proto;
279         
280         init_dest_info(dst);
281         dst->proto= get_proto(proto, uri_proto);
282 #ifdef USE_COMP
283         dst->comp=parsed_uri.comp;
284 #endif
285         dst->send_flags=sflags;
286 #ifdef HONOR_MADDR
287         if (parsed_uri.maddr_val.s && parsed_uri.maddr_val.len) {
288                 host=&parsed_uri.maddr_val;
289                 DBG("maddr dst: %.*s:%d\n", parsed_uri.maddr_val.len, 
290                                                                 parsed_uri.maddr_val.s, parsed_uri.port_no);
291         } else
292 #endif
293                 host=&parsed_uri.host;
294 #ifdef USE_DNS_FAILOVER
295         if (cfg_get(core, core_cfg, use_dns_failover) && dns_h){
296                 ip_found=0;
297                 do{
298                         /* try all the ips until we find a good send socket */
299                         err=dns_sip_resolve2su(dns_h, &to, host,
300                                                                 parsed_uri.port_no, &dst->proto, dns_flags);
301                         if (err!=0){
302                                 if (ip_found==0){
303                                         if (err!=-E_DNS_EOR)
304                                                 LOG(L_ERR, "ERROR: uri2dst: failed to resolve \"%.*s\" :"
305                                                                 "%s (%d)\n", host->len, ZSW(host->s),
306                                                                         dns_strerror(err), err);
307                                         return 0; /* error, no ip found */
308                                 }
309                                 break;
310                         }
311                         if (ip_found==0){
312                                 dst->to=to;
313                                 ip_found=1;
314                         }
315                         dst->send_sock = get_send_socket2(force_send_socket, &to,
316                                                                                                 dst->proto, 0);
317                         if (dst->send_sock){
318                                 dst->to=to;
319                                 return dst; /* found a good one */
320                         }
321                 }while(dns_srv_handle_next(dns_h, err));
322                 ERR("no corresponding socket for \"%.*s\" af %d\n", host->len, 
323                                 ZSW(host->s), dst->to.s.sa_family);
324                 /* try to continue */
325                 return dst;
326         }
327 #endif
328         if (sip_hostport2su(&dst->to, host, parsed_uri.port_no, &dst->proto)!=0){
329                 ERR("failed to resolve \"%.*s\"\n", host->len, ZSW(host->s));
330                 return 0;
331         }
332         dst->send_sock = get_send_socket2(force_send_socket, &dst->to,
333                                                                                 dst->proto, 0);
334         if (dst->send_sock==0) {
335                 ERR("no corresponding socket for af %d\n", dst->to.s.sa_family);
336                 /* ser_error = E_NO_SOCKET;*/
337                 /* try to continue */
338         }
339         return dst;
340 }
341
342
343
344 /*
345  * Convert a URI into a dest_info structure
346  * If the uri host resolves to multiple ips and dns_h!=0 the first ip for 
347  *  which a send socket is found will be used. If no send_socket are found,
348  *  the first ip is selected.
349  *
350  * params: dns_h - pointer to a valid dns_srv_handle structure (intialized!) or
351  *                 null. If null or use_dns_failover==0 normal dns lookup will
352  *                 be performed (no failover).
353  *         dst   - will be filled
354  *         msg   -  sip message used to set dst->send_sock and dst->send_flags,
355  *                 if 0 dst->send_sock will be set to the default w/o using 
356  *                  msg->force_send_socket (see get_send_socket()) and the 
357  *                  send_flags will be set to 0.
358  *         uri   - uri in str form
359  *         proto - if != PROTO_NONE, this protocol will be forced over the
360  *                 uri_proto, otherwise the uri proto will be used if set or
361  *                 the proto obtained from the dns lookup
362  * returns 0 on error, dst on success
363  */
364 #ifdef USE_DNS_FAILOVER
365 inline static struct dest_info *uri2dst(struct dns_srv_handle* dns_h,
366                                                                                 struct dest_info* dst,
367                                                                                 struct sip_msg *msg, str *uri, 
368                                                                                         int proto )
369 {
370         snd_flags_t sflags;
371         if (msg)
372                 return uri2dst2(dns_h, dst, msg->force_send_socket,
373                                                         msg->fwd_send_flags, uri, proto);
374         SND_FLAGS_INIT(&sflags);
375         return uri2dst2(dns_h, dst, 0, sflags, uri, proto);
376 }
377 #else
378 inline static struct dest_info *uri2dst(struct dest_info* dst,
379                                                                                 struct sip_msg *msg, str *uri, 
380                                                                                         int proto )
381 {
382         snd_flags_t sflags;
383         if (msg)
384                 return uri2dst2(dst, msg->force_send_socket, msg->fwd_send_flags,
385                                                 uri, proto);
386         SND_FLAGS_INIT(&sflags);
387         return uri2dst2(dst, 0, sflags, uri, proto);
388 }
389 #endif /* USE_DNS_FAILOVER */
390
391 #endif /* _TM_UT_H */