static int w_dlg_set_timeout(struct sip_msg *msg, char *pto, char *phe, char *phi) { int to = 0; unsigned int he = 0; unsigned int hi = 0; dlg_cell_t *dlg = NULL; if(fixup_get_ivalue(msg, (gparam_p)pto, &to)!=0) { LM_ERR("no timeout value\n"); return -1; } if(phe!=NULL) { if(fixup_get_ivalue(msg, (gparam_p)phe, (int*)&he)!=0) { LM_ERR("no hash entry value value\n"); return -1; } if(fixup_get_ivalue(msg, (gparam_p)phi, (int*)&hi)!=0) { LM_ERR("no hash id value value\n"); return -1; } dlg = dlg_lookup(he, hi); } else { dlg = dlg_get_msg_dialog(msg); } if(dlg==NULL) { LM_DBG("no dialog found\n"); return -1; } if(update_dlg_timeout(dlg, to) != 0) return -1; return 1; }
int dlg_set_timeout_by_profile(struct dlg_profile_table *profile, str *value, int timeout) { unsigned int i = 0; dlg_cell_t *this_dlg = NULL; struct dlg_profile_hash *ph = NULL; /* Private structure necessary for manipulating dialog * timeouts outside of profile locks. Admittedly, an * ugly hack, but avoids some concurrency issues. */ struct dlg_map_list { unsigned int h_id; unsigned int h_entry; struct dlg_map_list *next; } *map_head, *map_scan, *map_scan_next; map_head = NULL; /* If the profile has no value, iterate through every * node and set its timeout. */ if(profile->has_value == 0 || value == NULL) { lock_get(&profile->lock); for(i = 0; i < profile->size; i ++) { ph = profile->entries[i].first; if(!ph) continue; do { struct dlg_map_list *d = malloc(sizeof(struct dlg_map_list)); if(!d) return -1; memset(d, 0, sizeof(struct dlg_map_list)); d->h_id = ph->dlg->h_id; d->h_entry = ph->dlg->h_entry; if(map_head == NULL) map_head = d; else { d->next = map_head; map_head = d; } ph = ph->next; } while(ph != profile->entries[i].first); } lock_release(&profile->lock); } else { i = calc_hash_profile(value, NULL, profile); lock_get(&profile->lock); ph = profile->entries[i].first; if(ph) { do { if(ph && value->len == ph->value.len && memcmp(value->s, ph->value.s, value->len) == 0) { struct dlg_map_list *d = malloc(sizeof(struct dlg_map_list)); if(!d) return -1; memset(d, 0, sizeof(struct dlg_map_list)); d->h_id = ph->dlg->h_id; d->h_entry = ph->dlg->h_entry; if(map_head == NULL) map_head = d; else { d->next = map_head; map_head = d; } } ph = ph->next; } while(ph && ph != profile->entries[i].first); } lock_release(&profile->lock); } /* Walk the list and bulk-set the timeout */ for(map_scan = map_head; map_scan != NULL; map_scan = map_scan_next) { map_scan_next = map_scan->next; this_dlg = dlg_lookup(map_scan->h_entry, map_scan->h_id); if(!this_dlg) { LM_CRIT("Unable to find dialog %d:%d\n", map_scan->h_entry, map_scan->h_id); } else if(this_dlg->state >= DLG_STATE_EARLY) { if(update_dlg_timeout(this_dlg, timeout) < 0) { LM_ERR("Unable to set timeout on %d:%d\n", map_scan->h_entry, map_scan->h_id); } dlg_release(this_dlg); } free(map_scan); } return 0; }