all: updated FSF address in GPL text
[sip-router] / modules / registrar / path.c
1 /*
2  * $Id$
3  *
4  * Helper functions for Path support.
5  *
6  * Copyright (C) 2006 Andreas Granig <agranig@linguin.org>
7  *
8  * This file is part of Kamailio, a free SIP server.
9  *
10  * Kamailio is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version
14  *
15  * Kamailio is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License 
21  * along with this program; if not, write to the Free Software 
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23  *
24  */
25 /*!
26  * \file
27  * \brief SIP registrar module - Helper functions for Path support
28  * \ingroup registrar   
29  */  
30
31
32 #include "../../data_lump.h"
33 #include "../../parser/parse_rr.h"
34 #include "../../parser/parse_uri.h"
35 #include "../../lib/kcore/strcommon.h"
36 #include "path.h"
37 #include "reg_mod.h"
38
39
40 /*! \brief
41  * Combines all Path HF bodies into one string.
42  */
43 int build_path_vector(struct sip_msg *_m, str *path, str *received)
44 {
45         static char buf[MAX_PATH_SIZE];
46         static char uri_buf[MAX_URI_SIZE];
47         static str uri_str;
48         char *p;
49         struct hdr_field *hdr;
50         struct sip_uri puri;
51
52         rr_t *route = 0;
53
54         path->len = 0;
55         path->s = 0;
56         received->s = 0;
57         received->len = 0;
58
59         if(parse_headers(_m, HDR_EOH_F, 0) < 0) {
60                 LM_ERR("failed to parse the message\n");
61                 goto error;
62         }
63
64         for( hdr=_m->path,p=buf ; hdr ; hdr = next_sibling_hdr(hdr)) {
65                 /* check for max. Path length */
66                 if( p-buf+hdr->body.len+1 >= MAX_PATH_SIZE) {
67                         LM_ERR("Overall Path body exceeds max. length of %d\n",
68                                         MAX_PATH_SIZE);
69                         goto error;
70                 }
71                 if(p!=buf)
72                         *(p++) = ',';
73                 memcpy( p, hdr->body.s, hdr->body.len);
74                 p +=  hdr->body.len;
75         }
76
77         if (p!=buf) {
78                 /* check if next hop is a loose router */
79                 if (parse_rr_body( buf, p-buf, &route) < 0) {
80                         LM_ERR("failed to parse Path body, no head found\n");
81                         goto error;
82                 }
83                 if (parse_uri(route->nameaddr.uri.s,route->nameaddr.uri.len,&puri)<0){
84                         LM_ERR("failed to parse the first Path URI\n");
85                         goto error;
86                 }
87                 if (!puri.lr.s) {
88                         LM_ERR("first Path URI is not a loose-router, not supported\n");
89                         goto error;
90                 }
91                 if (path_use_params) {
92                         param_hooks_t hooks;
93                         param_t *params;
94
95                         if (parse_params(&(puri.params),CLASS_CONTACT,&hooks,&params)!=0){
96                                 LM_ERR("failed to parse parameters of first hop\n");
97                                 goto error;
98                         }
99
100                         if (hooks.contact.received) {
101                                 uri_str.s = uri_buf;
102                                 uri_str.len = MAX_URI_SIZE;
103                                 if (unescape_user(&(hooks.contact.received->body), &uri_str) < 0) {
104                                         LM_ERR("unescaping received failed\n");
105                                         goto error;
106                                 }
107                                 *received = uri_str;
108                                 LM_DBG("received is <%.*s>\n", received->len, received->s);
109                         }
110                                 
111                         /*for (;params; params = params->next) {
112                                 if (params->type == P_RECEIVED) {
113                                         *received = hooks.contact.received->body;
114                                         break;
115                                 }
116                         }*/
117                         free_params(params);
118                 }
119                 free_rr(&route);
120         }
121
122         path->s = buf;
123         path->len = p-buf;
124         LM_DBG("path is <%.*s>\n", path->len, path->s);
125         return 0;
126 error:
127         if(route) free_rr(&route);
128         return -1;
129 }
130