/**
 * Procedure to calculate the virtual queue ID from an incoming call.
 * This procedure also sets the 'arrival time' of the call.
 * The formula is id = md5sum { "REQ/RES:Method:from:to" }
 *
 * @param struct sip_msg *msg incoming SIP message
 * @return pointer to the new allocated call information
 */
queueID_t *
vq_get_call_id (struct sip_msg *msg)
{
  queueID_t *newcall_ID;
  char type[5];
  char string[256];
  char method[12];
  str from = {NULL, 0};
  str to = {NULL, 0};
  struct msg_start *fl;
  //struct hdr_field *hf;
  int isReq;
      
  MD5_CTX Md5Ctx;
  char HA1[HASHLEN];
  
  DBG ("Generating a queue ID...\n");
  
  memset (type, 0, sizeof(type));
  memset (string, 0, sizeof(string));
  memset (method, 0, sizeof(method));
  
  fl = &msg->first_line;
  
  isReq = fl->type;
  if (isReq != SIP_REQUEST) {
    DBG ("Not a SIP request");
    return NULL;
  }
  
  newcall_ID = shm_malloc (sizeof(queueID_t));
  if (!newcall_ID) {
    ERR ("Could not allocate memory !\n");
    return NULL;
  }

  // init time in the call_ID
  gettimeofday (&newcall_ID->time, NULL);
  memset (HA1, 0, HASHLEN);
  
  //DBG ("set call time\n");
  
  // calculate the hash
  // Use md5sum { "REQ/RES:Method:from:to" }
  MD5Init(&Md5Ctx);
  
  // add type REQ/RES
  snprintf (type, sizeof(type), "%d", fl->type);

  // add method
  memcpy (method, msg->first_line.u.request.method.s, msg->first_line.u.request.method.len);

  // add from
  cscf_get_from_uri (msg, &from);
  //DBG ("From 'uri': %.*s\n", from.len, from.s);
   
  // add to
  cscf_get_to_uri (msg, &to);
  //DBG ("To 'uri': %.*s\n", to.len, to.s);
  
  // put it together
  snprintf (string, sizeof(string), "%s:%s:%.*s:%.*s", type, method, from.len, from.s, to.len, to.s);
  LOG (L_INFO, "Calculated ID for \"%s\"\n", string);
    
  MD5Update(&Md5Ctx, string, strlen(string));
  
  MD5Final(HA1, &Md5Ctx);

  memcpy (newcall_ID->id, HA1, HASHLEN);
  print_hex ((void *)newcall_ID->id, (void *)newcall_ID->strid, HASHLEN);
  
  LOG (L_INFO, " is %s\n", newcall_ID->strid);

  return newcall_ID;

}
Exemple #2
0
int
add_rt_info(
	ptree_node_t *pn,
	rt_info_t* r,
	unsigned int rgid
	)
{
	rg_entry_t    *trg=NULL;
	rt_info_wrp_t *rtl_wrp=NULL;
	rt_info_wrp_t *rtlw=NULL;
	int i=0;

	if((NULL == pn) || (NULL == r))
		goto err_exit;

	if (NULL == (rtl_wrp = (rt_info_wrp_t*)shm_malloc(sizeof(rt_info_wrp_t)))) {
		LM_ERR("no more shm mem\n");
		goto err_exit;
	}
	memset( rtl_wrp, 0, sizeof(rt_info_wrp_t));
	rtl_wrp->rtl = r;

	if(NULL==pn->rg) {
		/* allocate the routing groups array */
		pn->rg_len = RG_INIT_LEN;
		if(NULL == (pn->rg = (rg_entry_t*)shm_malloc(
						pn->rg_len*sizeof(rg_entry_t)))) {
			/* recover the old pointer to be able to shm_free mem */
			goto err_exit;
		}
		memset( pn->rg, 0, pn->rg_len*sizeof(rg_entry_t));
		pn->rg_pos=0;
	}
	/* search for the rgid up to the rg_pos */
	for(i=0; (i<pn->rg_pos) && (pn->rg[i].rgid!=rgid); i++);
	if((i==pn->rg_len-1)&&(pn->rg[i].rgid!=rgid)) {
		/* realloc & copy the old rg */
		trg = pn->rg;
		if(NULL == (pn->rg = (rg_entry_t*)shm_malloc(
						2*pn->rg_len*sizeof(rg_entry_t)))) {
			/* recover the old pointer to be able to shm_free mem */
			pn->rg = trg;
			goto err_exit;
		}
		memset(pn->rg+pn->rg_len, 0, pn->rg_len*sizeof(rg_entry_t));
		memcpy(pn->rg, trg, pn->rg_len*sizeof(rg_entry_t));
		pn->rg_len*=2;
		shm_free( trg );
	}
	/* insert into list */
	r->ref_cnt++;
	if(NULL==pn->rg[i].rtlw){
		pn->rg[i].rtlw = rtl_wrp;
		pn->rg[i].rgid = rgid;
		pn->rg_pos++;
		goto ok_exit;
	}
	if( r->priority > pn->rg[i].rtlw->rtl->priority) {
		/* change the head of the list */
		rtl_wrp->next = pn->rg[i].rtlw;
		pn->rg[i].rtlw = rtl_wrp;
		goto ok_exit;
	}
	rtlw = pn->rg[i].rtlw;
	while( rtlw->next !=NULL) {
		if(r->priority > rtlw->next->rtl->priority) {
			rtl_wrp->next = rtlw->next;
			rtlw->next = rtl_wrp;
			goto ok_exit;
		}
		rtlw = rtlw->next;
	}
	/* the smallest priority is linked at the end */
	rtl_wrp->next=NULL;
	rtlw->next=rtl_wrp;
ok_exit:
	return 0;

err_exit:
	if (rtl_wrp) shm_free(rtl_wrp);
	return -1;
}
Exemple #3
0
rt_info_t*
build_rt_info(
	int priority,
	tmrec_t *trec,
	/* script routing table index */
	int route_idx,
	/* list of destinations indexes */
	char* dstlst,
	pgw_t* pgw_l
	) 
{
	char *tmp=NULL;
	char *ep=NULL;
	rt_info_t* rt = NULL;
	int *idx = NULL, *t_idx=NULL;
	int n=0, idx_size=0,i, grp_idx=0;
	long t=0;
	pgw_t *pgw=NULL;

	if(NULL == (rt = (rt_info_t*)shm_malloc(sizeof(rt_info_t)))) {
		LM_ERR("no more shm mem(1)\n");
		goto err_exit;
	}
	memset(rt, 0, sizeof(rt_info_t));

	idx_size = IDX_SIZE;
	if( NULL == (idx = (int*)shm_malloc(2*idx_size*sizeof(int)))) {
		LM_ERR("no more shm mem(2)\n");
		goto err_exit;
	}
	memset(idx, 0, 2*idx_size*sizeof(int));

	rt->priority = priority;
	rt->time_rec = trec;
	rt->route_idx = route_idx;
	tmp=dstlst;
	n=0;
	/* parse the dstlst */
	while(tmp && (*tmp!=0)) {
		errno = 0;
		t = strtol(tmp, &ep, 10);
		if (ep == tmp) {
			LM_ERR("bad id '%c' (%d)[%s]\n",
					*ep, (int)(ep-dstlst), dstlst);
			goto err_exit;
		}
		if ((!IS_SPACE(*ep)) && (*ep != SEP) && (*ep != SEP1)
				&& (*ep != SEP_GRP) && (*ep!=0)) {
			LM_ERR("bad char %c (%d) [%s]\n",
					*ep, (int)(ep-dstlst), dstlst);
			goto err_exit;
		}
		if (errno == ERANGE && (t== LONG_MAX || t== LONG_MIN)) {
			LM_ERR("out of bounds\n");
			goto err_exit;
		}
		idx[2*n]=t;
		idx[2*n+1]=grp_idx;
		if(*ep == SEP_GRP)
			grp_idx++;
		n++;
		/* reallocate the array which keeps the parsed indexes */
		if(n>=idx_size){
			if(NULL==((t_idx)=(int*)shm_malloc((idx_size*2*2)*sizeof(int)))) {
				LM_ERR("out of shm\n");
				goto err_exit;
			}
			memset(t_idx+(2*idx_size), 0, 2*idx_size*sizeof(int));
			memcpy(t_idx, idx, 2*idx_size*sizeof(int));
			shm_free(idx);
			idx_size*=2;
			idx=t_idx;
		}
		if(IS_SPACE(*ep))
			EAT_SPACE(ep);
		if(ep && (*ep == SEP || *ep == SEP1 || *ep == SEP_GRP))
			ep++;
		tmp = ep;
	}
	if(n==0) {
		LM_ERR("invalid n\n");
		goto err_exit;
	}
	/* create the pgwl */
	rt->pgwa_len = n;
	if(NULL ==
		(rt->pgwl=(pgw_list_t*)shm_malloc(rt->pgwa_len*sizeof(pgw_list_t)))) {
		goto err_exit;
	}
	memset(rt->pgwl, 0, rt->pgwa_len*sizeof(pgw_list_t));
	/* translate GW ids to GW pointers */
	for(i=0;i<n; i++){
		if ( NULL == (pgw = get_pgw(pgw_l, idx[2*i]))) {
			LM_ERR("invalid GW id %d\n",
				idx[2*i]);
			goto err_exit;
		}
		rt->pgwl[i].pgw=pgw;
		rt->pgwl[i].grpid=idx[2*i+1];
		/* LM_DBG("added to gwlist [%d/%d/%p]\n",
				idx[2*i], idx[2*i+1], pgw); */
	}

	shm_free(idx);
	return rt;

err_exit:
	if(NULL!=idx)
		shm_free(idx);
	if((NULL != rt) && 
		(NULL!=rt->pgwl))
		shm_free(rt->pgwl); 
	if(NULL!=rt)
		shm_free(rt);
	return NULL;
}
Exemple #4
0
char* create_as_action_reply(struct cell *c,struct tmcb_params *params,int uac_id,char processor_id,int *evt_len)
{
   int i;
   unsigned int code,flags;
   unsigned short int port;
   unsigned int k,len;
   char *buffer;
   struct sip_msg *msg;
   if(!(buffer=shm_malloc(ENCODED_MSG_SIZE))){
      LM_ERR("create_as_action_reply Out Of Memory !!\n");
      return 0;
   }
   msg=0;
   *evt_len=0;
   flags=0;
   if(params->rpl==FAKED_REPLY)
      flags=FAKED_REPLY_FLAG;
   /*length*/
   k=4;
   /*type*/
   buffer[k++]=(unsigned char)RES_IN;
   /*processor id*/
   buffer[k++]=processor_id;
   /*flags (by now, not used)*/
   flags=htonl(flags);
   memcpy(buffer+k,&flags,4);
   k+=4;
   /*recv info*/
   if(!(params->rpl == FAKED_REPLY)) {
      msg=params->rpl;
      /*protocol should be UDP,TCP,TLS or whatever*/
      buffer[k++]=(unsigned char)msg->rcv.proto;
      /*src ip len + src ip*/
      len=msg->rcv.src_ip.len;
      buffer[k++]=(unsigned char)len;
      memcpy(buffer+k,&(msg->rcv.src_ip.u),len);
      k+=len;
      /*dst ip len + dst ip*/
      len=msg->rcv.dst_ip.len;
      buffer[k++]=(unsigned char)len;
      memcpy(buffer+k,&(msg->rcv.dst_ip.u),len);
      k+=len;
      /*src port */
      port=htons(msg->rcv.src_port);
      memcpy(buffer+k,&port,2);
      k+=2;
      /*dst port */
      port=htons(msg->rcv.dst_port);
      memcpy(buffer+k,&port,2);
      k+=2;
   }else{
      /*protocol*/
      buffer[k++]=0;
      /*src ip len*/
      buffer[k++]=0;
      /*dst ip len*/
      buffer[k++]=0;
      /*skip src port and dst port*/
      buffer[k++]=0;
      buffer[k++]=0;
      buffer[k++]=0;
      buffer[k++]=0;
   }
   /*hash_index*/
   i=htonl(c->hash_index);
   memcpy(buffer+k,&i,4);
   k+=4;
   /*label*/
   i=(!strncmp(c->method.s,"CANCEL",6)) ? \
     htonl(((struct as_uac_param*)*params->param)->label) : \
	htonl(c->label);
   memcpy(buffer+k,&i,4);
   k+=4;
   /*uac_id*/
   uac_id=htonl(uac_id);
   memcpy(buffer+k,&uac_id,4);
   k+=4;
   /*code*/
   code=htonl(params->code);
   memcpy(buffer+k,&code,4);
   k+=4;
   /*length of event (hdr+payload-4), copied at the beginning*/
   if(params->rpl != FAKED_REPLY) {
      if((i=encode_msg(msg,buffer+k,ENCODED_MSG_SIZE-k))<0){
	 LM_ERR("failed to encode msg\n");
	 goto error;
      }
      k+=i;
   }
   *evt_len=k;
   k=htonl(k);
   memcpy(buffer,&k,4);
   return buffer;
error:
   return 0;
}
Exemple #5
0
int register_dlgcb(struct dlg_cell *dlg, int types, dialog_cb f,
										void *param, param_free_cb ff )
{
	struct dlg_callback *cb;

	if ( types&DLGCB_LOADED ) {
		if (types!=DLGCB_LOADED) {
			LM_CRIT("DLGCB_LOADED type must be register alone!\n");
			return -1;
		}
	} else if ( types&DLGCB_CREATED ) {
		if (types!=DLGCB_CREATED) {
			LM_CRIT("DLGCB_CREATED type must be register alone!\n");
			return -1;
		}
	} else {
		if (dlg==0) {
			LM_CRIT("non-DLGCB_CREATED type "
				"must be register to a dialog (dlg missing)!\n");
			return -1;
		}
	}
	cb = (struct dlg_callback*)shm_malloc(sizeof(struct dlg_callback));
	if (cb==0) {
		LM_ERR("no more shm mem\n");
		return -1;
	}

	cb->types = types;
	cb->callback = f;
	cb->param = param;
	cb->callback_param_free = ff;

	if ( types==DLGCB_CREATED ) {
		if (load_cbs==POINTER_CLOSED_MARKER) {
			LM_CRIT("DLGCB_CREATED type registered after shutdown!?!\n");
			goto error;
		}
		if (create_cbs==0) {
			/* not initialized yet */
			if ( (create_cbs=init_dlg_callback())==NULL ) {
				LM_ERR("no more shm mem\n");
				goto error;
			}
		}
		cb->next = create_cbs->first;
		create_cbs->first = cb;
		create_cbs->types |= types;
	} else if (types==DLGCB_LOADED) {
		if (load_cbs==POINTER_CLOSED_MARKER) {
			/* run the callback on the spot */
			run_load_callback(cb);
			destroy_dlg_callbacks_list(cb);
			return 0;
		}
		if (load_cbs==0) {
			/* not initialized yet */
			if ( (load_cbs=init_dlg_callback())==NULL ) {
				LM_ERR("no more shm mem\n");
				goto error;
			}
		}
		cb->next = load_cbs->first;
		load_cbs->first = cb;
		load_cbs->types |= types;
	} else {
		cb->next = dlg->cbs.first;
		dlg->cbs.first = cb;
		dlg->cbs.types |= types;
	}

	return 0;
error:
	shm_free(cb);
	return -1;
}
Exemple #6
0
int new_request(str *query, http_m_params_t *query_params, http_multi_cbe_t cb, void *param)
{

	LM_DBG("received query %.*s with timeout %d, tls_verify_peer %d, tls_verify_host %d (param=%p)\n", 
			query->len, query->s, query_params->timeout, query_params->tls_verify_peer, query_params->tls_verify_host, param);
	
	CURL *easy;
	CURLMcode rc;

	struct http_m_cell *cell;

	update_stat(requests, 1);

	easy = NULL;
	cell = NULL;

	easy = curl_easy_init();
	if (!easy) {
		LM_ERR("curl_easy_init() failed!\n");
		update_stat(errors, 1);
		return -1;
	}

	cell = build_http_m_cell(easy);
	if (!cell) {
		LM_ERR("cannot create cell!\n");
		update_stat(errors, 1);
		LM_DBG("cleaning up curl handler %p\n", easy);
		curl_easy_cleanup(easy);
		return -1;
	}

	link_http_m_cell(cell);

	cell->global = g;
	cell->easy=easy;
	cell->error[0] = '\0';
	cell->params = *query_params;
	cell->param = param;
	cell->cb = cb;
	cell->url = (char*)shm_malloc(query->len + 1);
	if (cell->url==0) {
		LM_ERR("no more shm mem\n");
		goto error;
	}
	strncpy(cell->url, query->s, query->len);
	cell->url[query->len] = '\0';

	curl_easy_setopt(cell->easy, CURLOPT_URL, cell->url);
	curl_easy_setopt(cell->easy, CURLOPT_WRITEFUNCTION, write_cb);
	curl_easy_setopt(cell->easy, CURLOPT_WRITEDATA, easy);
	if (curl_verbose) {
		curl_easy_setopt(cell->easy, CURLOPT_VERBOSE, 1L);
		curl_easy_setopt(cell->easy, CURLOPT_DEBUGFUNCTION, debug_cb);
	}
	curl_easy_setopt(cell->easy, CURLOPT_ERRORBUFFER, cell->error);
	curl_easy_setopt(cell->easy, CURLOPT_PRIVATE, cell);
	curl_easy_setopt(cell->easy, CURLOPT_SSL_VERIFYPEER, cell->params.tls_verify_peer);
	curl_easy_setopt(cell->easy, CURLOPT_SSL_VERIFYHOST, cell->params.tls_verify_host?2:0);
	curl_easy_setopt(cell->easy, CURLOPT_SSLVERSION, tls_version);

	if (cell->params.tls_client_cert) {
		curl_easy_setopt(cell->easy, CURLOPT_SSLCERT, cell->params.tls_client_cert);
	}

	if (cell->params.tls_client_key) {
		curl_easy_setopt(cell->easy, CURLOPT_SSLKEY, cell->params.tls_client_key);
	}

	if (cell->params.tls_ca_path) {
		curl_easy_setopt(cell->easy, CURLOPT_CAPATH, cell->params.tls_ca_path);
	}

	curl_easy_setopt(cell->easy, CURLOPT_HEADER, 1);
	if (cell->params.headers) {
		curl_easy_setopt(cell->easy, CURLOPT_HTTPHEADER, cell->params.headers);
	}

	if (cell->params.body.s && cell->params.body.len) {
		curl_easy_setopt(cell->easy, CURLOPT_POSTFIELDSIZE, (long)cell->params.body.len);
		curl_easy_setopt(cell->easy, CURLOPT_COPYPOSTFIELDS, cell->params.body.s);
	}

	switch (cell->params.method) {
	case 1:
		curl_easy_setopt(cell->easy, CURLOPT_CUSTOMREQUEST, "GET");
		break;
	case 2:
		curl_easy_setopt(cell->easy, CURLOPT_CUSTOMREQUEST, "POST");
		break;
	case 3:
		curl_easy_setopt(cell->easy, CURLOPT_CUSTOMREQUEST, "PUT");
		break;
	case 4:
		curl_easy_setopt(cell->easy, CURLOPT_CUSTOMREQUEST, "DELETE");
		break;
	default:
		break;
	}

	if (cell->params.username) {
		curl_easy_setopt(cell->easy, CURLOPT_USERNAME, cell->params.username);
		curl_easy_setopt(cell->easy, CURLOPT_HTTPAUTH, cell->params.authmethod);

		LM_DBG("set username to %s [authmethod %u]\n", cell->params.username, cell->params.authmethod);
	}

	if (cell->params.password) {
		curl_easy_setopt(cell->easy, CURLOPT_PASSWORD, cell->params.password);
	}

	LM_DBG("Adding easy %p to multi %p (%.*s)\n", cell->easy, g->multi, query->len, query->s);
	rc = curl_multi_add_handle(g->multi, cell->easy);
	if (check_mcode(rc, cell->error) < 0) {
		LM_ERR("error adding curl handler: %s\n", cell->error);
		goto error;
	}
	/* note that the add_handle() will set a time-out to trigger very soon so
	 *      that the necessary socket_action() call will be called by this app */
	return 0;

error:
	update_stat(errors, 1);
    if (easy) {
		LM_DBG("cleaning up curl handler %p\n", easy);
		curl_easy_cleanup(easy);
    }
    free_http_m_cell(cell);
    return -1;
}
Exemple #7
0
/* initialize ratelimit module */
static int mod_init(void)
{
	int i;

	LM_DBG("initializing ...\n");

	rl_lock = lock_alloc();
	if (! rl_lock) {
		LM_ERR("oom in lock_alloc()\n");
		return -1;
	}

	if (lock_init(rl_lock)==0) {
		LM_ERR("failed to init lock\n");
		return -1;
	}

	/* register timer to reset counters */
	if (register_timer_process(rl_timer, NULL, timer_interval,
	TIMER_PROC_INIT_FLAG) == NULL) {
		LM_ERR("could not register timer function\n");
		return -1;
	}

	/* load the SIGNALLING API */
	if(load_sig_api(&sigb)< 0) {
		LM_ERR("can't load signaling functions\n");
		return -1;
	}

	network_load_value = shm_malloc(sizeof(int));
	if (network_load_value==NULL) {
		LM_ERR("oom for network_load_value\n");
		return -1;
	}
	check_network_load = shm_malloc(sizeof(int));
	if (check_network_load==NULL) {
		LM_ERR("oom for check_network_load\n");
		return -1;
	}

	load_value = shm_malloc(sizeof(double));
	if (load_value==NULL) {
		LM_ERR("oom for load_value\n");
		return -1;
	}
	load_source = shm_malloc(sizeof(int));
	if (load_source==NULL) {
		LM_ERR("oom for load_source\n");
		return -1;
	}
	pid_kp = shm_malloc(sizeof(double));
	if (pid_kp==NULL) {
		LM_ERR("oom for pid_kp\n");
		return -1;
	}
	pid_ki = shm_malloc(sizeof(double));
	if (pid_ki==NULL) {
		LM_ERR("oom for pid_ki\n");
		return -1;
	}
	pid_kd = shm_malloc(sizeof(double));
	if (pid_kd==NULL) {
		LM_ERR("oom for pid_kd\n");
		return -1;
	}
	pid_setpoint = shm_malloc(sizeof(double));
	if (pid_setpoint==NULL) {
		LM_ERR("oom for pid_setpoint\n");
		return -1;
	}
	drop_rate = shm_malloc(sizeof(int));
	if (drop_rate==NULL) {
		LM_ERR("oom for drop_rate\n");
		return -1;
	}
	nqueues = shm_malloc(sizeof(int));
	if (nqueues==NULL) {
		LM_ERR("oom for nqueues\n");
		return -1;
	}
	rl_dbg_str = shm_malloc(sizeof(str));
	if (rl_dbg_str==NULL) {
		LM_ERR("oom for rl_dbg_str\n");
		return -1;
	}

	*network_load_value = 0;
	*check_network_load = 0;
	*load_value = 0.0;
	*load_source = load_source_mp;
	*pid_kp = 0.0;
	*pid_ki = -25.0;
	*pid_kd = 0.0;
	*pid_setpoint = 0.01 * (double)cfg_setpoint;
	*drop_rate      = 0;
	*nqueues = nqueues_mp;
	rl_dbg_str->s = NULL;
	rl_dbg_str->len = 0;

	for (i=0; i<MAX_PIPES; i++) {
		pipes[i].algo    = shm_malloc(sizeof(int));
		if (pipes[i].algo==NULL) {
			LM_ERR("oom for pipes[%d].algo\n", i);
			return -1;
		}
		pipes[i].limit   = shm_malloc(sizeof(int));
		if (pipes[i].limit==NULL) {
			LM_ERR("oom for pipes[%d].limit\n", i);
			return -1;
		}
		pipes[i].load    = shm_malloc(sizeof(int));
		if (pipes[i].load==NULL) {
			LM_ERR("oom for pipes[%d].load\n", i);
			return -1;
		}
		pipes[i].counter = shm_malloc(sizeof(int));
		if (pipes[i].counter==NULL) {
			LM_ERR("oom for pipes[%d].counter\n", i);
			return -1;
		}
		pipes[i].last_counter = shm_malloc(sizeof(int));
		if (pipes[i].last_counter==NULL) {
			LM_ERR("oom for pipes[%d].last_counter\n", i);
			return -1;
		}
		*pipes[i].algo    = pipes[i].algo_mp;
		*pipes[i].limit   = pipes[i].limit_mp;
		*pipes[i].load    = 0;
		*pipes[i].counter = 0;
		*pipes[i].last_counter = 0;
	}

	for (i=0; i<*nqueues; i++) {
		queues[i].pipe   = shm_malloc(sizeof(int));
		if (queues[i].pipe==NULL) {
			LM_ERR("oom for queues[%d].pipe\n", i);
			return -1;
		}
		queues[i].method = shm_malloc(sizeof(str));
		if (queues[i].method==NULL) {
			LM_ERR("oom for queues[%d].method\n", i);
			return -1;
		}

		*queues[i].pipe   = queues[i].pipe_mp;
		if (queues[i].method_mp.s == NULL) {
			LM_ERR("unexpected NULL method for queues[%d].method_mp\n", i);
			return -1;
		}
		if(str_cpy(queues[i].method, &queues[i].method_mp)) {
			LM_ERR("oom str_cpy(queues[%d].method\n", i);
			return -1;
		}
		pkg_free(queues[i].method_mp.s);
		queues[i].method_mp.s = NULL;
		queues[i].method_mp.len = 0;
	}

	set_check_network_load();

	rl_drop_reason.len = strlen(rl_drop_reason.s);

	return 0;
}
Exemple #8
0
/* adds a proto ip:port combination to the blacklist
 * returns 0 on success, -1 on error (blacklist full -- would use more then
 *  blst:_max_mem, or out of shm. mem.)
 */
inline static int dst_blacklist_add_ip(unsigned char err_flags,
									unsigned char proto,
									struct ip_addr* ip, unsigned short port,
									ticks_t timeout)
{
	int size;
	struct dst_blst_entry* e;
	unsigned short hash;
	ticks_t now;
	int ret;

	ret=0;
	if (ip->af==AF_INET){
		err_flags&=~BLST_IS_IPV6; /* make sure the ipv6 flag is reset */
		size=sizeof(struct dst_blst_entry);
	}else{
		err_flags|=BLST_IS_IPV6;
		size=sizeof(struct dst_blst_entry)+12 /* ipv6 addr - 4 */;
	}
	now=get_ticks_raw();
	hash=dst_blst_hash_no(proto, ip, port);
	/* check if the entry already exists */
	LOCK_BLST(hash);
		e=_dst_blacklist_lst_find(hash, ip, proto, port, now);
		if (e){
			e->flags|=err_flags;
			e->expire=now+timeout; /* update the timeout */
		}else{
			if (unlikely((*blst_mem_used+size) >=
					cfg_get(core, core_cfg, blst_max_mem))){
#ifdef USE_DST_BLACKLIST_STATS
				dst_blacklist_stats[process_no].bkl_lru_cnt++;
#endif
				UNLOCK_BLST(hash);
				/* first try to free some memory  (~ 12%), but don't
				 * spend more then 250 ms*/
				dst_blacklist_clean_expired(*blst_mem_used/16*14, 0,
															MS_TO_TICKS(250));
				if (unlikely(*blst_mem_used+size >=
						cfg_get(core, core_cfg, blst_max_mem))){
					ret=-1;
					goto error;
				}
				LOCK_BLST(hash);
			}
			e=shm_malloc(size);
			if (e==0){
				UNLOCK_BLST(hash);
				ret=E_OUT_OF_MEM;
				goto error;
			}
			*blst_mem_used+=size;
			e->flags=err_flags;
			e->proto=proto;
			e->port=port;
			memcpy(e->ip, ip->u.addr, ip->len);
			e->expire=now+timeout; /* update the timeout */
			e->next=0;
			dst_blacklist_lst_add(&dst_blst_hash[hash].first, e);
			BLST_HASH_STATS_INC(hash);
		}
	UNLOCK_BLST(hash);
error:
	return ret;
}
Exemple #9
0
static int mod_init(void)
{
	if(register_mi_mod(exports.name, mi_cmds)!=0)
	{
		LM_ERR("failed to register MI commands\n");
		return -1;
	}

	dp_db_url.len = dp_db_url.s ? strlen(dp_db_url.s) : 0;
	LM_DBG("db_url=%s/%d/%p\n", ZSW(dp_db_url.s), dp_db_url.len,dp_db_url.s);
	dp_table_name.len   = strlen(dp_table_name.s);
	dpid_column.len     = strlen( dpid_column.s);
	pr_column.len       = strlen(pr_column.s);
	match_op_column.len = strlen(match_op_column.s);
	match_exp_column.len= strlen(match_exp_column.s);
	match_len_column.len= strlen(match_len_column.s);
	subst_exp_column.len= strlen(subst_exp_column.s);
	repl_exp_column.len = strlen(repl_exp_column.s);
	attrs_column.len    = strlen(attrs_column.s);

	if(attr_pvar_s.s) {
		attr_pvar = (pv_spec_t *)shm_malloc(sizeof(pv_spec_t));
		if(!attr_pvar){
			LM_ERR("out of shm memory\n");
			return -1;
		}

		attr_pvar_s.len = strlen(attr_pvar_s.s);
		if( (pv_parse_spec(&attr_pvar_s, attr_pvar)==NULL) ||
		((attr_pvar->type != PVT_AVP) && (attr_pvar->type!=PVT_SCRIPTVAR))) {
				LM_ERR("invalid pvar name\n");
				return -1;
			}
	}

	default_par2 = (dp_param_p)shm_malloc(sizeof(dp_param_t));
	if(default_par2 == NULL){
		LM_ERR("no shm more memory\n");
		return -1;
	}
	memset(default_par2, 0, sizeof(dp_param_t));

	default_param_s.len = strlen(default_param_s.s);
	if (pv_parse_spec( &default_param_s, &default_par2->v.sp[0])==NULL) {
		LM_ERR("input pv is invalid\n");
		return -1;
	}

	default_param_s.len = strlen(default_param_s.s);
	if (pv_parse_spec( &default_param_s, &default_par2->v.sp[1])==NULL) {
		LM_ERR("output pv is invalid\n");
		return -1;
	}

	if(dp_fetch_rows<=0)
		dp_fetch_rows = 1000;

	if(init_data() != 0) {
		LM_ERR("could not initialize data\n");
		return -1;
	}

	return 0;
}
Exemple #10
0
int update_phtable(presentity_t* presentity, str pres_uri, str body)
{
	char* sphere= NULL;
	unsigned int hash_code;
	pres_entry_t* p;
	int ret= 0;
	str* xcap_doc= NULL;

	/* get new sphere */
	sphere= extract_sphere(body);
	if(sphere==NULL)
	{
		LM_DBG("no sphere defined in new body\n");
		return 0;
	}

	/* search for record in hash table */
	hash_code= core_case_hash(&pres_uri, NULL, phtable_size);
	
	lock_get(&pres_htable[hash_code].lock);

	p= search_phtable(&pres_uri, presentity->event->evp->type, hash_code);
	if(p== NULL)
	{
		lock_release(&pres_htable[hash_code].lock);
		goto done;
	}
	
	if(p->sphere)
	{
		if(strcmp(p->sphere, sphere)!= 0)
		{
			/* new sphere definition */
			shm_free(p->sphere);
		}
		else
		{
			/* no change in sphere definition */
			lock_release(&pres_htable[hash_code].lock);
			pkg_free(sphere);
			return 0;
		}
	
	}


	p->sphere= (char*)shm_malloc((strlen(sphere)+ 1)*sizeof(char));
	if(p->sphere== NULL)
	{
		lock_release(&pres_htable[hash_code].lock);
		ret= -1;
		goto done;
	}
	strcpy(p->sphere, sphere);
		
	lock_release(&pres_htable[hash_code].lock);

	/* call for watchers status update */

	if(presentity->event->get_rules_doc(&presentity->user, &presentity->domain,
				&xcap_doc)< 0)
	{
		LM_ERR("failed to retrieve xcap document\n");
		ret= -1;
		goto done;
	}

	update_watchers_status(pres_uri, presentity->event, xcap_doc);


done:

	if(xcap_doc)
	{
		if(xcap_doc->s)
			pkg_free(xcap_doc->s);
		pkg_free(xcap_doc);
	}

	if(sphere)
		pkg_free(sphere);
	return ret;
}
Exemple #11
0
int init_dst_blacklist()
{
	int ret;
#ifdef BLST_LOCK_PER_BUCKET
	int r;
#endif

	if (dst_blacklist_init==0) {
		/* the dst blacklist is turned off */
		default_core_cfg.use_dst_blacklist=0;
		return 0;
	}

	ret=-1;
#ifdef DST_BLACKLIST_HOOKS
	if (init_blacklist_hooks()!=0){
		ret=E_OUT_OF_MEM;
		goto error;
	}
#endif
	blst_mem_used=shm_malloc(sizeof(*blst_mem_used));
	if (blst_mem_used==0){
		ret=E_OUT_OF_MEM;
		goto error;
	}
	*blst_mem_used=0;
	dst_blst_hash=shm_malloc(sizeof(struct dst_blst_lst_head) *
											DST_BLST_HASH_SIZE);
	if (dst_blst_hash==0){
		ret=E_OUT_OF_MEM;
		goto error;
	}
	memset(dst_blst_hash, 0, sizeof(struct dst_blst_lst_head) *
								DST_BLST_HASH_SIZE);
#ifdef BLST_LOCK_PER_BUCKET
	for (r=0; r<DST_BLST_HASH_SIZE; r++){
		if (lock_init(&dst_blst_hash[r].lock)==0){
			ret=-1;
			goto error;
		}
	}
#elif defined BLST_LOCK_SET
	blst_lock_set=lock_set_alloc(DST_BLST_HASH_SIZE);
	if (blst_lock_set==0){
		ret=E_OUT_OF_MEM;
		goto error;
	}
	if (lock_set_init(blst_lock_set)==0){
		lock_set_dealloc(blst_lock_set);
		blst_lock_set=0;
		ret=-1;
		goto error;
	}
#else /* BLST_ONE_LOCK */
	blst_lock=lock_alloc();
	if (blst_lock==0){
		ret=E_OUT_OF_MEM;
		goto error;
	}
	if (lock_init(blst_lock)==0){
		lock_dealloc(blst_lock);
		blst_lock=0;
		ret=-1;
		goto error;
	}
#endif /* BLST*LOCK*/
	blst_timer_h=timer_alloc();
	if (blst_timer_h==0){
		ret=E_OUT_OF_MEM;
		goto error;
	}
	/* fix options */
	default_core_cfg.blst_max_mem<<=10; /* in Kb */ /* TODO: test with 0 */
	if (blst_timer_interval){
		timer_init(blst_timer_h, blst_timer, 0 ,0); /* slow timer */
		if (timer_add(blst_timer_h, S_TO_TICKS(blst_timer_interval))<0){
			LOG(L_CRIT, "BUG: init_dst_blacklist: failed to add the timer\n");
			timer_free(blst_timer_h);
			blst_timer_h=0;
			goto error;
		}
	}
	return 0;
error:
	destroy_dst_blacklist();
	return ret;
}
Exemple #12
0
subs_t* mem_copy_subs_noc(subs_t* s)
{
	int size;
	subs_t* dest;

	size= sizeof(subs_t)+ (s->pres_uri.len+ s->to_user.len
		+ s->to_domain.len+ s->from_user.len+ s->from_domain.len+ s->callid.len
		+ s->to_tag.len+ s->from_tag.len+s->sockinfo_str.len+s->event_id.len
		+ s->local_contact.len + s->record_route.len+
		+ s->reason.len+ s->watcher_user.len+ s->watcher_domain.len
		+ 1)*sizeof(char);

	dest= (subs_t*)shm_malloc(size);
	if(dest== NULL)
	{
		ERR_MEM(SHARE_MEM);
	}
	memset(dest, 0, size);
	size= sizeof(subs_t);

	CONT_COPY(dest, dest->pres_uri, s->pres_uri)
	CONT_COPY(dest, dest->to_user, s->to_user)
	CONT_COPY(dest, dest->to_domain, s->to_domain)
	CONT_COPY(dest, dest->from_user, s->from_user)
	CONT_COPY(dest, dest->from_domain, s->from_domain)
	CONT_COPY(dest, dest->watcher_user, s->watcher_user)
	CONT_COPY(dest, dest->watcher_domain, s->watcher_domain)
	CONT_COPY(dest, dest->to_tag, s->to_tag)
	CONT_COPY(dest, dest->from_tag, s->from_tag)
	CONT_COPY(dest, dest->callid, s->callid)
	CONT_COPY(dest, dest->sockinfo_str, s->sockinfo_str)
	CONT_COPY(dest, dest->local_contact, s->local_contact)
	CONT_COPY(dest, dest->record_route, s->record_route)
	if(s->event_id.s)
		CONT_COPY(dest, dest->event_id, s->event_id)
	if(s->reason.s)
		CONT_COPY(dest, dest->reason, s->reason)

	dest->event= s->event;
	dest->local_cseq= s->local_cseq;
	dest->remote_cseq= s->remote_cseq;
	dest->status= s->status;
	dest->version= s->version;
	dest->send_on_cback= s->send_on_cback;
	dest->expires= s->expires;
	dest->db_flag= s->db_flag;

	dest->contact.s= (char*)shm_malloc(s->contact.len* sizeof(char));
	if(dest->contact.s== NULL)
	{
		ERR_MEM(SHARE_MEM);
	}
	memcpy(dest->contact.s, s->contact.s, s->contact.len);
	dest->contact.len= s->contact.len;

	return dest;

error:
	if(dest)
			shm_free(dest);
	return NULL;
}
Exemple #13
0
subs_t* mem_copy_subs(subs_t* s, int mem_type)
{
	int size;
	subs_t* dest;

	size= sizeof(subs_t)+ (s->pres_uri.len+ s->to_user.len
		+ s->to_domain.len+ s->from_user.len+ s->from_domain.len+ s->callid.len
		+ s->to_tag.len+ s->from_tag.len+s->sockinfo_str.len+s->event_id.len
		+ s->local_contact.len+ s->contact.len+ s->record_route.len
		+ s->reason.len+ s->watcher_user.len+ s->watcher_domain.len
		+ 1)*sizeof(char);

	if(mem_type & PKG_MEM_TYPE)
		dest= (subs_t*)pkg_malloc(size);
	else
		dest= (subs_t*)shm_malloc(size);

	if(dest== NULL)
	{
		ERR_MEM((mem_type==PKG_MEM_TYPE)?PKG_MEM_STR:SHARE_MEM);
	}
	memset(dest, 0, size);
	size= sizeof(subs_t);

	CONT_COPY(dest, dest->pres_uri, s->pres_uri)
	CONT_COPY(dest, dest->to_user, s->to_user)
	CONT_COPY(dest, dest->to_domain, s->to_domain)
	CONT_COPY(dest, dest->from_user, s->from_user)
	CONT_COPY(dest, dest->from_domain, s->from_domain)
	CONT_COPY(dest, dest->watcher_user, s->watcher_user)
	CONT_COPY(dest, dest->watcher_domain, s->watcher_domain)
	CONT_COPY(dest, dest->to_tag, s->to_tag)
	CONT_COPY(dest, dest->from_tag, s->from_tag)
	CONT_COPY(dest, dest->callid, s->callid)
	CONT_COPY(dest, dest->sockinfo_str, s->sockinfo_str)
	CONT_COPY(dest, dest->local_contact, s->local_contact)
	CONT_COPY(dest, dest->contact, s->contact)
	CONT_COPY(dest, dest->record_route, s->record_route)
	if(s->event_id.s)
		CONT_COPY(dest, dest->event_id, s->event_id)
	if(s->reason.s)
		CONT_COPY(dest, dest->reason, s->reason)

	dest->event= s->event;
	dest->local_cseq= s->local_cseq;
	dest->remote_cseq= s->remote_cseq;
	dest->status= s->status;
	dest->version= s->version;
	dest->send_on_cback= s->send_on_cback;
	dest->expires= s->expires;
	dest->db_flag= s->db_flag;

	return dest;

error:
	if(dest)
	{
		if(mem_type & PKG_MEM_TYPE)
			pkg_free(dest);
		else
			shm_free(dest);
	}
	return NULL;
}
Exemple #14
0
/**
 * Loads the routing data from the database given in global
 * variable db_url and stores it in routing tree rd.
 *
 * @param rd Pointer to the route data tree where the routing data
 * shall be loaded into
 *
 * @return 0 means ok, -1 means an error occured
 *
 */
int load_route_data_db(struct route_data_t * rd) {
	db1_res_t * res = NULL;
	db_row_t * row = NULL;
	int i, ret;
	struct carrier_data_t * tmp_carrier_data;
	static str query_str;
	str tmp_scan_prefix, tmp_rewrite_host, tmp_rewrite_prefix,
		tmp_rewrite_suffix, tmp_host_name, tmp_reply_code, tmp_comment;
	str *p_tmp_comment;

	if( (strlen("SELECT DISTINCT  FROM  WHERE = ")
			+ carrierroute_table.len + columns[COL_DOMAIN]->len
			+ columns[COL_CARRIER]->len + 20) >  QUERY_LEN) {
		LM_ERR("query too long\n");
		return -1;
	}

	if((rd->carrier_num = load_carrier_map(rd)) <= 0){
		LM_ERR("error while retrieving carriers\n");
		goto errout;
	}

	if((rd->domain_num = load_domain_map(rd)) <= 0){
		LM_ERR("error while retrieving domains\n");
		goto errout;
	}

	if ((rd->carriers = shm_malloc(sizeof(struct carrier_data_t *) * rd->carrier_num)) == NULL) {
		SHM_MEM_ERROR;
		goto errout;
	}
	memset(rd->carriers, 0, sizeof(struct carrier_data_t *) * rd->carrier_num);

	for (i=0; i<rd->carrier_num; i++) {
		memset(query, 0, QUERY_LEN);
		ret = snprintf(query, QUERY_LEN, "SELECT DISTINCT %.*s FROM %.*s WHERE %.*s=%i",
		columns[COL_DOMAIN]->len, columns[COL_DOMAIN]->s, carrierroute_table.len,
		carrierroute_table.s, columns[COL_CARRIER]->len, columns[COL_CARRIER]->s, rd->carrier_map[i].id);
		if (ret < 0) {
			LM_ERR("error in snprintf");
			goto errout;
		}
		query_str.s = query;
		query_str.len = ret;

		if (carrierroute_dbf.raw_query(carrierroute_dbh, &query_str, &res) < 0) {
			LM_ERR("Failed to query database.\n");
			goto errout;
		}
		LM_INFO("carrier '%.*s' (id %i) has %i domains\n", rd->carrier_map[i].name.len, rd->carrier_map[i].name.s, rd->carrier_map[i].id, RES_ROW_N(res));
		tmp_carrier_data = create_carrier_data(rd->carrier_map[i].id, &rd->carrier_map[i].name, RES_ROW_N(res));
		if (tmp_carrier_data == NULL) {
			LM_ERR("can't create new carrier '%.*s'\n", rd->carrier_map[i].name.len, rd->carrier_map[i].name.s);
			goto errout;
		}
		if (add_carrier_data(rd, tmp_carrier_data) < 0) {
			LM_ERR("can't add carrier '%.*s'\n", rd->carrier_map[i].name.len, rd->carrier_map[i].name.s);
			destroy_carrier_data(tmp_carrier_data);
			goto errout;
		}
		carrierroute_dbf.free_result(carrierroute_dbh, res);
		res = NULL;
	}

	if (carrierroute_dbf.use_table(carrierroute_dbh, &carrierroute_table) < 0) {
		LM_ERR("Cannot set database table '%.*s'.\n", carrierroute_table.len, carrierroute_table.s);
		return -1;
	}

	if (DB_CAPABILITY(carrierroute_dbf, DB_CAP_FETCH)) {
		if (carrierroute_dbf.query(carrierroute_dbh, NULL, NULL, NULL, (db_key_t *) columns, 0,
				columns_load_num, NULL, NULL) < 0) {
			LM_ERR("Failed to query database to prepare fetch row.\n");
			return -1;
		}
		if(carrierroute_dbf.fetch_result(carrierroute_dbh, &res, cfg_get(carrierroute, carrierroute_cfg, fetch_rows)) < 0) {
			LM_ERR("Fetching rows failed\n");
			return -1;
		}
	} else {
		if (carrierroute_dbf.query(carrierroute_dbh, NULL, NULL, NULL, (db_key_t *) columns, 0,
				columns_load_num, NULL, &res) < 0) {
			LM_ERR("Failed to query database.\n");
			return -1;
		}
	}
	int n = 0;
	do {
		LM_DBG("loading, cycle %d", n++);
		for (i = 0; i < RES_ROW_N(res); ++i) {
			row = &RES_ROWS(res)[i];
			tmp_scan_prefix.s=(char *)row->values[COL_SCAN_PREFIX].val.string_val;
			tmp_rewrite_host.s=(char *)row->values[COL_REWRITE_HOST].val.string_val;
			tmp_rewrite_prefix.s=(char *)row->values[COL_REWRITE_PREFIX].val.string_val;
			tmp_rewrite_suffix.s=(char *)row->values[COL_REWRITE_SUFFIX].val.string_val;
			if (tmp_scan_prefix.s==NULL) tmp_scan_prefix.s="";
			if (tmp_rewrite_host.s==NULL) tmp_rewrite_host.s="";
			if (tmp_rewrite_prefix.s==NULL) tmp_rewrite_prefix.s="";
			if (tmp_rewrite_suffix.s==NULL) tmp_rewrite_suffix.s="";
			tmp_scan_prefix.len=strlen(tmp_scan_prefix.s);
			tmp_rewrite_host.len=strlen(tmp_rewrite_host.s);
			tmp_rewrite_prefix.len=strlen(tmp_rewrite_prefix.s);
			tmp_rewrite_suffix.len=strlen(tmp_rewrite_suffix.s);

			p_tmp_comment = NULL;
			if (load_comments) {
				tmp_comment.s = (char *)row->values[COL_COMMENT].val.string_val;
				if (tmp_comment.s==NULL) tmp_comment.s="";
				tmp_comment.len=strlen(tmp_comment.s);
				p_tmp_comment = &tmp_comment;
			}

			if (add_route(rd,
					row->values[COL_CARRIER].val.int_val,
					row->values[COL_DOMAIN].val.int_val,
					&tmp_scan_prefix,
					row->values[COL_FLAGS].val.int_val,
					row->values[COL_MASK].val.int_val,
					0,
					row->values[COL_PROB].val.double_val,
					&tmp_rewrite_host,
					row->values[COL_STRIP].val.int_val,
					&tmp_rewrite_prefix,
					&tmp_rewrite_suffix,
					1,
					0,
					-1,
					NULL,
					p_tmp_comment) == -1) {
				goto errout;
			}
		}
		if (DB_CAPABILITY(carrierroute_dbf, DB_CAP_FETCH)) {
			if(carrierroute_dbf.fetch_result(carrierroute_dbh, &res,  cfg_get(carrierroute, carrierroute_cfg, fetch_rows)) < 0) {
				LM_ERR("fetching rows failed\n");
				carrierroute_dbf.free_result(carrierroute_dbh, res);
				return -1;
			}
		} else {
			break;
		}
	} while(RES_ROW_N(res) > 0);

	carrierroute_dbf.free_result(carrierroute_dbh, res);
	res = NULL;
	
	if (carrierroute_dbf.use_table(carrierroute_dbh, &carrierfailureroute_table) < 0) {
		LM_ERR("cannot set database table '%.*s'.\n",
				carrierfailureroute_table.len, carrierfailureroute_table.s);
		return -1;
	}
	if (carrierroute_dbf.query(carrierroute_dbh, NULL, NULL, NULL, (db_key_t *)failure_columns, 0,
			failure_columns_load_num, NULL, &res) < 0) {
		LM_ERR("failed to query database.\n");
		return -1;
	}
	for (i = 0; i < RES_ROW_N(res); ++i) {
		row = &RES_ROWS(res)[i];
		tmp_scan_prefix.s=(char *)row->values[FCOL_SCAN_PREFIX].val.string_val;
		tmp_host_name.s=(char *)row->values[FCOL_HOST_NAME].val.string_val;
		tmp_reply_code.s=(char *)row->values[FCOL_REPLY_CODE].val.string_val;
		if (tmp_scan_prefix.s==NULL) tmp_scan_prefix.s="";
		if (tmp_host_name.s==NULL) tmp_host_name.s="";
		if (tmp_reply_code.s==NULL) tmp_reply_code.s="";
		tmp_scan_prefix.len=strlen(tmp_scan_prefix.s);
		tmp_host_name.len=strlen(tmp_host_name.s);
		tmp_reply_code.len=strlen(tmp_reply_code.s);
		p_tmp_comment = NULL;

		if (load_comments) {
			tmp_comment.s = (char *)row->values[FCOL_COMMENT].val.string_val;
			if (tmp_comment.s==NULL) tmp_comment.s="";
			tmp_comment.len=strlen(tmp_comment.s);
			p_tmp_comment = &tmp_comment;
		}

		if (add_failure_route(rd,
				row->values[FCOL_CARRIER].val.int_val,
				row->values[COL_DOMAIN].val.int_val,
				&tmp_scan_prefix,
				&tmp_host_name,
				&tmp_reply_code,
				row->values[FCOL_FLAGS].val.int_val,
				row->values[FCOL_MASK].val.int_val,
				row->values[FCOL_NEXT_DOMAIN].val.int_val,
				p_tmp_comment) == -1) {
			goto errout;
		}
	}

	carrierroute_dbf.free_result(carrierroute_dbh, res);
	return 0;

errout:
	if (res) {
		carrierroute_dbf.free_result(carrierroute_dbh, res);
	}
	return -1;
}
Exemple #15
0
static int mod_init(void)
{
	LM_INFO("Load-Balancer module - initializing\n");

	init_db_url( db_url , 0 /*cannot be null*/);

	/* Load dialog API */
	if (load_dlg_api(&lb_dlg_binds) != 0) {
		LM_ERR("Can't load dialog hooks");
		return -1;
	}

	/* data pointer in shm */
	curr_data = (struct lb_data**)shm_malloc( sizeof(struct lb_data*) );
	if (curr_data==0) {
		LM_CRIT("failed to get shm mem for data ptr\n");
		return -1;
	}
	*curr_data = 0;

	/* create & init lock */
	if ((ref_lock = lock_init_rw()) == NULL) {
		LM_CRIT("failed to init lock\n");
		return -1;
	}

	if (init_lb_bls()) {
		LM_ERR("BL INIT failed\n");
		return -1;
	}

	/* init and open DB connection */
	if (init_lb_db(&db_url, table_name)!=0) {
		LM_ERR("failed to initialize the DB support\n");
		return -1;
	}

	/* load data */
	if ( lb_reload_data()!=0 ) {
		LM_CRIT("failed to load load-balancing data\n");
		return -1;
	}

	/* close DB connection */
	lb_close_db();

	/* arm a function for probing */
	if (lb_prob_interval) {
		/* load TM API */
		if (load_tm_api(&lb_tmb)!=0) {
			LM_ERR("can't load TM API\n");
			return -1;
		}

		/* probing method */
		lb_probe_method.len = strlen(lb_probe_method.s);
		lb_probe_from.len = strlen(lb_probe_from.s);
		if (lb_probe_replies.s)
			lb_probe_replies.len = strlen(lb_probe_replies.s);

		/* register pinger function */
		if (register_timer( "lb-pinger", lb_prob_handler , NULL,
		lb_prob_interval)<0) {
			LM_ERR("failed to register probing handler\n");
			return -1;
		}

		if (lb_probe_replies.s) {
			lb_probe_replies.len = strlen(lb_probe_replies.s);
			if(parse_reply_codes( &lb_probe_replies, &probing_reply_codes,
			&probing_codes_no )< 0) {
				LM_ERR("Bad format for options_reply_code parameter"
					" - Need a code list separated by commas\n");
				return -1;
			}
		}

	}

	/* parse avps */
	if (parse_avp_spec(&grp_avp_name_s, &grp_avp_name)) {
		LM_ERR("cannot parse group avp\n");
		return -1;
	}
	if (parse_avp_spec(&mask_avp_name_s, &mask_avp_name)) {
		LM_ERR("cannot parse mask avp\n");
		return -1;
	}
	if (parse_avp_spec(&id_avp_name_s, &id_avp_name)) {
		LM_ERR("cannot parse id avp\n");
		return -1;
	}

	return 0;
}
void publ_cback_func(struct cell *t, int type, struct tmcb_params *ps)
{
	struct hdr_field* hdr= NULL;
	struct sip_msg* msg= NULL;
	ua_pres_t* presentity= NULL;
	ua_pres_t* db_presentity= NULL; 
	ua_pres_t* hentity= NULL;
	int found = 0;
	int size= 0;
	unsigned int lexpire= 0;
	str etag;
	unsigned int hash_code;
	db1_res_t *res=NULL;
	ua_pres_t dbpres;
	str pres_uri={0,0}, watcher_uri={0,0}, extra_headers={0,0};
	int end_transaction = 1;

	memset(&dbpres, 0, sizeof(dbpres));
	dbpres.pres_uri = &pres_uri;
	dbpres.watcher_uri = &watcher_uri;
	dbpres.extra_headers = &extra_headers;

	if (dbmode == PUA_DB_ONLY && pua_dbf.start_transaction)
	{
		if (pua_dbf.start_transaction(pua_db, DB_LOCKING_WRITE) < 0)
		{
			LM_ERR("in start_transaction\n");
			goto error;
		}
	}

	if(ps->param== NULL|| *ps->param== NULL)
	{
		LM_ERR("NULL callback parameter\n");
		goto error;
	}
	hentity= (ua_pres_t*)(*ps->param);

	msg= ps->rpl;
	if(msg == NULL)
	{
		LM_ERR("no reply message found\n ");
		goto error;
	}
	

	if(msg== FAKED_REPLY)
	{
		LM_DBG("FAKED_REPLY\n");
		goto done;
	}

	hash_code= core_hash(hentity->pres_uri, NULL, HASH_SIZE);

	if( ps->code>= 300 )
	{
		find_and_delete_record(hentity, hash_code);

		if(ps->code== 412 && hentity->body && hentity->flag!= MI_PUBLISH
				&& hentity->flag!= MI_ASYN_PUBLISH)
		{
			/* sent a PUBLISH within a dialog that no longer exists
			 * send again an intial PUBLISH */
			LM_DBG("received a 412 reply- try again to send PUBLISH\n");
			publ_info_t publ;
			memset(&publ, 0, sizeof(publ_info_t));
			publ.pres_uri= hentity->pres_uri; 
			publ.body= hentity->body;
			
			if(hentity->desired_expires== 0)
				publ.expires= -1;
			else
			if(hentity->desired_expires<= (int)time(NULL))
				publ.expires= 0;
			else
				publ.expires= hentity->desired_expires- (int)time(NULL)+ 3;

			publ.source_flag|= hentity->flag;
			publ.event|= hentity->event;
			publ.content_type= hentity->content_type;	
			publ.id= hentity->id;
			publ.extra_headers= hentity->extra_headers;
			publ.cb_param= hentity->cb_param;

			if (dbmode == PUA_DB_ONLY && pua_dbf.end_transaction)
			{
				if (pua_dbf.end_transaction(pua_db) < 0)
				{
					LM_ERR("in end_transaction\n");
					goto error;
				}
			}

			end_transaction = 0;

			if(send_publish(&publ)< 0)
			{
				LM_ERR("when trying to send PUBLISH\n");
				goto error;
			}
		}
		goto done;
	} /* code >= 300 */
	
	if( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("parsing headers\n");
		goto error;
	}	
	if(msg->expires== NULL || msg->expires->body.len<= 0)
	{
			LM_ERR("No Expires header found\n");
			goto error;
	}	
	
	if (!msg->expires->parsed && (parse_expires(msg->expires) < 0))
	{
		LM_ERR("cannot parse Expires header\n");
		goto error;
	}
	lexpire = ((exp_body_t*)msg->expires->parsed)->val;
	LM_DBG("lexpire= %u\n", lexpire);
		
	hdr = msg->headers;
	while (hdr!= NULL)
	{
		if(cmp_hdrname_strzn(&hdr->name, "SIP-ETag",8)==0 )
		{
			found = 1;
			break;
		}
		hdr = hdr->next;
	}
	if(found== 0) /* must find SIP-Etag header field in 200 OK msg*/
	{	
		LM_ERR("no SIP-ETag header field found\n");
		goto error;
	}
	etag= hdr->body;
		
	LM_DBG("completed with status %d [contact:%.*s]\n",
			ps->code, hentity->pres_uri->len, hentity->pres_uri->s);

	if (lexpire == 0)
	{
		find_and_delete_record(hentity, hash_code);
		goto done;
	}

	if (pua_dbf.affected_rows != NULL || dbmode != PUA_DB_ONLY)
	{
		if (find_and_update_record(hentity, hash_code, lexpire, &etag) > 0)
			goto done;
	}
	else
	{
		if ((db_presentity = get_record_puadb(hentity->id, &hentity->etag, &dbpres, &res)) != NULL)
		{
			update_record_puadb(hentity, lexpire, &etag);
			goto done;
		}
	}

	size= sizeof(ua_pres_t)+ sizeof(str)+ 
		(hentity->pres_uri->len+ hentity->tuple_id.len + 
		 hentity->id.len)* sizeof(char);
	if(hentity->extra_headers)
		size+= sizeof(str)+ hentity->extra_headers->len* sizeof(char);

	presentity= (ua_pres_t*)shm_malloc(size);
	if(presentity== NULL)
	{
		LM_ERR("no more share memory\n");
		goto error;
	}	
	memset(presentity, 0, size);

	size= sizeof(ua_pres_t);
	presentity->pres_uri= (str*)((char*)presentity+ size);
	size+= sizeof(str);

	presentity->pres_uri->s= (char*)presentity+ size;
	memcpy(presentity->pres_uri->s, hentity->pres_uri->s, 
			hentity->pres_uri->len);
	presentity->pres_uri->len= hentity->pres_uri->len;
	size+= hentity->pres_uri->len;
	
	presentity->tuple_id.s= (char*)presentity+ size;
	memcpy(presentity->tuple_id.s, hentity->tuple_id.s,
			hentity->tuple_id.len);
	presentity->tuple_id.len= hentity->tuple_id.len;
	size+= presentity->tuple_id.len;

	presentity->id.s=(char*)presentity+ size;
	memcpy(presentity->id.s, hentity->id.s, 
			hentity->id.len);
	presentity->id.len= hentity->id.len; 
	size+= presentity->id.len;
		
	if(hentity->extra_headers)
	{
		presentity->extra_headers= (str*)((char*)presentity+ size);
		size+= sizeof(str);
		presentity->extra_headers->s= (char*)presentity+ size;
		memcpy(presentity->extra_headers->s, hentity->extra_headers->s, 
				hentity->extra_headers->len);
		presentity->extra_headers->len= hentity->extra_headers->len;
		size+= hentity->extra_headers->len;
	}

	presentity->desired_expires= hentity->desired_expires;
	presentity->expires= lexpire+ (int)time(NULL);
	presentity->flag|= hentity->flag;
	presentity->event|= hentity->event;

	presentity->etag.s= (char*)shm_malloc(etag.len* sizeof(char));
	if(presentity->etag.s== NULL)
	{
		LM_ERR("No more share memory\n");
		goto error;
	}
	memcpy(presentity->etag.s, etag.s, etag.len);
	presentity->etag.len= etag.len;

	if (dbmode==PUA_DB_ONLY)
	{
		insert_record_puadb(presentity);
	}
	else
 	{
		lock_get(&HashT->p_records[hash_code].lock);
		insert_htable(presentity, hash_code);
		lock_release(&HashT->p_records[hash_code].lock);
	}
	LM_DBG("***Inserted in hash table\n");

done:
	if(hentity->ua_flag == REQ_OTHER)
	{
		run_pua_callbacks(hentity, msg);
	}
	if(*ps->param)
	{
		shm_free(*ps->param);
		*ps->param= NULL;
	}
	if(dbmode==PUA_DB_ONLY && presentity)
	{
		shm_free(presentity->etag.s);
		shm_free(presentity);
	}

	if (res) free_results_puadb(res);

	if (dbmode == PUA_DB_ONLY && pua_dbf.end_transaction && end_transaction)
	{
		if (pua_dbf.end_transaction(pua_db) < 0)
		{
			LM_ERR("in end_transaction\n");
			goto error;
		}
	}

	return;

error:
	if(*ps->param)
	{
		shm_free(*ps->param);
		*ps->param= NULL;
	}
	if(presentity) shm_free(presentity);

	if (res) free_results_puadb(res);

	if (dbmode == PUA_DB_ONLY && pua_dbf.abort_transaction)
	{
		if (pua_dbf.abort_transaction(pua_db) < 0)
			LM_ERR("in abort_transaction\n");
	}

	return;
}	
Exemple #17
0
static void *curl_shm_malloc(size_t size)
{
    void *p = shm_malloc(size);
    return p;
}
ua_pres_t* publish_cbparam(publ_info_t* publ,str* body,str* tuple_id,
		int ua_flag)
{
	int size;
	ua_pres_t* cb_param= NULL;

	size= sizeof(ua_pres_t)+ sizeof(str)+ (publ->pres_uri->len+ 
		+ publ->content_type.len+ publ->id.len+ 1)*sizeof(char);
	if(body && body->s && body->len)
		size+= sizeof(str)+ body->len* sizeof(char);
	if(publ->etag)
		size+= publ->etag->len* sizeof(char);
	if(publ->extra_headers)
		size+= sizeof(str)+ publ->extra_headers->len* sizeof(char);
	if(tuple_id )
		size+= tuple_id->len* sizeof(char);

	cb_param= (ua_pres_t*)shm_malloc(size);
	if(cb_param== NULL)
	{
		LM_ERR("ERROR no more share memory while allocating cb_param"
				" - size= %d\n", size);
		return NULL;
	}
	memset(cb_param, 0, size);
	
	size =  sizeof(ua_pres_t);

	cb_param->pres_uri = (str*)((char*)cb_param + size);
	size+= sizeof(str);
	cb_param->pres_uri->s = (char*)cb_param + size;
	memcpy(cb_param->pres_uri->s, publ->pres_uri->s ,
			publ->pres_uri->len ) ;
	cb_param->pres_uri->len= publ->pres_uri->len;
	size+= publ->pres_uri->len;

	if(publ->id.s && publ->id.len)
	{	
		cb_param->id.s = ((char*)cb_param+ size);
		memcpy(cb_param->id.s, publ->id.s, publ->id.len);
		cb_param->id.len= publ->id.len;
		size+= publ->id.len;
	}

	if(body && body->s && body->len)
	{
		cb_param->body = (str*)((char*)cb_param  + size);
		size+= sizeof(str);
		
		cb_param->body->s = (char*)cb_param + size;
		memcpy(cb_param->body->s, body->s ,
			body->len ) ;
		cb_param->body->len= body->len;
		size+= body->len;
	}
	if(publ->etag)
	{
		cb_param->etag.s = (char*)cb_param + size;
		memcpy(cb_param->etag.s, publ->etag->s ,
			publ->etag->len ) ;
		cb_param->etag.len= publ->etag->len;
		size+= publ->etag->len;
	}
	if(publ->extra_headers)
	{
		cb_param->extra_headers = (str*)((char*)cb_param  + size);
		size+= sizeof(str);
		cb_param->extra_headers->s = (char*)cb_param + size;
		memcpy(cb_param->extra_headers->s, publ->extra_headers->s ,
			publ->extra_headers->len ) ;
		cb_param->extra_headers->len= publ->extra_headers->len;
		size+= publ->extra_headers->len;
	}	

	if(publ->content_type.s && publ->content_type.len)
	{
		cb_param->content_type.s= (char*)cb_param + size;
		memcpy(cb_param->content_type.s, publ->content_type.s, publ->content_type.len);
		cb_param->content_type.len= publ->content_type.len;
		size+=  publ->content_type.len;
	}	
	if(tuple_id)
	{	
		cb_param->tuple_id.s = (char*)cb_param+ size;
		memcpy(cb_param->tuple_id.s, tuple_id->s ,tuple_id->len);
		cb_param->tuple_id.len= tuple_id->len;
		size+= tuple_id->len;
	}
	cb_param->event= publ->event;
	cb_param->flag|= publ->source_flag;
	cb_param->cb_param= publ->cb_param;
	cb_param->ua_flag= ua_flag;

	if(publ->expires< 0)
		cb_param->desired_expires= 0;
	else
		cb_param->desired_expires=publ->expires+ (int)time(NULL);

	return cb_param;
}
Exemple #19
0
/**
 * Creates an AAAAcctSession.
 * @param peer - accounting server FQDN.
 * @param dlgid - application-level id of accountable event or session
 * @returns the new AAAAcctSession*
 */
AAAAcctSession* AAACreateAcctSession(str* peer, str* dlgid)
{
	AAAAcctSession* s = NULL;
	
	LOG(L_INFO, "INF: AAACreateAcctSession\n");
		
	s = new_acc_session(dlgid);
	if (!s) return 0;		
	 
	//s = get_acc_session(dlgid);
	//if(s) goto error;
	
	s->state = ACC_ST_IDLE;

	s->peer_fqdn = shm_malloc(sizeof(str));
	s->peer_fqdn->len = peer->len;
	s->peer_fqdn->s = peer->s;

	s->dlgid = shm_malloc(sizeof(str));
	s->dlgid->len = dlgid->len;
	s->dlgid->s = dlgid->s;
	LOG(L_INFO, "s->dlgid: %.*s\n", s->dlgid->len, s->dlgid->s);
	
	s->sID = shm_malloc(sizeof(str));
	s->sID->len = 0;
	s->sID->s = 0;
	
	s->timeout = time(0) + 60; // TODO: use parameter "session_timeout"
	s->aii=0;
	
	/* generates a new session-ID */
	//if (generate_sessionID( s->sID, 0 )!=1) goto error;
	if (generate_sessionID( s->sID, 0, dlgid )!=1) goto error; // TODO: check pad length...
	LOG(L_INFO, "s->sID: %.*s\n", s->sID->len, s->sID->s);
	
	LOG(L_INFO, "s->hash: %d\n", s->hash);
	
	s->prev = NULL;
	s->next = NULL;
	
	// TODO: include pointer to sm_process function in acc_session
	//		to allow accounting client SM and server SM?
	/*
	if () {
		s->sm_process = acc_cli_sm_process;
	} else {
		s->sm_process = acc_serv_sm_process;
	}*/
		
	add_acc_session(s);
	s_unlock(s->hash);
	
	return s;

error:
	if (s) 
		LOG(L_ERR, "ERR: AAACreateAccSession: AAAAcctSession exists\n");
	else 	
		LOG(L_ERR, "ERR: AAACreateAccSession: Error on new AAAAcctSession \
			generation\n");
	
	return NULL;
}
Exemple #20
0
NODE* mem_copy_call_noc(ESCT* s){
	int size;
	NODE* dest = NULL;
	NODE* dest_atr;

	int   size_esgwri;
    int   size_esgw;
    int   size_esqk;
    int   size_callid;
    int   size_ert_srid;
    int   size_datetimestamp;
    int   size_lro;
    int   size_disposition;
    int   size_result; 
    int   size_source_organizationname;
    int   size_source_hostname;    
    int   size_source_nenaid;
    int   size_source_contact;
    int   size_source_certuri;
    int   size_vpc_organizationname;
    int   size_vpc_hostname;    
    int   size_vpc_nenaid;
    int   size_vpc_contact;
    int   size_vpc_certuri;
    int   size_call_id;
    int   size_local_tag;
    int   size_rem_tag;
    char *p;

	size_esgwri = s->esgwri? strlen(s->esgwri)+1:1;
   	size_esgw = s->esgw?strlen(s->esgw)+1:1;  	
    size_esqk = s->esqk? strlen(s->esqk)+1:1;
    size_callid = s->callid? strlen(s->callid)+1:1;   
    size_ert_srid = s->ert_srid? strlen(s->ert_srid)+1:1;
    size_datetimestamp = s->datetimestamp? strlen(s->datetimestamp)+1:1;
    size_lro = s->lro? strlen(s->lro)+1:1;   
    size_disposition = s->disposition? strlen(s->disposition)+1:1;
    size_result = s->result? strlen(s->result)+1:1;    
    size_source_organizationname = s->source->organizationname? strlen(s->source->organizationname)+1:1;
    size_source_hostname = s->source->hostname? strlen(s->source->hostname)+1:1;    
    size_source_nenaid = s->source->nenaid? strlen(s->source->nenaid)+1:1;
    size_source_contact = s->source->contact? strlen(s->source->contact)+1:1;
    size_source_certuri = s->source->certuri? strlen(s->source->certuri)+1:1;    
    size_vpc_organizationname = s->vpc->organizationname? strlen(s->vpc->organizationname)+1:1;
    size_vpc_hostname = s->vpc->hostname? strlen(s->vpc->hostname)+1:1;    
    size_vpc_nenaid = s->vpc->nenaid? strlen(s->vpc->nenaid)+1:1;
    size_vpc_contact = s->vpc->contact? strlen(s->vpc->contact)+1:1;
    size_vpc_certuri = s->vpc->certuri? strlen(s->vpc->certuri)+1:1;
    size_call_id = s->eme_dlg_id->call_id? strlen(s->eme_dlg_id->call_id)+1:1;
    size_local_tag = s->eme_dlg_id->local_tag? strlen(s->eme_dlg_id->local_tag)+1:1;
    size_rem_tag = s->eme_dlg_id->rem_tag? strlen(s->eme_dlg_id->rem_tag)+1:1;    

	size= sizeof(NODE)+ sizeof(ESCT)+ (2 * sizeof(NENA)) + sizeof(struct dialog_set) + size_esgw + size_esqk+ size_callid + size_ert_srid 
	      + MAX_TIME_SIZE + size_lro + MAX_DISPOSITION_SIZE + size_result + size_call_id + size_local_tag + size_rem_tag + size_source_organizationname 
	      + size_source_hostname + size_source_nenaid + size_source_contact + size_source_certuri + size_vpc_organizationname + size_vpc_hostname 
	      + size_vpc_nenaid + size_vpc_contact + size_vpc_certuri; 

	p= (char*)shm_malloc(size);
	if(p== NULL){
		//ERR_MEM(SHARE_MEM);
		goto error;
	}
	memset(p, 0, size);

	dest = (NODE*)p;	
	p = p + sizeof(NODE);
	dest->esct = (ESCT*)p;		
	p = p + sizeof(ESCT);
	dest->esct->eme_dlg_id = (struct dialog_set*)p;	

	size= sizeof(struct dialog_set );	
	CONT_COPY(dest->esct->eme_dlg_id, dest->esct->eme_dlg_id->call_id, s->eme_dlg_id->call_id);
	CONT_COPY(dest->esct->eme_dlg_id, dest->esct->eme_dlg_id->local_tag, s->eme_dlg_id->local_tag);
	CONT_COPY(dest->esct->eme_dlg_id, dest->esct->eme_dlg_id->rem_tag, s->eme_dlg_id->rem_tag);

	p = p + size;
	dest->esct->source = (NENA*)p;
	size= sizeof(NENA);	
	CONT_COPY(dest->esct->source, dest->esct->source->organizationname, s->source->organizationname);
	CONT_COPY(dest->esct->source, dest->esct->source->hostname, s->source->hostname);
	CONT_COPY(dest->esct->source, dest->esct->source->nenaid, s->source->nenaid);
	CONT_COPY(dest->esct->source, dest->esct->source->contact, s->source->contact);
	CONT_COPY(dest->esct->source, dest->esct->source->certuri, s->source->certuri);

	p = p + size;
	dest->esct->vpc = (NENA*)p;
	size= sizeof(NENA);
	CONT_COPY(dest->esct->vpc, dest->esct->vpc->organizationname, s->vpc->organizationname);
	CONT_COPY(dest->esct->vpc, dest->esct->vpc->hostname, s->vpc->hostname);
	CONT_COPY(dest->esct->vpc, dest->esct->vpc->nenaid, s->vpc->nenaid);
	CONT_COPY(dest->esct->vpc, dest->esct->vpc->contact, s->vpc->contact);
	CONT_COPY(dest->esct->vpc, dest->esct->vpc->certuri, s->vpc->certuri);

	p = p + size;
	dest_atr = (NODE*)p;
	size = 0;
	CONT_COPY(dest_atr, dest->esct->esgw, s->esgw);
	CONT_COPY(dest_atr, dest->esct->esqk, s->esqk);
	CONT_COPY(dest_atr, dest->esct->callid, s->callid);
	CONT_COPY(dest_atr, dest->esct->ert_srid, s->ert_srid);

	if(s->datetimestamp){	
		dest->esct->datetimestamp= (char*)dest_atr+ size;
		memcpy(dest->esct->datetimestamp, s->datetimestamp, strlen(s->datetimestamp));
		size+=  MAX_TIME_SIZE;
	}

	CONT_COPY(dest_atr, dest->esct->lro, s->lro);

	if(s->disposition){	
		dest->esct->disposition= (char*)dest_atr+ size;
		memcpy(dest->esct->disposition, s->disposition, strlen(s->disposition));
		size+=  MAX_DISPOSITION_SIZE;
	}

	CONT_COPY(dest_atr, dest->esct->result, s->result);

	dest->esct->ert_resn= s->ert_resn;
	dest->esct->ert_npa= s->ert_npa;
	dest->esct->timeout= s->timeout;

	dest->esct->esgwri= (char*)shm_malloc(size_esgwri);
	if(dest->esct->esgwri== NULL){
		//ERR_MEM(SHARE_MEM);
		goto error;
	}
	memset(dest->esct->esgwri, 0, size_esgwri);
	memcpy(dest->esct->esgwri, s->esgwri, size_esgwri - 1);

	return dest;

error:
	if(dest)
			shm_free(dest);
	return NULL;
}
Exemple #21
0
int imc_handle_invite(struct sip_msg* msg, imc_cmd_t *cmd,
		struct sip_uri *src, struct sip_uri *dst)
{
	imc_room_p room = 0;
	imc_member_p member = 0;
	int flag_member = 0;
	int size = 0;
	int i = 0;
	int add_domain = 0;
	int add_sip = 0;
	str uri = {0, 0};
	str body;
	str room_name;
	struct sip_uri inv_uri;
	del_member_t *cback_param = NULL;
	int result;


	size = cmd->param[0].len+2 ;
	add_domain = 1;
	add_sip = 0;
	while (i<size )
	{
		if(cmd->param[0].s[i]== '@')
		{
			add_domain = 0;
			break;
		}
		i++;
	}

	if(add_domain)
		size += dst->host.len;

	if(cmd->param[0].len<4 || strncasecmp(cmd->param[0].s, "sip:", 4)!=0)
	{
		size += 4;
		add_sip = 1;
	}

	uri.s = (char*)pkg_malloc(size *sizeof(char));
	if(uri.s == NULL)
	{
		LM_ERR("no more pkg memory\n");
		goto error;
	}
	size= 0;
	if(add_sip)
	{
		strcpy(uri.s, "sip:");
		size=4;
	}

	memcpy(uri.s+size, cmd->param[0].s, cmd->param[0].len);
	size += cmd->param[0].len;

	if(add_domain)
	{
		uri.s[size] = '@';
		size++;
		memcpy(uri.s+ size, dst->host.s, dst->host.len);
		size+= dst->host.len;
	}
	uri.len = size;

	if(parse_uri(uri.s, uri.len, &inv_uri)!=0)
	{
		LM_ERR("bad uri [%.*s]!\n", uri.len, uri.s);
		goto error;
	}

	room_name = (cmd->param[1].s)?cmd->param[1]:dst->user;
	room = imc_get_room(&room_name, &dst->host);
	if(room== NULL || (room->flags&IMC_ROOM_DELETED))
	{
		LM_ERR("the room does not exist [%.*s]!\n",
				room_name.len, room_name.s);
		goto error;
	}
	member= imc_get_member(room, &src->user, &src->host);

	if(member==NULL)
	{
		LM_ERR("user [%.*s] is not member of[%.*s]!\n",
			src->user.len, src->user.s, room_name.len, room_name.s);
		goto error;
	}
	if(!(member->flags & IMC_MEMBER_OWNER) &&
			!(member->flags & IMC_MEMBER_ADMIN))
	{
		LM_ERR("user [%.*s] has no right to invite"
				" other users!\n", src->user.len, src->user.s);
		goto error;
	}

	member= imc_get_member(room, &inv_uri.user, &inv_uri.host);
	if(member!=NULL)
	{
		LM_ERR("user [%.*s] is already member"
				" of the room!\n", inv_uri.user.len, inv_uri.user.s);
		goto error;
	}

	flag_member |= IMC_MEMBER_INVITED;
	member=imc_add_member(room, &inv_uri.user, &inv_uri.host, flag_member);
	if(member == NULL)
	{
		LM_ERR("adding member [%.*s]\n",
				inv_uri.user.len, inv_uri.user.s);
		goto error;
	}

	body.len = 13 + member->uri.len - 4/* sip: */ + 28;
	if(body.len>=IMC_BUF_SIZE || member->uri.len>=IMC_BUF_SIZE
			|| room->uri.len>=IMC_BUF_SIZE)
	{
		LM_ERR("buffer size overflow\n");
		goto error;
	}

	body.s = imc_body_buf;
	memcpy(body.s, "INVITE from: ", 13);
	memcpy(body.s+13, member->uri.s + 4, member->uri.len - 4);
	memcpy(body.s+ 9 + member->uri.len, "(Type: '#accept' or '#deny')", 28);
	body.s[body.len] = '\0';

	LM_DBG("to=[%.*s]\nfrom=[%.*s]\nbody=[%.*s]\n",
			member->uri.len,member->uri.s,room->uri.len, room->uri.s,
			body.len, body.s);

	cback_param = (del_member_t*)shm_malloc(sizeof(del_member_t));
	if(cback_param==NULL)
	{
		LM_ERR("no more shm\n");
		goto error;
	}
	memset(cback_param, 0, sizeof(del_member_t));
	cback_param->room_name = room->name;
	cback_param->room_domain = room->domain;
	cback_param->member_name = member->user;
	cback_param->member_domain = member->domain;
	cback_param->inv_uri = member->uri;
	/*?!?! possible race with 'remove user' */
	result= tmb.t_request(&imc_msg_type,				/* Request Method */
				&member->uri,							/* Request-URI */
				&member->uri,							/* To */
				&room->uri,								/* From */
				&imc_hdr_ctype,							/* Extra headers */
				&body,						            /* Message body */
				(outbound_proxy.s)?&outbound_proxy:NULL,/* outbound proxy*/
				imc_inv_callback,						/* callback function*/
				(void*)(cback_param),					/* callback param*/
				NULL
			);
	if(result< 0)
	{
		LM_ERR("in tm send request\n");
		shm_free(cback_param);
		goto error;
	}
	if(uri.s!=NULL)
		pkg_free(uri.s);

	imc_release_room(room);

	return 0;

error:
	if(uri.s!=0)
		pkg_free(uri.s);

	if(room!=NULL)
		imc_release_room(room);

	return -1;
}
Exemple #22
0
void * wrap_shm_malloc(size_t size)
{
	return shm_malloc(size);
}
Exemple #23
0
/*Actions are composed as follows:
 * (the action length and type as always= 5 bytes)
 * 4:uac_id
 *
 * int request(str* method, str* req_uri, str* to, str* from, str* headers, str* body, transaction_cb c, void* cp)
 * TODO performance speedup: instead of using
 * dynamically allocated memory for headers,body,totag,reason and my_msg
 * use static buffers.
 *
 */
int ac_uac_req(as_p the_as,char *action,int len)
{
   unsigned int flags,cseq;
   char err_buf[MAX_REASON_LEN],processor_id;
   struct sip_msg *my_msg;
   struct to_body *fb,*tb;
   struct cseq_body *cseqb;
   struct as_uac_param *the_param;
   dlg_t *my_dlg;
   int k,retval,uac_id,sip_error,ret,err_ret;
   str headers,body,fake_uri;
   char *p;

   headers.s=body.s=fake_uri.s=NULL;
   my_dlg=NULL;
   my_msg=NULL;
   the_param=NULL;
   k=0;

   net2hostL(flags,action,k);
   net2hostL(uac_id,action,k);

   processor_id=action[k++];

   if(!(headers.s=pkg_malloc(MAX_HEADER))){
      LM_ERR("Out of Memory!!");
      goto error;
   }
   headers.len=0;
   LM_DBG("Action UAC Message: uac_id:%d processor_id=%d\n",uac_id,processor_id);
   if (!(my_msg = parse_ac_msg(HDR_EOH_F,action+k,len-k))) {
      LM_ERR("out of memory!\n");
      goto error;
   }
   if(my_msg->first_line.type==SIP_REPLY){
      LM_ERR("trying to create a UAC with a SIP response!!\n");
      goto error;
   }
   if(parse_headers(my_msg,HDR_EOH_F,0)==-1){
      LM_ERR("ERROR:seas:ac_uac_req:parsing headers\n");
      goto error;
   }
   if(parse_from_header(my_msg)<0){
      LM_ERR("parsing from header ! \n");
      goto error;
   }
   if(check_transaction_quadruple(my_msg)==0){
      as_action_fail_resp(uac_id,SE_UAC,"Headers missing (to,from,call-id,cseq)?",0);
      LM_ERR("Headers missing (to,from,call-id,cseq)?");
      goto error;
   }
   if(!(get_from(my_msg)) || !(get_from(my_msg)->tag_value.s) || 
	 !(get_from(my_msg)->tag_value.len)){
      as_action_fail_resp(uac_id,SE_UAC,"From tag missing",0);
      LM_ERR("From tag missing");
      goto error;
   }
   fb=my_msg->from->parsed;
   tb=my_msg->to->parsed;
   cseqb=my_msg->cseq->parsed;
   if(0!=(str2int(&cseqb->number,&cseq))){
      LM_DBG("unable to parse CSeq\n");
      goto error;
   }
   if(my_msg->first_line.u.request.method_value != METHOD_ACK &&
	 my_msg->first_line.u.request.method_value != METHOD_CANCEL) {
      /** we trick req_within */
      cseq--;
   }
   if(seas_f.tmb.new_dlg_uac(&(my_msg->callid->body),&(fb->tag_value),cseq,\
	    &(fb->uri),&(tb->uri),&my_dlg) < 0) {
      as_action_fail_resp(uac_id,SE_UAC,"Error creating new dialog",0);
      LM_ERR("Error while creating new dialog\n");
      goto error;
   }
   if(seas_f.tmb.dlg_add_extra(my_dlg,&(fb->display),&(tb->display)) < 0 ) {
      as_action_fail_resp(uac_id,SE_UAC,
         "Error adding the display names to the new dialog",0);
      LM_ERR("failed to add display names to the new dialog\n");
      goto error;
   }

   if(tb->tag_value.s && tb->tag_value.len)
      shm_str_dup(&my_dlg->id.rem_tag,&tb->tag_value);
   /**Awful hack: to be able to set our own CSeq, from_tag and call-ID we have
    * to use req_within instead of req_outside (it sets it's own CSeq,Call-ID
    * and ftag), so we have to simulate that the dialog is already in completed
    * state so...
    */
   server_signature=0;
   my_dlg->state = DLG_CONFIRMED;
   if(0>(headers.len=extract_allowed_headers(my_msg,1,-1,HDR_CONTENTLENGTH_F|HDR_ROUTE_F|HDR_TO_F|HDR_FROM_F|HDR_CALLID_F|HDR_CSEQ_F,headers.s,MAX_HEADER))) {
      LM_ERR("Unable to extract allowed headers!!\n");
      goto error;
   }
   headers.s[headers.len]=0;
   /*let's get the body*/
   if (get_body(my_msg,&body)!=0) {
      LM_ERR("failed to get body\n");
      goto error;
   }
   if(body.len!=0){
      if(!(p=pkg_malloc(body.len+1))){
          LM_ERR("Out of Memory!");
          goto error;
      }
      memcpy(p,body.s,body.len);
      body.s=p;
      body.s[body.len]=0;
      LM_DBG("Trying to construct a Sip Request with: body:%d[%.*s] headers:%d[%.*s]\n",\
	    body.len,body.len,body.s,headers.len,headers.len,headers.s);
      /*t_reply_with_body un-ref-counts the transaction, so dont use it anymore*/
   }
   /*Now... create the UAC !!
    * it would be great to know the hash_index and the label that have been assigned
    * to our newly created cell, but t_uac does not leave any way for us to know...
    * only that when that transaction transitions its state (ie. a response is received,
    * a timeout is reached, etc...) the callback will be called with the given parameter.
    *
    * So the only way we have to know who we are, is passing as a parameter a structure with
    * 2 pointers: one to the app_server and the other, the identifier of the UAC (uac_id).
    *
    */
   if(!(the_param=shm_malloc(sizeof(struct as_uac_param)))){
      LM_ERR("out of shared memory\n");
      goto error;
   }
   the_param->who=my_as;
   the_param->uac_id=uac_id;
   the_param->processor_id=processor_id;
   the_param->destroy_cb_set=0;

   shm_str_dup(&my_dlg->rem_target,&my_msg->first_line.u.request.uri);

   if (my_msg->route) {
      if (parse_rr(my_msg->route) < 0) {
	 LM_ERR( "Error while parsing Route body\n");
	 goto error;
      }
      /* TODO route_set should be a shm copy of my_msg->route->parsed */
      my_dlg->route_set=(rr_t*)my_msg->route->parsed;
      /** this SHOULD be:
       shm_duplicate_rr(&my_dlg->route_set,my_msg->route->parsed);
       * but it will last more...
       */
   }
   calculate_hooks(my_dlg);
   if(flags & SPIRAL_FLAG){
      memcpy(headers.s+headers.len,SPIRAL_HDR CRLF,SPIRAL_HDR_LEN + CRLF_LEN);
      headers.len+=SPIRAL_HDR_LEN+CRLF_LEN;
      headers.s[headers.len]=0;
      fake_uri.s=pkg_malloc(200);
      fake_uri.len=print_local_uri(the_as,processor_id,fake_uri.s,200);

      if(fake_uri.len<0){
	 LM_ERR("printing local uri\n");
	 goto error;
      }
      my_dlg->hooks.next_hop=&fake_uri;
   }
   my_dlg->T_flags=T_NO_AUTOACK_FLAG|T_PASS_PROVISIONAL_FLAG ;
   ret=seas_f.tmb.t_request_within(&(my_msg->first_line.u.request.method),&headers,&body,my_dlg,uac_cb,(void *)the_param,NULL);
   /** now undo all the fakes we have put in my_dlg*/
   /*because my_dlg->route_set should be shm but we fake it (its pkg_mem)*/
   my_dlg->route_set=(rr_t *)0;
   if (ret <= 0) {
      err_ret = err2reason_phrase(ret,&sip_error,err_buf, sizeof(err_buf), "SEAS/UAC");
      LM_ERR("Error on request_within %s\n",err_buf );
      if(err_ret > 0) {
	 as_action_fail_resp(uac_id,ret,err_buf,0);
      }else{
	 as_action_fail_resp(uac_id,E_UNSPEC,"500 SEAS/UAC error",0);
      }
      goto error;
   }
   retval=0;
   goto exit;
error:
   retval = -1;
   if(the_param)
      shm_free(the_param);
exit:
   seas_f.tmb.free_dlg(my_dlg);
   if(headers.s)
      pkg_free(headers.s);
   if(body.s)
      pkg_free(body.s);
   if(fake_uri.s)
      pkg_free(fake_uri.s);
   if(my_msg){
      if(my_msg->headers)
	 free_hdr_field_lst(my_msg->headers);
      pkg_free(my_msg);
   }
   return retval;
}
Exemple #24
0
static int mod_init(void)
{

	str def_str = str_init(DEFAULT_PARTITION);
	dp_head_p el = dp_get_head(def_str);

	LM_INFO("initializing module...\n");

	init_db_url( default_dp_db_url , 0 /*can be null*/);

	dpid_column.len     	= strlen(dpid_column.s);
	pr_column.len       	= strlen(pr_column.s);
	match_op_column.len 	= strlen(match_op_column.s);
	match_exp_column.len	= strlen(match_exp_column.s);
	match_flags_column.len	= strlen(match_flags_column.s);
	subst_exp_column.len	= strlen(subst_exp_column.s);
	repl_exp_column.len 	= strlen(repl_exp_column.s);
	attrs_column.len    	= strlen(attrs_column.s);
	timerec_column.len      = strlen(timerec_column.s);
	disabled_column.len 	= strlen(disabled_column.s);

	if (default_dp_db_url.s) {
		default_dp_db_url.len = strlen(default_dp_db_url.s);

		if (!el) {
			default_dp_partition.len = sizeof(DEFAULT_PARTITION) - 1;
			default_dp_partition.s = pkg_malloc(default_dp_partition.len);

			if (!default_dp_partition.s) {
				LM_ERR("No more pkg memory\n");
				return -1;
			}
			memcpy(default_dp_partition.s, DEFAULT_PARTITION,
							 default_dp_partition.len);
		} else {
			default_dp_partition.s = el->partition.s;
			default_dp_partition.len = el->partition.len;
		}

		dp_head_insert( DP_TYPE_URL, default_dp_db_url,
							 default_dp_partition);
	}

	if (default_dp_table.s) {
		if (!default_dp_partition.s) {
			if (!el) {
				LM_ERR("DB URL not defined for partition default!\n");
				return -1;
			} else {
				default_dp_partition.s = el->partition.s;
				default_dp_partition.len = el->partition.len;
			}
		}

		default_dp_table.len = strlen(default_dp_table.s);
		dp_head_insert( DP_TYPE_TABLE, default_dp_table,
							 default_dp_partition);
	}

	el = dp_hlist;

	for (el = dp_hlist; el ; el = el->next) {
		//db_url must be set
		if (!el->dp_db_url.s) {
			LM_ERR("DB URL is not defined for partition %.*s!\n",
						el->partition.len,el->partition.s);
			return -1;
		}

		if (!el->dp_table_name.s) {
			el->dp_table_name.len = sizeof(DP_TABLE_NAME) - 1;
			el->dp_table_name.s = pkg_malloc(el->dp_table_name.len);
			if(!el->dp_table_name.s){
				LM_ERR("No more pkg mem\n");
				return -1;
			}
			memcpy(el->dp_table_name.s, DP_TABLE_NAME,
							 el->dp_table_name.len);
		}
	}

	default_par2 = (dp_param_p)shm_malloc(sizeof(dp_param_t));
	if(default_par2 == NULL){
		LM_ERR("no shm more memory\n");
		return -1;
	}
	memset(default_par2, 0, sizeof(dp_param_t));

	default_param_s.len = strlen(default_param_s.s);
	if (pv_parse_spec( &default_param_s, &default_par2->v.sp[0])==NULL) {
		LM_ERR("input pv is invalid\n");
		return -1;
	}

	default_param_s.len = strlen(default_param_s.s);
	if (pv_parse_spec( &default_param_s, &default_par2->v.sp[1])==NULL) {
		LM_ERR("output pv is invalid\n");
		return -1;
	}

	dp_print_list();
	if(init_data() != 0) {
		LM_ERR("could not initialize data\n");
		return -1;
	}

	return 0;
#undef init_db_url_part
}
Exemple #25
0
/*
 * get all IMPUs as string from a subscription related to an impurecord. apply filter for barring (assumed to be called with lock on impurec)
 * you should have some for of lock on the subscription (ie a reference)
 * barring-1 get all barred
 * barring-0 get all unbarred
 * barring-(-1) get all records
 * NB. Remember to free the block of memory pointed to by impus (pkg_malloc)
 */
int get_impus_from_subscription_as_string(udomain_t* _d, impurecord_t* impu_rec, int barring, str** impus, int* num_impus, int is_shm) {
    int i, j, count;
    *num_impus = 0;
    *impus = 0;
    ims_public_identity* impi;
    int bytes_needed = 0;
    int len = 0;

    LM_DBG("getting IMPU subscription set\n");

    if (!impu_rec) {
        LM_ERR("no impu record provided\n");
        return 1;
    }

    if (!impu_rec->s) {
        LM_DBG("no subscription associated with impu\n");
        return 0;
    }

    lock_subscription(impu_rec->s);
    for (i = 0; i < impu_rec->s->service_profiles_cnt; i++) {
        for (j = 0; j < impu_rec->s->service_profiles[i].public_identities_cnt; j++) {
            impi = &(impu_rec->s->service_profiles[i].public_identities[j]);
            LM_DBG("Got Record %.*s (%i)\n", impi->public_identity.len,
              impi->public_identity.s, impi->public_identity.len);

            if (barring < 0) {
                //get all records
                bytes_needed += impi->public_identity.len;
                (*num_impus)++;
            } else {
                if (impi->barring == barring) {
                    //add the record to the list
                    bytes_needed += impi->public_identity.len;
                    (*num_impus)++;
                }
            }
        }
    }
    LM_DBG("num of records returned is %d and we need %d bytes\n", *num_impus, bytes_needed);

    len = (sizeof (str)*(*num_impus)) + bytes_needed;
    if (is_shm)
        *impus = (str*) shm_malloc(len); 
    else 
        *impus = (str*) pkg_malloc(len); //TODO: rather put this on the stack... dont' fragment pkg....
    
    if (*impus == 0) {
        if (is_shm)
            LM_ERR("no more shm_mem\n");
        else 
            LM_ERR("no more pkg_mem\n");
        return 1;
    }
    char* ptr = (char*) (*impus + *num_impus);

    //now populate the data
    count = 0;
    for (i = 0; i < impu_rec->s->service_profiles_cnt; i++) {
        for (j = 0; j < impu_rec->s->service_profiles[i].public_identities_cnt; j++) {
            impi = &(impu_rec->s->service_profiles[i].public_identities[j]);
            if (barring < 0) {
                //get all records
                (*impus)[count].s = ptr;
                memcpy(ptr, impi->public_identity.s, impi->public_identity.len);
                (*impus)[count].len = impi->public_identity.len;
                ptr += impi->public_identity.len;
                count++;
            } else {
                if (impi->barring == barring) {
                    //add the record to the list
                    (*impus)[count].s = ptr;
                    memcpy(ptr, impi->public_identity.s, impi->public_identity.len);
                    (*impus)[count].len = impi->public_identity.len;
                    ptr += impi->public_identity.len;
                    count++;
                }
            }
        }
    }

    if (ptr != ((char*) *impus + len)) {
        LM_CRIT("buffer overflow\n");
        return 1;
    }

    unlock_subscription(impu_rec->s);

    return 0;
}
int jsonrpc_request(struct sip_msg* _m, char* _method, char* _params, char* _cb_route, char* _err_route, char* _cb_pv)
{
  str method;
  str params;
  str cb_route;
  str err_route;
	

	if (fixup_get_svalue(_m, (gparam_p)_method, &method) != 0) {
		LM_ERR("cannot get method value\n");
		return -1;
	}
	if (fixup_get_svalue(_m, (gparam_p)_params, &params) != 0) {
		LM_ERR("cannot get params value\n");
		return -1;
	}
	if (fixup_get_svalue(_m, (gparam_p)_cb_route, &cb_route) != 0) {
		LM_ERR("cannot get cb_route value\n");
		return -1;
	}

	if (fixup_get_svalue(_m, (gparam_p)_err_route, &err_route) != 0) {
		LM_ERR("cannot get err_route value\n");
		return -1;
	}

	tm_cell_t *t = 0;
	t = tmb.t_gett();
	if (t==NULL || t==T_UNDEFINED)
	{
		if(tmb.t_newtran(_m)<0)
		{
			LM_ERR("cannot create the transaction\n");
			return -1;
		}
		t = tmb.t_gett();
		if (t==NULL || t==T_UNDEFINED)
		{
			LM_ERR("cannot look up the transaction\n");
			return -1;
		}
	}

	unsigned int hash_index;
	unsigned int label;

	if (tmb.t_suspend(_m, &hash_index, &label) < 0) {
		LM_ERR("t_suspend() failed\n");
		return -1;
	}

	struct jsonrpc_pipe_cmd *cmd;
	if (!(cmd = (struct jsonrpc_pipe_cmd *) shm_malloc(sizeof(struct jsonrpc_pipe_cmd))))
		return memory_error();

	memset(cmd, 0, sizeof(struct jsonrpc_pipe_cmd));

	pv_spec_t *cb_pv = (pv_spec_t*)shm_malloc(sizeof(pv_spec_t));
	if (!cb_pv)
		return memory_error();

	cb_pv = memcpy(cb_pv, (pv_spec_t *)_cb_pv, sizeof(pv_spec_t));

	cmd->method = shm_strdup(&method);
	cmd->params = shm_strdup(&params);
	cmd->cb_route = shm_strdup(&cb_route);
	cmd->err_route = shm_strdup(&err_route);
	cmd->cb_pv = cb_pv;
	cmd->msg = _m;
	cmd->t_hash = hash_index;
	cmd->t_label = label;
	
	if (write(cmd_pipe, &cmd, sizeof(cmd)) != sizeof(cmd)) {
		LM_ERR("failed to write to io pipe: %s\n", strerror(errno));
		return -1;
	}

	return 0;
}
Exemple #27
0
int
add_dst(
	rt_data_t *r,
	/* id */
	int id,
	/* ip address */ 
	char* ip,
	/* strip len */
	int strip,
	/* pri prefix */
	char* pri,
	/* dst type*/
	int type,
	/* dst attrs*/
	char* attrs
	)
{
	pgw_t *pgw=NULL, *tmp=NULL;
	pgw_addr_t *tmpa=NULL;
	struct hostent* he;
	struct sip_uri uri;
	struct ip_addr ipa;
	int l_ip,l_pri,l_attrs;
#define GWABUF_MAX_SIZE	512
	char gwabuf[GWABUF_MAX_SIZE];
	str gwas;

	if (NULL==r || NULL==ip) {
		LM_ERR("invalid parametres\n");
		goto err_exit;
	}

	l_ip = strlen(ip);
	l_pri = pri?strlen(pri):0;
	l_attrs = attrs?strlen(attrs):0;

	pgw = (pgw_t*)shm_malloc(sizeof(pgw_t) + l_ip + l_pri + l_attrs);
	if (NULL==pgw) {
		LM_ERR("no more shm mem (%u)\n",
			(unsigned int)(sizeof(pgw_t)+l_ip+l_pri +l_attrs));
		goto err_exit;
	}
	memset(pgw,0,sizeof(pgw_t));

	pgw->ip.len= l_ip;
	pgw->ip.s = (char*)(pgw+1);
	memcpy(pgw->ip.s, ip, l_ip);

	if (pri) {
		pgw->pri.len = l_pri;
		pgw->pri.s = ((char*)(pgw+1))+l_ip;
		memcpy(pgw->pri.s, pri, l_pri);
	}
	if (attrs) {
		pgw->attrs.len = l_attrs;
		pgw->attrs.s = ((char*)(pgw+1))+l_ip+l_pri;
		memcpy(pgw->attrs.s, attrs, l_attrs);
	}
	pgw->id = id;
	pgw->strip = strip;
	pgw->type = type;

	/* add address in the list */
	if(pgw->ip.len<5 || (strncasecmp("sip:", ip, 4)
			&&strncasecmp("sips:", ip, 5)))
	{
		if(pgw->ip.len+4>=GWABUF_MAX_SIZE) {
			LM_ERR("GW address (%d) longer "
				"than %d\n",pgw->ip.len+4,GWABUF_MAX_SIZE);
			goto err_exit;
		}
		memcpy(gwabuf, "sip:", 4);
		memcpy(gwabuf+4, ip, pgw->ip.len);
		gwas.s = gwabuf;
		gwas.len = 4+pgw->ip.len;
	} else {
		gwas.s = ip;
		gwas.len = pgw->ip.len;
	}

	memset(&uri, 0, sizeof(struct sip_uri));
	if(parse_uri(gwas.s, gwas.len, &uri)!=0) {
		LM_ERR("invalid uri <%.*s>\n",
			gwas.len, gwas.s);
		goto err_exit;
	}
	/* note we discard the port discovered by the resolve function - we are
	interested only in the port that was actually configured. */
	if ((he=sip_resolvehost( &uri.host, NULL, (char*)(void*)&uri.proto))==0 ) {
		if(dr_force_dns)
		{
			LM_ERR("cannot resolve <%.*s>\n",
				uri.host.len, uri.host.s);
			goto err_exit;
		} else {
			LM_DBG("cannot resolve <%.*s> - won't be used"
					" by is_from_gw()\n", uri.host.len, uri.host.s);
			goto done;
		}
	}
	hostent2ip_addr(&ipa, he, 0);
	tmpa = r->pgw_addr_l;
	while(tmpa) {
		if(tmpa->type==type && uri.port_no==tmpa->port
		&& ip_addr_cmp(&ipa, &tmpa->ip)) {
			LM_DBG("gw ip addr [%s]:%d loaded\n",
				ip_addr2a(&ipa), uri.port_no);
			goto done;
		}
		tmpa = tmpa->next;
	}
	
	LM_DBG("new gw ip addr [%s]\n", ip);
	tmpa = (pgw_addr_t*)shm_malloc(sizeof(pgw_addr_t));
	if(tmpa==NULL) {
		LM_ERR("no more shm mem (%u)\n",
			(unsigned int)sizeof(pgw_addr_t));
		goto err_exit;
	}
	memset(tmpa, 0, sizeof(pgw_addr_t));
	memcpy(&tmpa->ip, &ipa, sizeof(struct ip_addr));
	tmpa->port = uri.port_no;
	tmpa->type = type;
	tmpa->strip = strip;
	tmpa->next = r->pgw_addr_l;
	r->pgw_addr_l = tmpa;

done:
	if(NULL==r->pgw_l)
		r->pgw_l = pgw;
	else {
		tmp = r->pgw_l;
		while(NULL != tmp->next)
			tmp = tmp->next;
		tmp->next = pgw;
	}
	return 0;

err_exit:
	if(NULL!=pgw)
		shm_free(pgw);
	return -1;
}
Exemple #28
0
int global_init(void)
{
	int   i, net_pipe[2], foo;
	char  *p;
	struct socket_info* si;

	/* load the TM API */
	if (load_tm_api(&tmb)!=0) {
		LM_ERR("failed to load TM API\n");
		goto error;
	}

	/*fix domain length*/
	if (domain_str) {
		domain.s = domain_str;
		domain.len = strlen(domain_str);
	} else {
		si=get_first_socket();
		if (si==0){
			LM_CRIT("null listen socket list\n");
			goto error;
		}
		/*do I have to add port?*/
		i = (si->port_no_str.len && si->port_no!=5060);
		domain.len = si->name.len + i*(si->port_no_str.len+1);
		domain.s = (char*)pkg_malloc(domain.len);
		if (!domain.s) {
			LM_ERR("no more pkg memory!\n");
			goto error;
		}
		p = domain.s;
		memcpy(p,si->name.s,si->name.len);
		p += si->name.len;
		if (i) {
			*p=':'; p++;
			memcpy(p,si->port_no_str.s, si->port_no_str.len);
			p += si->port_no_str.len;
		}
	}

	/* creates pipes for networks */
	for(i=0;i<nr_of_networks;i++)
	{
		/* create the pipe*/
		if (pipe(net_pipe)==-1) {
			LM_ERR("failed create pipe!\n");
			goto error;
		}
		networks[i].pipe_out = net_pipe[0];
		net_pipes_in[i] = net_pipe[1];
		/* sets reading from pipe to non blocking */
		if ((foo=fcntl(net_pipe[0],F_GETFL,0))<0) {
			LM_ERR("failed to get flag for pipe - fcntl\n");
			goto error;
		}
		foo |= O_NONBLOCK;
		if (fcntl(net_pipe[0],F_SETFL,foo)<0) {
			LM_ERR("failed to set flag for pipe"
				" - fcntl\n");
			goto error;
		}
	}

	/* if report will be used, init the report queue */
	if (sms_report_type!=NO_REPORT && !init_report_queue()) {
		LM_ERR("no more share memory!\n");
		goto error;
	}

	/* alloc in shm for queued_msgs */
	queued_msgs = (int*)shm_malloc(sizeof(int));
	if (!queued_msgs) {
		LM_ERR("no more share memory!\n");
		goto error;
	}
	*queued_msgs = 0;

	return 1;
error:
	return -1;
}
Exemple #29
0
reg_subscriber* new_subscriber(str* presentity_uri, str* watcher_uri, str* watcher_contact, subscriber_data_t* subscriber_data) {
    subs_t subs;
    reg_subscriber *s;

    int len;
    char *p;
    unsigned int hash_code = 0;
    
    memset(&subs, 0, sizeof(subs_t));
    
    len = sizeof (reg_subscriber) + subscriber_data->callid->len
            + subscriber_data->ftag->len + subscriber_data->ttag->len
            + watcher_contact->len + watcher_uri->len + presentity_uri->len
            + subscriber_data->record_route->len + subscriber_data->sockinfo_str->len;

    LM_DBG("Creating new subscription to reg");

    s = (reg_subscriber*) shm_malloc(len);
    if (s == 0) {
        LM_ERR("no more shm mem (%d)\n", len);
        return 0;
    }
    memset(s, 0, len);

    s->local_cseq = subscriber_data->local_cseq;

    s->event = subscriber_data->event;

    s->expires = subscriber_data->expires;

    p = (char*) (s + 1);

    s->call_id.s = p;
    s->call_id.len = subscriber_data->callid->len;
    memcpy(p, subscriber_data->callid->s, subscriber_data->callid->len);
    p += subscriber_data->callid->len;

    s->to_tag.s = p;
    s->to_tag.len = subscriber_data->ttag->len;
    memcpy(p, subscriber_data->ttag->s, subscriber_data->ttag->len);
    p += subscriber_data->ttag->len;

    s->from_tag.s = p;
    s->from_tag.len = subscriber_data->ftag->len;
    memcpy(p, subscriber_data->ftag->s, subscriber_data->ftag->len);
    p += subscriber_data->ftag->len;

    s->watcher_uri.s = p;
    s->watcher_uri.len = watcher_uri->len;
    memcpy(p, watcher_uri->s, watcher_uri->len);
    p += watcher_uri->len;

    s->watcher_contact.s = p;
    s->watcher_contact.len = watcher_contact->len;
    memcpy(p, watcher_contact->s, watcher_contact->len);
    p += watcher_contact->len;

    s->record_route.s = p;
    s->record_route.len = subscriber_data->record_route->len;
    memcpy(p, subscriber_data->record_route->s, subscriber_data->record_route->len);
    p += subscriber_data->record_route->len;

    s->sockinfo_str.s = p;
    s->sockinfo_str.len = subscriber_data->sockinfo_str->len;
    memcpy(p, subscriber_data->sockinfo_str->s, subscriber_data->sockinfo_str->len);
    p += subscriber_data->sockinfo_str->len;

    s->presentity_uri.s = p;
    s->presentity_uri.len = presentity_uri->len;
    memcpy(p, presentity_uri->s, presentity_uri->len);
    p += presentity_uri->len;

    if (p != (((char*) s) + len)) {
        LM_CRIT("buffer overflow\n");
        free_subscriber(s);
        return 0;
    }
    
    /*This lets us get presentity URI info for subsequent SUBSCRIBEs that don't have presentity URI as req URI*/
    
    subs.pres_uri = s->presentity_uri;
    subs.from_tag = s->from_tag;
    subs.to_tag = s->to_tag;
    subs.callid = s->call_id;
    
    hash_code = core_hash(&subs.callid, &subs.to_tag, sub_dialog_hash_size);
    
    LM_DBG("Adding sub dialog hash info with call_id: <%.*s> and ttag <%.*s> amd ftag <%.*s> and hash code <%d>", subs.callid.len, subs.callid.s, subs.to_tag.len, subs.to_tag.s, subs.from_tag.len,  subs.from_tag.s, hash_code);
    
    if (pres_insert_shtable(sub_dialog_table, hash_code, &subs))
    {
	LM_ERR("while adding new subscription\n");
	return 0;
    }

    return s;
}
Exemple #30
0
static void
__dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
{
	struct sip_msg *request = _params->req;
	struct dlginfo_cell *dlginfo;
	int len;

	if (request->REQ_METHOD != METHOD_INVITE)
		return;

	if(send_publish_flag > -1 && !(request->flags & (1<<send_publish_flag)))
		return;

	LM_DBG("new INVITE dialog created: from=%.*s\n", dlg->from_uri.len, dlg->from_uri.s);

	/* create dlginfo structure to store important data inside the module*/
	len = sizeof(struct dlginfo_cell) + 
			dlg->from_uri.len + 
			dlg->to_uri.len + 
			dlg->callid.len + 
			dlg->tag[0].len +
			dlg->req_uri.len +
			dlg->contact[0].len;

	dlginfo = (struct dlginfo_cell*)shm_malloc( len );
	if (dlginfo==0) {
		LM_ERR("no more shm mem (%d)\n",len);
		return;
	}
	memset( dlginfo, 0, len);

	/* copy from dlg structure to dlginfo structure */
	dlginfo->lifetime     = override_lifetime ? override_lifetime : dlg->lifetime;
	dlginfo->from_uri.s   = (char*)dlginfo + sizeof(struct dlginfo_cell);
	dlginfo->from_uri.len = dlg->from_uri.len;
	dlginfo->to_uri.s     = dlginfo->from_uri.s + dlg->from_uri.len;
	dlginfo->to_uri.len   = dlg->to_uri.len;
	dlginfo->callid.s     = dlginfo->to_uri.s + dlg->to_uri.len;
	dlginfo->callid.len   = dlg->callid.len;
	dlginfo->from_tag.s   = dlginfo->callid.s + dlg->callid.len;
	dlginfo->from_tag.len = dlg->tag[0].len;
	dlginfo->req_uri.s    = dlginfo->from_tag.s + dlginfo->from_tag.len;
	dlginfo->req_uri.len  = dlg->req_uri.len;
	dlginfo->from_contact.s   = dlginfo->req_uri.s + dlginfo->req_uri.len;
	dlginfo->from_contact.len = dlg->contact[0].len;

	memcpy(dlginfo->from_uri.s, dlg->from_uri.s, dlg->from_uri.len);
	memcpy(dlginfo->to_uri.s, dlg->to_uri.s, dlg->to_uri.len);
	memcpy(dlginfo->callid.s, dlg->callid.s, dlg->callid.len);
	memcpy(dlginfo->from_tag.s, dlg->tag[0].s, dlg->tag[0].len);
	memcpy(dlginfo->req_uri.s, dlg->req_uri.s, dlg->req_uri.len);
	memcpy(dlginfo->from_contact.s, dlg->contact[0].s, dlg->contact[0].len);

	if (use_pubruri_avps) {

		dlginfo->pubruris_caller = get_str_list(pubruri_caller_avp_type,pubruri_caller_avp_name);
		dlginfo->pubruris_callee = get_str_list(pubruri_callee_avp_type,pubruri_callee_avp_name);

	} else {

		dlginfo->pubruris_caller = (struct str_list*)shm_malloc( sizeof(struct str_list) );

		if (dlginfo->pubruris_caller==0) {
			LM_ERR("no more shm mem (%d)\n", (int) sizeof(struct str_list));
			return;
		}
		memset( dlginfo->pubruris_caller, 0, sizeof(struct str_list));

		dlginfo->pubruris_caller->s=dlginfo->from_uri;


		dlginfo->pubruris_callee = (struct str_list*)shm_malloc( sizeof(struct str_list) );

		if (dlginfo->pubruris_callee==0) {
			LM_ERR("no more shm mem (%d)\n", (int) sizeof(struct str_list));
			return;
		}
		memset( dlginfo->pubruris_callee, 0, sizeof(struct str_list));

		if(include_req_uri) {
			dlginfo->pubruris_callee->s = dlginfo->req_uri;
		} else {
			dlginfo->pubruris_callee->s = dlginfo->to_uri;
		}

	}

	/* register dialog callbacks which triggers sending PUBLISH */
	if (dlg_api.register_dlgcb(dlg, 
		DLGCB_FAILED| DLGCB_CONFIRMED_NA | DLGCB_TERMINATED | DLGCB_EXPIRED |
		DLGCB_REQ_WITHIN | DLGCB_EARLY,
		__dialog_sendpublish, dlginfo, free_dlginfo_cell) != 0) {
		LM_ERR("cannot register callback for interesting dialog types\n");
		return;
	}

#ifdef PUA_DIALOGINFO_DEBUG
	/* dialog callback testing (registered last to be executed frist) */
	if (dlg_api.register_dlgcb(dlg, 
		DLGCB_FAILED| DLGCB_CONFIRMED_NA | DLGCB_CONFIRMED | DLGCB_REQ_WITHIN | DLGCB_TERMINATED |
		DLGCB_EXPIRED | DLGCB_EARLY | DLGCB_RESPONSE_FWDED | DLGCB_RESPONSE_WITHIN  |
		DLGCB_MI_CONTEXT | DLGCB_DESTROY,
		__dialog_cbtest, NULL, NULL) != 0) {
		LM_ERR("cannot register callback for all dialog types\n");
		return;
	}
#endif

	dialog_publish_multi("Trying", dlginfo->pubruris_caller, &(dlg->from_uri), (include_req_uri)?&(dlg->req_uri):&(dlg->to_uri), &(dlg->callid), 1, dlginfo->lifetime, 0, 0, 0, 0, send_publish_flag==-1?1:0);
}