// Copies Logical Page from fromlp to tolp. int lp_copy (struct lpage *fromlp, struct lpage **tolp) { struct lpage *newlp = NULL; paddr_t frompa; paddr_t topa; off_t swapaddr; int result; DEBUG(DB_VM, "LPage: lp_copy\n"); lock_acquire(fromlp -> lock); frompa = fromlp -> paddr & PAGE_FRAME; if (frompa == INVALID_PADDR) { swapaddr = fromlp -> swapaddr; lock_release(fromlp -> lock); frompa = cm_allocuserpage(fromlp); if (frompa == INVALID_PADDR) { return (ENOMEM); } KASSERT(cm_pageispinned(frompa)); lock_acquire(paging_lock); swap_pagein(frompa, swapaddr); lock_acquire(fromlp -> lock); lock_release(paging_lock); KASSERT((fromlp -> paddr & PAGE_FRAME) == INVALID_PADDR); fromlp -> paddr = frompa | LPF_LOCKED; } else { cm_pin(frompa); } KASSERT(cm_pageispinned(frompa)); result = lp_setup(&newlp, &topa); if (result) { cm_unpin(frompa); lock_release(fromlp -> lock); return (result); } KASSERT(cm_pageispinned(topa)); KASSERT(cm_pageispinned(frompa)); cm_copypage(frompa, topa); cm_unpin(topa); cm_unpin(frompa); lock_release(fromlp -> lock); lock_release(newlp -> lock); *tolp = newlp; return (0); }
static struct mi_root* mi_cc_list_agents(struct mi_root *cmd_tree, void *param) { struct cc_agent *agent; struct mi_root *rpl_tree; struct mi_node *node; struct mi_node *rpl; struct mi_attr *attr; str state; static str s_free={"free", 4}; static str s_wrapup={"wrapup", 6}; static str s_incall={"incall", 6}; char *p; int len; int i; rpl_tree = init_mi_tree( 200, MI_SSTR("OK") ); if ( rpl_tree==NULL) return NULL; rpl = &rpl_tree->node; rpl->flags |= MI_IS_ARRAY; /* block access to data */ lock_get( data->lock ); for(i=0; i< 2; i++) { for( agent=data->agents[i] ; agent ; agent=agent->next ) { node = add_mi_node_child( rpl, MI_DUP_VALUE, "Agent", 5, agent->id.s, agent->id.len ); if (node==NULL) goto error; p = int2str( (unsigned long)(agent->ref_cnt), &len); attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Ref"), p, len); if (attr==NULL) goto error; if(!agent->loged_in) attr = add_mi_attr( node, MI_DUP_VALUE, "Loged in", 8, "NO", 2); else { attr = add_mi_attr( node, MI_DUP_VALUE, "Loged in", 8, "YES", 3); if (attr==NULL) goto error; switch ( agent->state ) { case CC_AGENT_FREE: state = s_free; break; case CC_AGENT_WRAPUP: state = s_wrapup; break; case CC_AGENT_INCALL: state = s_incall; break; default: state.s =0; state.len = 0; } attr = add_mi_attr( node, MI_DUP_VALUE, "State", 5, state.s, state.len ); } if (attr==NULL) goto error; } } lock_release( data->lock ); return rpl_tree; error: lock_release( data->lock ); return 0; }
static struct mi_root* mi_cc_list_queue(struct mi_root *cmd_tree, void *param) { struct mi_root *rpl_tree; struct mi_node *node; struct mi_attr *attr; struct mi_node *rpl; struct cc_call *call; unsigned int n, now; char *p; int len; str *s; rpl_tree = init_mi_tree( 200, MI_SSTR("OK") ); if ( rpl_tree==NULL) return NULL; rpl = &rpl_tree->node; rpl->flags |= MI_IS_ARRAY; n = 0; now = get_ticks(); /* block access to data */ lock_get( data->lock ); for ( call=data->queue.first ; call ; call=call->lower_in_queue, n++) { p = int2str( (unsigned long)n, &len); node = add_mi_node_child( rpl, MI_DUP_VALUE, "Call", 4, p, len); if (node==NULL) goto error; p = int2str( (unsigned long)(now-call->last_start), &len); attr = add_mi_attr( node, MI_DUP_VALUE, "Waiting for", 11, p, len); if (attr==NULL) goto error; p = int2str( (unsigned long)(call->eta), &len); attr = add_mi_attr( node, MI_DUP_VALUE, "ETW", 3, p, len); if (attr==NULL) goto error; /* flow data */ node = add_mi_node_child( node, MI_DUP_VALUE, "Flow", 4, call->flow->id.s, call->flow->id.len); if (node==NULL) goto error; p = int2str( (unsigned long)(call->flow->priority), &len); attr = add_mi_attr( node, MI_DUP_VALUE, "Priority", 8, p, len); if (attr==NULL) goto error; s = get_skill_by_id(data,call->flow->skill); if (s) { attr = add_mi_attr( node, MI_DUP_VALUE, "Skill", 5, s->s, s->len); if (attr==NULL) goto error; } } /* release the readers */ lock_release( data->lock ); return rpl_tree; error: lock_release( data->lock ); free_mi_tree(rpl_tree); return NULL; }
dbt_cache_p dbt_cache_get_db(str *_s) { dbt_cache_p _dcache=NULL;; if(!_dbt_cachesem || !_dbt_cachedb) { LM_ERR("dbtext cache is not initialized! Check if you loaded" " dbtext before any other module that uses it\n"); return NULL; } if(!_s || !_s->s || _s->len<=0) return NULL; LM_DBG("looking for db %.*s!\n",_s->len,_s->s); lock_get(_dbt_cachesem); _dcache = *_dbt_cachedb; while(_dcache) { if(_dcache->name.len==_s->len && !strncasecmp(_dcache->name.s, _s->s, _s->len)) { LM_DBG("db already cached!\n"); goto done; } _dcache = _dcache->next; } if(!dbt_is_database(_s)) { LM_ERR("database [%.*s] does not exists!\n", _s->len, _s->s); goto done; } LM_DBG("new db!\n"); _dcache = (dbt_cache_p)shm_malloc(sizeof(dbt_cache_t)); if(!_dcache) { LM_ERR(" no shm memory for dbt_cache_t.\n"); goto done; } memset(_dcache, 0, sizeof(dbt_cache_t)); _dcache->name.s = (char*)shm_malloc((_s->len+1)*sizeof(char)); if(!_dcache->name.s) { LM_ERR(" no shm memory for s!!\n"); shm_free(_dcache); _dcache = NULL; goto done; } memcpy(_dcache->name.s, _s->s, _s->len); _dcache->name.s[_s->len] = '\0'; _dcache->name.len = _s->len; if(*_dbt_cachedb) _dcache->next = *_dbt_cachedb; *_dbt_cachedb = _dcache; done: lock_release(_dbt_cachesem); return _dcache; }
void store_b2b_dlg(b2b_table htable, unsigned int hsize, int type, int no_lock) { int i; dlg_leg_t* leg; b2b_dlg_t* dlg; if (!b2be_dbf.init) return; qvals[0].val.int_val = type; //LM_DBG("storing b2b_entities type '%d' in db\n", type); if(b2be_dbf.use_table(b2be_db, &b2be_dbtable)< 0) { LM_ERR("sql use table failed\n"); return; } for(i = 0; i< hsize; i++) { if(!no_lock) lock_get(&htable[i].lock); dlg = htable[i].first; while(dlg) { if(dlg->state < B2B_CONFIRMED || dlg->db_flag == NO_UPDATEDB_FLAG) { dlg = dlg->next; continue; } qvals[1].val.str_val = dlg->tag[0]; qvals[2].val.str_val = dlg->tag[1]; qvals[3].val.str_val = dlg->callid; if(dlg->db_flag == INSERTDB_FLAG ) { qvals[4].val.str_val = dlg->ruri; qvals[5].val.str_val = dlg->from_uri; qvals[6].val.str_val = dlg->from_dname; qvals[7].val.str_val = dlg->to_uri; qvals[8].val.str_val = dlg->to_dname; qvals[9].val.str_val = dlg->route_set[0]; qvals[10].val.str_val= dlg->route_set[1]; if(dlg->send_sock) qvals[11].val.str_val= dlg->send_sock->sock_str; else { qvals[11].val.str_val.s = 0; qvals[11].val.str_val.len = 0; } qvals[12].val.str_val= dlg->param; } qvals[13].val.int_val = dlg->state; qvals[14].val.int_val = dlg->cseq[0]; qvals[15].val.int_val = dlg->cseq[1]; qvals[16].val.int_val = dlg->last_method; qvals[17].val.int_val = dlg->last_reply_code; qvals[18].val.int_val = dlg->last_invite_cseq; qvals[19].val.str_val = dlg->contact[0]; qvals[20].val.str_val = dlg->contact[1]; leg = dlg->legs; if(leg) /* there can only be one leg as we do not deal with dialogs in early state */ { qvals[21].val.str_val= leg->tag; qvals[22].val.int_val= leg->cseq; qvals[23].val.str_val= leg->contact; qvals[24].val.str_val= leg->route_set; } if(dlg->db_flag == INSERTDB_FLAG) { /* insert into database */ if(b2be_dbf.insert(b2be_db, qcols, qvals, DB_COLS_NO)< 0) { LM_ERR("Sql insert failed\n"); if(!no_lock) lock_release(&htable[i].lock); return; } } else { if(b2be_dbf.update(b2be_db, qcols, 0, qvals, qcols+n_start_update, qvals+n_start_update, n_query_update, DB_COLS_NO-n_start_update)< 0) { LM_ERR("Sql update failed\n"); if(!no_lock) lock_release(&htable[i].lock); return; } } dlg->db_flag = NO_UPDATEDB_FLAG; dlg = dlg->next; } if(!no_lock) lock_release(&htable[i].lock); } }
int wsconn_add(struct receive_info rcv, unsigned int sub_protocol) { int cur_cons, max_cons; int id = rcv.proto_reserved1; int id_hash = tcp_id_hash(id); ws_connection_t *wsc; LM_DBG("wsconn_add id [%d]\n", id); /* Allocate and fill in new WebSocket connection */ wsc = shm_malloc(sizeof(ws_connection_t) + BUF_SIZE); if (wsc == NULL) { LM_ERR("allocating shared memory\n"); return -1; } memset(wsc, 0, sizeof(ws_connection_t) + BUF_SIZE); wsc->id = id; wsc->id_hash = id_hash; wsc->state = WS_S_OPEN; wsc->rcv = rcv; wsc->sub_protocol = sub_protocol; wsc->run_event = 0; wsc->frag_buf.s = ((char*)wsc) + sizeof(ws_connection_t); atomic_set(&wsc->refcnt, 0); LM_DBG("wsconn_add new wsc => [%p], ref => [%d]\n", wsc, atomic_get(&wsc->refcnt)); WSCONN_LOCK; /* Add to WebSocket connection table */ wsconn_listadd(wsconn_id_hash[wsc->id_hash], wsc, id_next, id_prev); /* Add to the end of the WebSocket used list */ wsc->last_used = (int)time(NULL); if (wsconn_used_list->head == NULL) wsconn_used_list->head = wsconn_used_list->tail = wsc; else { wsc->used_prev = wsconn_used_list->tail; wsconn_used_list->tail->used_next = wsc; wsconn_used_list->tail = wsc; } wsconn_ref(wsc); WSCONN_UNLOCK; LM_DBG("wsconn_add added to conn_table wsc => [%p], ref => [%d]\n", wsc, atomic_get(&wsc->refcnt)); /* Update connection statistics */ lock_get(wsstat_lock); update_stat(ws_current_connections, 1); cur_cons = get_stat_val(ws_current_connections); max_cons = get_stat_val(ws_max_concurrent_connections); if (max_cons < cur_cons) update_stat(ws_max_concurrent_connections, cur_cons - max_cons); if (wsc->sub_protocol == SUB_PROTOCOL_SIP) { update_stat(ws_sip_current_connections, 1); cur_cons = get_stat_val(ws_sip_current_connections); max_cons = get_stat_val(ws_sip_max_concurrent_connections); if (max_cons < cur_cons) update_stat(ws_sip_max_concurrent_connections, cur_cons - max_cons); } else if (wsc->sub_protocol == SUB_PROTOCOL_MSRP) { update_stat(ws_msrp_current_connections, 1); cur_cons = get_stat_val(ws_msrp_current_connections); max_cons = get_stat_val(ws_msrp_max_concurrent_connections); if (max_cons < cur_cons) update_stat(ws_msrp_max_concurrent_connections, cur_cons - max_cons); } lock_release(wsstat_lock); return 0; }
void releaseUser(struct lock *lock){ lock_release(lock); }
/** * UnLocks the dialog counter variable */ inline void s_dialog_count_unlock() { lock_release(scscf_dialog_count_lock); }
static void mdd_lockdep_pd_release(struct mdd_object *obj) { lock_release(&obj->dep_map, 0, RETIP); }
void timer_send_notify(unsigned int ticks,void *param) { db_key_t query_cols[2], update_cols[1], result_cols[7]; db_val_t query_vals[2], update_vals[1]; int did_col, resource_uri_col, auth_state_col, reason_col, body_col, ctype_col; int n_result_cols= 0, i; db_res_t *result= NULL; char* prev_did= NULL, * curr_did= NULL; db_row_t *row; db_val_t *row_vals; char* resource_uri; str body; str callid, to_tag, from_tag; xmlDocPtr rlmi_doc= NULL; xmlNodePtr list_node= NULL, instance_node= NULL, resource_node; unsigned int hash_code= 0; int len; int size= BUF_REALLOC_SIZE, buf_len= 0; char* buf= NULL, *auth_state= NULL; int contor= 0, auth_state_flag; str bstr= {0, 0}; str rlmi_cont= {0, 0}, multi_cont; subs_t* s, *dialog= NULL; char* rl_uri= NULL; char* str_aux = NULL; str ctype, cid; int add_len; query_cols[0]= &str_updated_col; query_vals[0].type = DB_INT; query_vals[0].nul = 0; query_vals[0].val.int_val= UPDATED_TYPE; result_cols[did_col= n_result_cols++]= &str_rlsubs_did_col; result_cols[resource_uri_col= n_result_cols++]= &str_resource_uri_col; result_cols[auth_state_col= n_result_cols++]= &str_auth_state_col; result_cols[ctype_col= n_result_cols++]= &str_content_type_col; result_cols[reason_col= n_result_cols++]= &str_reason_col; result_cols[body_col= n_result_cols++]= &str_presence_state_col; /* query in alfabetical order after rlsusbs_did * (resource list Subscribe dialog indentifier)*/ if (rls_dbf.use_table(rls_db, &rlpres_table) < 0) { LM_ERR("in use_table\n"); goto done; } if(rls_dbf.query(rls_db, query_cols, 0, query_vals, result_cols, 1, n_result_cols, &str_rlsubs_did_col, &result)< 0) { LM_ERR("in sql query\n"); goto done; } if(result== NULL || result->n<= 0) goto done; /* update the rlpres table */ update_cols[0]= &str_updated_col; update_vals[0].type = DB_INT; update_vals[0].nul = 0; update_vals[0].val.int_val= NO_UPDATE_TYPE; if (rls_dbf.use_table(rls_db, &rlpres_table) < 0) { LM_ERR("in use_table\n"); goto error; } if(rls_dbf.update(rls_db, query_cols, 0, query_vals, update_cols, update_vals, 1, 1)< 0) { LM_ERR("in sql update\n"); goto error; } /* generate the boundary string */ bstr.s= generate_string((int)time(NULL), BOUNDARY_STRING_LEN); if(bstr.s == NULL) { LM_ERR("failed to generate random string\n"); goto error; } bstr.len= strlen(bstr.s); /* for the multipart body , use here also an initial allocated * and reallocated on need buffer */ buf= pkg_malloc(size); if(buf== NULL) { ERR_MEM(PKG_MEM_STR); } LM_DBG("found %d records with updated state\n", result->n); for(i= 0; i< result->n; i++) { row = &result->rows[i]; row_vals = ROW_VALUES(row); curr_did= (char*)row_vals[did_col].val.string_val; resource_uri= (char*)row_vals[resource_uri_col].val.string_val; auth_state_flag= row_vals[auth_state_col].val.int_val; body.s= (char*)row_vals[body_col].val.string_val; body.len= strlen(body.s); ctype.s = (char*)row_vals[ctype_col].val.string_val; ctype.len = strlen(ctype.s); /* if all the info for one dialog have been collected -> send notify */ /* the 'dialog' variable must be filled with the dialog info */ /* 'buf' must contain the body */ if(prev_did!= NULL && strcmp(prev_did, curr_did)) { xmlDocDumpMemory(rlmi_doc,(xmlChar**)(void*)&rlmi_cont.s, &rlmi_cont.len); multi_cont.s= buf; multi_cont.len= buf_len; if(agg_body_sendn_update(&dialog->pres_uri, bstr, &rlmi_cont, (buf_len==0)?NULL:&multi_cont, dialog, hash_code)<0) { LM_ERR("in function agg_body_sendn_update\n"); goto error; } xmlFree(rlmi_cont.s); xmlFreeDoc(rlmi_doc); rlmi_doc= NULL; pkg_free(rl_uri); rl_uri= NULL; pkg_free(dialog); dialog= NULL; } /* for the new dialog -> search the dialog info and * fill the dialog structure and start a new rlmi document */ if(prev_did== NULL || strcmp(prev_did, curr_did)) { /* search the subscription in rlsubs_table*/ if( parse_rlsubs_did(curr_did, &callid, &from_tag, &to_tag)< 0) { LM_ERR("bad format for " "resource list Subscribe dialog indentifier(rlsubs did)\n"); prev_did = NULL; continue; } hash_code= core_hash(&callid, &to_tag, hash_size); lock_get(&rls_table[hash_code].lock); s= pres_search_shtable(rls_table,callid,to_tag,from_tag,hash_code); if(s== NULL) { LM_DBG("record not found in hash_table [rlsubs_did]= %s\n", curr_did); LM_DBG("callid= %.*s\tfrom_tag= %.*s\tto_tag= %.*s\n", callid.len, callid.s,from_tag.len,from_tag.s, to_tag.len,to_tag.s); lock_release(&rls_table[hash_code].lock); prev_did = NULL; continue; } LM_DBG("Found rl-subs record in hash table\n"); /* save dialog info and rl_uri*/ dialog= pres_copy_subs(s, PKG_MEM_TYPE); if(dialog== NULL) { LM_ERR("while copying subs_t structure\n"); lock_release(&rls_table[hash_code].lock); goto done; } dialog->expires-= (int)time(NULL); lock_release(&rls_table[hash_code].lock); /* make new rlmi and multipart documents */ rlmi_doc= xmlNewDoc(BAD_CAST "1.0"); if(rlmi_doc== NULL) { LM_ERR("when creating new xml doc\n"); goto done; } list_node= xmlNewNode(NULL, BAD_CAST "list"); if(list_node== NULL) { LM_ERR("while creating new xml node\n"); goto done; } rl_uri= (char*)pkg_malloc((dialog->pres_uri.len+ 1)* sizeof(char)); if(rl_uri== NULL) { ERR_MEM(PKG_MEM_STR); } memcpy(rl_uri, dialog->pres_uri.s, dialog->pres_uri.len); rl_uri[dialog->pres_uri.len]= '\0'; xmlNewProp(list_node, BAD_CAST "uri", BAD_CAST rl_uri); xmlNewProp(list_node, BAD_CAST "xmlns", BAD_CAST "urn:ietf:params:xml:ns:rlmi"); xmlNewProp(list_node, BAD_CAST "version", BAD_CAST int2str(dialog->version, &len)); xmlNewProp(list_node, BAD_CAST "fullState", BAD_CAST "false"); xmlDocSetRootElement(rlmi_doc, list_node); buf_len= 0; /* !!!! for now I will include the auth state without checking if * it has changed - > in future chech if it works */ } /* add a node in rlmi_doc and if any presence state registered add * it in the buffer */ resource_node= xmlNewChild(list_node,NULL,BAD_CAST "resource", NULL); if(resource_node== NULL) { LM_ERR("when adding resource child\n"); goto done; } xmlNewProp(resource_node, BAD_CAST "uri", BAD_CAST resource_uri); /* there might be more records with the same uri- more instances- * search and add them all */ contor= 0; while(1) { contor++; cid.s= NULL; instance_node= xmlNewChild(resource_node, NULL, BAD_CAST "instance", NULL); if(instance_node== NULL) { LM_ERR("while adding instance child\n"); goto error; } str_aux = generate_string(contor, 8); if(str_aux == NULL) { LM_ERR("failed to create random string\n"); goto error; } xmlNewProp(instance_node, BAD_CAST "id", BAD_CAST str_aux); pkg_free(str_aux); auth_state= get_auth_string(auth_state_flag); if(auth_state== NULL) { LM_ERR("bad authorization status flag\n"); goto error; } xmlNewProp(instance_node, BAD_CAST "state", BAD_CAST auth_state); if(auth_state_flag & ACTIVE_STATE) { cid.s= generate_cid(resource_uri, strlen(resource_uri)); cid.len = strlen(cid.s); xmlNewProp(instance_node, BAD_CAST "cid", BAD_CAST cid.s); } else if(auth_state_flag & TERMINATED_STATE) { xmlNewProp(instance_node, BAD_CAST "reason", BAD_CAST row_vals[resource_uri_col].val.string_val); } /* add in the multipart buffer */ if(cid.s) { APPEND_MULTIPART_BODY(); pkg_free(cid.s); cid.s = NULL; } i++; if(i== result->n) { i--; break; } row = &result->rows[i]; row_vals = ROW_VALUES(row); if(strncmp(row_vals[resource_uri_col].val.string_val,resource_uri, strlen(resource_uri)) || strncmp(curr_did, row_vals[did_col].val.string_val, strlen(curr_did))) { i--; break; } resource_uri= (char*)row_vals[resource_uri_col].val.string_val; auth_state_flag= row_vals[auth_state_col].val.int_val; body.s= (char*)row_vals[body_col].val.string_val; body.len = strlen(body.s); } prev_did= curr_did; } if(rlmi_doc) { xmlDocDumpMemory( rlmi_doc,(xmlChar**)(void*)&rlmi_cont.s, &rlmi_cont.len); multi_cont.s= buf; multi_cont.len= buf_len; if(agg_body_sendn_update(&dialog->pres_uri, bstr, &rlmi_cont, (buf_len==0)?NULL:&multi_cont, dialog, hash_code)<0) { LM_ERR("in function agg_body_sendn_update\n"); goto error; } xmlFree(rlmi_cont.s); pkg_free(rl_uri); rl_uri= NULL; pkg_free(dialog); dialog= NULL; } error: done: if(result) rls_dbf.free_result(rls_db, result); if(rlmi_doc) xmlFreeDoc(rlmi_doc); if(rl_uri) pkg_free(rl_uri); if(bstr.s) pkg_free(bstr.s); if(buf) pkg_free(buf); if(dialog) pkg_free(dialog); return; }
/** * UnLocks the required slot of the dialog hash table * @param hash - index of the slot to unlock */ inline void d_unlock(unsigned int hash) { lock_release(s_dialogs[(hash)].lock); // LOG(L_CRIT,"RELEASED %d\n",hash); }
/** * Timer function for peer management. * This is registered as a timer by peer_manager_init() and gets called every * #PEER_MANAGER_TIMER seconds. Then it looks on what changed and triggers events. * @param now - time of call * @param ptr - generic pointer for timers - not used */ int peer_timer(time_t now,void *ptr) { peer *p,*n; int i; LM_DBG("peer_timer(): taking care of peers...\n"); lock_get(peer_list_lock); p = peer_list->head; while(p){ lock_get(p->lock); n = p->next; if (p->disabled && (p->state != Closed || p->state != Closing)) { LM_DBG("Peer [%.*s] has been disabled - shutting down\n", p->fqdn.len, p->fqdn.s); if (p->state == I_Open) sm_process(p, Stop, 0, 1, p->I_sock); if (p->state == R_Open) sm_process(p, Stop, 0, 1, p->R_sock); lock_release(p->lock); p = n; continue; } if (p->activity+config->tc<=now){ LM_INFO("peer_timer(): Peer %.*s \tState %d \n",p->fqdn.len,p->fqdn.s,p->state); switch (p->state){ /* initiating connection */ case Closed: if (p->is_dynamic && config->drop_unknown_peers){ remove_peer(p); free_peer(p,1); break; } if (!p->disabled) { touch_peer(p); sm_process(p,Start,0,1,0); } break; /* timeouts */ case Wait_Conn_Ack: case Wait_I_CEA: case Closing: case Wait_Returns: case Wait_Conn_Ack_Elect: touch_peer(p); sm_process(p,Timeout,0,1,0); break; /* inactivity detected */ case I_Open: case R_Open: if (p->waitingDWA){ p->waitingDWA = 0; if (p->state==I_Open) sm_process(p,I_Peer_Disc,0,1,p->I_sock); if (p->state==R_Open) sm_process(p,R_Peer_Disc,0,1,p->R_sock); LM_WARN("Inactivity on peer [%.*s] and no DWA, Closing peer...\n", p->fqdn.len, p->fqdn.s); } else { p->waitingDWA = 1; Snd_DWR(p); touch_peer(p); LM_DBG("Inactivity on peer [%.*s], sending DWR... - if we don't get a reply, the peer will be closed\n", p->fqdn.len, p->fqdn.s); } break; /* ignored states */ /* unknown states */ default: LM_ERR("peer_timer(): Peer %.*s inactive in state %d\n", p->fqdn.len,p->fqdn.s,p->state); } } lock_release(p->lock); p = n; } lock_release(peer_list_lock); log_peer_list(); i = config->tc/5; if (i<=0) i=1; return i; }
static void db_update(unsigned int ticks,void *param) { ua_pres_t* p= NULL; db_key_t q_cols[20], result_cols[1]; db1_res_t *res= NULL; db_key_t db_cols[5]; db_val_t q_vals[20], db_vals[5]; db_op_t db_ops[1] ; int n_query_cols= 0, n_query_update= 0; int n_update_cols= 0; int i; int puri_col,pid_col,expires_col,flag_col,etag_col,tuple_col,event_col; int watcher_col,callid_col,totag_col,fromtag_col,record_route_col,cseq_col; int no_lock= 0, contact_col, desired_expires_col, extra_headers_col; int remote_contact_col, version_col; if (dbmode==PUA_DB_ONLY) return; if(ticks== 0 && param == NULL) no_lock= 1; /* cols and values used for insert */ q_cols[puri_col= n_query_cols] = &str_pres_uri_col; q_vals[puri_col].type = DB1_STR; q_vals[puri_col].nul = 0; n_query_cols++; q_cols[pid_col= n_query_cols] = &str_pres_id_col; q_vals[pid_col].type = DB1_STR; q_vals[pid_col].nul = 0; n_query_cols++; q_cols[flag_col= n_query_cols] = &str_flag_col; q_vals[flag_col].type = DB1_INT; q_vals[flag_col].nul = 0; n_query_cols++; q_cols[event_col= n_query_cols] = &str_event_col; q_vals[event_col].type = DB1_INT; q_vals[event_col].nul = 0; n_query_cols++; q_cols[watcher_col= n_query_cols] = &str_watcher_uri_col; q_vals[watcher_col].type = DB1_STR; q_vals[watcher_col].nul = 0; n_query_cols++; q_cols[callid_col= n_query_cols] = &str_call_id_col; q_vals[callid_col].type = DB1_STR; q_vals[callid_col].nul = 0; n_query_cols++; q_cols[totag_col= n_query_cols] = &str_to_tag_col; q_vals[totag_col].type = DB1_STR; q_vals[totag_col].nul = 0; n_query_cols++; q_cols[fromtag_col= n_query_cols] = &str_from_tag_col; q_vals[fromtag_col].type = DB1_STR; q_vals[fromtag_col].nul = 0; n_query_cols++; q_cols[etag_col= n_query_cols] = &str_etag_col; q_vals[etag_col].type = DB1_STR; q_vals[etag_col].nul = 0; n_query_cols++; q_cols[tuple_col= n_query_cols] = &str_tuple_id_col; q_vals[tuple_col].type = DB1_STR; q_vals[tuple_col].nul = 0; n_query_cols++; q_cols[cseq_col= n_query_cols]= &str_cseq_col; q_vals[cseq_col].type = DB1_INT; q_vals[cseq_col].nul = 0; n_query_cols++; q_cols[expires_col= n_query_cols] = &str_expires_col; q_vals[expires_col].type = DB1_INT; q_vals[expires_col].nul = 0; n_query_cols++; q_cols[desired_expires_col= n_query_cols] = &str_desired_expires_col; q_vals[desired_expires_col].type = DB1_INT; q_vals[desired_expires_col].nul = 0; n_query_cols++; q_cols[record_route_col= n_query_cols] = &str_record_route_col; q_vals[record_route_col].type = DB1_STR; q_vals[record_route_col].nul = 0; n_query_cols++; q_cols[contact_col= n_query_cols] = &str_contact_col; q_vals[contact_col].type = DB1_STR; q_vals[contact_col].nul = 0; n_query_cols++; q_cols[remote_contact_col= n_query_cols] = &str_remote_contact_col; q_vals[remote_contact_col].type = DB1_STR; q_vals[remote_contact_col].nul = 0; n_query_cols++; q_cols[version_col= n_query_cols] = &str_version_col; q_vals[version_col].type = DB1_INT; q_vals[version_col].nul = 0; n_query_cols++; /* must keep this the last column to be inserted */ q_cols[extra_headers_col= n_query_cols] = &str_extra_headers_col; q_vals[extra_headers_col].type = DB1_STR; q_vals[extra_headers_col].nul = 0; n_query_cols++; /* cols and values used for update */ db_cols[0]= &str_expires_col; db_vals[0].type = DB1_INT; db_vals[0].nul = 0; db_cols[1]= &str_cseq_col; db_vals[1].type = DB1_INT; db_vals[1].nul = 0; db_cols[2]= &str_etag_col; db_vals[2].type = DB1_STR; db_vals[2].nul = 0; db_cols[3]= &str_desired_expires_col; db_vals[3].type = DB1_INT; db_vals[3].nul = 0; db_cols[4]= &str_version_col; db_vals[4].type = DB1_INT; db_vals[4].nul = 0; result_cols[0]= &str_expires_col; if(pua_db== NULL) { LM_ERR("null database connection\n"); return; } if(pua_dbf.use_table(pua_db, &db_table)< 0) { LM_ERR("in use table\n"); return ; } for(i=0; i<HASH_SIZE; i++) { if(!no_lock) lock_get(&HashT->p_records[i].lock); p = HashT->p_records[i].entity->next; while(p) { if((int)p->expires - (int)time(NULL)< 0) { p= p->next; continue; } switch(p->db_flag) { case NO_UPDATEDB_FLAG: { LM_DBG("NO_UPDATEDB_FLAG\n"); break; } case UPDATEDB_FLAG: { LM_DBG("UPDATEDB_FLAG\n"); n_update_cols= 0; n_query_update= 0; q_vals[puri_col].val.str_val = *(p->pres_uri); n_query_update++; q_vals[pid_col].val.str_val = p->id; n_query_update++; q_vals[flag_col].val.int_val = p->flag; n_query_update++; q_vals[event_col].val.int_val = p->event; n_query_update++; if(p->watcher_uri) { q_vals[watcher_col].val.str_val = *(p->watcher_uri); n_query_update++; q_vals[callid_col].val.str_val = p->call_id; n_query_update++; q_vals[totag_col].val.str_val = p->to_tag; n_query_update++; q_vals[fromtag_col].val.str_val = p->from_tag; n_query_update++; } db_vals[0].val.int_val= p->expires; n_update_cols++; db_vals[1].val.int_val= p->cseq ; n_update_cols++; db_vals[2].val.str_val= p->etag ; n_update_cols++; db_vals[3].val.int_val= p->desired_expires; n_update_cols++; db_vals[4].val.int_val= p->version; n_update_cols++; LM_DBG("Updating:n_query_update= %d\tn_update_cols= %d\n", n_query_update, n_update_cols); if(pua_dbf.query(pua_db, q_cols, 0, q_vals, result_cols, n_query_update, 1, 0, &res)< 0) { LM_ERR("while querying db table pua\n"); if(!no_lock) lock_release(&HashT->p_records[i].lock); if(res) pua_dbf.free_result(pua_db, res); return ; } if(res && res->n> 0) { if(pua_dbf.update(pua_db, q_cols, 0, q_vals, db_cols, db_vals, n_query_update, n_update_cols)<0) { LM_ERR("while updating in database\n"); if(!no_lock) lock_release(&HashT->p_records[i].lock); pua_dbf.free_result(pua_db, res); res= NULL; return ; } pua_dbf.free_result(pua_db, res); res= NULL; } else { if(res) { pua_dbf.free_result(pua_db, res); res= NULL; } LM_DBG("UPDATEDB_FLAG and no record found\n"); // p->db_flag= INSERTDB_FLAG; } break; } case INSERTDB_FLAG: { LM_DBG("INSERTDB_FLAG\n"); q_vals[puri_col].val.str_val = *(p->pres_uri); q_vals[pid_col].val.str_val = p->id; q_vals[flag_col].val.int_val = p->flag; if(p->call_id.s) { LM_DBG("p->callid = %.*s\n", p->call_id.len, p->call_id.s); q_vals[callid_col].val.str_val = p->call_id; } else { LM_DBG("p->callid is empty\n"); q_vals[callid_col].val.str_val.s = ""; q_vals[callid_col].val.str_val.len = 0; } q_vals[fromtag_col].val.str_val = p->from_tag; q_vals[cseq_col].val.int_val= p->cseq; q_vals[expires_col].val.int_val = p->expires; q_vals[desired_expires_col].val.int_val = p->desired_expires; q_vals[event_col].val.int_val = p->event; q_vals[version_col].val.int_val = p->version; if((p->watcher_uri)) q_vals[watcher_col].val.str_val = *(p->watcher_uri); else { q_vals[watcher_col].val.str_val.s = ""; q_vals[watcher_col].val.str_val.len = 0; } if(p->tuple_id.s == NULL) { q_vals[tuple_col].val.str_val.s=""; q_vals[tuple_col].val.str_val.len=0; } else q_vals[tuple_col].val.str_val = p->tuple_id; if(p->etag.s == NULL) { q_vals[etag_col].val.str_val.s=""; q_vals[etag_col].val.str_val.len=0; } else q_vals[etag_col].val.str_val = p->etag; if (p->to_tag.s == NULL) { q_vals[totag_col].val.str_val.s=""; q_vals[totag_col].val.str_val.len=0; } else q_vals[totag_col].val.str_val = p->to_tag; if(p->record_route.s== NULL) { q_vals[record_route_col].val.str_val.s= ""; q_vals[record_route_col].val.str_val.len = 0; } else q_vals[record_route_col].val.str_val = p->record_route; if(p->contact.s == NULL) { q_vals[contact_col].val.str_val.s = ""; q_vals[contact_col].val.str_val.len = 0; } else q_vals[contact_col].val.str_val = p->contact; if(p->remote_contact.s) { q_vals[remote_contact_col].val.str_val = p->remote_contact; LM_DBG("p->remote_contact = %.*s\n", p->remote_contact.len, p->remote_contact.s); } else { q_vals[remote_contact_col].val.str_val.s = ""; q_vals[remote_contact_col].val.str_val.len = 0; } if(p->extra_headers) q_vals[extra_headers_col].val.str_val = *(p->extra_headers); else { q_vals[extra_headers_col].val.str_val.s = ""; q_vals[extra_headers_col].val.str_val.len = 0; } if(pua_dbf.insert(pua_db, q_cols, q_vals,n_query_cols )<0) { LM_ERR("while inserting in db table pua\n"); if(!no_lock) lock_release(&HashT->p_records[i].lock); return ; } break; } } p->db_flag= NO_UPDATEDB_FLAG; p= p->next; } if(!no_lock) lock_release(&HashT->p_records[i].lock); } db_vals[0].val.int_val= (int)time(NULL)- 10; db_ops[0]= OP_LT; if(pua_dbf.delete(pua_db, db_cols, db_ops, db_vals, 1) < 0) { LM_ERR("while deleting from db table pua\n"); } return ; }
static int db_restore(void) { ua_pres_t* p= NULL; db_key_t result_cols[19]; db1_res_t *res= NULL; db_row_t *row = NULL; db_val_t *row_vals= NULL; str pres_uri, pres_id; str etag, tuple_id; str watcher_uri, call_id; str to_tag, from_tag, remote_contact; str record_route, contact, extra_headers; int size= 0, i; int n_result_cols= 0; int puri_col,pid_col,expires_col,flag_col,etag_col, desired_expires_col; int watcher_col,callid_col,totag_col,fromtag_col,cseq_col,remote_contact_col; int event_col,contact_col,tuple_col,record_route_col, extra_headers_col; int version_col; unsigned int hash_code; if (dbmode==PUA_DB_ONLY) { LM_ERR( "db_restore shouldn't be called in PUA_DB_ONLY mode\n" ); return(-1); } result_cols[puri_col=n_result_cols++] = &str_pres_uri_col; result_cols[pid_col=n_result_cols++] = &str_pres_id_col; result_cols[expires_col=n_result_cols++]= &str_expires_col; result_cols[flag_col=n_result_cols++] = &str_flag_col; result_cols[etag_col=n_result_cols++] = &str_etag_col; result_cols[tuple_col=n_result_cols++] = &str_tuple_id_col; result_cols[watcher_col=n_result_cols++]= &str_watcher_uri_col; result_cols[callid_col=n_result_cols++] = &str_call_id_col; result_cols[totag_col=n_result_cols++] = &str_to_tag_col; result_cols[fromtag_col=n_result_cols++]= &str_from_tag_col; result_cols[cseq_col= n_result_cols++] = &str_cseq_col; result_cols[event_col= n_result_cols++] = &str_event_col; result_cols[record_route_col= n_result_cols++] = &str_record_route_col; result_cols[contact_col= n_result_cols++] = &str_contact_col; result_cols[remote_contact_col= n_result_cols++] = &str_remote_contact_col; result_cols[extra_headers_col= n_result_cols++] = &str_extra_headers_col; result_cols[desired_expires_col= n_result_cols++] = &str_desired_expires_col; result_cols[version_col= n_result_cols++] = &str_version_col; if(!pua_db) { LM_ERR("null database connection\n"); return -1; } if(pua_dbf.use_table(pua_db, &db_table)< 0) { LM_ERR("in use table\n"); return -1; } if(db_fetch_query(&pua_dbf, pua_fetch_rows, pua_db, 0, 0, 0, result_cols, 0, n_result_cols, 0, &res)< 0) { LM_ERR("while querrying table\n"); if(res) { pua_dbf.free_result(pua_db, res); res = NULL; } return -1; } if(res==NULL) return -1; if(res->n<=0) { LM_INFO("the query returned no result\n"); pua_dbf.free_result(pua_db, res); res = NULL; return 0; } do { LM_DBG("found %d db entries\n", res->n); for(i =0 ; i< res->n ; i++) { row = &res->rows[i]; row_vals = ROW_VALUES(row); pres_uri.s= (char*)row_vals[puri_col].val.string_val; pres_uri.len = strlen(pres_uri.s); LM_DBG("pres_uri= %.*s\n", pres_uri.len, pres_uri.s); memset(&etag, 0, sizeof(str)); memset(&tuple_id, 0, sizeof(str)); memset(&watcher_uri, 0, sizeof(str)); memset(&call_id, 0, sizeof(str)); memset(&to_tag, 0, sizeof(str)); memset(&from_tag, 0, sizeof(str)); memset(&record_route, 0, sizeof(str)); memset(&pres_id, 0, sizeof(str)); memset(&contact, 0, sizeof(str)); memset(&remote_contact, 0, sizeof(str)); memset(&extra_headers, 0, sizeof(str)); pres_id.s= (char*)row_vals[pid_col].val.string_val; if(pres_id.s) pres_id.len = strlen(pres_id.s); if(row_vals[etag_col].val.string_val) { etag.s= (char*)row_vals[etag_col].val.string_val; etag.len = strlen(etag.s); tuple_id.s= (char*)row_vals[tuple_col].val.string_val; tuple_id.len = strlen(tuple_id.s); } if(row_vals[watcher_col].val.string_val) { watcher_uri.s= (char*)row_vals[watcher_col].val.string_val; watcher_uri.len = strlen(watcher_uri.s); call_id.s= (char*)row_vals[callid_col].val.string_val; call_id.len = strlen(call_id.s); to_tag.s= (char*)row_vals[totag_col].val.string_val; to_tag.len = strlen(to_tag.s); from_tag.s= (char*)row_vals[fromtag_col].val.string_val; from_tag.len = strlen(from_tag.s); if(row_vals[record_route_col].val.string_val) { record_route.s= (char*)row_vals[record_route_col].val.string_val; record_route.len= strlen(record_route.s); } contact.s= (char*)row_vals[contact_col].val.string_val; contact.len = strlen(contact.s); remote_contact.s= (char*)row_vals[remote_contact_col].val.string_val; remote_contact.len = strlen(remote_contact.s); } extra_headers.s= (char*)row_vals[extra_headers_col].val.string_val; if(extra_headers.s) extra_headers.len= strlen(extra_headers.s); else extra_headers.len= 0; size= sizeof(ua_pres_t)+ sizeof(str)+ (pres_uri.len+ pres_id.len+ tuple_id.len)* sizeof(char); if(extra_headers.s) size+= sizeof(str)+ extra_headers.len* sizeof(char); if(watcher_uri.s) size+= sizeof(str)+ (watcher_uri.len+ call_id.len+ to_tag.len+ from_tag.len+ record_route.len+ contact.len)* sizeof(char); p= (ua_pres_t*)shm_malloc(size); if(p== NULL) { LM_ERR("no more share memmory"); goto error; } memset(p, 0, size); size= sizeof(ua_pres_t); p->pres_uri= (str*)((char*)p+ size); size+= sizeof(str); p->pres_uri->s= (char*)p + size; memcpy(p->pres_uri->s, pres_uri.s, pres_uri.len); p->pres_uri->len= pres_uri.len; size+= pres_uri.len; if(pres_id.s) { p->id.s= (char*)p + size; memcpy(p->id.s, pres_id.s, pres_id.len); p->id.len= pres_id.len; size+= pres_id.len; } if(tuple_id.s && tuple_id.len) { p->tuple_id.s= (char*)p + size; memcpy(p->tuple_id.s, tuple_id.s, tuple_id.len); p->tuple_id.len= tuple_id.len; size+= tuple_id.len; } if(watcher_uri.s && watcher_uri.len) { p->watcher_uri= (str*)((char*)p+ size); size+= sizeof(str); p->watcher_uri->s= (char*)p+ size; memcpy(p->watcher_uri->s, watcher_uri.s, watcher_uri.len); p->watcher_uri->len= watcher_uri.len; size+= watcher_uri.len; p->to_tag.s= (char*)p+ size; memcpy(p->to_tag.s, to_tag.s, to_tag.len); p->to_tag.len= to_tag.len; size+= to_tag.len; p->from_tag.s= (char*)p+ size; memcpy(p->from_tag.s, from_tag.s, from_tag.len); p->from_tag.len= from_tag.len; size+= from_tag.len; p->call_id.s= (char*)p + size; memcpy(p->call_id.s, call_id.s, call_id.len); p->call_id.len= call_id.len; size+= call_id.len; if(record_route.s && record_route.len) { p->record_route.s= (char*)p + size; memcpy(p->record_route.s, record_route.s, record_route.len); p->record_route.len= record_route.len; size+= record_route.len; } p->contact.s= (char*)p + size; memcpy(p->contact.s, contact.s, contact.len); p->contact.len= contact.len; size+= contact.len; p->cseq= row_vals[cseq_col].val.int_val; p->remote_contact.s= (char*)shm_malloc(remote_contact.len* sizeof(char)); if(p->remote_contact.s== NULL) { LM_ERR("No more shared memory\n"); goto error; } memcpy(p->remote_contact.s, remote_contact.s, remote_contact.len); p->remote_contact.len= remote_contact.len; p->version= row_vals[version_col].val.int_val; } if(extra_headers.s) { p->extra_headers= (str*)((char*)p+ size); size+= sizeof(str); p->extra_headers->s= (char*)p+ size; memcpy(p->extra_headers->s, extra_headers.s, extra_headers.len); p->extra_headers->len= extra_headers.len; size+= extra_headers.len; } LM_DBG("size= %d\n", size); p->event= row_vals[event_col].val.int_val; p->expires= row_vals[expires_col].val.int_val; p->desired_expires= row_vals[desired_expires_col].val.int_val; p->flag|= row_vals[flag_col].val.int_val; memset(&p->etag, 0, sizeof(str)); if(etag.s && etag.len) { /* alloc separately */ p->etag.s= (char*)shm_malloc(etag.len* sizeof(char)); if(p->etag.s== NULL) { LM_ERR("no more share memory\n"); goto error; } memcpy(p->etag.s, etag.s, etag.len); p->etag.len= etag.len; } print_ua_pres(p); hash_code= core_hash(p->pres_uri, p->watcher_uri, HASH_SIZE); lock_get(&HashT->p_records[hash_code].lock); insert_htable(p, hash_code); lock_release(&HashT->p_records[hash_code].lock); } } while((db_fetch_next(&pua_dbf, pua_fetch_rows, pua_db, &res)==1) && (RES_ROW_N(res)>0)); pua_dbf.free_result(pua_db, res); res = NULL; if(pua_dbf.delete(pua_db, 0, 0 , 0, 0) < 0) { LM_ERR("while deleting information from db\n"); goto error; } return 0; error: if(res) pua_dbf.free_result(pua_db, res); if(p) shm_free(p); return -1; }
static int b2bl_add_tuple(b2bl_tuple_t* tuple, str* params[]) { b2bl_tuple_t* shm_tuple= NULL; unsigned int hash_index, local_index; str* b2bl_key; b2bl_entity_id_t* entity; int i; b2b_notify_t cback; str* client_id = NULL; unsigned int logic_restored = 0; LM_DBG("Add tuple key [%.*s]\n", tuple->key->len, tuple->key->s); if(b2bl_parse_key(tuple->key, &hash_index, &local_index)< 0) { LM_ERR("Wrong formatted b2b logic key\n"); return -1; } shm_tuple = b2bl_insert_new(NULL, hash_index, tuple->scenario, params, (tuple->sdp.s?&tuple->sdp:NULL), NULL, local_index, &b2bl_key, UPDATEDB_FLAG); if(shm_tuple == NULL) { LM_ERR("Failed to insert new tuple\n"); return -1; } shm_tuple->lifetime = tuple->lifetime; lock_release(&b2bl_htable[hash_index].lock); shm_tuple->scenario_state= tuple->scenario_state; shm_tuple->next_scenario_state= tuple->next_scenario_state; /* add entities */ for(i=0; i< MAX_BRIDGE_ENT; i++) { if(!tuple->bridge_entities[i]->to_uri.len) continue; LM_DBG("Restore logic info for tuple:entity [%.*s][%d]\n", b2bl_key->len, b2bl_key->s, i); if(tuple->bridge_entities[i]->type == B2B_SERVER) cback = b2b_server_notify; else cback = b2b_client_notify; /* restore to the entities from b2b_entities module * the parameter and callback function */ if(b2b_api.restore_logic_info(tuple->bridge_entities[i]->type, &tuple->bridge_entities[i]->key, cback)< 0) LM_WARN("Failed to restore logic info for tuple:entity [%.*s][%d]\n", b2bl_key->len, b2bl_key->s, i); else logic_restored = 1; entity= b2bl_create_new_entity(tuple->bridge_entities[i]->type, &tuple->bridge_entities[i]->key,&tuple->bridge_entities[i]->to_uri, &tuple->bridge_entities[i]->from_uri, 0, &tuple->bridge_entities[i]->scenario_id, 0); if(client_id) pkg_free(client_id); if(entity == NULL) { LM_ERR("Failed to create entity %d\n", i); goto error; } shm_tuple->bridge_entities[i]= entity; /* put the pointer in clients or servers array */ // FIXME: check if the restore logic is ok if(tuple->bridge_entities[i]->type == B2B_SERVER) { if (shm_tuple->servers[0]) shm_tuple->servers[1] = entity; else shm_tuple->servers[0] = entity; } else { if (shm_tuple->clients[0]) shm_tuple->clients[1] = entity; else shm_tuple->clients[0] = entity; } } if(shm_tuple->bridge_entities[1]) shm_tuple->bridge_entities[1]->peer = shm_tuple->bridge_entities[0]; if(shm_tuple->bridge_entities[0]) shm_tuple->bridge_entities[0]->peer = shm_tuple->bridge_entities[1]; /* Mark tuple without entities as expired */ if(logic_restored==0) shm_tuple->lifetime = 1; return 0; error: shm_free(shm_tuple); return -1; }
int as_copy(struct addrspace *old, struct addrspace **ret) { struct addrspace *newas; newas = as_create(); if (newas==NULL) { return ENOMEM; } // kprintf(" **** inside as copy **** \n"); // spinlock_acquire(newas->as_splock); // spinlock_acquire(old->as_splock); if(use_small_lock == true && swapping_started == true) { lock_acquire(newas->as_lock); lock_acquire(old->as_lock); } else if(use_big_lock == true && swapping_started == true) lock_acquire(as_lock); struct as_region* r_old = old->as_region_list; while(r_old != NULL) { struct as_region* r_new = (struct as_region*)kmalloc(sizeof(struct as_region)); if(r_new == NULL) { if(use_big_lock == true && swapping_started == true) lock_release(as_lock); else if(use_small_lock == true && swapping_started == true) { lock_release(old->as_lock); lock_release(newas->as_lock); } //spinlock_release(old->as_splock); //spinlock_release(newas->as_splock); as_destroy(newas); return ENOMEM; } r_new->region_base = r_old->region_base; r_new->region_npages = r_old->region_npages; r_new->can_read = r_old->can_read; r_new->can_write = r_old->can_write; r_new->can_execute = r_old->can_execute; int ret = region_list_add_node(&newas->as_region_list,r_new); if(ret == -1) { if(use_big_lock == true && swapping_started == true) lock_release(as_lock); else if(use_small_lock == true && swapping_started == true) { lock_release(old->as_lock); lock_release(newas->as_lock); } // spinlock_release(old->as_splock); // spinlock_release(newas->as_splock); as_destroy(newas); return ENOMEM; } r_old = r_old->next; } struct page_table_entry* p_old = old->as_page_list; while(p_old != NULL) { struct page_table_entry* p_new = (struct page_table_entry*)kmalloc(sizeof(struct page_table_entry)); if(p_new == NULL) { if(use_big_lock == true && swapping_started == true) lock_release(as_lock); else if(use_small_lock == true && swapping_started == true) { lock_release(old->as_lock); lock_release(newas->as_lock); } // spinlock_release(old->as_splock); // spinlock_release(newas->as_splock); as_destroy(newas); return ENOMEM; } p_new->vaddr = p_old->vaddr; p_new->swap_pos = -1; KASSERT(p_old->page_state != SWAPPING); while(p_old->page_state == SWAPPING) { thread_yield(); } // if(!spinlock_do_i_hold) // KASSERT(p_old->page_state != SWAPPING); if(p_old->page_state == MAPPED) { if(use_page_lock == true && swapping_started == true) lock_acquire(coremap[(p_old->paddr)/PAGE_SIZE].page_lock); if(p_old->page_state == MAPPED) { paddr_t paddr = get_user_page(p_old->vaddr, false, newas); KASSERT(p_old->page_state == MAPPED); // int spl = splhigh(); if(use_small_lock == true && swapping_started == true) { if(lock_do_i_hold(newas->as_lock) == false) lock_acquire(newas->as_lock); if(lock_do_i_hold(old->as_lock) == false) lock_acquire(newas->as_lock); } else if(use_big_lock == true && swapping_started == true) { if(lock_do_i_hold(as_lock) == false) lock_acquire(as_lock); } if(paddr == 0) { if(use_big_lock == true && swapping_started == true) lock_release(as_lock); else if(use_small_lock == true && swapping_started == true) { lock_release(old->as_lock); lock_release(newas->as_lock); } // spinlock_release(old->as_splock); // spinlock_release(newas->as_splock); as_destroy(newas); return ENOMEM; } uint32_t old_index = p_old->paddr/PAGE_SIZE; KASSERT(coremap[old_index].is_victim == false); KASSERT(coremap[paddr/PAGE_SIZE].is_victim == false); memmove((void*)PADDR_TO_KVADDR(paddr), (const void *)PADDR_TO_KVADDR(p_old->paddr), //use this? or PADDR_TO_KVADDR like dumbvm does?. But why does dumbvm do that in the first place. PAGE_SIZE); // i know why, cannot call functions on user memory addresses. So convert it into a kv address. // the function will translate it into a physical address again and free it. ugly Hack. but no other way. p_new->paddr = paddr; p_new->page_state = MAPPED; // splx(spl); int ret = page_list_add_node(&newas->as_page_list,p_new); if(ret == -1) { if(use_big_lock == true && swapping_started == true) lock_release(as_lock); else if(use_small_lock == true && swapping_started == true) { lock_release(old->as_lock); lock_release(newas->as_lock); } // spinlock_release(old->as_splock); // spinlock_release(newas->as_splock); as_destroy(newas); return ENOMEM; } if(use_page_lock == true && swapping_started == true) { if(lock_do_i_hold(coremap[paddr/PAGE_SIZE].page_lock) == true) lock_release(coremap[paddr/PAGE_SIZE].page_lock); if(lock_do_i_hold(coremap[(p_old->paddr/PAGE_SIZE)].page_lock) == true) lock_release(coremap[(p_old->paddr/PAGE_SIZE)].page_lock); } } } if(p_old->page_state == SWAPPED) { // this page is in disk, so we need to create a copy of that page somewhere in disk and then update the page table entry of the new process. // going with the disk->memory->disk approach suggested in a recitation video by jinghao shi. // Allocate a buffer at vm_bootstrap of size 4k (1 page). Use this buffer to temporarily copy data from disk to here and then to disk again // then clear the buffer. This buffer is a shared resource, so we need a lock around it. // kprintf("in as_copy swap code \n"); // spinlock_release(old->as_splock); // spinlock_release(newas->as_splock); swap_in(p_old->vaddr,old,copy_buffer_vaddr, p_old->swap_pos); // kprintf("completed swap in \n"); int pos = mark_swap_pos(p_new->vaddr, newas); KASSERT(pos != -1); int err = write_to_disk(KVADDR_TO_PADDR(copy_buffer_vaddr)/PAGE_SIZE, pos); // kprintf("completed writing to disk \n"); KASSERT(err == 0); // spinlock_acquire(newas->as_splock); // spinlock_acquire(old->as_splock); // as_zero_region(KVADDR_TO_PADDR(copy_buffer_vaddr),1); p_new->page_state = SWAPPED; p_new->swap_pos = pos; p_new->paddr = 0; if(use_page_lock == true && swapping_started == true) { if(lock_do_i_hold(coremap[(p_old->paddr/PAGE_SIZE)].page_lock) == true) lock_release(coremap[(p_old->paddr/PAGE_SIZE)].page_lock); } } p_old = p_old->next; } newas->as_heap_start = old->as_heap_start; newas->as_heap_end = old->as_heap_end; *ret = newas; if(use_big_lock == true && swapping_started == true) lock_release(as_lock); else if(use_small_lock == true && swapping_started == true) { lock_release(old->as_lock); lock_release(newas->as_lock); } // kprintf("exiting as copy \n"); // spinlock_release(old->as_splock); // spinlock_release(newas->as_splock); return 0; }
/* * Create a semaphore. */ static int semfs_creat(struct vnode *dirvn, const char *name, bool excl, mode_t mode, struct vnode **resultvn) { struct semfs_vnode *dirsemv = dirvn->vn_data; struct semfs *semfs = dirsemv->semv_semfs; struct semfs_direntry *dent; struct semfs_sem *sem; unsigned i, num, empty, semnum; int result; (void)mode; if (!strcmp(name, ".") || !strcmp(name, "..")) { return EEXIST; } lock_acquire(semfs->semfs_dirlock); num = semfs_direntryarray_num(semfs->semfs_dents); empty = num; for (i=0; i<num; i++) { dent = semfs_direntryarray_get(semfs->semfs_dents, i); if (dent == NULL) { if (empty == num) { empty = i; } continue; } if (!strcmp(dent->semd_name, name)) { /* found */ if (excl) { lock_release(semfs->semfs_dirlock); return EEXIST; } result = semfs_getvnode(semfs, dent->semd_semnum, resultvn); lock_release(semfs->semfs_dirlock); return result; } } /* create it */ sem = semfs_sem_create(name); if (sem == NULL) { result = ENOMEM; goto fail_unlock; } lock_acquire(semfs->semfs_tablelock); result = semfs_sem_insert(semfs, sem, &semnum); lock_release(semfs->semfs_tablelock); if (result) { goto fail_uncreate; } dent = semfs_direntry_create(name, semnum); if (dent == NULL) { goto fail_uninsert; } if (empty < num) { semfs_direntryarray_set(semfs->semfs_dents, empty, dent); } else { result = semfs_direntryarray_add(semfs->semfs_dents, dent, &empty); if (result) { goto fail_undent; } } result = semfs_getvnode(semfs, semnum, resultvn); if (result) { goto fail_undir; } sem->sems_linked = true; lock_release(semfs->semfs_dirlock); return 0; fail_undir: semfs_direntryarray_set(semfs->semfs_dents, empty, NULL); fail_undent: semfs_direntry_destroy(dent); fail_uninsert: lock_acquire(semfs->semfs_tablelock); semfs_semarray_set(semfs->semfs_sems, semnum, NULL); lock_release(semfs->semfs_tablelock); fail_uncreate: semfs_sem_destroy(sem); fail_unlock: lock_release(semfs->semfs_dirlock); return result; }
void __stdcall sniffer_receive(DWORD_PTR Param, DWORD_PTR ThParam, HANDLE hPacket, LPVOID pPacketData, DWORD IncPacketSize) { CaptureJob *j; HANDLE pkt; unsigned char *pktbuf; unsigned char *pktmax; struct eth_hdr *eth; struct ip_hdr *ip; struct tcp_hdr *tcp; // struct udp_hdr *udp; j = (CaptureJob *)Param; pktbuf = (unsigned char *)pPacketData; pktmax = pktbuf + IncPacketSize; // Only process active jobs if(!j->active) return; // Traffic filtering goes here do { // Skip matching on short packets if(IncPacketSize < ETH_HDR_LEN + IP_HDR_LEN + TCP_HDR_LEN) { dprintf("sniffer>> skipping exclusion because the packet is too small"); break; } // Match IP packets if(!peername4) { dprintf("sniffer>> skipping exclusion because peername4 is not defined"); break; } // Skip non-IP packets eth = (struct eth_hdr *) pktbuf; if(ntohs(eth->eth_type) != ETH_TYPE_IP) { dprintf("sniffer>> skipping non-IP packet from filter"); break; } // Skip non-TCP/UDP packets ip = (struct ip_hdr *) &pktbuf[ETH_HDR_LEN]; if(ip->ip_p != IP_PROTO_TCP && ip->ip_p != IP_PROTO_UDP) { dprintf("sniffer>> skipping non-TCP/UDP packet from filter: %d", ip->ip_p); break; } if(ip->ip_p == IP_PROTO_TCP) { tcp = (struct tcp_hdr *) &pktbuf[ETH_HDR_LEN + (ip->ip_hl * 4)]; if( (unsigned char *)tcp + TCP_HDR_LEN > pktmax) { dprintf("sniffer>> TCP packet is too short"); break; } // Ignore our own control session's traffic if ( (memcmp(&ip->ip_src, &peername4->sin_addr, 4) == 0 && tcp->th_sport == peername4->sin_port) || (memcmp(&ip->ip_dst, &peername4->sin_addr, 4) == 0 && tcp->th_dport == peername4->sin_port) ) { return; } // TODO: Scan through a list of included/excluded ports } // All done matching exclusions } while(0); // Thread-synchronized access to the queue // -- PKS, per job locking would be finer grained. // however, it probably doesn't matter. lock_acquire(snifferm); if(j->idx_pkts >= j->max_pkts) j->idx_pkts = 0; j->cur_pkts++; j->cur_bytes += IncPacketSize; pkt = PktCreate(j->mtu); PktCopyPacketToPacket(pkt, hPacket); if(j->pkts[j->idx_pkts]) PktDestroy(j->pkts[j->idx_pkts]); j->pkts[j->idx_pkts] = pkt; j->idx_pkts++; lock_release(snifferm); }
void cmd_pipe_cb(int fd, short event, void *arg) { struct jsonrpc_pipe_cmd *cmd; if (read(fd, &cmd, sizeof(cmd)) != sizeof(cmd)) { ERR("FATAL ERROR: failed to read from command pipe: %s\n", strerror(errno)); return; } switch(cmd->type) { case CMD_CLOSE: if(cmd->server) { wait_close(cmd->server); } goto end; break; case CMD_RECONNECT: if(cmd->server) { wait_reconnect(cmd->server); } goto end; break; case CMD_CONNECT: if(cmd->server) { bev_connect(cmd->server); } goto end; break; case CMD_UPDATE_SERVER_GROUP: if(cmd->new_grp) { jsonrpc_server_group_t* old_grp = *global_server_group; *global_server_group = cmd->new_grp; free_server_group(&old_grp); } lock_release(jsonrpc_server_group_lock); goto end; break; case CMD_SEND: break; default: ERR("Unrecognized pipe command: %d\n", cmd->type); goto end; break; } /* command is SEND */ jsonrpc_req_cmd_t* req_cmd = cmd->req_cmd; if(req_cmd == NULL) { ERR("req_cmd is NULL. Invalid send command\n"); goto end; } jsonrpc_request_t* req = NULL; req = create_request(req_cmd); if (!req || !req->payload) { json_t* error = internal_error(JRPC_ERR_REQ_BUILD, NULL); pv_value_t val; char* freeme = NULL; jsontoval(&val, &freeme, error); if(req_cmd->route.len <=0 && send_to_script(&val, req_cmd)<0) { ERR("Failed to build request (method: %.*s, params: %.*s)\n", STR(req_cmd->method), STR(req_cmd->params)); } if(freeme) free(freeme); if(error) json_decref(error); free_req_cmd(req_cmd); goto end; } int sent = jsonrpc_send(req_cmd->conn, req, req_cmd->notify_only); char* type; if (sent<0) { if (req_cmd->notify_only == false) { type = "Request"; } else { type = "Notification"; } WARN("%s could not be sent to connection group: %.*s\n", type, STR(req_cmd->conn)); fail_request(JRPC_ERR_SEND, req, "Failed to send request"); } end: free_pipe_cmd(cmd); }
DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); unsigned int ifid, i; unsigned int bcnt; CaptureJob *j; DWORD result; check_pssdk(); dprintf("sniffer>> capture_dump_read()"); ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID); bcnt = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_BYTE_COUNT); bcnt = min(bcnt, 32*1024*1024); dprintf("sniffer>> capture_dump_read(0x%.8x, %d)", ifid, bcnt); result = ERROR_SUCCESS; do { // the interface is invalid if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) { packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0); goto fail; } j = &open_captures[ifid]; if(! j->dbuf) { packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0); goto fail; } if(j->didx + bcnt > j->dlen) { bcnt = j->dlen - j->didx; } packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, bcnt); packet_add_tlv_raw(response, TLV_TYPE_SNIFFER_PACKET, (unsigned char *)j->dbuf+j->didx, bcnt); j->didx += bcnt; } while(0); // Free memory if the read is complete if(j->didx >= j->dlen-1) { free(j->dbuf); j->dbuf = NULL; j->didx = 0; j->dlen = 0; // if dump occurs when interface is not active, i.e sniff has ended, release info if (j->active == 0) { dprintf("sniffer>> capture_dump_read, release CaptureJob"); lock_acquire(snifferm); for(i=0; i<j->max_pkts; i++) { if(!j->pkts[i]) break; PktDestroy(j->pkts[i]); j->pkts[i] = NULL; } free(j->pkts); memset(j, 0, sizeof(CaptureJob)); lock_release(snifferm); } } fail: packet_transmit_response(result, remote, response); return ERROR_SUCCESS; }
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_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 retreive 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; }
DWORD request_sniffer_capture_dump(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); unsigned int ifid; unsigned int rbuf,mbuf; unsigned int *tmp; CaptureJob *j; DWORD result,pcnt,rcnt,i; #ifdef _WIN64 ULONGLONG thilo; #endif DWORD thi, tlo; check_pssdk(); dprintf("sniffer>> capture_dump()"); ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID); dprintf("sniffer>> capture_dump(0x%.8x)", ifid); result = ERROR_SUCCESS; lock_acquire(snifferm); do { // the interface is invalid if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) { result = ERROR_INVALID_PARAMETER; break; } j = &open_captures[ifid]; // the interface was not captured #ifdef _WIN32 if(! j->adp) #else if(! j->pcap) #endif { result = ERROR_INVALID_PARAMETER; break; } // Free any existing packet buffer if(j->dbuf) { free(j->dbuf); j->dbuf = NULL; j->dlen = 0; j->didx = 0; } // Add basic stats pcnt = 0; rcnt = 0; mbuf = (1024*1024); j->dbuf = malloc(mbuf); rbuf = 0; for(i=0; i<j->max_pkts; i++) { if(!j->pkts[i]) break; rbuf += (8 + 8 + 4 + PktGetPacketSize(j->pkts[i])); if(mbuf < rbuf) { mbuf += (1024*1024); j->dbuf = realloc(j->dbuf, mbuf); if(!j->dbuf) { dprintf("sniffer>> realloc of %d bytes failed!", rbuf); result = ERROR_NOT_ENOUGH_MEMORY; break; } } tmp = (unsigned int *)( j->dbuf + rcnt ); #ifdef _WIN64 thilo = PktGetId(j->pkts[i]); thi = (DWORD)(thilo >> 32); tlo = (DWORD)(thilo & 0xFFFFFFFF); #else tlo = PktGetId(j->pkts[i], &thi); #endif *tmp = htonl(thi); tmp++; *tmp = htonl(tlo); tmp++; #ifdef _WIN64 thilo = PktGetTimeStamp(j->pkts[i]); thi = (DWORD)(thilo >> 32); tlo = (DWORD)(thilo & 0xFFFFFFFF); #else tlo = PktGetTimeStamp(j->pkts[i], &thi); #endif *tmp = htonl(thi); tmp++; *tmp = htonl(tlo); tmp++; tlo = PktGetPacketSize(j->pkts[i]); *tmp = htonl(tlo); tmp++; memcpy(j->dbuf+rcnt+20, PktGetPacketData(j->pkts[i]), tlo); rcnt += 20 + tlo; pcnt++; PktDestroy(j->pkts[i]); j->pkts[i] = NULL; } j->dlen = rcnt; packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, pcnt); packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, rcnt); // add capture datalink, needed when saving capture file, use TLV_TYPE_SNIFFER_INTERFACE_ID not to create a new TLV type packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_INTERFACE_ID, j->capture_linktype); dprintf("sniffer>> finished processing packets"); j->cur_bytes = 0; j->cur_pkts = 0; j->idx_pkts = 0; } while(0); lock_release(snifferm); packet_transmit_response(result, remote, response); return ERROR_SUCCESS; }
dbt_table_p dbt_db_get_table(dbt_cache_p _dc, const str *_s) { dbt_table_p _tbc = NULL; int hash; int hashidx; if(!_dbt_cachetbl || !_dc || !_s || !_s->s || _s->len<=0) { LM_ERR("invalid parameter"); return NULL; } hash = core_hash(&_dc->name, _s, DBT_CACHETBL_SIZE); hashidx = hash % DBT_CACHETBL_SIZE; lock_get(&_dbt_cachetbl[hashidx].sem); _tbc = _dbt_cachetbl[hashidx].dtp; while(_tbc) { if(_tbc->hash==hash && _tbc->dbname.len == _dc->name.len && _tbc->name.len == _s->len && !strncasecmp(_tbc->dbname.s, _dc->name.s, _dc->name.len) && !strncasecmp(_tbc->name.s, _s->s, _s->len)) { /* found - if cache mode or no-change, return */ if(db_mode==0 || dbt_check_mtime(_s, &(_dc->name), &(_tbc->mt))!=1) { LM_DBG("cache or mtime succeeded for [%.*s]\n", _tbc->name.len, _tbc->name.s); return _tbc; } break; } _tbc = _tbc->next; } /* new table */ if(_tbc) /* free old one */ { dbt_db_del_table(_dc, _s, 0); } _tbc = dbt_load_file(_s, &(_dc->name)); if(!_tbc) { LM_ERR("could not load database from file [%.*s]", _s->len, _s->s); lock_release(&_dbt_cachetbl[hashidx].sem); return NULL; } _tbc->hash = hash; _tbc->next = _dbt_cachetbl[hashidx].dtp; if(_dbt_cachetbl[hashidx].dtp) _dbt_cachetbl[hashidx].dtp->prev = _tbc; _dbt_cachetbl[hashidx].dtp = _tbc; /* table is locked */ return _tbc; }
int sys_read(int fd, userptr_t buf, int len, int* retval) { // argument checks. if(fd <0 || fd>= OPEN_MAX) return EBADF; int result; char kern_buffer[len + 1]; // are we using this properly?.. check jinghao's blog for example // no actual use for the kern buffer, just doing this to check if memory location is valid. if(buf!= NULL) { result = copyin(buf, kern_buffer, len); // using this because users are stupid/malicious and can pass invalid memory addresses to the kernel. if(result) { kprintf("read copy in bad \n"); return result; } } struct file_handle* fh = get_file_handle(curproc->t_file_table, fd); if(fh == NULL) return EBADF; if(!can_read(fh->openflags)) // could have other flags Or'd with O_RDONLY, need to change this. return EBADF; // !!!! Should we do copyin's to kernel space, or will the VOP_WRITE take care of the invalid address issue for us. lock_acquire(fh->fh_lock); // IS this really necessary??.. turns out it is , offset should be synchronized. imagine if parent and child call this at the same time. struct iovec iov; struct uio u; iov.iov_ubase = (userptr_t)buf; iov.iov_len = len; // length of the memory space u.uio_iov = &iov; u.uio_iovcnt = 1; u.uio_resid = len; // amount to read from the file u.uio_offset = fh->offset; u.uio_segflg = UIO_USERSPACE; u.uio_rw = UIO_READ; u.uio_space = proc_getas(); // lifted from loadelf.c, is this the right way to do it? result = VOP_READ(fh->file, &u); if (result) { lock_release(fh->fh_lock); return result; } if (u.uio_resid != 0) { // kprintf("ELF: short read on segment - file truncated?\n"); } // should update offset in the file handle.use lock. uio_offset will be updated. can use it directly. fh->offset = u.uio_offset; lock_release(fh->fh_lock); *retval = len - u.uio_resid; // number of bytes gets returned to the user return 0; }
static struct mi_root* mi_cc_list_flows(struct mi_root *cmd, void *param) { struct cc_flow *flow; struct mi_root *rpl_tree; struct mi_node *node; struct mi_node *rpl; struct mi_attr *attr; int len; char *p; rpl_tree = init_mi_tree( 200, MI_SSTR("OK") ); if ( rpl_tree==NULL) return NULL; rpl = &rpl_tree->node; rpl->flags |= MI_IS_ARRAY; /* block access to data */ lock_get( data->lock ); for( flow=data->flows; flow ; flow=flow->next ) { node = add_mi_node_child( rpl, MI_DUP_VALUE, MI_SSTR("Flow"), flow->id.s, flow->id.len ); if (node==NULL) goto error; p = int2str( (unsigned long)(flow->avg_call_duration), &len); attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Avg Call Duration"), p, len); if (attr==NULL) goto error; p = int2str( (unsigned long)(flow->processed_calls), &len); attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Processed Calls"), p, len); if (attr==NULL) goto error; p = int2str( (unsigned long)(flow->logged_agents), &len); attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Logged Agents"), p, len); if (attr==NULL) goto error; p = int2str( (unsigned long)(flow->ongoing_calls), &len); attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Ongoing Calls"), p, len); if (attr==NULL) goto error; p = int2str( (unsigned long)(flow->ref_cnt), &len); attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Ref"), p, len); if (attr==NULL) goto error; } lock_release( data->lock ); return rpl_tree; error: lock_release( data->lock ); return 0; }
/** * run keep-alive list * */ int dlg_ka_run(ticks_t ti) { dlg_ka_t *dka; dlg_cell_t *dlg; if(dlg_ka_interval<=0) return 0; while(1) { /* get head item */ lock_get(dlg_ka_list_lock); if(*dlg_ka_list_head==NULL) { lock_release(dlg_ka_list_lock); return 0; } dka = *dlg_ka_list_head; #if 0 LM_DBG("dlg ka timer at %lu for" " dlg[%u,%u] on %lu\n", (unsigned long)ti, dka->iuid.h_entry, dka->iuid.h_id, (unsigned long)dka->katime); #endif if(dka->katime>ti) { lock_release(dlg_ka_list_lock); return 0; } if(*dlg_ka_list_head == *dlg_ka_list_tail) { *dlg_ka_list_head = NULL; *dlg_ka_list_tail = NULL; } else { *dlg_ka_list_head = dka->next; } lock_release(dlg_ka_list_lock); /* send keep-alive for dka */ dlg = dlg_get_by_iuid(&dka->iuid); if(dlg==NULL) { shm_free(dka); dka = NULL; } else { if((dka->iflags & DLG_IFLAG_KA_SRC) && (dlg->state==DLG_STATE_CONFIRMED)) dlg_send_ka(dlg, DLG_CALLER_LEG); if((dka->iflags & DLG_IFLAG_KA_DST) && (dlg->state==DLG_STATE_CONFIRMED)) dlg_send_ka(dlg, DLG_CALLEE_LEG); if(dlg->state==DLG_STATE_DELETED) { shm_free(dka); dka = NULL; } dlg_release(dlg); } /* append to tail */ if(dka!=NULL) { dka->katime = ti + dlg_ka_interval; lock_get(dlg_ka_list_lock); if(*dlg_ka_list_tail!=NULL) (*dlg_ka_list_tail)->next = dka; if(*dlg_ka_list_head==NULL) *dlg_ka_list_head = dka; *dlg_ka_list_tail = dka; lock_release(dlg_ka_list_lock); } } return 0; }
static struct mi_root* mi_cc_list_calls(struct mi_root *cmd_tree, void *param) { struct cc_call *call; struct cc_agent *agent; struct mi_root *rpl_tree; struct mi_node *node; struct mi_node *rpl; struct mi_attr *attr; char *p; int len; static str call_state[12]= {{"none", 4}, {"welcome", 7}, {"queued", 6}, {"toagent", 7}, {"ended", 5}}; rpl_tree = init_mi_tree( 200, MI_SSTR("OK") ); if ( rpl_tree==NULL) return NULL; rpl = &rpl_tree->node; rpl->flags |= MI_IS_ARRAY; /* block access to data */ lock_get( data->lock ); for( call=data->list.first ; call ; call=call->next_list ) { node = add_mi_node_child( rpl, MI_DUP_VALUE, "Call", 4, call->b2bua_id.s, call->b2bua_id.len); if (node==NULL) goto error; p = int2str( (unsigned long)(call->ref_cnt), &len); attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Ref"), p, len); if (attr==NULL) goto error; if(call->ign_cback) attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("State"), MI_SSTR("ignored")); else attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("State"), call_state[call->state].s, call_state[call->state].len); if (attr==NULL) goto error; LM_DBG("call->recv_time= %d, ticks= %d\n", call->recv_time, get_ticks()); if(call->state != CC_CALL_ENDED) { p = int2str( (unsigned long)(call->recv_time?(get_ticks() - call->recv_time):0), &len); attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Call Time"), p, len); if (attr==NULL) goto error; if(call->flow) { attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Flow"), call->flow->id.s, call->flow->id.len); if (attr==NULL) goto error; } } if(call->agent) { agent = call->agent; attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Agent"), agent->id.s, agent->id.len); if (attr==NULL) goto error; } } lock_release( data->lock ); return rpl_tree; error: lock_release( data->lock ); return 0; }
void b2b_logic_dump(int no_lock) { b2bl_tuple_t* tuple; int i; int n_insert_cols; if(b2bl_dbf.use_table(b2bl_db, &b2bl_dbtable)< 0) { LM_ERR("sql use table failed\n"); return; } for(i = 0; i< b2bl_hsize; i++) { if(!no_lock) lock_get(&b2bl_htable[i].lock); tuple = b2bl_htable[i].first; while(tuple) { /* check the state of the scenario instantiation */ if(tuple->db_flag == NO_UPDATEDB_FLAG) goto next; if(tuple->key == NULL) { LM_ERR("No key stored\n"); goto next; } if(tuple->bridge_entities[0]==NULL || tuple->bridge_entities[1]== NULL) { LM_ERR("Bridge entities is NULL\n"); if(tuple->bridge_entities[0]==NULL) LM_DBG("0 NULL\n"); else LM_DBG("1 NULL\n"); goto next; } qvals[0].val.str_val = *tuple->key; if(tuple->db_flag == INSERTDB_FLAG) { if(tuple->scenario) qvals[1].val.str_val = tuple->scenario->id; else{ qvals[1].val.str_val.len = 0; qvals[1].val.str_val.s = ""; } qvals[2].val.str_val = tuple->scenario_params[0]; qvals[3].val.str_val = tuple->scenario_params[1]; qvals[4].val.str_val = tuple->scenario_params[2]; qvals[5].val.str_val = tuple->scenario_params[3]; qvals[6].val.str_val = tuple->scenario_params[4]; qvals[7].val.str_val = tuple->sdp; } qvals[8].val.int_val = tuple->scenario_state; qvals[9].val.int_val = tuple->next_scenario_state; qvals[10].val.int_val = tuple->lifetime - get_ticks() + (int)time(NULL); qvals[11].val.int_val = tuple->bridge_entities[0]->type; qvals[12].val.str_val = tuple->bridge_entities[0]->scenario_id; qvals[13].val.str_val = tuple->bridge_entities[0]->to_uri; qvals[14].val.str_val = tuple->bridge_entities[0]->from_uri; qvals[15].val.str_val = tuple->bridge_entities[0]->key; qvals[16].val.int_val = tuple->bridge_entities[1]->type; qvals[17].val.str_val = tuple->bridge_entities[1]->scenario_id; qvals[18].val.str_val = tuple->bridge_entities[1]->to_uri; qvals[19].val.str_val = tuple->bridge_entities[1]->from_uri; qvals[20].val.str_val = tuple->bridge_entities[1]->key; n_insert_cols = 21; if(tuple->bridge_entities[2]) { qvals[21].val.int_val = tuple->bridge_entities[2]->type; qvals[22].val.str_val = tuple->bridge_entities[2]->scenario_id; qvals[23].val.str_val = tuple->bridge_entities[2]->to_uri; qvals[24].val.str_val = tuple->bridge_entities[2]->from_uri; qvals[25].val.str_val = tuple->bridge_entities[2]->key; } n_insert_cols = DB_COLS_NO; /* insert into database */ if(tuple->db_flag == INSERTDB_FLAG) { if(b2bl_dbf.insert(b2bl_db, qcols, qvals, n_insert_cols)< 0) { LM_ERR("Sql insert failed\n"); if(!no_lock) lock_release(&b2bl_htable[i].lock); return; } } else { /*do update */ if(b2bl_dbf.update(b2bl_db, qcols, 0, qvals, qcols+n_query_update, qvals+n_query_update, 1, DB_COLS_NO - n_query_update)< 0) { LM_ERR("Sql update failed\n"); if(!no_lock) lock_release(&b2bl_htable[i].lock); return; } } tuple->db_flag = NO_UPDATEDB_FLAG; next: tuple = tuple->next; } if(!no_lock) lock_release(&b2bl_htable[i].lock); } }
static void terminate_call(struct cc_call *call, b2bl_dlg_stat_t* stat, call_state prev_state) { str un, fid, aid; int type; if(prev_state == CC_CALL_ENDED) { LM_CRIT("BUG - terminate state \n"); return; } LM_DBG("terminating call %p (stat=%p)\n",call,stat); lock_get( data->lock ); prepare_cdr( call, &un, &fid , &aid); if (prev_state==CC_CALL_TOAGENT) { /* free the agent */ if (stat && stat->call_time && prev_state==CC_CALL_TOAGENT) { call->agent->state = CC_AGENT_WRAPUP; call->agent->last_call_end = get_ticks(); call->flow->processed_calls ++; call->flow->avg_call_duration = ( ((float)stat->call_time + ((float)call->flow->avg_call_duration * (call->flow->processed_calls-1)) ) ) / call->flow->processed_calls ; /* update awt for established calls */ update_awt( stat->start_time - call->recv_time ); update_cc_flow_awt(call->flow, stat->start_time - call->recv_time); update_cc_agent_att(call->agent, stat->call_time); } else { call->agent->state = CC_AGENT_FREE; /* update awt for failed calls */ update_awt( get_ticks() - call->recv_time ); update_cc_flow_awt( call->flow, get_ticks() - call->recv_time ); } /* update last_call_end for agent */ cc_db_update_agent_end_call(call->agent); call->agent->ref_cnt--; call->agent = NULL; } else { /* update awt for failed calls */ update_awt( get_ticks() - call->recv_time ); update_cc_flow_awt( call->flow, get_ticks() - call->recv_time ); } /* remove the call from queue (if there) */ if ( is_call_in_queue(data, call) ) { cc_queue_rmv_call( data, call); call->ref_cnt--; } call->flow->ongoing_calls--; lock_release( data->lock ); if (call->setup_time==-1 && stat) call->setup_time = stat->setup_time; /* generate CDR */ type = (stat==NULL) ? -1 : ((prev_state==CC_CALL_TOAGENT && stat->call_time)? 0 : 1); cc_write_cdr( &un, &fid, &aid, type, call->recv_time, ((type==0)? stat->start_time : get_ticks()) - call->recv_time , (type==0)?stat->call_time:0 , call->setup_time, call->no_rejections, call->fst_flags, call->id); cc_db_delete_call(call); }
dbt_table_p dbt_db_get_table(dbt_cache_p _dc, str *_s) { dbt_table_p _tbc = NULL; int hash; int hashidx; if(!_dbt_cachetbl || !_dc || !_s || !_s->s || _s->len<=0) return NULL; hash = core_hash(&_dc->name, _s, DBT_CACHETBL_SIZE); hashidx = hash % DBT_CACHETBL_SIZE; lock_get(&_dbt_cachetbl[hashidx].sem); _tbc = _dbt_cachetbl[hashidx].dtp; while(_tbc) { if(_tbc->hash==hash && _tbc->dbname.len == _dc->name.len && _tbc->name.len == _s->len && !strncasecmp(_tbc->dbname.s, _dc->name.s, _dc->name.len) && !strncasecmp(_tbc->name.s, _s->s, _s->len)) { /* found - if cache mode or no-change, return */ if(db_mode==0 || dbt_check_mtime(_s, &(_dc->name), &(_tbc->mt))!=1) { LM_DBG("cache or mtime succeeded\n"); return _tbc; } break; } _tbc = _tbc->next; } /* new table */ if(_tbc) /* free old one */ { lock_release(&_dbt_cachetbl[hashidx].sem); dbt_db_del_table(_dc, _s); lock_get(&_dbt_cachetbl[hashidx].sem); } _tbc = dbt_load_file(_s, &(_dc->name)); #ifdef DBT_EXTRA_DEBUG LM_DBG("%.*s\n", _s->len, _s->s); dbt_print_table(_tbc, NULL); #endif if(!_tbc) { lock_release(&_dbt_cachetbl[hashidx].sem); return NULL; } _tbc->hash = hash; _tbc->next = _dbt_cachetbl[hashidx].dtp; if(_dbt_cachetbl[hashidx].dtp) _dbt_cachetbl[hashidx].dtp->prev = _tbc; _dbt_cachetbl[hashidx].dtp = _tbc; /* table is locked */ return _tbc; }