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