#include "../../sr_module.h" #include "../../crc.h" #include #include "sipcapture.h" #include "hash_mode.h" static int get_source(struct _sipcapture_object *sco, enum hash_source source, str *source_string); static int get_call_id (struct _sipcapture_object *sco, str *source_string); static int get_from_user (struct _sipcapture_object *sco, str *source_string); static int get_to_user (struct _sipcapture_object *sco, str *source_string); static int first_token (str *source_string); int hash_func (struct _sipcapture_object * sco, enum hash_source source, int denominator) { int ret; unsigned int hash; str source_string; if(get_source (sco, source, &source_string) == -1) { return -1; } LM_DBG("source string: [%.*s]\n", source_string.len, source_string.s); crc32_uint(&source_string, &hash); ret = hash % denominator; return ret; } static int get_source (struct _sipcapture_object *sco, enum hash_source source, str *source_string) { source_string->s = NULL; source_string->len = 0; switch (source) { case hs_call_id: return get_call_id (sco, source_string); case hs_from_user: return get_from_user(sco, source_string); case hs_to_user: return get_to_user(sco, source_string); default: LM_ERR("unknown hash source %i.\n", (int) source); return -1; } } static int get_call_id (struct _sipcapture_object * sco, str *source_string) { if (!sco->callid.s || !sco->callid.len) { return -1; } source_string->s = sco->callid.s; source_string->len = sco->callid.len; first_token (source_string); return 0; } static int get_from_user (struct _sipcapture_object * sco, str *source_string) { if (!sco->from_user.s || !sco->from_user.len) { return -1; } source_string->s = sco->from_user.s; source_string->len = sco->from_user.len; return 0; } static int get_to_user (struct _sipcapture_object * sco, str *source_string) { if (!sco->to_user.s || !sco->to_user.len) { return -1; } source_string->s = sco->to_user.s; source_string->len = sco->to_user.len; return 0; } static int first_token (str *source_string) { size_t len; if (source_string->s == NULL || source_string->len == 0) { return 0; } while (source_string->len > 0 && isspace (*source_string->s)) { ++source_string->s; --source_string->len; } for (len = 0; len < source_string->len; ++len) { if (isspace (source_string->s[len])) { source_string->len = len; break; } } return 0; } enum hash_source get_hash_source (const char *hash_source){ if (strcasecmp ("call_id", hash_source) == 0){ return hs_call_id; } else if (strcasecmp("from_user", hash_source) == 0) { return hs_from_user; } else if (strcasecmp("to_user", hash_source) == 0) { return hs_to_user; } else { return hs_error; } }