tm, tmx: move small redundant skip_hf macro to ut.h
[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 #endif
87 #ifdef USE_TLS
88                                 case PROTO_TLS:
89 #endif
90 #ifdef USE_SCTP
91                                 case PROTO_SCTP:
92 #endif
93                                                 return proto;
94                                 default:
95                                                 LOG(L_ERR, "ERROR: get_proto: unsupported transport:"
96                                                                 " %d\n", proto );
97                                                 return PROTO_NONE;
98                         }
99                 case PROTO_UDP: /* some protocol has been forced -- take it */
100 #ifdef USE_TCP
101                 case PROTO_TCP:
102 #endif
103 #ifdef USE_TLS
104                 case PROTO_TLS:
105 #endif
106 #ifdef USE_SCTP
107                 case PROTO_SCTP:
108 #endif
109                         return force_proto;
110                 default:
111                         LOG(L_ERR, "ERROR: get_proto: unsupported forced protocol: "
112                                         "%d\n", force_proto);
113                         return PROTO_NONE;
114         }
115 }
116
117
118
119 /*
120  * Convert a URI into a proxy structure
121  */
122 inline static struct proxy_l *uri2proxy( str *uri, int proto )
123 {
124         struct sip_uri parsed_uri;
125         struct proxy_l *p;
126         enum sip_protos uri_proto;
127
128         if (parse_uri(uri->s, uri->len, &parsed_uri) < 0) {
129                 LOG(L_ERR, "ERROR: uri2proxy: bad_uri: %.*s\n",
130                     uri->len, uri->s );
131                 return 0;
132         }
133         
134         if (parsed_uri.type==SIPS_URI_T){
135                 if (parsed_uri.proto==PROTO_UDP) {
136                         LOG(L_ERR, "ERROR: uri2proxy: bad transport for sips uri: %d\n",
137                                         parsed_uri.proto);
138                         return 0;
139                 }else
140                         uri_proto=PROTO_TLS;
141         }else
142                 uri_proto=parsed_uri.proto;
143 #ifdef HONOR_MADDR
144         if (parsed_uri.maddr_val.s && parsed_uri.maddr_val.len) {
145                 p = mk_proxy(&parsed_uri.maddr_val, 
146                                           parsed_uri.port_no, 
147                                           get_proto(proto, uri_proto));
148                 if (p == 0) {
149                         LOG(L_ERR, "ERROR: uri2proxy: bad maddr param in URI <%.*s>\n",
150                                 uri->len, ZSW(uri->s));
151                         return 0;
152                 }
153         } else
154 #endif
155         p = mk_proxy(&parsed_uri.host, 
156                                   parsed_uri.port_no, 
157                                   get_proto(proto, uri_proto));
158         if (p == 0) {
159                 LOG(L_ERR, "ERROR: uri2proxy: bad host name in URI <%.*s>\n",
160                     uri->len, ZSW(uri->s));
161                 return 0;
162         }
163         
164         return p;
165 }
166
167
168
169 /*
170  * parse uri and return send related information
171  * params: uri - uri in string form
172  *         host - filled with the uri host part
173  *         port - filled with the uri port
174  *         proto - if != PROTO_NONE, this protocol will be forced over the
175  *                 uri_proto, otherwise the uri proto will be used 
176  *                 (value/return)
177  *         comp - compression (if used)
178  * returns 0 on success, < 0 on error
179  */
180 inline static int get_uri_send_info(str* uri, str* host, unsigned short* port,
181                                                                         char* proto, short* comp)
182 {
183         struct sip_uri parsed_uri;
184         enum sip_protos uri_proto;
185         
186         if (parse_uri(uri->s, uri->len, &parsed_uri) < 0) {
187                 LOG(L_ERR, "ERROR: get_uri_send_info: bad_uri: %.*s\n",
188                                         uri->len, uri->s );
189                 return -1;
190         }
191         
192         if (parsed_uri.type==SIPS_URI_T){
193                 if (parsed_uri.proto==PROTO_UDP) {
194                         LOG(L_ERR, "ERROR: get_uri_send_info: bad transport for"
195                                                 " sips uri: %d\n", parsed_uri.proto);
196                         return -1;
197                 }else
198                         uri_proto=PROTO_TLS;
199         }else
200                 uri_proto=parsed_uri.proto;
201         
202         *proto= get_proto(*proto, uri_proto);
203 #ifdef USE_COMP
204         *comp=parsed_uri.comp;
205 #endif
206 #ifdef HONOR_MADDR
207         if (parsed_uri.maddr_val.s && parsed_uri.maddr_val.len) {
208                 *host=parsed_uri.maddr_val;
209                 DBG("maddr dst: %.*s:%d\n", parsed_uri.maddr_val.len, 
210                                 parsed_uri.maddr_val.s, parsed_uri.port_no);
211         } else
212 #endif
213                 *host=parsed_uri.host;
214         *port=parsed_uri.port_no;
215         return 0;
216 }
217
218
219
220 /*
221  * Convert a URI into a dest_info structure.
222  * Same as uri2dst, but uses directly force_send_socket instead of msg.
223  * If the uri host resolves to multiple ips and dns_h!=0 the first ip for 
224  *  which a send socket is found will be used. If no send_socket are found,
225  *  the first ip is selected.
226  *
227  * params: dns_h - pointer to a valid dns_srv_handle structure (intialized!) or
228  *                 null. If null or use_dns_failover==0 normal dns lookup will
229  *                 be performed (no failover).
230  *         dst   - will be filled
231  *         force_send_sock - if 0 dst->send_sock will be set to the default 
232  *                 (see get_send_socket2()) 
233  *         sflags - send flags
234  *         uri   - uri in str form
235  *         proto - if != PROTO_NONE, this protocol will be forced over the
236  *                 uri_proto, otherwise the uri proto will be used if set or
237  *                 the proto obtained from the dns lookup
238  * returns 0 on error, dst on success
239  */
240 #ifdef USE_DNS_FAILOVER
241 inline static struct dest_info *uri2dst2(struct dns_srv_handle* dns_h,
242                                                                                 struct dest_info* dst,
243                                                                                 struct socket_info *force_send_socket,
244                                                                                 snd_flags_t sflags,
245                                                                                 str *uri, int proto )
246 #else
247 inline static struct dest_info *uri2dst2(struct dest_info* dst,
248                                                                                 struct socket_info *force_send_socket,
249                                                                                 snd_flags_t sflags,
250                                                                                 str *uri, int proto )
251 #endif
252 {
253         struct sip_uri parsed_uri;
254         enum sip_protos uri_proto;
255         str* host;
256 #ifdef USE_DNS_FAILOVER
257         int ip_found;
258         union sockaddr_union to;
259         int err;
260 #endif
261
262         if (parse_uri(uri->s, uri->len, &parsed_uri) < 0) {
263                 LOG(L_ERR, "ERROR: uri2dst: bad_uri: %.*s\n",
264                     uri->len, uri->s );
265                 return 0;
266         }
267         
268         if (parsed_uri.type==SIPS_URI_T){
269                 if (parsed_uri.proto==PROTO_UDP) {
270                         LOG(L_ERR, "ERROR: uri2dst: bad transport for sips uri: %d\n",
271                                         parsed_uri.proto);
272                         return 0;
273                 }else
274                         uri_proto=PROTO_TLS;
275         }else
276                 uri_proto=parsed_uri.proto;
277         
278         init_dest_info(dst);
279         dst->proto= get_proto(proto, uri_proto);
280 #ifdef USE_COMP
281         dst->comp=parsed_uri.comp;
282 #endif
283         dst->send_flags=sflags;
284 #ifdef HONOR_MADDR
285         if (parsed_uri.maddr_val.s && parsed_uri.maddr_val.len) {
286                 host=&parsed_uri.maddr_val;
287                 DBG("maddr dst: %.*s:%d\n", parsed_uri.maddr_val.len, 
288                                                                 parsed_uri.maddr_val.s, parsed_uri.port_no);
289         } else
290 #endif
291                 host=&parsed_uri.host;
292 #ifdef USE_DNS_FAILOVER
293         if (cfg_get(core, core_cfg, use_dns_failover) && dns_h){
294                 ip_found=0;
295                 do{
296                         /* try all the ips until we find a good send socket */
297                         err=dns_sip_resolve2su(dns_h, &to, host,
298                                                                 parsed_uri.port_no, &dst->proto, dns_flags);
299                         if (err!=0){
300                                 if (ip_found==0){
301                                         if (err!=-E_DNS_EOR)
302                                                 LOG(L_ERR, "ERROR: uri2dst: failed to resolve \"%.*s\" :"
303                                                                 "%s (%d)\n", host->len, ZSW(host->s),
304                                                                         dns_strerror(err), err);
305                                         return 0; /* error, no ip found */
306                                 }
307                                 break;
308                         }
309                         if (ip_found==0){
310                                 dst->to=to;
311                                 ip_found=1;
312                         }
313                         dst->send_sock = get_send_socket2(force_send_socket, &to,
314                                                                                                 dst->proto, 0);
315                         if (dst->send_sock){
316                                 dst->to=to;
317                                 return dst; /* found a good one */
318                         }
319                 }while(dns_srv_handle_next(dns_h, err));
320                 ERR("no corresponding socket for \"%.*s\" af %d\n", host->len, 
321                                 ZSW(host->s), dst->to.s.sa_family);
322                 /* try to continue */
323                 return dst;
324         }
325 #endif
326         if (sip_hostport2su(&dst->to, host, parsed_uri.port_no, &dst->proto)!=0){
327                 ERR("failed to resolve \"%.*s\"\n", host->len, ZSW(host->s));
328                 return 0;
329         }
330         dst->send_sock = get_send_socket2(force_send_socket, &dst->to,
331                                                                                 dst->proto, 0);
332         if (dst->send_sock==0) {
333                 ERR("no corresponding socket for af %d\n", dst->to.s.sa_family);
334                 /* ser_error = E_NO_SOCKET;*/
335                 /* try to continue */
336         }
337         return dst;
338 }
339
340
341
342 /*
343  * Convert a URI into a dest_info structure
344  * If the uri host resolves to multiple ips and dns_h!=0 the first ip for 
345  *  which a send socket is found will be used. If no send_socket are found,
346  *  the first ip is selected.
347  *
348  * params: dns_h - pointer to a valid dns_srv_handle structure (intialized!) or
349  *                 null. If null or use_dns_failover==0 normal dns lookup will
350  *                 be performed (no failover).
351  *         dst   - will be filled
352  *         msg   -  sip message used to set dst->send_sock and dst->send_flags,
353  *                 if 0 dst->send_sock will be set to the default w/o using 
354  *                  msg->force_send_socket (see get_send_socket()) and the 
355  *                  send_flags will be set to 0.
356  *         uri   - uri in str form
357  *         proto - if != PROTO_NONE, this protocol will be forced over the
358  *                 uri_proto, otherwise the uri proto will be used if set or
359  *                 the proto obtained from the dns lookup
360  * returns 0 on error, dst on success
361  */
362 #ifdef USE_DNS_FAILOVER
363 inline static struct dest_info *uri2dst(struct dns_srv_handle* dns_h,
364                                                                                 struct dest_info* dst,
365                                                                                 struct sip_msg *msg, str *uri, 
366                                                                                         int proto )
367 {
368         snd_flags_t sflags;
369         if (msg)
370                 return uri2dst2(dns_h, dst, msg->force_send_socket,
371                                                         msg->fwd_send_flags, uri, proto);
372         SND_FLAGS_INIT(&sflags);
373         return uri2dst2(dns_h, dst, 0, sflags, uri, proto);
374 }
375 #else
376 inline static struct dest_info *uri2dst(struct dest_info* dst,
377                                                                                 struct sip_msg *msg, str *uri, 
378                                                                                         int proto )
379 {
380         snd_flags_t sflags;
381         if (msg)
382                 return uri2dst2(dst, msg->force_send_socket, msg->fwd_send_flags,
383                                                 uri, proto);
384         SND_FLAGS_INIT(&sflags);
385         return uri2dst2(dst, 0, sflags, uri, proto);
386 }
387 #endif /* USE_DNS_FAILOVER */
388
389
390
391 #if 0
392 /*
393  * Convert a URI into the corresponding sockaddr_union (address to send to) and
394  *  send socket_info (socket/address from which to send)
395  *  to_su is filled with the destination and the socket_info that will be 
396  *  used for sending is returned.
397  *  On error return 0.
398  *
399  *  NOTE: this function is deprecated, you should use uri2dst instead
400  */
401 static inline struct socket_info *uri2sock(struct sip_msg* msg, str *uri,
402                                                                         union sockaddr_union *to_su, int proto)
403 {
404         struct dest_info dst;
405
406         if (uri2dst(&dst, msg, uri, proto)==0){
407                 LOG(L_ERR, "ERROR: uri2sock: Can't create a dst proxy\n");
408                 ser_error=E_BAD_ADDRESS;
409                 return 0;
410         }
411         *to_su=dst.to; /* copy su */
412         
413         /* we use dst->send_socket since uri2dst just set it correctly*/
414         if (dst.send_sock==0) {
415                 LOG(L_ERR, "ERROR: uri2sock: no corresponding socket for af %d\n", 
416                     to_su->s.sa_family);
417                 ser_error = E_NO_SOCKET;
418         }
419         return dst.send_sock;
420 }
421 #endif
422
423 #endif /* _TM_UT_H */