registrar/path.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * Helper functions for Path support.
00005  *
00006  * Copyright (C) 2006 Andreas Granig <agranig@linguin.org>
00007  *
00008  * This file is part of Kamailio, a free SIP server.
00009  *
00010  * Kamailio is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version
00014  *
00015  * Kamailio is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License 
00021  * along with this program; if not, write to the Free Software 
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  */
00032 #include "../../data_lump.h"
00033 #include "../../parser/parse_rr.h"
00034 #include "../../parser/parse_uri.h"
00035 #include "path.h"
00036 #include "reg_mod.h"
00037 
00041 int build_path_vector(struct sip_msg *_m, str *path, str *received)
00042 {
00043         static char buf[MAX_PATH_SIZE];
00044         char *p;
00045         struct hdr_field *hdr;
00046         struct sip_uri puri;
00047 
00048         rr_t *route = 0;
00049 
00050         path->len = 0;
00051         path->s = 0;
00052         received->s = 0;
00053         received->len = 0;
00054 
00055         if(parse_headers(_m, HDR_EOH_F, 0) < 0) {
00056                 LM_ERR("failed to parse the message\n");
00057                 goto error;
00058         }
00059 
00060         for( hdr=_m->path,p=buf ; hdr ; hdr = next_sibling_hdr(hdr)) {
00061                 /* check for max. Path length */
00062                 if( p-buf+hdr->body.len+1 >= MAX_PATH_SIZE) {
00063                         LM_ERR("Overall Path body exceeds max. length of %d\n",
00064                                         MAX_PATH_SIZE);
00065                         goto error;
00066                 }
00067                 if(p!=buf)
00068                         *(p++) = ',';
00069                 memcpy( p, hdr->body.s, hdr->body.len);
00070                 p +=  hdr->body.len;
00071         }
00072 
00073         if (p!=buf) {
00074                 /* check if next hop is a loose router */
00075                 if (parse_rr_body( buf, p-buf, &route) < 0) {
00076                         LM_ERR("failed to parse Path body, no head found\n");
00077                         goto error;
00078                 }
00079                 if (parse_uri(route->nameaddr.uri.s,route->nameaddr.uri.len,&puri)<0){
00080                         LM_ERR("failed to parse the first Path URI\n");
00081                         goto error;
00082                 }
00083                 if (!puri.lr.s) {
00084                         LM_ERR("first Path URI is not a loose-router, not supported\n");
00085                         goto error;
00086                 }
00087                 if (path_use_params) {
00088                         param_hooks_t hooks;
00089                         param_t *params;
00090 
00091                         if (parse_params(&(puri.params),CLASS_CONTACT,&hooks,&params)!=0){
00092                                 LM_ERR("failed to parse parameters of first hop\n");
00093                                 goto error;
00094                         }
00095                         if (hooks.contact.received)
00096                                 *received = hooks.contact.received->body;
00097                         /*for (;params; params = params->next) {
00098                                 if (params->type == P_RECEIVED) {
00099                                         *received = hooks.contact.received->body;
00100                                         break;
00101                                 }
00102                         }*/
00103                         free_params(params);
00104                 }
00105                 free_rr(&route);
00106         }
00107 
00108         path->s = buf;
00109         path->len = p-buf;
00110         return 0;
00111 error:
00112         if(route) free_rr(&route);
00113         return -1;
00114 }
00115