mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
4.9 KiB
184 lines
4.9 KiB
/* $Id$
|
|
*
|
|
* Copyright (C) 2006-2007 VozTelecom Sistemas S.L
|
|
*
|
|
* This file is part of Kamailio, a free SIP server.
|
|
*
|
|
* Kamailio 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
|
|
*
|
|
* Kamailio 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 <string.h>
|
|
|
|
#include "cluster.h"
|
|
#include "seas.h"
|
|
#include "../../dprint.h"
|
|
#include "../../mem/mem.h"
|
|
|
|
char *cluster_cfg;
|
|
|
|
#define eat_spaces(_p) \
|
|
while( *(_p)==' ' || *(_p)=='\t' ){\
|
|
(_p)++;}
|
|
|
|
|
|
/**
|
|
* Parses the PING configuration string. Its format is
|
|
* "ping_period:pings_lost:ping_timeout"
|
|
* ping_period : time between pings
|
|
* pings_lost: number of lost pings before failure
|
|
* ping_timeout: time to consider a ping failed
|
|
*
|
|
* returns
|
|
* 0 if no clusters present
|
|
* -1 if config is malformed (unable to parse);
|
|
* 1 if config is successfully set
|
|
*/
|
|
int parse_cluster_cfg(void)
|
|
{
|
|
char *p,*start;
|
|
int n,k;
|
|
struct as_entry **entry,*tmp,*tmp2;
|
|
|
|
if((p=cluster_cfg)==0 || *cluster_cfg==0){
|
|
return 0;
|
|
}
|
|
entry=&as_list;
|
|
|
|
while (*p)
|
|
{
|
|
eat_spaces(p);
|
|
/*get cluster name*/
|
|
start = p;
|
|
while (*p!=' ' && *p!='\t' && *p!='[' && *p!=0)
|
|
p++;
|
|
if ( p==start || *p==0 ){
|
|
LM_ERR("cluster names must only contain alphanumeric chars\n");
|
|
goto error;
|
|
}
|
|
if (!((*entry)=(struct as_entry*)shm_malloc(sizeof(struct as_entry)))) {
|
|
LM_ERR("Out of shm mem for as_entry\n");
|
|
goto error;
|
|
}
|
|
memset(*entry,0,sizeof(struct as_entry));
|
|
if (!((*entry)->name.s=shm_malloc(p-start))) {
|
|
LM_ERR("Out of shm malloc for cluster name\n");
|
|
goto error;
|
|
}
|
|
memcpy((*entry)->name.s, start, p-start);
|
|
(*entry)->name.len=p-start;
|
|
(*entry)->connected=0;
|
|
(*entry)->type=CLUSTER_TYPE;
|
|
(*entry)->u.cs.name=(*entry)->name;
|
|
/*get as names*/
|
|
eat_spaces(p);
|
|
if (*p!='['){
|
|
LM_ERR("Malformed cluster cfg string %s\n",cluster_cfg);
|
|
goto error;
|
|
}
|
|
p++;
|
|
n=0;
|
|
while (*p!=']')
|
|
{
|
|
eat_spaces(p);
|
|
start = p;
|
|
while(*p!=' ' && *p!='\t' && *p!=']' && *p!=',' && *p!=0)
|
|
p++;
|
|
if ( p==start || *p==0 )
|
|
goto error;
|
|
if (!((*entry)->u.cs.as_names[n].s=shm_malloc(p-start))) {
|
|
LM_ERR("Out of shm_mem for AS name in cluster\n");
|
|
goto error;
|
|
}
|
|
(*entry)->u.cs.as_names[n].len=p-start;
|
|
memcpy((*entry)->u.cs.as_names[n].s,start,p-start);
|
|
n++;
|
|
if(n>=MAX_AS_PER_CLUSTER){
|
|
LM_ERR("too many AS per cluster\n");
|
|
goto error;
|
|
}
|
|
eat_spaces(p);
|
|
if (*p==',') {
|
|
p++;
|
|
eat_spaces(p);
|
|
}
|
|
}
|
|
p++;
|
|
(*entry)->u.cs.num=n;
|
|
/* end of element */
|
|
eat_spaces(p);
|
|
if (*p==',')
|
|
p++;
|
|
eat_spaces(p);
|
|
entry=&((*entry)->next);
|
|
}
|
|
for (tmp=as_list;tmp->next;tmp=tmp->next){
|
|
LM_DBG("%.*s\n",tmp->name.len,tmp->name.s);
|
|
}
|
|
LM_DBG("%.*s\n",tmp->name.len,tmp->name.s);
|
|
entry=&(tmp->next);
|
|
for(tmp=as_list;tmp;tmp=tmp->next){
|
|
if (tmp->type!=CLUSTER_TYPE)
|
|
continue;
|
|
LM_DBG("cluster:[%.*s]\n",tmp->name.len,tmp->name.s);
|
|
for(k=0;k<tmp->u.cs.num;k++){
|
|
LM_DBG("\tAS:[%.*s]\n",tmp->u.cs.as_names[k].len,tmp->u.cs.as_names[k].s);
|
|
for (tmp2=as_list;tmp2;tmp2=tmp2->next) {
|
|
if (tmp2->type== AS_TYPE && tmp->u.cs.as_names[k].len == tmp2->name.len &&
|
|
!memcmp(tmp->u.cs.as_names[k].s,tmp2->name.s,tmp2->name.len)) {
|
|
tmp->u.cs.servers[k]=&tmp2->u.as;
|
|
break;
|
|
}
|
|
}
|
|
if(tmp2)
|
|
continue;
|
|
if (!((*entry)=shm_malloc(sizeof(struct as_entry)))) {
|
|
LM_ERR("Out of shm mem \n");
|
|
goto error;
|
|
}
|
|
memset(*entry,0,sizeof(struct as_entry));
|
|
(*entry)->type=AS_TYPE;
|
|
if (!((*entry)->name.s=shm_malloc(tmp->u.cs.as_names[k].len))) {
|
|
LM_ERR("out of shm mem\n");
|
|
goto error;
|
|
}
|
|
memcpy((*entry)->name.s,tmp->u.cs.as_names[k].s,tmp->u.cs.as_names[k].len);
|
|
(*entry)->name.len=tmp->u.cs.as_names[k].len;
|
|
(*entry)->u.as.name=(*entry)->name;
|
|
tmp->u.cs.servers[k]=&(*entry)->u.as;
|
|
entry=&((*entry)->next);
|
|
}
|
|
}
|
|
for(tmp=as_list;tmp;tmp=tmp->next){
|
|
LM_DBG("%.*s %s",tmp->name.len,tmp->name.s,tmp->next?"":"\n");
|
|
}
|
|
return 1;
|
|
error:
|
|
tmp=as_list;
|
|
while(tmp){
|
|
for(k=0;k<tmp->u.cs.num;k++){
|
|
if(tmp->u.cs.as_names[k].s)
|
|
shm_free(tmp->u.cs.as_names[k].s);
|
|
}
|
|
if(tmp->name.s)
|
|
shm_free(tmp->name.s);
|
|
tmp2=tmp;
|
|
tmp=tmp->next;
|
|
shm_free(tmp2);
|
|
}
|
|
as_list=(struct as_entry *)0;
|
|
return -1;
|
|
}
|