/** * rewrites the request URI of msg by calculating a rule, using * crc32 for hashing. The request URI is used to determine tree node * the given _tree is the used routing tree * * @param msg the current SIP message * @param _tree the routing tree to be used (string or pseudo-variable * @param _domain the requested routing domain * * @return 1 on success, -1 on failure */ int tree_route_uri(struct sip_msg * msg, char * _tree, char * _domain) { struct rewrite_data * rd = NULL; pv_elem_t *model; str carrier_name; int index; str ruser; str ruri; if (!_tree) { LM_ERR("bad parameters\n"); return -1; } if (parse_sip_msg_uri(msg) < 0) { return -1; } /* Retrieve carrier name from parameter */ model = (pv_elem_t*)_tree; if (pv_printf_s(msg, model, &carrier_name)<0) { LM_ERR("cannot print the format\n"); return -1; } if ((index = find_tree(carrier_name)) < 0) LM_WARN("could not find carrier %.*s\n", carrier_name.len, carrier_name.s); else LM_DBG("tree %.*s has id %i\n", carrier_name.len, carrier_name.s, index); ruser.s = msg->parsed_uri.user.s; ruser.len = msg->parsed_uri.user.len; ruri.s = msg->parsed_uri.user.s; ruri.len = msg->parsed_uri.user.len; do { rd = get_data(); } while (rd == NULL); if (index < 0) { if (fallback_default) { LM_NOTICE("invalid tree id %i specified, use default tree\n", index); index = rd->default_carrier_index; } else { LM_ERR("invalid tree id %i specified and fallback deactivated\n", index); release_data(rd); return -1; } } release_data(rd); return carrier_rewrite_msg(index, (int)(long)_domain, &ruri, msg, &ruser, shs_call_id, alg_crc32); }
/** * prints the routing data * * @param cmd_tree the MI command tree * @param param the parameter * * @return code 200 on success, code 400 or 500 on failure */ struct mi_root* dump_fifo (struct mi_root* cmd_tree, void *param) { struct route_data_t * rd; str *tmp_str; str empty_str = str_init("<empty>"); if((rd = get_data ()) == NULL) { LM_ERR("error during retrieve data\n"); return init_mi_tree(500, "error during command processing", 31); } struct mi_root* rpl_tree; struct mi_node* node = NULL; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if(rpl_tree == NULL) goto error2; node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "Printing routing information:"); if(node == NULL) goto error; LM_DBG("start processing of data\n"); int i, j; for (i = 0; i < rd->carrier_num; i++) { if (rd->carriers[i]) { tmp_str = (rd->carriers[i] ? rd->carriers[i]->name : &empty_str); node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "Printing tree for carrier '%.*s' (%i)\n", tmp_str->len, tmp_str->s, rd->carriers[i] ? rd->carriers[i]->id : 0); if(node == NULL) goto error; for (j=0; j<rd->carriers[i]->domain_num; j++) { if (rd->carriers[i]->domains[j] && rd->carriers[i]->domains[j]->tree) { tmp_str = (rd->carriers[i]->domains[j] ? rd->carriers[i]->domains[j]->name : &empty_str); node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "Printing tree for domain '%.*s' (%i)\n", tmp_str->len, tmp_str->s, rd->carriers[i]->domains[j]->id); if(node == NULL) goto error; if (dump_tree_recursor (&rpl_tree->node, rd->carriers[i]->domains[j]->tree, "") < 0) goto error; } } } } release_data (rd); return rpl_tree; error: free_mi_tree(rpl_tree); error2: release_data (rd); return 0; }
void agent_flush_cache (void) { ITEM r; if (DBG_CACHE) log_debug ("agent_flush_cache\n"); for (r=thecache; r; r = r->next) { if (!r->lockcount && r->pw) { if (DBG_CACHE) log_debug (" flushing `%s'\n", r->key); release_data (r->pw); r->pw = NULL; r->accessed = 0; } else if (r->lockcount && r->pw) { if (DBG_CACHE) log_debug (" marked `%s' for flushing\n", r->key); r->accessed = 0; r->ttl = 0; } } }
static void _vdp_video_mem_unmap (GstVdpVideoMemory * vmem) { GST_DEBUG ("surface:%d", vmem->surface); release_data (vmem); }
Ndb_move_data::~Ndb_move_data() { delete m_sourceattr; delete m_targetattr; m_sourceattr = 0; m_targetattr = 0; release_data(); }
/** * prints the routing data * * @param mi_root the fifo command tree * @param param the parameter * * @return code 200 on success, code 400 or 500 on failure */ struct mi_root* dump_fifo (struct mi_root* cmd_tree, void *param) { struct rewrite_data * rd; if((rd = get_data ()) == NULL) { LM_ERR("error during retrieve data\n"); return init_mi_tree(500, "error during command processing", 31); } struct mi_root* rpl_tree; struct mi_node* node = NULL; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if(rpl_tree == NULL) return 0; node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "Printing routing information:"); if(node == NULL) goto error; LM_DBG("start processing of data\n"); int i, j; for (i = 0; i < rd->tree_num; i++) { if (rd->carriers[i]) { node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "Printing tree for carrier %s (%i)\n", rd->carriers[i] ? rd->carriers[i]->name.s : "<empty>", rd->carriers[i] ? rd->carriers[i]->id : 0); if(node == NULL) goto error; for (j=0; j<rd->carriers[i]->tree_num; j++) { if (rd->carriers[i]->trees[j] && rd->carriers[i]->trees[j]->tree) { node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "Printing tree for domain %s\n", rd->carriers[i]->trees[j] ? rd->carriers[i]->trees[j]->name.s : "<empty>"); if(node == NULL) goto error; dump_tree_recursor (&rpl_tree->node, rd->carriers[i]->trees[j]->tree, ""); } } } } release_data (rd); return rpl_tree; return 0; error: release_data (rd); free_mi_tree(rpl_tree); return 0; }
/***********************************************************************//** * @brief Resize column data * * @param[in] index Start index. * @param[in] number Number of elements to add/remove. * * Adds or removes elements from specified index on. Adding is done if * @p number is a positive number, removing if @p number is negative. * Note that the method does not change the validity of the arguments. * This needs to be done by the client. ***************************************************************************/ void GFitsTableCFloatCol::resize_data(const int& index, const int& number) { // Continue only if number of elements is not zero if (number != 0) { // If data are not available then load them now if (m_data == NULL) fetch_data(); // If elements should be removed then do not allocate new memory // but just move elements forward and change the logical size of // memory. Only if all elements should be removed the memory is // released. if (number < 0) { int left = index - number; GFits::cfloat* dst = m_data + index; GFits::cfloat* src = m_data + left; int num = m_size - left; for (int i = 0; i < num; ++i) { *dst++ = *src++; } m_size += number; if (m_size < 1) { release_data(); } } // If elements should be added then allocate new memory, copy over // the old data and initialise the new elements else { int left = m_size - index; m_size += number; GFits::cfloat* new_data = new GFits::cfloat[m_size]; GFits::cfloat* dst = new_data; GFits::cfloat* src = m_data; for (int i = 0; i < index; ++i) { *dst++ = *src++; } for (int i = 0; i < number; ++i) { dst->re = 0.0; dst->im = 0.0; dst++; } for (int i = 0; i < left; ++i) { *dst++ = *src++; } if (m_data != NULL) delete [] m_data; m_data = new_data; } } // endif: number was non-zero // Return return; }
void release_all_resources() { int ret; ret = lib.deinit(); if (ret == -1) LOG("Library termination failed\n"); kill_all(); release_data(); fflush(stderr); fclose(stderr); }
/***********************************************************************//** * @brief Allocate data ***************************************************************************/ void GFitsImageDouble::alloc_data(void) { // Release any existing data release_data(); // Allocate new data if (m_num_pixels > 0) { m_pixels = new double[m_num_pixels]; } // Return return; }
static int rewrite_msg(int domain, str * uri, struct sip_msg * msg, str * user, enum hash_source hash_source, enum hash_algorithm alg) { int index; struct rewrite_data * rd; do { rd = get_data(); } while (rd == NULL); index = rd->default_carrier_index; release_data(rd); return carrier_rewrite_msg(index, domain, uri, msg, user, hash_source, alg); }
int Ndb_move_data::move_batch() { int ret = 0; Op& op = m_op; op.rows_in_batch = 0; op.truncated_in_batch = 0; do { int res; CHK2((res = op.scanop->nextResult(true)) != -1, (op.scanop->getNdbError())); require(res == 0 || res == 1); if (res == 1) { op.end_of_scan = true; op.ndb->closeTransaction(op.scantrans); op.scantrans = 0; break; } require(op.updatetrans == 0); op.updatetrans = op.ndb->startTransaction(); CHK2(op.updatetrans != 0, (op.ndb->getNdbError())); do { CHK1(move_row() == 0); op.rows_in_batch++; CHK2((res = op.scanop->nextResult(false)) != -1, (op.scanop->getNdbError())); require(res == 0 || res == 2); } while (res == 0); CHK1(ret == 0); if (m_error_insert && ndb_rand() % 5 == 0) { invoke_error_insert(); CHK1(false); } CHK2(op.updatetrans->execute(NdbTransaction::Commit) == 0, (op.updatetrans->getNdbError())); op.ndb->closeTransaction(op.updatetrans); op.updatetrans = 0; } while (0); release_data(); return ret; }
/** * The fixup funcions will use the initial mapping. * If the mapping changes afterwards (eg. due to cr_reload_routes), * the names used in the routing script will not be mapped * to the correct IDs! * @param name domain name * @return domain id */ static int domain_name_2_id(const str *name) { int id; struct route_data_t * rd; do { rd = get_data(); } while (rd == NULL); id = map_name2id(rd->domain_map, rd->domain_num, name); release_data(rd); return id; }
gboolean gst_vdp_video_memory_unmap (GstVideoMeta * meta, guint plane, GstMapInfo * info) { GstVdpVideoMemory *vmem = (GstVdpVideoMemory *) gst_buffer_get_memory (meta->buffer, 0); GST_DEBUG ("plane:%d", plane); GST_FIXME ("implement unmap (and potential upload on last unmap)"); release_data (vmem); return TRUE; }
/** * rewrites the request URI of msg after determining the * new destination URI * * @param carrier the requested carrier * @param domain the requested routing domain * @param uri the URI to be rewritten * @param msg the current 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 * * @return 1 on success, -1 on failure */ static int carrier_rewrite_msg(int carrier, int domain, str * uri, struct sip_msg * msg, str * user, enum hash_source hash_source, enum hash_algorithm alg) { struct rewrite_data *rd; struct route_tree * rt; struct action act; str dest; int ret; do { rd = get_data(); } while (rd == NULL); if (carrier >= rd->tree_num) { LM_ERR("desired carrier doesn't exist. (We only have %ld carriers, " "you wanted %d.)\n", (long)(rd->tree_num) - 1, carrier); ret = -1; goto unlock_and_out; } if ((rt = get_route_tree_by_id(rd->carriers[carrier], domain)) == NULL) { LM_ERR("desired routing domain doesn't exist, uri %.*s, carrier %d, domain %d\n", user->len, user->s, carrier, domain); ret = -1; goto unlock_and_out; } if (rewrite_uri_recursor(rt->tree, uri, &dest, msg, user, hash_source, alg) != 0) { LM_ERR("during rewrite_uri_recursor, uri %.*s, carrier %d, domain %d\n", user->len, user->s, carrier, domain); ret = -1; goto unlock_and_out; } LM_INFO("uri %.*s was rewritten to %.*s\n", user->len, user->s, dest.len, dest.s); act.type = SET_URI_T; act.elem[0].type= STRING_ST; act.elem[0].u.string = dest.s; act.next = NULL; ret = do_action(&act, msg); if (ret < 0) { LM_ERR("Error in do_action()\n"); } pkg_free(dest.s); unlock_and_out: release_data(rd); return ret; }
int main (int argc, char *argv[]) { GnomeProgram *program; char *description; if (! g_thread_supported ()) { g_thread_init (NULL); gdk_threads_init (); } bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); description = g_strdup_printf ("- %s", _("View and organize your images")); context = g_option_context_new (description); g_free (description); g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE); program = gnome_program_init ("gthumb", VERSION, LIBGNOMEUI_MODULE, argc, argv, GNOME_PARAM_GOPTION_CONTEXT, context, GNOME_PARAM_HUMAN_READABLE_NAME, _("gThumb"), GNOME_PARAM_APP_PREFIX, GTHUMB_PREFIX, GNOME_PARAM_APP_SYSCONFDIR, GTHUMB_SYSCONFDIR, GNOME_PARAM_APP_DATADIR, GTHUMB_DATADIR, GNOME_PARAM_APP_LIBDIR, GTHUMB_LIBDIR, NULL); gnome_vfs_init (); gnome_authentication_manager_init (); glade_gnome_init (); gthumb_init (); initialize_data (); prepare_app (); gdk_threads_enter (); gtk_main (); gdk_threads_leave (); release_data (); return 0; }
void agent_flush_cache (void) { ITEM r; if (DBG_CACHE) log_debug ("agent_flush_cache\n"); for (r=thecache; r; r = r->next) { if (r->pw) { if (DBG_CACHE) log_debug (" flushing '%s'\n", r->key); release_data (r->pw); r->pw = NULL; r->accessed = 0; } } }
int main (int argc, char **argv) { GtkApplication *app; int status; program_argv0 = argv[0]; g_type_init (); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); app = fr_application_new (); status = g_application_run (G_APPLICATION (app), argc, argv); release_data (); g_object_unref (app); return status; }
/** * rewrites the request URI of msg after determining the * new destination URI * * @param _msg the current SIP message * @param _carrier the requested carrier * @param _domain the requested routing domain * @param _prefix_matching the user to be used for prefix matching * @param _rewrite_user the localpart of the URI to be rewritten * @param _hsrc the SIP header used for hashing * @param _halg the hash algorithm used for hashing * @param _dstavp the name of the destination AVP where the used host name is stored * * @return 1 on success, -1 on failure */ int cr_do_route(struct sip_msg * _msg, struct multiparam_t *_carrier, struct multiparam_t *_domain, pv_elem_t *_prefix_matching, pv_elem_t *_rewrite_user, enum hash_source _hsrc, enum hash_algorithm _halg, struct multiparam_t *_dstavp) { int carrier_id; int domain_id; str rewrite_user; str prefix_matching; flag_t flags; struct rewrite_data * rd; struct carrier_tree * ct; struct route_tree * rt; struct action act; str dest; int ret; ret = -1; carrier_id = mp2carrier_id(_msg, _carrier); domain_id = mp2domain_id(_msg, _domain); if (domain_id < 0) { LM_ERR("invalid domain id %d\n", domain_id); return -1; } if (pv_printf_s(_msg, _rewrite_user, &rewrite_user)<0) { LM_ERR("cannot print the rewrite_user\n"); return -1; } if (pv_printf_s(_msg, _prefix_matching, &prefix_matching)<0) { LM_ERR("cannot print the prefix_matching\n"); return -1; } flags = _msg->flags; do { rd = get_data(); } while (rd == NULL); ct=NULL; if (carrier_id < 0) { if (fallback_default) { LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id); ct = rd->carriers[rd->default_carrier_index]; } } else if (carrier_id == 0) { ct = rd->carriers[rd->default_carrier_index]; } else { ct = get_carrier_tree(carrier_id, rd); if (ct == NULL) { if (fallback_default) { LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id); ct = rd->carriers[rd->default_carrier_index]; } } } if (ct == NULL) { LM_ERR("cannot get carrier tree\n"); goto unlock_and_out; } rt = get_route_tree_by_id(ct, domain_id); if (rt == NULL) { LM_ERR("desired routing domain doesn't exist, prefix %.*s, carrier %d, domain %d\n", prefix_matching.len, prefix_matching.s, carrier_id, domain_id); goto unlock_and_out; } if (rewrite_uri_recursor(rt->tree, &prefix_matching, flags, &dest, _msg, &rewrite_user, _hsrc, _halg, _dstavp) != 0) { /* this is not necessarily an error, rewrite_recursor does already some error logging */ LM_INFO("rewrite_uri_recursor doesn't complete, uri %.*s, carrier %d, domain %d\n", prefix_matching.len, prefix_matching.s, carrier_id, domain_id); goto unlock_and_out; } LM_INFO("uri %.*s was rewritten to %.*s\n", rewrite_user.len, rewrite_user.s, dest.len, dest.s); act.type = SET_URI_T; act.elem[0].type= STR_ST; act.elem[0].u.s = dest; act.next = NULL; ret = do_action(&act, _msg); if (ret < 0) { LM_ERR("Error in do_action()\n"); } pkg_free(dest.s); unlock_and_out: release_data(rd); return ret; }
/** * Loads next domain from failure routing table and stores it in an AVP. * * @param _msg the current SIP message * @param _carrier the requested carrier * @param _domain the requested routing domain * @param _prefix_matching the user to be used for prefix matching * @param _host the host name to be used for rule matching * @param _reply_code the reply code to be used for rule matching * @param _dstavp the name of the destination AVP * * @return 1 on success, -1 on failure */ int cr_load_next_domain(struct sip_msg * _msg, gparam_t *_carrier, gparam_t *_domain, gparam_t *_prefix_matching, gparam_t *_host, gparam_t *_reply_code, gparam_t *_dstavp) { int carrier_id, domain_id, ret = -1; str prefix_matching, host, reply_code; flag_t flags; struct route_data_t * rd; struct carrier_data_t * carrier_data; struct domain_data_t * domain_data; if (fixup_get_svalue(_msg, _prefix_matching, &prefix_matching)<0) { LM_ERR("cannot print the prefix_matching\n"); return -1; } if (fixup_get_svalue(_msg, _host, &host)<0) { LM_ERR("cannot print the host\n"); return -1; } if (fixup_get_svalue(_msg, _reply_code, &reply_code)<0) { LM_ERR("cannot print the reply_code\n"); return -1; } flags = _msg->flags; do { rd = get_data(); } while (rd == NULL); carrier_id = cr_gp2id(_msg, _carrier, rd->carrier_map, rd->carrier_num); if (carrier_id < 0) { LM_ERR("invalid carrier id %d\n", carrier_id); release_data(rd); return -1; } domain_id = cr_gp2id(_msg, _domain, rd->domain_map, rd->domain_num); if (domain_id < 0) { LM_ERR("invalid domain id %d\n", domain_id); release_data(rd); return -1; } carrier_data=NULL; if (carrier_id < 0) { if (cfg_get(carrierroute, carrierroute_cfg, fallback_default)) { LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id); carrier_data = get_carrier_data(rd, rd->default_carrier_id); } } else if (carrier_id == 0) { carrier_data = get_carrier_data(rd, rd->default_carrier_id); } else { carrier_data = get_carrier_data(rd, carrier_id); if (carrier_data == NULL) { if (cfg_get(carrierroute, carrierroute_cfg, fallback_default)) { LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id); carrier_data = get_carrier_data(rd, rd->default_carrier_id); } } } if (carrier_data == NULL) { LM_ERR("cannot get carrier data\n"); goto unlock_and_out; } domain_data = get_domain_data(carrier_data, domain_id); if (domain_data == NULL) { LM_ERR("desired routing domain doesn't exist, prefix %.*s, carrier %d, domain %d\n", prefix_matching.len, prefix_matching.s, carrier_id, domain_id); goto unlock_and_out; } if (set_next_domain_recursor(domain_data->failure_tree, &prefix_matching, &host, &reply_code, flags, _dstavp) != 0) { LM_INFO("set_next_domain_recursor doesn't complete, prefix '%.*s', carrier %d, domain %d\n", prefix_matching.len, prefix_matching.s, carrier_id, domain_id); goto unlock_and_out; } ret = 1; unlock_and_out: release_data(rd); return ret; }
void _delvec(QSP_ARG_DECL Data_Obj *dp) { assert(dp!=NULL); assert(OBJ_NAME(dp)!=NULL); #ifdef ZOMBIE_SUPPORT // This should go back in eventually! if( OBJ_FLAGS(dp) & DT_STATIC && OWNS_DATA(dp) ){ sprintf(ERROR_STRING,"delvec: static object %s will be made a zombie",OBJ_NAME(dp)); advise(ERROR_STRING); make_zombie(dp); return; } if( OBJ_REFCOUNT(dp) > 0 ){ /* This zombie business was introduced at a time * when a displayed image had to be kept around * to refresh its window... with the current * X windows implementation of viewers that is * no longer the case, so this may be unecessary... * * But another case arises when we have a static * object in the expression language, that gets * deleted outside of the expression language. * This shouldn't be done, but we don't want to * be able to crash the program either... */ sprintf(ERROR_STRING,"delvec: object %s (refcount = %d) will be made a zombie",OBJ_NAME(dp),dp->dt_refcount); advise(ERROR_STRING); make_zombie(dp); return; } #endif /* ZOMBIE_SUPPORT */ // If the object has been exported, we need to delete // the associated identifier... // // BUT if it was exported, then it may be referenced!? // So it should be static... // // If we have references, and are therefore keeping the // object as a zombie, then we don't want to delete the // identifier, and we probably don't want to change the // object's name... if( IS_EXPORTED(dp) ){ Identifier *idp; idp = id_of(OBJ_NAME(dp)); assert( idp != NULL ); delete_id((Item *)idp); } if( OBJ_CHILDREN( dp ) != NULL ){ delete_subobjects(dp); } if( OBJ_PARENT(dp) != NULL ){ disown_child(dp); } if( IS_TEMP(dp) ){ if( OBJ_DECLFILE(dp) != NULL ){ sprintf(ERROR_STRING,"delvec %s: temp object has declfile %s!?\n", OBJ_NAME(dp),OBJ_DECLFILE(dp)); advise(ERROR_STRING); } release_tmp_obj(dp); /* * Most likely called when parent is deleted. * Temp objects are not hashed, and are not dynamically * allocated. * * Simply mark as free by clearing name field. */ return; } // We might clean this up by making the release // function a platform member... if( OWNS_DATA(dp) ){ if( ! UNKNOWN_SHAPE(OBJ_SHAPE(dp)) ){ release_data(dp); } } // In the first OpenCL implementation, we used subbuffers, which had // to be released here even for subimages. But now we handle subobjects // ourselves, managing offsets, so non-data-owners don't need to release. rls_shape( OBJ_SHAPE(dp) ); // We don't need to do this if we have garbage collection? /* The name might be null if we had an error creating the object... */ if( OBJ_DECLFILE(dp) != NULL ){ rls_str( OBJ_DECLFILE(dp) ); } #ifdef ZOMBIE_SUPPORT /* BUG context code assumes that this is really deleted... */ // not sure I understand the above comment? if( IS_ZOMBIE(dp) ){ // The object is a zombie that is no longer referenced... /* NOTE: we used to release the struct here with givbuf, * but in the current implementation of the item package, * objects aren't allocated with getbuf! */ // The object has already been removed from the dictionary, // so we don't need to call del_item... /* put this back on the free list... */ recycle_item(dobj_itp,dp); } else { del_item(dobj_itp, dp ); } #else /* ! ZOMBIE_SUPPORT */ DELETE_OBJ_ITEM(dp); // del_dobj - item function #endif /* ! ZOMBIE_SUPPORT */ // used to release the name here // and set to null, but that is done in del_item }
/* Store the string DATA in the cache under KEY and mark it with a maximum lifetime of TTL seconds. If there is already data under this key, it will be replaced. Using a DATA of NULL deletes the entry. A TTL of 0 is replaced by the default TTL and a TTL of -1 set infinite timeout. CACHE_MODE is stored with the cache entry and used to select different timeouts. */ int agent_put_cache (const char *key, cache_mode_t cache_mode, const char *data, int ttl) { gpg_error_t err = 0; ITEM r; if (DBG_CACHE) log_debug ("agent_put_cache '%s' (mode %d) requested ttl=%d\n", key, cache_mode, ttl); housekeeping (); if (!ttl) { switch(cache_mode) { case CACHE_MODE_SSH: ttl = opt.def_cache_ttl_ssh; break; default: ttl = opt.def_cache_ttl; break; } } if ((!ttl && data) || cache_mode == CACHE_MODE_IGNORE) return 0; for (r=thecache; r; r = r->next) { if (((cache_mode != CACHE_MODE_USER && cache_mode != CACHE_MODE_NONCE) || r->cache_mode == cache_mode) && !strcmp (r->key, key)) break; } if (r) /* Replace. */ { if (r->pw) { release_data (r->pw); r->pw = NULL; } if (data) { r->created = r->accessed = gnupg_get_time (); r->ttl = ttl; r->cache_mode = cache_mode; err = new_data (data, &r->pw); if (err) log_error ("error replacing cache item: %s\n", gpg_strerror (err)); } } else if (data) /* Insert. */ { r = xtrycalloc (1, sizeof *r + strlen (key)); if (!r) err = gpg_error_from_syserror (); else { strcpy (r->key, key); r->created = r->accessed = gnupg_get_time (); r->ttl = ttl; r->cache_mode = cache_mode; err = new_data (data, &r->pw); if (err) xfree (r); else { r->next = thecache; thecache = r; } } if (err) log_error ("error inserting cache item: %s\n", gpg_strerror (err)); } return err; }
/** * rewrites the request URI of msg after determining the * new destination URI * * @param _msg the current SIP message * @param _carrier the requested carrier * @param _domain the requested routing domain * @param _prefix_matching the user to be used for prefix matching * @param _rewrite_user the localpart of the URI to be rewritten * @param _hsrc the SIP header used for hashing * @param _halg the hash algorithm used for hashing * @param _dstavp the name of the destination AVP where the used host name is stored * * @return 1 on success, -1 on failure */ int cr_do_route(struct sip_msg * _msg, gparam_t *_carrier, gparam_t *_domain, gparam_t *_prefix_matching, gparam_t *_rewrite_user, enum hash_source _hsrc, enum hash_algorithm _halg, gparam_t *_dstavp) { int carrier_id, domain_id, ret = -1; str rewrite_user, prefix_matching, dest; flag_t flags; struct route_data_t * rd; struct carrier_data_t * carrier_data; struct domain_data_t * domain_data; struct action act; struct run_act_ctx ra_ctx; if (fixup_get_svalue(_msg, _rewrite_user, &rewrite_user)<0) { LM_ERR("cannot print the rewrite_user\n"); return -1; } if (fixup_get_svalue(_msg, _prefix_matching, &prefix_matching)<0) { LM_ERR("cannot print the prefix_matching\n"); return -1; } flags = _msg->flags; do { rd = get_data(); } while (rd == NULL); carrier_id = cr_gp2id(_msg, _carrier, rd->carrier_map, rd->carrier_num); if (carrier_id < 0) { LM_ERR("invalid carrier id %d\n", carrier_id); release_data(rd); return -1; } domain_id = cr_gp2id(_msg, _domain, rd->domain_map, rd->domain_num); if (domain_id < 0) { LM_ERR("invalid domain id %d\n", domain_id); release_data(rd); return -1; } carrier_data=NULL; if (carrier_id < 0) { if (cfg_get(carrierroute, carrierroute_cfg, fallback_default)) { LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id); carrier_data = get_carrier_data(rd, rd->default_carrier_id); } } else if (carrier_id == 0) { carrier_data = get_carrier_data(rd, rd->default_carrier_id); } else { carrier_data = get_carrier_data(rd, carrier_id); if (carrier_data == NULL) { if (cfg_get(carrierroute, carrierroute_cfg, fallback_default)) { LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id); carrier_data = get_carrier_data(rd, rd->default_carrier_id); } } } if (carrier_data == NULL) { LM_ERR("cannot get carrier data\n"); goto unlock_and_out; } domain_data = get_domain_data(carrier_data, domain_id); if (domain_data == NULL) { LM_ERR("desired routing domain doesn't exist, prefix %.*s, carrier %d, domain %d\n", prefix_matching.len, prefix_matching.s, carrier_id, domain_id); goto unlock_and_out; } if (rewrite_uri_recursor(domain_data->tree, &prefix_matching, flags, &dest, _msg, &rewrite_user, _hsrc, _halg, _dstavp) != 0) { /* this is not necessarily an error, rewrite_recursor does already some error logging */ LM_INFO("rewrite_uri_recursor doesn't complete, uri %.*s, carrier %d, domain %d\n", prefix_matching.len, prefix_matching.s, carrier_id, domain_id); goto unlock_and_out; } LM_INFO("uri %.*s was rewritten to %.*s, carrier %d, domain %d\n", rewrite_user.len, rewrite_user.s, dest.len, dest.s, carrier_id, domain_id); memset(&act, 0, sizeof(act)); act.type = SET_URI_T; act.val[0].type = STRING_ST; act.val[0].u.string = dest.s; init_run_actions_ctx(&ra_ctx); ret = do_action(&ra_ctx, &act, _msg); if (ret < 0) { LM_ERR("Error in do_action()\n"); } unlock_and_out: release_data(rd); return ret; }
/** * rewrites the request URI of msg by calculating a rule, using * crc32 for hashing. The request URI is used to determine tree node * the given _user is used to determine the routing tree. * * @param msg the current SIP message * @param _uri the URI to determine the route tree (string or pseudo-variable) * @param _domain the requested routing domain * * @return 1 on success, -1 on failure */ int user_route_uri(struct sip_msg * _msg, char * _uri, char * _domain) { pv_elem_t *model; str uri, user, str_domain, ruser, ruri; struct sip_uri puri; int carrier_id, domain, index; domain = (int)(long)_domain; struct rewrite_data * rd = NULL; struct carrier_tree * ct = NULL; if (!_uri) { LM_ERR("bad parameter\n"); return -1; } if (parse_sip_msg_uri(_msg) < 0) { return -1; } /* Retrieve uri from parameter */ model = (pv_elem_t*)_uri; if (pv_printf_s(_msg, model, &uri)<0) { LM_ERR("cannot print the format\n"); return -1; } if (parse_uri(uri.s, uri.len, &puri) < 0) { LM_ERR("Error while parsing URI\n"); return -5; } user = puri.user; str_domain = puri.host; ruser.s = _msg->parsed_uri.user.s; ruser.len = _msg->parsed_uri.user.len; ruri.s = _msg->parsed_uri.user.s; ruri.len = _msg->parsed_uri.user.len; do { rd = get_data(); } while (rd == NULL); if ((carrier_id = load_user_carrier(&user, &str_domain)) < 0) { release_data(rd); return -1; } else if (carrier_id == 0) { index = rd->default_carrier_index; } else { if ((ct = get_carrier_tree(carrier_id, rd)) == NULL) { if (fallback_default) { index = rd->default_carrier_index; } else { LM_ERR("desired routing tree with id %i doesn't exist\n", carrier_id); release_data(rd); return -1; } } else { index = ct->index; } } release_data(rd); return carrier_rewrite_msg(index, domain, &ruri, _msg, &ruser, shs_call_id, alg_crc32); }
/* Check whether there are items to expire. */ static void housekeeping (void) { ITEM r, rprev; time_t current = gnupg_get_time (); /* First expire the actual data */ for (r=thecache; r; r = r->next) { if (r->pw && r->ttl >= 0 && r->accessed + r->ttl < current) { if (DBG_CACHE) log_debug (" expired '%s' (%ds after last access)\n", r->key, r->ttl); release_data (r->pw); r->pw = NULL; r->accessed = current; } } /* Second, make sure that we also remove them based on the created stamp so that the user has to enter it from time to time. */ for (r=thecache; r; r = r->next) { unsigned long maxttl; switch (r->cache_mode) { case CACHE_MODE_SSH: maxttl = opt.max_cache_ttl_ssh; break; default: maxttl = opt.max_cache_ttl; break; } if (r->pw && r->created + maxttl < current) { if (DBG_CACHE) log_debug (" expired '%s' (%lus after creation)\n", r->key, opt.max_cache_ttl); release_data (r->pw); r->pw = NULL; r->accessed = current; } } /* Third, make sure that we don't have too many items in the list. Expire old and unused entries after 30 minutes */ for (rprev=NULL, r=thecache; r; ) { if (!r->pw && r->ttl >= 0 && r->accessed + 60*30 < current) { ITEM r2 = r->next; if (DBG_CACHE) log_debug (" removed '%s' (mode %d) (slot not used for 30m)\n", r->key, r->cache_mode); xfree (r); if (!rprev) thecache = r2; else rprev->next = r2; r = r2; } else { rprev = r; r = r->next; } } }
/* Store DATA of length DATALEN in the cache under KEY and mark it with a maximum lifetime of TTL seconds. If there is already data under this key, it will be replaced. Using a DATA of NULL deletes the entry. A TTL of 0 is replaced by the default TTL and a TTL of -1 set infinite timeout. CACHE_MODE is stored with the cache entry and used to select different timeouts. */ int agent_put_cache (const char *key, cache_mode_t cache_mode, const char *data, int ttl) { ITEM r; if (DBG_CACHE) log_debug ("agent_put_cache `%s' requested ttl=%d mode=%d\n", key, ttl, cache_mode); housekeeping (); if (!ttl) { switch(cache_mode) { case CACHE_MODE_SSH: ttl = opt.def_cache_ttl_ssh; break; default: ttl = opt.def_cache_ttl; break; } } if (!ttl || cache_mode == CACHE_MODE_IGNORE) return 0; for (r=thecache; r; r = r->next) { if (!r->lockcount && !strcmp (r->key, key)) break; } if (r) { /* replace */ if (r->pw) { release_data (r->pw); r->pw = NULL; } if (data) { r->created = r->accessed = gnupg_get_time (); r->ttl = ttl; r->cache_mode = cache_mode; r->pw = new_data (data, strlen (data)+1); if (!r->pw) log_error ("out of core while allocating new cache item\n"); } } else if (data) { /* simply insert */ r = xtrycalloc (1, sizeof *r + strlen (key)); if (!r) log_error ("out of core while allocating new cache control\n"); else { strcpy (r->key, key); r->created = r->accessed = gnupg_get_time (); r->ttl = ttl; r->cache_mode = cache_mode; r->pw = new_data (data, strlen (data)+1); if (!r->pw) { log_error ("out of core while allocating new cache item\n"); xfree (r); } else { r->next = thecache; thecache = r; } } } return 0; }
/** * prints the routing data * * @param rpc - RPC API structure * @param ctx - RPC context */ void cr_rpc_dump_routes(rpc_t* rpc, void* ctx) { struct route_data_t * rd; str *tmp_str; str empty_str = str_init("<empty>"); void* th; void* ih; void* dh; void* eh; void* fh; void* gh; int i, j; if((rd = get_data ()) == NULL) { LM_ERR("error during retrieve data\n"); rpc->fault(ctx, 500, "Internal error - cr data"); return; } /* add root node */ if (rpc->add(ctx, "{", &th) < 0) { rpc->fault(ctx, 500, "Internal error root reply"); goto error; } if(rpc->struct_add(th, "[", "routes", &ih)<0) { rpc->fault(ctx, 500, "Internal error - routes structure"); goto error; } LM_DBG("start processing of data\n"); for (i = 0; i < rd->carrier_num; i++) { if (rd->carriers[i]) { if (rpc->array_add(ih, "{", &dh)<0) { LM_ERR("add carrier data failure at count %d\n", i); rpc->fault(ctx, 500, "Response failure - carrier data"); goto error; } tmp_str = (rd->carriers[i] ? rd->carriers[i]->name : &empty_str); if(rpc->struct_add(dh, "Sd[", "carrier", tmp_str, "id", (rd->carriers[i] ? rd->carriers[i]->id : 0), "domains", &eh)<0) { LM_ERR("add carrier structure failure at count %d" " (carrier: %d/%.*s)\n", i, tmp_str->len, tmp_str->len, tmp_str->s); rpc->fault(ctx, 500, "Internal error - carrier structure"); goto error; } for (j=0; j<rd->carriers[i]->domain_num; j++) { if (rd->carriers[i]->domains[j] && rd->carriers[i]->domains[j]->tree) { if (rpc->array_add(eh, "{", &fh)<0) { LM_ERR("add domain data failure at count %d/%d\n", i, j); rpc->fault(ctx, 500, "Response failure - domain data"); goto error; } tmp_str = (rd->carriers[i]->domains[j] ? rd->carriers[i]->domains[j]->name : &empty_str); if(rpc->struct_add(fh, "Sd[", "domain", tmp_str, "id", rd->carriers[i]->domains[j]->id, "data", &gh)<0) { LM_ERR("add domain structure failure at count %d/%d\n", i, j); rpc->fault(ctx, 500, "Internal error - domain structure"); goto error; } if (cr_rpc_dump_tree_recursor (rpc, ctx, gh, rd->carriers[i]->domains[j]->tree, "") < 0) { LM_ERR("dump tree recursor failure at count %d/%d\n", i, j); goto error; } } } } } release_data (rd); return; error: release_data (rd); return; }
/** * Loads next domain from failure routing table and stores it in an AVP. * * @param _msg the current SIP message * @param _carrier the requested carrier * @param _domain the requested routing domain * @param _prefix_matching the user to be used for prefix matching * @param _host the host name to be used for rule matching * @param _reply_code the reply code to be used for rule matching * @param _dstavp the name of the destination AVP * * @return 1 on success, -1 on failure */ int cr_load_next_domain(struct sip_msg * _msg, struct multiparam_t *_carrier, struct multiparam_t *_domain, pv_elem_t *_prefix_matching, pv_elem_t *_host, pv_elem_t *_reply_code, struct multiparam_t *_dstavp) { int carrier_id; int domain_id; str prefix_matching; str host; str reply_code; flag_t flags; struct rewrite_data * rd; struct carrier_tree * ct; struct route_tree * rt; int ret; ret = -1; carrier_id = mp2carrier_id(_msg, _carrier); domain_id = mp2domain_id(_msg, _domain); if (domain_id < 0) { LM_ERR("invalid domain id %d\n", domain_id); return -1; } if (pv_printf_s(_msg, _prefix_matching, &prefix_matching)<0) { LM_ERR("cannot print the prefix_matching\n"); return -1; } if (pv_printf_s(_msg, _host, &host)<0) { LM_ERR("cannot print the host\n"); return -1; } if (pv_printf_s(_msg, _reply_code, &reply_code)<0) { LM_ERR("cannot print the reply_code\n"); return -1; } flags = _msg->flags; do { rd = get_data(); } while (rd == NULL); ct=NULL; if (carrier_id < 0) { if (fallback_default) { LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id); ct = rd->carriers[rd->default_carrier_index]; } } else if (carrier_id == 0) { ct = rd->carriers[rd->default_carrier_index]; } else { ct = get_carrier_tree(carrier_id, rd); if (ct == NULL) { if (fallback_default) { LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id); ct = rd->carriers[rd->default_carrier_index]; } } } if (ct == NULL) { LM_ERR("cannot get carrier tree\n"); goto unlock_and_out; } rt = get_route_tree_by_id(ct, domain_id); if (rt == NULL) { LM_ERR("desired routing domain doesn't exist, prefix %.*s, carrier %d, domain %d\n", prefix_matching.len, prefix_matching.s, carrier_id, domain_id); goto unlock_and_out; } if (set_next_domain_recursor(rt->failure_tree, &prefix_matching, &host, &reply_code, flags, _dstavp) != 0) { LM_ERR("during set_next_domain_recursor, prefix '%.*s', carrier %d, domain %d\n", prefix_matching.len, prefix_matching.s, carrier_id, domain_id); goto unlock_and_out; } ret = 1; unlock_and_out: release_data(rd); return ret; }