/** * Initializes the Peer Manager. * The initial list of peers is taken from the configuration provided * @param config - configuration for initial peers * @returns 1 */ int peer_manager_init(dp_config *config) { int i; peer *p; LM_DBG("peer_manager_init(): Peer Manager initialization...\n"); peer_list = shm_malloc(sizeof(peer_list_t)); peer_list->head = 0; peer_list->tail = 0; peer_list_lock = lock_alloc(); peer_list_lock = lock_init(peer_list_lock); hopbyhop_id = shm_malloc(sizeof(AAAMsgIdentifier)); endtoend_id = shm_malloc(sizeof(AAAMsgIdentifier)); msg_id_lock = lock_alloc(); msg_id_lock = lock_init(msg_id_lock); kam_srand((unsigned int)time(0)); *hopbyhop_id = kam_rand(); *endtoend_id = (time(0)&0xFFF)<<20; *endtoend_id |= kam_rand() & 0xFFFFF; for(i=0;i<config->peers_cnt;i++){ p = new_peer(config->peers[i].fqdn,config->peers[i].realm,config->peers[i].port,config->peers[i].src_addr); if (!p) continue; p->is_dynamic = 0; add_peer(p); } add_timer(1,0,&peer_timer,0); return 1; }
/* * Secret parameter was not used so we generate * a random value here */ static inline int generate_random_secret(void) { int i; sec_rand1 = (char*)pkg_malloc(RAND_SECRET_LEN); sec_rand2 = (char*)pkg_malloc(RAND_SECRET_LEN); if (!sec_rand1 || !sec_rand2) { LM_ERR("No memory left\n"); if (sec_rand1){ pkg_free(sec_rand1); sec_rand1=0; } return -1; } /* srandom(time(0)); -- seeded by core */ for(i = 0; i < RAND_SECRET_LEN; i++) { sec_rand1[i] = 32 + (int)(95.0 * kam_rand() / (KAM_RAND_MAX + 1.0)); } secret1.s = sec_rand1; secret1.len = RAND_SECRET_LEN; for(i = 0; i < RAND_SECRET_LEN; i++) { sec_rand2[i] = 32 + (int)(95.0 * kam_rand() / (KAM_RAND_MAX + 1.0)); } secret2.s = sec_rand2; secret2.len = RAND_SECRET_LEN; /* DBG("Generated secret: '%.*s'\n", secret.len, secret.s); */ return 0; }
int select_sys_unique(str* res, select_t* s, struct sip_msg* msg) { #define UNIQUE_ID_PID_LEN 4 #define UNIQUE_ID_TIME_LEN 8 #define UNIQUE_ID_FIX_LEN (UNIQUE_ID_PID_LEN+1+UNIQUE_ID_TIME_LEN+1) #define UNIQUE_ID_RAND_LEN 8 static char uniq_id[UNIQUE_ID_FIX_LEN+UNIQUE_ID_RAND_LEN]; static int uniq_for_pid = -1; int i; if (uniq_for_pid != getpid()) { /* first call for this process */ int cb, rb, x, l; char *c; /* init gloabally uniq part */ c = int2str_base_0pad(getpid(), &l, 16, UNIQUE_ID_PID_LEN); memcpy(uniq_id, c, UNIQUE_ID_PID_LEN); uniq_id[UNIQUE_ID_PID_LEN] = '-'; c = int2str_base_0pad(time(NULL), &l, 16, UNIQUE_ID_TIME_LEN); memcpy(uniq_id+UNIQUE_ID_PID_LEN+1, c, UNIQUE_ID_TIME_LEN); uniq_id[UNIQUE_ID_PID_LEN+1+UNIQUE_ID_TIME_LEN] = '-'; /* init random part */ for (i = KAM_RAND_MAX, rb=0; i; rb++, i>>=1); for (i = UNIQUE_ID_FIX_LEN, cb = 0, x = 0; i < UNIQUE_ID_FIX_LEN+UNIQUE_ID_RAND_LEN; i++) { if (!cb) { cb = rb; x = kam_rand(); } uniq_id[i] = fourbits2char[x & 0x0F]; x >>= rb; cb -= rb; } uniq_for_pid = getpid(); }
/*! * \brief Initialize the global dialog table * \param size size of the table * \return 0 on success, -1 on failure */ int init_dlg_table(unsigned int size) { unsigned int i; dlg_ka_list_head = (dlg_ka_t **)shm_malloc(sizeof(dlg_ka_t *)); if(dlg_ka_list_head==NULL) { LM_ERR("no more shm mem (h)\n"); goto error0; } dlg_ka_list_tail = (dlg_ka_t **)shm_malloc(sizeof(dlg_ka_t *)); if(dlg_ka_list_tail==NULL) { LM_ERR("no more shm mem (t)\n"); goto error0; } *dlg_ka_list_head = NULL; *dlg_ka_list_tail = NULL; dlg_ka_list_lock = (gen_lock_t*)shm_malloc(sizeof(gen_lock_t)); if(dlg_ka_list_lock==NULL) { LM_ERR("no more shm mem (l)\n"); goto error0; } lock_init(dlg_ka_list_lock); d_table = (struct dlg_table*)shm_malloc ( sizeof(struct dlg_table) + size*sizeof(struct dlg_entry)); if (d_table==0) { LM_ERR("no more shm mem (1)\n"); goto error0; } memset( d_table, 0, sizeof(struct dlg_table) ); d_table->size = size; d_table->entries = (struct dlg_entry*)(d_table+1); for( i=0 ; i<size; i++ ) { memset( &(d_table->entries[i]), 0, sizeof(struct dlg_entry) ); if(lock_init(&d_table->entries[i].lock)<0) { LM_ERR("failed to init lock for slot: %d\n", i); goto error1; } d_table->entries[i].next_id = kam_rand() % (3*size); } return 0; error1: shm_free( d_table ); d_table = NULL; error0: if(dlg_ka_list_head!=NULL) shm_free(dlg_ka_list_head); if(dlg_ka_list_tail!=NULL) shm_free(dlg_ka_list_tail); dlg_ka_list_head = NULL; dlg_ka_list_tail = NULL; return -1; }
/*! \brief * Return an expire value in the range [ default_expires - range%, default_expires + range% ] */ static inline int get_expire_val(void) { int expires = cfg_get(registrar, registrar_cfg, default_expires); int range = cfg_get(registrar, registrar_cfg, default_expires_range); /* if no range is given just return default_expires */ if (range == 0) return expires; /* select a random value in the range */ return expires - (float) range / 100 * expires + (float) (kam_rand() % 100) / 100 * 2 * (float) range / 100 * expires; }
/* \brief * Return randomized expires between expires-range% and expires. * RFC allows only value less or equal to the one provided by UAC. */ static inline int randomize_expires( int expires, int range ) { int range_min; /* if no range is given just return expires */ if(range == 0) return expires; range_min = expires - (float)range/100 * expires; return range_min + (float)(kam_rand()%100)/100 * ( expires - range_min ); }
static int pl_drop(struct sip_msg * msg, unsigned int low, unsigned int high) { str hdr; int ret; LM_DBG("(%d, %d)\n", low, high); if (slb.freply != 0) { if (low != 0 && high != 0) { hdr.s = (char *)pkg_malloc(64); if (hdr.s == 0) { LM_ERR("Can't allocate memory for Retry-After header\n"); return 0; } hdr.len = 0; if (! hdr.s) { LM_ERR("no memory for hdr\n"); return 0; } if (high == low) { hdr.len = snprintf(hdr.s, 63, "Retry-After: %d\r\n", low); } else { hdr.len = snprintf(hdr.s, 63, "Retry-After: %d\r\n", low + kam_rand() % (high - low + 1)); } if (add_lump_rpl(msg, hdr.s, hdr.len, LUMP_RPL_HDR)==0) { LM_ERR("Can't add header\n"); pkg_free(hdr.s); return 0; } ret = slb.freply(msg, pl_drop_code, &pl_drop_reason); pkg_free(hdr.s); } else { ret = slb.freply(msg, pl_drop_code, &pl_drop_reason); } } else { LM_ERR("Can't send reply\n"); return 0; } return ret; }
static int pv_get_random_val(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { int n; int l = 0; char *ch; if(msg==NULL || res==NULL) return -1; n = kam_rand(); ch = int2str(n , &l); res->rs.s = ch; res->rs.len = l; res->ri = n; res->flags = PV_VAL_STR|PV_VAL_INT|PV_TYPE_INT; return 0; }
static int rand_event(struct sip_msg *bar, char *foo1, char *foo2) { double tmp; /* most of the time this will be disabled completly. Tis will also fix the * problem with the corner cases if rand() returned zero or RAND_MAX */ if ((*probability) == 0) return -1; if ((*probability) == 100) return 1; tmp = ((double) kam_rand() / KAM_RAND_MAX); LM_DBG("generated random %f\n", tmp); if (tmp < ((double) (*probability) / 100)) { LM_DBG("return true\n"); return 1; } else { LM_DBG("return false\n"); return -1; } }
int xl_child_init(int rank) { int i, x, rb, cb; for (i=KAM_RAND_MAX, rb=0; i; rb++, i>>=1); cb=x=0; /* x asiignment to make gcc happy */ for (i=0; i<UNIQUE_ID_LEN; i++) { if (!cb) { cb=rb; x=kam_rand(); } UNIQUE_ID[i]=fourbits2char[x&0x0F]; x>>=rb; cb-=rb; } return 0; }
/** * writes the uri dest using the flags and rule list of rf_head * * @param rf_head the head of the route flags list * @param flags user defined flags * @param dest the returned new destination URI * @param msg the sip message * @param user the localpart of the uri to be rewritten * @param hash_source the SIP header used for hashing * @param alg the algorithm used for hashing * @param descavp the name of the AVP where the description is stored * * @return 0 on success, -1 on failure, 1 on empty rule list */ static int rewrite_on_rule(struct route_flags *rf_head, flag_t flags, str * dest, struct sip_msg * msg, const str * user, const enum hash_source hash_source, const enum hash_algorithm alg, gparam_t *descavp) { struct route_flags * rf; struct route_rule * rr; int prob; assert(rf_head != NULL); LM_DBG("searching for matching routing rules"); for (rf = rf_head; rf != NULL; rf = rf->next) { /* LM_DBG("actual flags %i, searched flags %i, mask %i and match %i", rf->flags, flags, rf->mask, flags&rf->mask); */ if ((flags&rf->mask) == rf->flags) break; } if (rf==NULL) { LM_INFO("did not find a match for flags %d\n", flags); return -1; } if (rf->rule_list == NULL) { LM_INFO("empty rule list\n"); return 1; } switch (alg) { case alg_crc32: { static avp_value_t used_dests[MAX_DESTINATIONS]; static int no_dests = 0; avp_value_t cr_new_uri; if(rf->dice_max == 0) { LM_ERR("invalid dice_max value\n"); return -1; } if ((prob = hash_func(msg, hash_source, rf->dice_max)) < 0) { LM_ERR("could not hash message with CRC32"); return -1; } /* This auto-magically takes the last rule if anything is broken. * Sometimes the hash result is zero. If the first rule is off * (has a probablility of zero) then it has also a dice_to of * zero and the message could not be routed at all if we use * '<' here. Thus the '<=' is necessary. * * cr_uri_already_used is a function that checks that the selected * rule has not been previously used as a failed destinatin */ for (rr = rf->rule_list; rr->next!= NULL && rr->dice_to <= prob ; rr = rr->next) {} //LM_DBG("CR: candidate hashed destination is: <%.*s>\n", rr->host.len, rr->host.s); if (cr_avoid_failed_dests) { if (is_route_type(FAILURE_ROUTE) && (mode == CARRIERROUTE_MODE_DB) ){ build_used_uris_list(used_dests, &no_dests); if (cr_uri_already_used(rr->host, used_dests, no_dests) ) { //LM_DBG("CR: selecting new destination !!! \n"); for (rr = rf->rule_list; rr!= NULL && cr_uri_already_used(rr->host, used_dests, no_dests); rr = rr->next) {} /* are there any destinations that were not already used? */ if (rr == NULL) { LM_NOTICE("All gateways from this group were already used\n"); return -1; } /* this is a hack: we do not take probabilities into consideration if first destination * was previously tried */ do { int rule_no = kam_rand() % rf->rule_num; //LM_DBG("CR: trying rule_no=%d \n", rule_no); for (rr = rf->rule_list; (rule_no > 0) && (rr->next!=NULL) ; rule_no-- , rr = rr->next) {} } while (cr_uri_already_used(rr->host, used_dests, no_dests)); LM_DBG("CR: candidate selected destination is: <%.*s>\n", rr->host.len, rr->host.s); } } } /*This should be regarded as an ELSE branch for the if above * ( status exists for mode == CARRIERROUTE_MODE_FILE */ if (!rr->status) { if (!rr->backup) { LM_ERR("all routes are off\n"); return -1; } else { if (!rr->backup->rr) { LM_ERR("all routes are off\n"); return -1; } rr = rr->backup->rr; } } if (cr_avoid_failed_dests) { //LM_DBG("CR: destination is: <%.*s>\n", rr->host.len, rr->host.s); cr_new_uri.s = rr->host; /* insert used destination into avp, in case corresponding request fails and * another destination has to be used; this new destination must not be one * that failed before */ if (mode == CARRIERROUTE_MODE_DB){ if ( add_avp( AVP_VAL_STR | AVP_NAME_STR, cr_uris_avp, cr_new_uri) < 0){ LM_ERR("set AVP failed\n"); return -1; } //print_cr_uri_avp(); } } break; } case alg_crc32_nofallback: if ((prob = (hash_func(msg, hash_source, rf->max_targets))) < 0) { LM_ERR("could not hash message with CRC32"); return -1; } /* Instead of search the whole rule_list if there is something broken * this function just tries only a backup rule and otherwise * returns -1. This way we get an error */ if ((rr = get_rule_by_hash(rf, prob + 1)) == NULL) { LM_CRIT("no route found\n"); return -1; } break; default: LM_ERR("invalid hash algorithm\n"); return -1; } return actually_rewrite(rr, dest, msg, user, descavp); }
int fork_tcp_process(int child_id, char *desc, int r, int *reader_fd_1) { int pid, child_process_no; int sockfd[2]; int reader_fd[2]; /* for comm. with the tcp children read */ int ret; int i; unsigned int new_seed1; unsigned int new_seed2; /* init */ sockfd[0]=sockfd[1]=-1; reader_fd[0]=reader_fd[1]=-1; ret=-1; if (!is_main){ LM_CRIT("called from a non \"main\" process\n"); goto error; } if (tcp_main_pid){ LM_CRIT("called _after_ starting tcp main\n"); goto error; } if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){ LM_ERR("socketpair failed: %s\n", strerror(errno)); goto error; } if (socketpair(AF_UNIX, SOCK_STREAM, 0, reader_fd)<0){ LM_ERR("socketpair failed: %s\n", strerror(errno)); goto error; } if (tcp_fix_child_sockets(reader_fd)<0){ LM_ERR("failed to set non blocking on child sockets\n"); /* continue, it's not critical (it will go slower under * very high connection rates) */ } lock_get(process_lock); /* set the local process_no */ if (*process_count>=estimated_proc_no) { LM_CRIT("Process limit of %d exceeded. Simulating fork fail\n", estimated_proc_no); lock_release(process_lock); goto error; } child_process_no = *process_count; new_seed1=kam_rand(); new_seed2=random(); pid = fork(); if (pid<0) { lock_release(process_lock); ret=pid; goto end; } if (pid==0){ is_main=0; /* a forked process cannot be the "main" one */ process_no=child_process_no; /* close unneeded unix sockets */ close_extra_socks(child_id, process_no); /* same for unneeded tcp_children <-> tcp_main unix socks */ for (i=0; i<r; i++){ if (tcp_children[i].unix_sock>=0){ close(tcp_children[i].unix_sock); /* tcp_children is per process, so it's safe to change * the unix_sock to -1 */ tcp_children[i].unix_sock=-1; } } daemon_status_on_fork_cleanup(); kam_srand(new_seed1); fastrand_seed(kam_rand()); srandom(new_seed2+time(0)); shm_malloc_on_fork(); #ifdef PROFILING monstartup((u_long) &_start, (u_long) &etext); #endif #ifdef FORK_DONT_WAIT /* record pid twice to avoid the child using it, before - * parent gets a chance to set it*/ pt[process_no].pid=getpid(); #else /* wait for parent to get out of critical zone */ lock_get(process_lock); lock_release(process_lock); #endif close(sockfd[0]); unix_tcp_sock=sockfd[1]; close(reader_fd[0]); if (reader_fd_1) *reader_fd_1=reader_fd[1]; if ((child_id!=PROC_NOCHLDINIT) && (init_child(child_id) < 0)) { LM_ERR("init_child failed for process %d, pid %d, \"%s\"\n", process_no, pt[process_no].pid, pt[process_no].desc); return -1; } return pid; } else { /* parent */ (*process_count)++; #ifdef FORK_DONT_WAIT lock_release(process_lock); #endif /* add the process to the list in shm */ pt[child_process_no].pid=pid; pt[child_process_no].unix_sock=sockfd[0]; pt[child_process_no].idx=r; if (desc){ snprintf(pt[child_process_no].desc, MAX_PT_DESC, "%s child=%d", desc, r); } #ifdef FORK_DONT_WAIT #else lock_release(process_lock); #endif close(sockfd[1]); close(reader_fd[1]); tcp_children[r].pid=pid; tcp_children[r].proc_no=child_process_no; tcp_children[r].busy=0; tcp_children[r].n_reqs=0; tcp_children[r].unix_sock=reader_fd[0]; ret=pid; goto end; } error: if (sockfd[0]!=-1) close(sockfd[0]); if (sockfd[1]!=-1) close(sockfd[1]); if (reader_fd[0]!=-1) close(reader_fd[0]); if (reader_fd[1]!=-1) close(reader_fd[1]); end: return ret; }
/** * Forks a new process. * @param child_id - rank, if equal to PROC_NOCHLDINIT init_child will not be * called for the new forked process (see sr_module.h) * @param desc - text description for the process table * @param make_sock - if to create a unix socket pair for it * @returns the pid of the new process */ int fork_process(int child_id, char *desc, int make_sock) { int pid, child_process_no; int ret; unsigned int new_seed1; unsigned int new_seed2; #ifdef USE_TCP int sockfd[2]; #endif if(unlikely(fork_delay>0)) sleep_us(fork_delay); ret=-1; #ifdef USE_TCP sockfd[0]=sockfd[1]=-1; if(make_sock && !tcp_disable){ if (!is_main){ LM_CRIT("called from a non " "\"main\" process! If forking from a module's " "child_init() fork only if rank==PROC_MAIN or" " give up tcp send support (use 0 for make_sock)\n"); goto error; } if (tcp_main_pid){ LM_CRIT("called, but tcp main is already started\n"); goto error; } if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){ LM_ERR("socketpair failed: %s\n", strerror(errno)); goto error; } } #endif lock_get(process_lock); if (*process_count>=estimated_proc_no) { LM_CRIT("Process limit of %d exceeded. Will simulate fork fail.\n", estimated_proc_no); lock_release(process_lock); goto error; } child_process_no = *process_count; new_seed1=kam_rand(); new_seed2=random(); pid = fork(); if (pid<0) { lock_release(process_lock); ret=pid; goto error; }else if (pid==0){ /* child */ is_main=0; /* a forked process cannot be the "main" one */ process_no=child_process_no; daemon_status_on_fork_cleanup(); /* close tcp unix sockets if this is not tcp main */ #ifdef USE_TCP close_extra_socks(child_id, process_no); #endif /* USE_TCP */ kam_srand(new_seed1); fastrand_seed(kam_rand()); srandom(new_seed2+time(0)); shm_malloc_on_fork(); #ifdef PROFILING monstartup((u_long) &_start, (u_long) &etext); #endif #ifdef FORK_DONT_WAIT /* record pid twice to avoid the child using it, before * parent gets a chance to set it*/ pt[process_no].pid=getpid(); #else /* wait for parent to get out of critical zone. * this is actually relevant as the parent updates * the pt & process_count. */ lock_get(process_lock); lock_release(process_lock); #endif #ifdef USE_TCP if (make_sock && !tcp_disable){ close(sockfd[0]); unix_tcp_sock=sockfd[1]; } #endif if ((child_id!=PROC_NOCHLDINIT) && (init_child(child_id) < 0)) { LM_ERR("init_child failed for process %d, pid %d, \"%s\"\n", process_no, pt[process_no].pid, pt[process_no].desc); return -1; } return pid; } else { /* parent */ (*process_count)++; #ifdef FORK_DONT_WAIT lock_release(process_lock); #endif /* add the process to the list in shm */ pt[child_process_no].pid=pid; if (desc){ strncpy(pt[child_process_no].desc, desc, MAX_PT_DESC-1); } #ifdef USE_TCP if (make_sock && !tcp_disable){ close(sockfd[1]); pt[child_process_no].unix_sock=sockfd[0]; pt[child_process_no].idx=-1; /* this is not a "tcp" process*/ } #endif #ifdef FORK_DONT_WAIT #else lock_release(process_lock); #endif ret=pid; goto end; } error: #ifdef USE_TCP if (sockfd[0]!=-1) close(sockfd[0]); if (sockfd[1]!=-1) close(sockfd[1]); #endif end: return ret; }
static int update_pw_dialogs_dbonlymode(subs_t* subs, subs_t** subs_array) { db_key_t query_cols[5], db_cols[3]; db_val_t query_vals[5], db_vals[3]; db_key_t result_cols[26]; int n_query_cols=0, n_result_cols=0, n_update_cols=0; int event_col, pres_uri_col, watcher_user_col, watcher_domain_col; int r_pres_uri_col,r_to_user_col,r_to_domain_col; int r_from_user_col,r_from_domain_col,r_callid_col; int r_to_tag_col,r_from_tag_col,r_sockinfo_col; int r_event_id_col,r_local_contact_col,r_contact_col; int r_record_route_col, r_reason_col; int r_event_col, r_local_cseq_col, r_remote_cseq_col; int r_status_col, r_version_col; int r_expires_col, r_watcher_user_col, r_watcher_domain_col; int r_flags_col, r_user_agent_col; db1_res_t *result= NULL; db_val_t *row_vals; db_row_t *rows; int nr_rows, loop; subs_t s, *cs; str ev_sname; if(pa_db == NULL) { LM_ERR("null database connection\n"); return(-1); } if (pa_dbf.use_table(pa_db, &active_watchers_table) < 0) { LM_ERR("use table failed\n"); return(-1); } query_cols[event_col=n_query_cols]= &str_event_col; query_vals[event_col].nul= 0; query_vals[event_col].type= DB1_STR; query_vals[event_col].val.str_val= subs->event->name ; n_query_cols++; query_cols[pres_uri_col=n_query_cols]= &str_presentity_uri_col; query_vals[pres_uri_col].nul= 0; query_vals[pres_uri_col].type= DB1_STR; query_vals[pres_uri_col].val.str_val= subs->pres_uri; n_query_cols++; query_cols[watcher_user_col=n_query_cols]= &str_watcher_username_col; query_vals[watcher_user_col].nul= 0; query_vals[watcher_user_col].type= DB1_STR; query_vals[watcher_user_col].val.str_val= subs->watcher_user; n_query_cols++; query_cols[watcher_domain_col=n_query_cols]= &str_watcher_domain_col; query_vals[watcher_domain_col].nul= 0; query_vals[watcher_domain_col].type= DB1_STR; query_vals[watcher_domain_col].val.str_val= subs->watcher_domain; n_query_cols++; result_cols[r_to_user_col=n_result_cols++] = &str_to_user_col; result_cols[r_to_domain_col=n_result_cols++] = &str_to_domain_col; result_cols[r_from_user_col=n_result_cols++] = &str_from_user_col; result_cols[r_from_domain_col=n_result_cols++] = &str_from_domain_col; result_cols[r_watcher_user_col=n_result_cols++] = &str_watcher_username_col; result_cols[r_watcher_domain_col=n_result_cols++] = &str_watcher_domain_col; result_cols[r_callid_col=n_result_cols++] = &str_callid_col; result_cols[r_to_tag_col=n_result_cols++] = &str_to_tag_col; result_cols[r_from_tag_col=n_result_cols++] = &str_from_tag_col; result_cols[r_sockinfo_col=n_result_cols++] = &str_socket_info_col; result_cols[r_event_id_col=n_result_cols++] = &str_event_id_col; result_cols[r_local_contact_col=n_result_cols++] = &str_local_contact_col; result_cols[r_record_route_col=n_result_cols++] = &str_record_route_col; result_cols[r_reason_col=n_result_cols++] = &str_reason_col; result_cols[r_local_cseq_col=n_result_cols++] = &str_local_cseq_col; result_cols[r_version_col=n_result_cols++] = &str_version_col; result_cols[r_expires_col=n_result_cols++] = &str_expires_col; result_cols[r_event_col=n_result_cols++] = &str_event_col; result_cols[r_pres_uri_col=n_result_cols++] = &str_presentity_uri_col; result_cols[r_contact_col=n_result_cols++] = &str_contact_col; /* these ones are unused for some reason !!! */ result_cols[r_remote_cseq_col=n_result_cols++] = &str_remote_cseq_col; result_cols[r_status_col=n_result_cols++] = &str_status_col; /*********************************************/ result_cols[r_flags_col=n_result_cols++] = &str_flags_col; result_cols[r_user_agent_col=n_result_cols++] = &str_user_agent_col; if(pa_dbf.query(pa_db, query_cols, 0, query_vals, result_cols, n_query_cols, n_result_cols, 0, &result )< 0) { LM_ERR("Can't query db\n"); if(result) pa_dbf.free_result(pa_db, result); return(-1); } if(result == NULL) return(-1); nr_rows = RES_ROW_N(result); LM_DBG("found %d matching dialogs\n", nr_rows); if (nr_rows <= 0) { pa_dbf.free_result(pa_db, result); return 0; } rows = RES_ROWS(result); /* get the results and fill in return data structure */ for (loop=0; loop <nr_rows; loop++) { row_vals = ROW_VALUES(&rows[loop]); memset(&s, 0, sizeof(subs_t)); s.status= subs->status; s.reason.s= subs->reason.s; s.reason.len= s.reason.s?strlen(s.reason.s):0; //>>>>>>>>>> s.pres_uri.s= (char*)row_vals[r_pres_uri_col].val.string_val; s.pres_uri.len= s.pres_uri.s?strlen(s.pres_uri.s):0; s.to_user.s= (char*)row_vals[r_to_user_col].val.string_val; s.to_user.len= s.to_user.s?strlen(s.to_user.s):0; s.to_domain.s= (char*)row_vals[r_to_domain_col].val.string_val; s.to_domain.len= s.to_domain.s?strlen(s.to_domain.s):0; s.from_user.s= (char*)row_vals[r_from_user_col].val.string_val; s.from_user.len= s.from_user.s?strlen(s.from_user.s):0; s.from_domain.s= (char*)row_vals[r_from_domain_col].val.string_val; s.from_domain.len= s.from_domain.s?strlen(s.from_domain.s):0; s.watcher_user.s= (char*)row_vals[r_watcher_user_col].val.string_val; s.watcher_user.len= s.watcher_user.s?strlen(s.watcher_user.s):0; s.watcher_domain.s= (char*)row_vals[r_watcher_domain_col].val.string_val; s.watcher_domain.len= s.watcher_domain.s?strlen(s.watcher_domain.s):0; s.event_id.s=(char*)row_vals[r_event_id_col].val.string_val; s.event_id.len= (s.event_id.s)?strlen(s.event_id.s):0; s.to_tag.s= (char*)row_vals[r_to_tag_col].val.string_val; s.to_tag.len= s.to_tag.s?strlen(s.to_tag.s):0; s.from_tag.s= (char*)row_vals[r_from_tag_col].val.string_val; s.from_tag.len= s.from_tag.s?strlen(s.from_tag.s):0; s.callid.s= (char*)row_vals[r_callid_col].val.string_val; s.callid.len= s.callid.s?strlen(s.callid.s):0; s.record_route.s= (char*)row_vals[r_record_route_col].val.string_val; s.record_route.len= (s.record_route.s)?strlen(s.record_route.s):0; s.contact.s= (char*)row_vals[r_contact_col].val.string_val; s.contact.len= s.contact.s?strlen(s.contact.s):0; s.sockinfo_str.s = (char*)row_vals[r_sockinfo_col].val.string_val; s.sockinfo_str.len = s.sockinfo_str.s?strlen(s.sockinfo_str.s):0; s.local_contact.s = (char*)row_vals[r_local_contact_col].val.string_val; s.local_contact.len = s.local_contact.s?strlen(s.local_contact.s):0; ev_sname.s= (char*)row_vals[r_event_col].val.string_val; ev_sname.len= ev_sname.s?strlen(ev_sname.s):0; s.event = contains_event(&ev_sname, NULL); if(s.event == NULL) { LM_ERR("event not found and set to NULL\n"); } s.local_cseq = row_vals[r_local_cseq_col].val.int_val; s.expires = row_vals[r_expires_col].val.int_val; if( s.expires > (int)time(NULL) + expires_offset) s.expires -= (int)time(NULL); else s.expires = 0; s.version = row_vals[r_version_col].val.int_val; s.flags = row_vals[r_flags_col].val.int_val; s.user_agent.s= (char*)row_vals[r_user_agent_col].val.string_val; s.user_agent.len= (s.user_agent.s)?strlen(s.user_agent.s):0; cs = mem_copy_subs(&s, PKG_MEM_TYPE); if (cs == NULL) { LM_ERR("while copying subs_t structure\n"); /* tidy up and return */ pa_dbf.free_result(pa_db, result); return(-1); } cs->local_cseq++; cs->next= (*subs_array); (*subs_array)= cs; printf_subs(cs); } pa_dbf.free_result(pa_db, result); if (pres_notifier_processes == 0 && subs->status == TERMINATED_STATUS) { /* delete the records */ if(pa_dbf.delete(pa_db, query_cols, 0, query_vals, n_query_cols)< 0) { LM_ERR("sql delete failed\n"); return(-1); } return(0); } /* otherwise we update the records */ db_cols[n_update_cols] = &str_status_col; db_vals[n_update_cols].type = DB1_INT; db_vals[n_update_cols].nul = 0; db_vals[n_update_cols].val.int_val = subs->status; n_update_cols++; db_cols[n_update_cols] = &str_reason_col; db_vals[n_update_cols].type = DB1_STR; db_vals[n_update_cols].nul = 0; db_vals[n_update_cols].val.str_val= subs->reason; n_update_cols++; db_cols[n_update_cols] = &str_updated_col; db_vals[n_update_cols].type = DB1_INT; db_vals[n_update_cols].nul = 0; if (subs->callid.len == 0 || subs->from_tag.len == 0) { db_vals[n_update_cols].val.int_val = (int) ((kam_rand() / (KAM_RAND_MAX + 1.0)) * (pres_waitn_time * pres_notifier_poll_rate * pres_notifier_processes)); } else { db_vals[n_update_cols].val.int_val = core_case_hash(&subs->callid, &subs->from_tag, 0) % (pres_waitn_time * pres_notifier_poll_rate * pres_notifier_processes); } n_update_cols++; if(pa_dbf.update(pa_db, query_cols, 0, query_vals, db_cols,db_vals,n_query_cols,n_update_cols) < 0) { LM_ERR("DB update failed\n"); return(-1); } return(0); }