/** * Copyright 2016 (C) Federico Cabiddu * Copyright 2016 (C) Giacomo Vacca * Copyright 2016 (C) Orange - Camille Oudot * * This file is part of Kamailio, a free SIP server. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * * * This file is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ /*! \file * \brief Kamailio http_async_client :: Hash functions * \ingroup http_async_client */ #include "hm_hash.h" extern int hash_size; /*! * \brief Initialize the global http multi table * \param size size of the table * \return 0 on success, -1 on failure */ int init_http_m_table(unsigned int size) { unsigned int i; hm_table = (struct http_m_table*)shm_malloc ( sizeof(struct http_m_table) + size*sizeof(struct http_m_entry) ); if (hm_table==0) { LM_ERR("no more shm mem\n"); return -1; } memset( hm_table, 0, sizeof(struct http_m_table) ); hm_table->size = size; hm_table->entries = (struct http_m_entry*)(hm_table+1); for( i=0 ; ientries[i]), 0, sizeof(struct http_m_entry) ); } LM_DBG("hash table %p initialized with size %d\n", hm_table, size); return 0; } unsigned int build_hash_key(void *p) { str *hash_str; char *pointer_str; int len; unsigned int hash; pointer_str = (char *)pkg_malloc(sizeof(p) + 1); if (pointer_str==0) { LM_ERR("no more pkg mem\n"); return 0; } sprintf(pointer_str, "%p", p); len = strlen(pointer_str); LM_DBG("received id %p (%d)-> %s (%d)\n", p, (int)sizeof(p), pointer_str, len); hash_str = (str *)pkg_malloc(sizeof(str)); if (hash_str==0) { LM_ERR("no more pkg mem\n"); pkg_free(pointer_str); return 0; } hash_str->s = pointer_str; hash_str->len = len; hash = core_hash(hash_str, 0, hash_size); LM_DBG("hash for %p is %d\n", p, hash); pkg_free(pointer_str); pkg_free(hash_str); return hash; } struct http_m_cell* build_http_m_cell(void *p) { struct http_m_cell *cell= NULL; int len; len = sizeof(struct http_m_cell); cell = (struct http_m_cell*)shm_malloc(len); if (cell==0) { LM_ERR("no more shm mem\n"); return 0; } memset( cell, 0, len); cell->hmt_entry = build_hash_key(p); cell->easy = p; LM_DBG("hash id for %p is %d\n", p, cell->hmt_entry); return cell; } void link_http_m_cell(struct http_m_cell *cell) { struct http_m_entry *hmt_entry; hmt_entry = &(hm_table->entries[cell->hmt_entry]); LM_DBG("linking new cell %p to table %p [%u]\n", cell, hm_table, cell->hmt_entry); if (hmt_entry->first==0) { hmt_entry->first = cell; hmt_entry->first = hmt_entry->last = cell; } else { hmt_entry->last->next = cell; cell->prev = hmt_entry->last; hmt_entry->last = cell; } return; } struct http_m_cell *http_m_cell_lookup(CURL *p) { struct http_m_entry *hmt_entry; struct http_m_cell *current_cell; unsigned int entry_idx; entry_idx = build_hash_key(p); hmt_entry = &(hm_table->entries[entry_idx]); for (current_cell = hmt_entry->first; current_cell; current_cell = current_cell->next) { if (current_cell->easy == p) { LM_DBG("http_m_cell with easy=%p found on table entry %u\n\n", p, entry_idx); return current_cell; } } /* not found */ LM_DBG("No http_m_cell with easy=%p found on table entry %u", p, entry_idx); return 0; } void free_http_m_cell(struct http_m_cell *cell) { if (!cell) return; if(cell->params.headers) { if(cell->params.headers) curl_slist_free_all(cell->params.headers); } if (cell->reply) { if (cell->reply->result) { if (cell->reply->result->s) { shm_free(cell->reply->result->s); } shm_free(cell->reply->result); } shm_free(cell->reply); } if (cell->url) shm_free(cell->url); if (cell->post_data) { shm_free(cell->post_data); } shm_free(cell); }