Пример #1
0
int sruid_reinit(sruid_t *sid, int mode)
{
	int i;
	char sep;

	if(sid==NULL)
		return -1;

	sep = sid->buf[4];
	sid->buf[5] = '\0';

	if(server_id!=0)
		i = snprintf(sid->buf+5, SRUID_SIZE - 5 /*so far*/ - 8 /* extra int */,
			"%x%c%x%c%x%c", (unsigned int)server_id, sep,
			(unsigned int)time(NULL), sep, (unsigned int)my_pid(), sep);
	else
		i = snprintf(sid->buf+5, SRUID_SIZE - 5 /*so far*/ - 8 /* extra int */,
			"%x%c%x%c",
			(unsigned int)time(NULL), sep, (unsigned int)my_pid(), sep);
	if(i<=0 || i>SRUID_SIZE-13)
	{
		LM_ERR("could not re-initialize sruid struct - output len: %d\n", i);
		return -1;
	}
	sid->out = sid->buf + i + 5;
	sid->uid.s = sid->buf;
	sid->mode = (sruid_mode_t)mode;
	LM_DBG("re-init root for sruid is [%.*s] (%u / %d)\n", i+5, sid->uid.s,
			sid->counter, i+5);
	return 0;
}
Пример #2
0
int sruid_init(sruid_t *sid, char sep, char *cid, int mode)
{
	int i;

	if(sid==NULL)
		return -1;
	memset(sid, 0, sizeof(sruid_t));
	memcpy(sid->buf, "srid", 4);
	if(cid!=NULL)
	{
		for(i=0; i<4 && cid[i]!='\0'; i++)
			sid->buf[i] = cid[i];
	}
	sid->buf[4] = sep;

	if(server_id!=0)
		i = snprintf(sid->buf+5, SRUID_SIZE - 5 /*so far*/ - 8 /* extra int */,
			"%x%c%x%c%x%c", (unsigned int)server_id, sep,
			(unsigned int)time(NULL), sep, (unsigned int)my_pid(), sep);
	else
		i = snprintf(sid->buf+5, SRUID_SIZE - 5 /*so far*/ - 8 /* extra int */,
			"%x%c%x%c",
			(unsigned int)time(NULL), sep, (unsigned int)my_pid(), sep);
	if(i<=0 || i>SRUID_SIZE-13)
	{
		LM_ERR("could not initialize sruid struct - output len: %d\n", i);
		return -1;
	}
	sid->out = sid->buf + i + 5;
	sid->uid.s = sid->buf;
	sid->mode = (sruid_mode_t)mode;
	LM_DBG("root for sruid is [%.*s] (%u / %d)\n", i+5, sid->uid.s,
			sid->counter, i+5);
	return 0;
}
Пример #3
0
/* Dumps pkg memory status.
 * Per-child process callback that is called
 * when mem_dump_pkg cfg var is changed.
 */
void mem_dump_pkg_cb(str *gname, str *name)
{
	int	old_memlog;
	int memlog;

	if (cfg_get(core, core_cfg, mem_dump_pkg) == my_pid()) {
		/* set memlog to ALERT level to force
		printing the log messages */
		old_memlog = cfg_get(core, core_cfg, memlog);
		memlog = L_ALERT;
		/* ugly hack to temporarily switch memlog to something visible,
		 * possible race with a parallel cfg_set */
		((struct cfg_group_core*)core_cfg)->memlog=memlog;

		if (cfg_get(core, core_cfg, mem_summary) & 1) {
			LOG(memlog, "Memory status (pkg) of process %d:\n", my_pid());
			pkg_status();
		}
		if (cfg_get(core, core_cfg, mem_summary) & 4) {
			LOG(memlog, "Memory still-in-use summary (pkg) of process %d:\n",
					my_pid());
			pkg_sums();
		}

		((struct cfg_group_core*)core_cfg)->memlog=old_memlog;
	}
}
Пример #4
0
/**
 * \brief Child initialization, generates suffix
 * \param rank not used
 * \return 0 on success, -1 on error
 */
int child_init_callid(int rank) 
{
	struct socket_info *si;
	
	/* on tcp/tls bind_address is 0 so try to get the first address we listen
	 * on no matter the protocol */
	si=bind_address?bind_address:get_first_socket();
	if (si==0){
		LOG(L_CRIT, "BUG: child_init_callid: null socket list\n");
		return -1;
	}
	callid_suffix.s = callid_buf + callid_prefix.len;

	callid_suffix.len = snprintf(callid_suffix.s, CALLID_SUFFIX_LEN,
				     "%c%d@%.*s", '-', my_pid(), 
				     si->address_str.len,
				     si->address_str.s);
	if ((callid_suffix.len == -1) || (callid_suffix.len > CALLID_SUFFIX_LEN)) {
		LOG(L_ERR, "ERROR: child_init_callid: buffer too small\n");
		return -1;
	}

	DBG("DEBUG: callid: '%.*s'\n", callid_prefix.len + callid_suffix.len, callid_prefix.s);
	return 0;
}
Пример #5
0
bool fillinRunningKateAppInstances(KateRunningInstanceMap *map)
{
  QDBusConnectionInterface *i = QDBusConnection::sessionBus().interface ();
  
  // look up all running kate instances and there sessions
  QDBusReply<QStringList> servicesReply = i->registeredServiceNames ();
  QStringList services;
  if (servicesReply.isValid())
    services = servicesReply.value ();

  QString serviceName;

  QString my_pid(QString("%1").arg(getpid()).toLatin1());

  foreach (const QString &s, services)
  {
    if (s.startsWith ("org.kde.kate-"))
    {
      if (s.contains(my_pid)) continue;
      KateRunningInstanceInfo* rii=new KateRunningInstanceInfo(s);
      if (rii->valid)
      {
        if (map->contains(rii->sessionName)) return false; //ERROR no two instances may have the same session name
        map->insert(rii->sessionName,rii);        
        //std::cerr<<qPrintable(s)<<"running instance:"<< rii->sessionName.toUtf8().data()<<std::endl;
      } else delete rii;
    }
  }
  return true;
}
Пример #6
0
/**
 * init module function
 */
static int mod_init(void)
{
	LM_NOTICE("initializing JSON-RPC module ...\n");

	if (jrpc_connect_timeout <= 0) {
		LM_ERR("invalid value for connect timeout (%d)! "
				"Please specify a positive value in milliseconds!\n", jrpc_connect_timeout);
		return -1;
	}

	if (jrpc_write_timeout <= 0) {
		LM_ERR("invalid value for write timeout (%d)! "
				"Please specify a positive value in milliseconds!\n", jrpc_write_timeout);
		return -1;
	}

	if (jrpc_read_timeout <= 0) {
		LM_ERR("invalid value for read timeout (%d)! "
				"Please specify a positive value in milliseconds!\n", jrpc_read_timeout);
		return -1;
	}

	jsonrpc_id_index = my_pid() & USHRT_MAX;
	jsonrpc_id_index |= rand() << sizeof(unsigned short);
	return 0;
}
Пример #7
0
/**
 * Initialize children
 */
static int child_init(int rank)
{
	LM_DBG("child [%d]  pid [%d]\n", rank, getpid());
	if (rls_dbf.init==0)
	{
		LM_CRIT("database not bound\n");
		return -1;
	}
	rls_db = rls_dbf.init(db_url.s);
	if (!rls_db)
	{
		LM_ERR("child %d: Error while connecting database\n",
				rank);
		return -1;
	}
	else
	{
		if (rls_dbf.use_table(rls_db, rlsubs_table) < 0)  
		{
			LM_ERR("child %d: Error in use_table rlsubs_table\n", rank);
			return -1;
		}
		if (rls_dbf.use_table(rls_db, rlpres_table) < 0)  
		{
			LM_ERR("child %d: Error in use_table rlpres_table\n", rank);
			return -1;
		}

		LM_DBG("child %d: Database connection opened successfully\n", rank);
	}

	pid= my_pid();
	return 0;
}
Пример #8
0
/**
 * Create a new connection identifier
 * \param url database URL
 * \param pooling whether or not a pooled connection may be used
 * \return connection identifier, or zero on error
 */
struct db_id* new_db_id(const str* url, db_pooling_t pooling)
{
	static int poolid=0;
	struct db_id* ptr;

	if (!url || !url->s) {
		LM_ERR("invalid parameter\n");
		return 0;
	}

	ptr = (struct db_id*)pkg_malloc(sizeof(struct db_id));
	if (!ptr) {
		LM_ERR("no private memory left\n");
		goto err;
	}
	memset(ptr, 0, sizeof(struct db_id));

	if (parse_db_url(ptr, url) < 0) {
		LM_ERR("error while parsing database URL: '%.*s' \n", url->len, url->s);
		goto err;
	}

	if (pooling == DB_POOLING_NONE) ptr->poolid = ++poolid;
	else ptr->poolid = 0;
	ptr->pid = my_pid();

	return ptr;

 err:
	if (ptr) pkg_free(ptr);
	return 0;
}
Пример #9
0
/**
 * Create a new connection identifier
 * \param url database URL
 * \return connection identifier, or zero on error
 */
struct db_id* new_db_id(const str* url)
{
	struct db_id* ptr;

	if (!url || !url->s) {
		LM_ERR("invalid parameter\n");
		return 0;
	}

	ptr = (struct db_id*)pkg_malloc(sizeof(struct db_id));
	if (!ptr) {
		LM_ERR("no private memory left\n");
		goto err;
	}
	memset(ptr, 0, sizeof(struct db_id));

	if (parse_db_url(ptr, url) < 0) {
		LM_ERR("error while parsing database URL: '%.*s' \n", url->len, url->s);
		goto err;
	}
	ptr->pid = my_pid();

	return ptr;

 err:
	if (ptr) pkg_free(ptr);
	return 0;
}
Пример #10
0
int dlg_cfg_cb(sip_msg_t *msg, unsigned int flags, void *cbp)
{
	dlg_cell_t *dlg;
	if(flags&POST_SCRIPT_CB) {
		dlg = dlg_get_ctx_dialog();
		if(dlg!=NULL) {
			if(_dlg_ctx.t==0 && (dlg->state==DLG_STATE_UNCONFIRMED
						|| _dlg_ctx.expect_t==1)) {
				if(_dlg_ctx.cpid!=0 && _dlg_ctx.cpid==my_pid()) {
					/* release to destroy dialog if created by this process
					 * and request was not forwarded */
					if(dlg->state==DLG_STATE_UNCONFIRMED) {
						LM_DBG("new dialog with no transaction after config"
									" execution\n");
					} else {
						LM_DBG("dialog with no expected transaction after"
								" config execution\n");
					}
					dlg_release(dlg);
				}
			}
			/* get ctx dlg increased ref count - release now */
			dlg_release(dlg);
		}
	}
	memset(&_dlg_ctx, 0, sizeof(dlg_ctx_t));

	return 1;
}
Пример #11
0
int dbg_init_mypid(void)
{
	if(_dbg_pid_list==NULL)
		return -1;
	if(process_no>=_dbg_pid_no)
		return -1;
	_dbg_pid_list[process_no].pid = (unsigned int)my_pid();
	if(_dbg_breakpoint==1)
		_dbg_pid_list[process_no].set |= DBG_ABKPOINT_ON;
	if(_dbg_cfgtrace==1)
		_dbg_pid_list[process_no].set |= DBG_CFGTRACE_ON;
	if(_dbg_reset_msgid==1)
	{
		LM_DBG("[%d] create locks\n", process_no);
		_dbg_pid_list[process_no].lock = lock_alloc();
		if(_dbg_pid_list[process_no].lock==NULL)
		{
			LM_ERR("cannot allocate the lock\n");
			return -1;
		}
		if(lock_init(_dbg_pid_list[process_no].lock)==NULL)
		{
			LM_ERR("cannot init the lock\n");
			lock_dealloc(_dbg_pid_list[process_no].lock);
			return -1;
		}
	}
	return 0;
}
Пример #12
0
/*!
 * \brief Callback function that checks if reset_msgid is set
 *  and modifies msg->id if necessary.
 * \param msg SIP message
 * \param flags unused
 * \param bar unused
 * \return 1 on success, -1 on failure
 */
int dbg_msgid_filter(struct sip_msg *msg, unsigned int flags, void *bar)
{
	unsigned int process_no = my_pid();
	int indx = dbg_get_pid_index(process_no);
	unsigned int msgid_base = 0;
	unsigned int msgid_new = 0;
	if(indx<0) return -1;
	LM_DBG("process_no:%d indx:%d\n", process_no, indx);
	lock_get(_dbg_pid_list[indx].lock);
	if(_dbg_pid_list[indx].reset_msgid==1)
	{
		LM_DBG("reset_msgid! msgid_base:%d\n", msg->id);
		_dbg_pid_list[indx].reset_msgid = 0;
		_dbg_pid_list[indx].msgid_base = msg->id - 1;
	}
	msgid_base = _dbg_pid_list[indx].msgid_base;
	lock_release(_dbg_pid_list[indx].lock);
	if(msg->id > msgid_base)
	{
		msgid_new = msg->id - msgid_base;
		LM_DBG("msg->id:%d msgid_base:%d -> %d\n",
			msg->id, msgid_base, msgid_new);
		msg->id = msgid_new;
	}
	else
	{
		LM_DBG("msg->id:%d already processed\n", msg->id);
	}
	return 1;
}
Пример #13
0
void worker_loop(int id) {
	dmq_worker_t* worker = &workers[id];
	dmq_job_t* current_job;
	peer_reponse_t peer_response;
	int ret_value;
	for(;;) {
		LM_DBG("dmq_worker [%d %d] getting lock\n", id, my_pid());
		lock_get(&worker->lock);
		LM_DBG("dmq_worker [%d %d] lock acquired\n", id, my_pid());
		/* multiple lock_release calls might be performed, so remove from queue until empty */
		do {
			/* fill the response with 0's */
			memset(&peer_response, 0, sizeof(peer_response));
			current_job = job_queue_pop(worker->queue);
			/* job_queue_pop might return NULL if queue is empty */
			if(current_job) {
				ret_value = current_job->f(current_job->msg, &peer_response);
				if(ret_value < 0) {
					LM_ERR("running job failed\n");
					continue;
				}
				/* add the body to the reply */
				if(peer_response.body.s) {
					if(set_reply_body(current_job->msg, &peer_response.body, &peer_response.content_type) < 0) {
						LM_ERR("error adding lumps\n");
						continue;
					}
				}
				/* send the reply */
				if(slb.freply(current_job->msg, peer_response.resp_code, &peer_response.reason) < 0)
				{
					LM_ERR("error sending reply\n");
				}
				
				/* if body given, free the lumps and free the body */
				if(peer_response.body.s) {
					del_nonshm_lump_rpl(&current_job->msg->reply_lump);
					pkg_free(peer_response.body.s);
				}
				LM_DBG("sent reply\n");
				shm_free(current_job->msg);
				shm_free(current_job);
				worker->jobs_processed++;
			}
		} while(job_queue_size(worker->queue) > 0);
	}
}
Пример #14
0
struct sip_msg* faked_msg_next(void)
{
	_faked_msg.id = 1 + _faked_msg_no++;
	_faked_msg.pid = my_pid();
	memset(&_faked_msg.tval, 0, sizeof(struct timeval));
	clear_branches();
	return &_faked_msg;
}
Пример #15
0
static int child_init(int rank)
{
	LM_NOTICE("init_child [%d]  pid [%d]\n", rank, getpid());

	pid = my_pid();

	return 0;
}
Пример #16
0
void dprint(char * format, ...)
{
	va_list ap;

	fprintf(stderr, "%2d(%d) ", process_no, my_pid());
	va_start(ap, format);
	vfprintf(stderr,format,ap);
	fflush(stderr);
	va_end(ap);
}
Пример #17
0
/* Child initialization function */
static int child_init(int rank)
{	
	int i = my_pid();

	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN) {
		return 0; /* do nothing for the main process */
	}
	LM_DBG("*** http_client module initializing process %d\n", i);

	return 0;
}
Пример #18
0
int dbg_init_mypid(void)
{
	if(_dbg_pid_list==NULL)
		return -1;
	if(process_no>=_dbg_pid_no)
		return -1;
	_dbg_pid_list[process_no].pid = (unsigned int)my_pid();
	if(_dbg_breakpoint==1)
		_dbg_pid_list[process_no].set |= DBG_ABKPOINT_ON;
	if(_dbg_cfgtrace==1)
		_dbg_pid_list[process_no].set |= DBG_CFGTRACE_ON;
	return 0;
}
Пример #19
0
/**
 * recursive/re-entrant lock of the slot in hash table
 */
void ht_slot_lock(ht_t *ht, int idx)
{
	int mypid;

	mypid = my_pid();
	if (likely(atomic_get(&ht->entries[idx].locker_pid) != mypid)) {
		lock_get(&ht->entries[idx].lock);
		atomic_set(&ht->entries[idx].locker_pid, mypid);
	} else {
		/* locked within the same process that executed us */
		ht->entries[idx].rec_lock_level++;
	}
}
Пример #20
0
/*!
 * \brief  Get lock for a slot
 * \param _d domain
 * \param i slot number
 */
void lock_ulslot(udomain_t* _d, int i) {
#ifdef EXTRA_DEBUG
    LM_DBG("LOCKING UDOMAIN SLOT [%d]\n", i);
#endif
    int mypid;
    mypid = my_pid();
    if (likely(atomic_get(&_d->table[i].locker_pid) != mypid)) {
        lock_get(_d->table[i].lock);
        atomic_set(&_d->table[i].locker_pid, mypid);
    } else {
        /* locked within the same process that executed us */
        _d->table[i].recursive_lock_level++;
    }
}
Пример #21
0
void _lc_core_log_udp(int lpriority, const char *format, ...)
{
	va_list arglist;
	char obuf[LC_LOG_MSG_MAX_SIZE];
	int n;

	va_start(arglist, format);

	n = 0;
	n += snprintf(obuf + n, LC_LOG_MSG_MAX_SIZE - n, "(%d) ", my_pid());
	n += vsnprintf(obuf + n, LC_LOG_MSG_MAX_SIZE - n, format, arglist);
	va_end(arglist);
	if(udp_send(&_lc_udp_dst, obuf, n)!=0) {
		LM_DBG("udp send returned non zero\n");
	}
}
Пример #22
0
int pkg_proc_stats_myinit(int rank)
{
	struct mem_info info;
	if(_pkg_proc_stats_list==NULL)
		return -1;
	if(process_no>=_pkg_proc_stats_no)
		return -1;
	_pkg_proc_stats_list[process_no].pid = (unsigned int)my_pid();
	_pkg_proc_stats_list[process_no].rank = rank;

	/* init pkg usage values */
	pkg_info(&info);
	_pkg_proc_stats_list[process_no].available = info.free;
	_pkg_proc_stats_list[process_no].used = info.used;
	_pkg_proc_stats_list[process_no].real_used = info.real_used;
	_pkg_proc_stats_list[process_no].total_size = info.total_size;
	_pkg_proc_stats_list[process_no].total_frags = info.total_frags;
	return 0;
}
Пример #23
0
/**
 * initialize children
 */
static int child_init(int rank)
{
  	int i, newpid;
	if (rank == PROC_MAIN) {
		/* fork worker processes */
		for(i = 0; i < num_workers; i++) {
			init_worker(&workers[i]);
			LM_DBG("starting worker process %d\n", i);
			newpid = fork_process(PROC_NOCHLDINIT, "DMQ WORKER", 0);
			if(newpid < 0) {
				LM_ERR("failed to form process\n");
				return -1;
			} else if(newpid == 0) {
				/* child - this will loop forever */
				worker_loop(i);
			} else {
				workers[i].pid = newpid;
			}
		}
		/* notification_node - the node from which the Kamailio instance
		 * gets the server list on startup.
		 * the address is given as a module parameter in dmq_notification_address
		 * the module MUST have this parameter if the Kamailio instance is not
		 * a master in this architecture
		 */
		if(dmq_notification_address.s) {
			notification_node = add_server_and_notify(&dmq_notification_address);
			if(!notification_node) {
				LM_ERR("cannot retrieve initial nodelist from %.*s\n",
				       STR_FMT(&dmq_notification_address));
				return -1;
			}
		}
		return 0;
	}
	if(rank == PROC_INIT || rank == PROC_TCP_MAIN) {
		/* do nothing for the main process */
		return 0;
	}

	pid = my_pid();
	return 0;
}
Пример #24
0
int xcaps_generate_etag_hdr(str *etag)
{
	etag->len = snprintf(xcaps_hdr_buf, XCAPS_HDR_SIZE,
			"ETag: \"sr-%d-%d-%d\"\r\n", xcaps_init_time, my_pid(),
			xcaps_etag_counter++);
	if(etag->len <0)
	{
		LM_ERR("error printing etag\n ");
		return -1;
	}
	if(etag->len >= XCAPS_HDR_SIZE)
	{
		LM_ERR("etag buffer overflow\n");
		return -1;
	}

	etag->s = xcaps_hdr_buf;
	etag->s[etag->len] = '\0';
	return 0;
}
Пример #25
0
static void xmpp_process(int rank)
{
	/* if this blasted server had a decent I/O loop, we'd
	 * just add our socket to it and connect().
	 */
	close(pipe_fds[1]);

	pid = my_pid();
	*xmpp_pid = pid;

	LM_DBG("started child connection process\n");
	if (!strcmp(backend, "component")) {
		backend_mode = XMPP_COMP;
		xmpp_component_child_process(pipe_fds[0]);
	}
	else if (!strcmp(backend, "server")) {
		backend_mode = XMPP_SERV;
		xmpp_server_child_process(pipe_fds[0]);
	}
}
Пример #26
0
unsigned long sr_ssl_id_f()
{
	return my_pid();
}
Пример #27
0
/* WARNING: buf must be 0 terminated (buf[len]=0) or some things might 
 * break (e.g.: modules/textops)
 */
int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info) 
{
	struct sip_msg* msg;
	struct run_act_ctx ctx;
	int ret;
#ifdef STATS
	int skipped = 1;
	struct timeval tvb, tve;	
	struct timezone tz;
	unsigned int diff;
#endif
	str inb;

	inb.s = buf;
	inb.len = len;
	sr_event_exec(SREV_NET_DATA_IN, (void*)&inb);
	len = inb.len;

	msg=pkg_malloc(sizeof(struct sip_msg));
	if (msg==0) {
		LOG(L_ERR, "ERROR: receive_msg: no mem for sip_msg\n");
		goto error00;
	}
	msg_no++;
	/* number of vias parsed -- good for diagnostic info in replies */
	via_cnt=0;

	memset(msg,0, sizeof(struct sip_msg)); /* init everything to 0 */
	/* fill in msg */
	msg->buf=buf;
	msg->len=len;
	/* zero termination (termination of orig message bellow not that
	   useful as most of the work is done with scratch-pad; -jiri  */
	/* buf[len]=0; */ /* WARNING: zero term removed! */
	msg->rcv=*rcv_info;
	msg->id=msg_no;
	msg->pid=my_pid();
	msg->set_global_address=default_global_address;
	msg->set_global_port=default_global_port;
	
	if(likely(sr_msg_time==1)) msg_set_time(msg);

	if (parse_msg(buf,len, msg)!=0){
		if(sr_event_exec(SREV_RCV_NOSIP, (void*)msg)!=0) {
			LOG(cfg_get(core, core_cfg, corelog),
				"core parsing of SIP message failed (%s:%d/%d)\n",
				ip_addr2a(&msg->rcv.src_ip), (int)msg->rcv.src_port,
				(int)msg->rcv.proto);
			sr_core_ert_run(msg, SR_CORE_ERT_RECEIVE_PARSE_ERROR);
		}
		goto error02;
	}
	DBG("After parse_msg...\n");


	/* ... clear branches from previous message */
	clear_branches();

	if (msg->first_line.type==SIP_REQUEST){
		ruri_mark_new(); /* ruri is usable for forking (not consumed yet) */
		if (!IS_SIP(msg)){
			if ((ret=nonsip_msg_run_hooks(msg))!=NONSIP_MSG_ACCEPT){
				if (unlikely(ret==NONSIP_MSG_ERROR))
					goto error03;
				goto end; /* drop the message */
			}
		}
		/* sanity checks */
		if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
			/* no via, send back error ? */
			LOG(L_ERR, "ERROR: receive_msg: no via found in request\n");
			STATS_BAD_MSG();
			goto error02;
		}
		/* check if necessary to add receive?->moved to forward_req */
		/* check for the alias stuff */
#ifdef USE_TCP
		if (msg->via1->alias && cfg_get(tcp, tcp_cfg, accept_aliases) && 
				(((rcv_info->proto==PROTO_TCP) && !tcp_disable)
#ifdef USE_TLS
					|| ((rcv_info->proto==PROTO_TLS) && !tls_disable)
#endif
				)
			){
			if (tcpconn_add_alias(rcv_info->proto_reserved1, msg->via1->port,
									rcv_info->proto)!=0){
				LOG(L_ERR, " ERROR: receive_msg: tcp alias failed\n");
				/* continue */
			}
		}
#endif

	/*	skip: */
		DBG("preparing to run routing scripts...\n");
#ifdef  STATS
		gettimeofday( & tvb, &tz );
#endif
		/* execute pre-script callbacks, if any; -jiri */
		/* if some of the callbacks said not to continue with
		   script processing, don't do so
		   if we are here basic sanity checks are already done
		   (like presence of at least one via), so you can count
		   on via1 being parsed in a pre-script callback --andrei
		*/
		if (exec_pre_script_cb(msg, REQUEST_CB_TYPE)==0 )
		{
			STATS_REQ_FWD_DROP();
			goto end; /* drop the request */
		}

		set_route_type(REQUEST_ROUTE);
		/* exec the routing script */
		if (run_top_route(main_rt.rlist[DEFAULT_RT], msg, 0)<0){
			LOG(L_WARN, "WARNING: receive_msg: "
					"error while trying script\n");
			goto error_req;
		}

#ifdef STATS
		gettimeofday( & tve, &tz );
		diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
		stats->processed_requests++;
		stats->acc_req_time += diff;
		DBG("successfully ran routing scripts...(%d usec)\n", diff);
		STATS_RX_REQUEST( msg->first_line.u.request.method_value );
#endif

		/* execute post request-script callbacks */
		exec_post_script_cb(msg, REQUEST_CB_TYPE);
	}else if (msg->first_line.type==SIP_REPLY){
		/* sanity checks */
		if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
			/* no via, send back error ? */
			LOG(L_ERR, "ERROR: receive_msg: no via found in reply\n");
			STATS_BAD_RPL();
			goto error02;
		}

#ifdef STATS
		gettimeofday( & tvb, &tz );
		STATS_RX_RESPONSE ( msg->first_line.u.reply.statuscode / 100 );
#endif
		
		/* execute pre-script callbacks, if any; -jiri */
		/* if some of the callbacks said not to continue with
		   script processing, don't do so
		   if we are here basic sanity checks are already done
		   (like presence of at least one via), so you can count
		   on via1 being parsed in a pre-script callback --andrei
		*/
		if (exec_pre_script_cb(msg, ONREPLY_CB_TYPE)==0 )
		{
			STATS_RPL_FWD_DROP();
			goto end; /* drop the reply */
		}

		/* exec the onreply routing script */
		if (onreply_rt.rlist[DEFAULT_RT]){
			set_route_type(CORE_ONREPLY_ROUTE);
			ret=run_top_route(onreply_rt.rlist[DEFAULT_RT], msg, &ctx);
#ifndef NO_ONREPLY_ROUTE_ERROR
			if (unlikely(ret<0)){
				LOG(L_WARN, "WARNING: receive_msg: "
						"error while trying onreply script\n");
				goto error_rpl;
			}else
#endif /* NO_ONREPLY_ROUTE_ERROR */
			if (unlikely(ret==0 || (ctx.run_flags&DROP_R_F))){
				STATS_RPL_FWD_DROP();
				goto skip_send_reply; /* drop the message, no error */
			}
		}
		/* send the msg */
		forward_reply(msg);
	skip_send_reply:
#ifdef STATS
		gettimeofday( & tve, &tz );
		diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
		stats->processed_responses++;
		stats->acc_res_time+=diff;
		DBG("successfully ran reply processing...(%d usec)\n", diff);
#endif

		/* execute post reply-script callbacks */
		exec_post_script_cb(msg, ONREPLY_CB_TYPE);
	}

end:
#ifdef STATS
	skipped = 0;
#endif
	/* free possible loaded avps -bogdan */
	reset_avps();
#ifdef WITH_XAVP
	xavp_reset_list();
#endif
	DBG("receive_msg: cleaning up\n");
	free_sip_msg(msg);
	pkg_free(msg);
#ifdef STATS
	if (skipped) STATS_RX_DROPS;
#endif
	return 0;
#ifndef NO_ONREPLY_ROUTE_ERROR
error_rpl:
	/* execute post reply-script callbacks */
	exec_post_script_cb(msg, ONREPLY_CB_TYPE);
	reset_avps();
#ifdef WITH_XAVP
	xavp_reset_list();
#endif
	goto error02;
#endif /* NO_ONREPLY_ROUTE_ERROR */
error_req:
	DBG("receive_msg: error:...\n");
	/* execute post request-script callbacks */
	exec_post_script_cb(msg, REQUEST_CB_TYPE);
error03:
	/* free possible loaded avps -bogdan */
	reset_avps();
#ifdef WITH_XAVP
	xavp_reset_list();
#endif
error02:
	free_sip_msg(msg);
	pkg_free(msg);
error00:
	STATS_RX_DROPS;
	return -1;
}
Пример #28
0
/*!
 * \brief Create a new dialog from a sip message
 *
 * Create a new dialog from a SIP message, register a callback
 * to keep track of the dialog with help of the tm module.
 * This function is either called from the request callback, or
 * from the dlg_manage function in the configuration script.
 * \see dlg_onreq
 * \see w_dlg_manage
 * \param req SIP message
 * \param t transaction
 * \param run_initial_cbs if set zero, initial callbacks are not executed
 * \return 0 on success, -1 on failure
 */ 
int dlg_new_dialog(sip_msg_t *req, struct cell *t, const int run_initial_cbs)
{
	dlg_cell_t *dlg;
	str s;
	str callid;
    str ftag;
    str ttag;
    str req_uri;
    unsigned int dir;

	dlg = dlg_get_ctx_dialog();
    if(dlg != NULL) {
		dlg_release(dlg);
        return -1;
	}

	if(req->first_line.u.request.method_value != METHOD_INVITE)
		return -1;

    if(pre_match_parse( req, &callid, &ftag, &ttag, 0)<0) {
        LM_WARN("pre-matching failed\n");
        return -1;
    }

    if(ttag.s!=0 && ttag.len!=0)
        return -1;

    if(pv_printf_s(req, ruri_param_model, &req_uri)<0) {
        LM_ERR("error - cannot print the r-uri format\n");
        return -1;
    }
    trim(&req_uri);

	dir = DLG_DIR_NONE;
	/* search dialog by SIP attributes
	 * - hash table slot is left locked  */
	dlg = dlg_search(&callid, &ftag, &ttag, &dir);
	if(dlg) {
		if (detect_spirals) {
			if (spiral_detected == 1) {
				dlg_hash_release(&callid);
				return 0;
			}

			if ( dlg->state != DLG_STATE_DELETED ) {
				LM_DBG("Callid '%.*s' found, must be a spiraled request\n",
					callid.len, callid.s);
				spiral_detected = 1;

				if (run_initial_cbs)
					run_dlg_callbacks( DLGCB_SPIRALED, dlg, req, NULL,
							DLG_DIR_DOWNSTREAM, 0);
				/* set ctx dlg id shortcuts */
				_dlg_ctx.iuid.h_entry = dlg->h_entry;
				_dlg_ctx.iuid.h_id = dlg->h_id;
				/* search_dlg() has incremented the ref count by 1 */
				dlg_release(dlg);
				dlg_hash_release(&callid);
				return 0;
			}
			dlg_release(dlg);
		}
    }
    spiral_detected = 0;

    dlg = build_new_dlg (&callid /*callid*/,
                         &(get_from(req)->uri) /*from uri*/,
                         &(get_to(req)->uri) /*to uri*/,
                         &ftag/*from_tag*/,
                         &req_uri /*r-uri*/ );

	if (dlg==0) {
		dlg_hash_release(&callid);
		LM_ERR("failed to create new dialog\n");
		return -1;
	}

	/* save caller's tag, cseq, contact and record route*/
	if (populate_leg_info(dlg, req, t, DLG_CALLER_LEG,
			&(get_from(req)->tag_value)) !=0) {
		dlg_hash_release(&callid);
		LM_ERR("could not add further info to the dialog\n");
		shm_free(dlg);
		return -1;
	}

	/* Populate initial varlist: */
	dlg->vars = get_local_varlist_pointer(req, 1);

	/* after dlg_search() slot was kept locked */
	link_dlg(dlg, 0, 1);
	/* unlock after dlg_search() */
	dlg_hash_release(&callid);

	dlg->lifetime = get_dlg_timeout(req);
	s.s   = _dlg_ctx.to_route_name;
	s.len = strlen(s.s);
	dlg_set_toroute(dlg, &s);
	dlg->sflags |= _dlg_ctx.flags;
	dlg->iflags |= _dlg_ctx.iflags;

	if (dlg_send_bye!=0 || _dlg_ctx.to_bye!=0)
		dlg->iflags |= DLG_IFLAG_TIMEOUTBYE;

    if (run_initial_cbs)  run_create_callbacks( dlg, req);

	/* first INVITE seen (dialog created, unconfirmed) */
	if ( seq_match_mode!=SEQ_MATCH_NO_ID &&
			add_dlg_rr_param( req, dlg->h_entry, dlg->h_id)<0 ) {
		LM_ERR("failed to add RR param\n");
		goto error;
	}

    if_update_stat( dlg_enable_stats, processed_dlgs, 1);

	_dlg_ctx.cpid = my_pid();
    _dlg_ctx.iuid.h_entry = dlg->h_entry;
    _dlg_ctx.iuid.h_id = dlg->h_id;
    set_current_dialog(req, dlg);

	return 0;

error:
	if (!spiral_detected)
		dlg_unref(dlg, 1);               // undo ref regarding linking
	return -1;
}
Пример #29
0
/*!
 * \brief Function that is registered as RR callback for dialog tracking
 * 
 * Function that is registered as RR callback for dialog tracking. It
 * sets the appropriate events after the SIP method and run the state
 * machine to update the dialog state. It updates then the saved
 * dialogs and also the statistics.
 * \param req SIP request
 * \param route_params record-route parameter
 * \param param unused
 */
void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
{
	dlg_cell_t *dlg;
	dlg_iuid_t *iuid;
	str val, callid, ftag, ttag;
	int h_entry, h_id, new_state, old_state, unref, event, timeout, reset;
	unsigned int dir;
	int ret = 0;

	dlg = dlg_get_ctx_dialog();
	if (dlg!=NULL) {
		dlg_release(dlg);
		return;
	}

	/* skip initial requests - they may end up here because of the
	 * preloaded route */
	if ( (!req->to && parse_headers(req, HDR_TO_F,0)<0) || !req->to ) {
		LM_ERR("bad request or missing TO hdr :-/\n");
		return;
	}
	if ( get_to(req)->tag_value.len==0 )
		return;

	dlg = 0;
	dir = DLG_DIR_NONE;

	if ( seq_match_mode!=SEQ_MATCH_NO_ID ) {
		if( d_rrb.get_route_param( req, &rr_param, &val)!=0) {
			LM_DBG("Route param '%.*s' not found\n", rr_param.len,rr_param.s);
			if (seq_match_mode==SEQ_MATCH_STRICT_ID )
				return;
		} else {
			LM_DBG("route param is '%.*s' (len=%d)\n",val.len,val.s,val.len);

			if ( parse_dlg_rr_param( val.s, val.s+val.len, &h_entry, &h_id)<0 )
				return;

			dlg = dlg_lookup(h_entry, h_id);
			if (dlg==0) {
				LM_WARN("unable to find dialog for %.*s "
					"with route param '%.*s' [%u:%u]\n",
					req->first_line.u.request.method.len,
					req->first_line.u.request.method.s,
					val.len,val.s, h_entry, h_id);
				if (seq_match_mode==SEQ_MATCH_STRICT_ID )
					return;
			} else {
				if (pre_match_parse( req, &callid, &ftag, &ttag, 1)<0) {
					// lookup_dlg has incremented the ref count by 1
					dlg_release(dlg);
					return;
				}
				if (match_dialog( dlg, &callid, &ftag, &ttag, &dir )==0) {
					LM_WARN("tight matching failed for %.*s with callid='%.*s'/%d, "
							"ftag='%.*s'/%d, ttag='%.*s'/%d and direction=%d\n",
							req->first_line.u.request.method.len,
							req->first_line.u.request.method.s,
							callid.len, callid.s, callid.len,
							ftag.len, ftag.s, ftag.len,
							ttag.len, ttag.s, ttag.len, dir);
					LM_WARN("dialog identification elements are callid='%.*s'/%d, "
							"caller tag='%.*s'/%d, callee tag='%.*s'/%d\n",
							dlg->callid.len, dlg->callid.s, dlg->callid.len,
							dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s,
							dlg->tag[DLG_CALLER_LEG].len,
							dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s,
							dlg->tag[DLG_CALLEE_LEG].len);
					// lookup_dlg has incremented the ref count by 1
					dlg_release(dlg);

					// Reset variables in order to do a lookup based on SIP-Elements.
					dlg = 0;
					dir = DLG_DIR_NONE;

					if (seq_match_mode==SEQ_MATCH_STRICT_ID )
						return;
				}
			}
		}
	}

	if (dlg==0) {
		if (pre_match_parse( req, &callid, &ftag, &ttag, 1)<0)
			return;
		/* TODO - try to use the RR dir detection to speed up here the
		 * search -bogdan */
		dlg = get_dlg(&callid, &ftag, &ttag, &dir);
		if (dlg==0){
			LM_DBG("Callid '%.*s' not found\n",
				req->callid->body.len, req->callid->body.s);
			return;
		}
	}

    /* set current dialog - re-use ref increment from dlg_get() above */
    set_current_dialog( req, dlg);
    _dlg_ctx.iuid.h_entry = dlg->h_entry;
    _dlg_ctx.iuid.h_id = dlg->h_id;

	if (req->first_line.u.request.method_value != METHOD_ACK) {
		iuid = dlg_get_iuid_shm_clone(dlg);
		if(iuid!=NULL)
		{
			/* register callback for the replies of this request */
			if ( d_tmb.register_tmcb( req, 0, TMCB_RESPONSE_IN|TMCB_ON_FAILURE,
					dlg_onreply, (void*)iuid, dlg_iuid_sfree)<0 ) {
				LM_ERR("failed to register TMCB (3)\n");
				shm_free(iuid);
			}
			iuid = NULL;
		}
	}
	
	/* run state machine */
	switch ( req->first_line.u.request.method_value ) {
		case METHOD_PRACK:
			event = DLG_EVENT_REQPRACK; break;
		case METHOD_ACK:
			event = DLG_EVENT_REQACK; break;
		case METHOD_BYE:
			event = DLG_EVENT_REQBYE; break;
		default:
			event = DLG_EVENT_REQ;
	}

	next_state_dlg( dlg, event, &old_state, &new_state, &unref);

	CURR_DLG_ID = req->id;
	CURR_DLG_LIFETIME = (unsigned int)(time(0))-dlg->start_ts;
	CURR_DLG_STATUS = new_state;

	dlg_run_event_route(dlg, req, old_state, new_state);

	/* delay deletion of dialog until transaction has died off in order
	 * to absorb in-air messages */
	if (new_state==DLG_STATE_DELETED && old_state!=DLG_STATE_DELETED) {
		iuid = dlg_get_iuid_shm_clone(dlg);
		if(iuid!=NULL) {
			if ( d_tmb.register_tmcb(req, NULL, TMCB_DESTROY,
					unref_dlg_from_cb, (void*)iuid, dlg_iuid_sfree)<0 ) {
				LM_ERR("failed to register deletion delay function\n");
				shm_free(iuid);
			} else {
				dlg_ref(dlg, 1);
			}
		}
	}

	if (new_state==DLG_STATE_CONFIRMED && old_state!=DLG_STATE_CONFIRMED)
		dlg_ka_add(dlg);

	/* run actions for the transition */
	if (event==DLG_EVENT_REQBYE && new_state==DLG_STATE_DELETED &&
	old_state!=DLG_STATE_DELETED) {
		LM_DBG("BYE successfully processed\n");
		/* remove from timer */
		ret = remove_dialog_timer(&dlg->tl);
		if (ret < 0) {
			LM_CRIT("unable to unlink the timer on dlg %p [%u:%u] "
				"with clid '%.*s' and tags '%.*s' '%.*s'\n",
				dlg, dlg->h_entry, dlg->h_id,
				dlg->callid.len, dlg->callid.s,
				dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s,
				dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s);
		} else if (ret > 0) {
			LM_WARN("inconsitent dlg timer data on dlg %p [%u:%u] "
				"with clid '%.*s' and tags '%.*s' '%.*s'\n",
				dlg, dlg->h_entry, dlg->h_id,
				dlg->callid.len, dlg->callid.s,
				dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s,
				dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s);
		} else {
			/* one extra unref due to removal from timer list */
			unref++;
		}
		/* dialog terminated (BYE) */
        dlg_terminated( req, dlg, dir);

		dlg_unref(dlg, unref);

		_dlg_ctx.cpid = my_pid();
		_dlg_ctx.expect_t = 1;
		dlg_set_ctx_iuid(dlg);

		if_update_stat( dlg_enable_stats, active_dlgs, -1);
		goto done;
	}

	if ( (event==DLG_EVENT_REQ || event==DLG_EVENT_REQACK)
	&& (new_state==DLG_STATE_CONFIRMED || new_state==DLG_STATE_EARLY)) {

		timeout = get_dlg_timeout(req);
		if (timeout!=default_timeout) {
			dlg->lifetime = timeout;
		}
		reset = !((dlg->iflags & DLG_IFLAG_TIMER_NORESET) || dlg_timeout_noreset);

		if ((new_state!=DLG_STATE_EARLY) && (old_state!=DLG_STATE_CONFIRMED || reset)) {
			if (update_dlg_timer( &dlg->tl, dlg->lifetime )==-1) {
				LM_ERR("failed to update dialog lifetime\n");
			} else {
				dlg->dflags |= DLG_FLAG_CHANGED;
			}
		}
		if(event != DLG_EVENT_REQACK) {
			if(dlg_refresh_contacts(dlg, req, dir)!=0) {
				LM_ERR("contacts update failed\n");
			} else {
				dlg->dflags |= DLG_FLAG_CHANGED;
			}
			if(update_cseqs(dlg, req, dir)!=0) {
				LM_ERR("cseqs update failed\n");
			} else {
				dlg->dflags |= DLG_FLAG_CHANGED;
			}
		}
		if(dlg_db_mode==DB_MODE_REALTIME && (dlg->dflags&DLG_FLAG_CHANGED)) {
			update_dialog_dbinfo(dlg);
		}

		if (old_state==DLG_STATE_CONFIRMED_NA) {
			LM_DBG("confirming ACK successfully processed\n");

			/* confirming ACK request */
			run_dlg_callbacks( DLGCB_CONFIRMED, dlg, req, NULL, dir, 0);
		} else {
			LM_DBG("sequential request successfully processed\n");

			/* within dialog request */
			run_dlg_callbacks( DLGCB_REQ_WITHIN, dlg, req, NULL, dir, 0);

			if ( (event!=DLG_EVENT_REQACK) &&
					(dlg->cbs.types)&DLGCB_RESPONSE_WITHIN ) {
				iuid = dlg_get_iuid_shm_clone(dlg);
				if(iuid!=NULL)
				{
					/* register callback for the replies of this request */
					if ( d_tmb.register_tmcb( req, 0, TMCB_RESPONSE_FWDED,
							(dir==DLG_DIR_UPSTREAM)?dlg_seq_down_onreply:
														dlg_seq_up_onreply,
							(void*)iuid, dlg_iuid_sfree)<0 ) {
						LM_ERR("failed to register TMCB (2)\n");
						shm_free(iuid);
					}
				}
			}
		}
	}

	if(new_state==DLG_STATE_CONFIRMED && old_state==DLG_STATE_CONFIRMED_NA){
		dlg->dflags |= DLG_FLAG_CHANGED;
		if(dlg_db_mode == DB_MODE_REALTIME)
			update_dialog_dbinfo(dlg);
	}

done:
	dlg_release(dlg);
	return;
}
Пример #30
0
static unsigned long tls_get_id(void)
{
	return my_pid();
}