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; }
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; }
/* 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; } }
/** * \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; }
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; }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }
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; }
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; }
/*! * \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; }
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(¤t_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); } }
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; }
static int child_init(int rank) { LM_NOTICE("init_child [%d] pid [%d]\n", rank, getpid()); pid = my_pid(); return 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); }
/* 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; }
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; }
/** * 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++; } }
/*! * \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++; } }
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"); } }
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; }
/** * 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; }
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; }
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]); } }
unsigned long sr_ssl_id_f() { return my_pid(); }
/* 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; }
/*! * \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; }
/*! * \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; }
static unsigned long tls_get_id(void) { return my_pid(); }