From 7b71bca8a40395341920d4d329de5af1896224c5 Mon Sep 17 00:00:00 2001 From: George Joseph Date: Wed, 2 Mar 2016 14:55:48 -0700 Subject: config_transport: Fix objects returned by ast_sip_get_transport_states ast_sip_get_transport_states was returning a container of internal_state objects instead of ast_sip_transport_state objects. This was causing transport lookups to fail, most noticably in res_pjsip_nat, which couldn't find the correct external addresses. This was causing contacts to go out with internal ip addresses. ASTERISK-25830 #close Reported-by: Sean Bright Change-Id: I1aee6a2fd46c42e8dd0af72498d17de459ac750e --- res/res_pjsip/config_transport.c | 77 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 2 deletions(-) (limited to 'res/res_pjsip') diff --git a/res/res_pjsip/config_transport.c b/res/res_pjsip/config_transport.c index e7bda5f05..61a979c88 100644 --- a/res/res_pjsip/config_transport.c +++ b/res/res_pjsip/config_transport.c @@ -108,6 +108,56 @@ static int internal_state_cmp(void *obj, void *arg, int flags) return CMP_MATCH; } +/*! \brief hashing function for state objects */ +static int transport_state_hash(const void *obj, const int flags) +{ + const struct ast_sip_transport_state *object; + const char *key; + + switch (flags & OBJ_SEARCH_MASK) { + case OBJ_SEARCH_KEY: + key = obj; + break; + case OBJ_SEARCH_OBJECT: + object = obj; + key = object->id; + break; + default: + ast_assert(0); + return 0; + } + return ast_str_hash(key); +} + +/*! \brief comparator function for state objects */ +static int transport_state_cmp(void *obj, void *arg, int flags) +{ + const struct ast_sip_transport_state *object_left = obj; + const struct ast_sip_transport_state *object_right = arg; + const char *right_key = arg; + int cmp; + + switch (flags & OBJ_SEARCH_MASK) { + case OBJ_SEARCH_OBJECT: + right_key = object_right->id; + /* Fall through */ + case OBJ_SEARCH_KEY: + cmp = strcmp(object_left->id, right_key); + break; + case OBJ_SEARCH_PARTIAL_KEY: + /* Not supported by container. */ + ast_assert(0); + return 0; + default: + cmp = 0; + break; + } + if (cmp) { + return 0; + } + return CMP_MATCH; +} + static int sip_transport_to_ami(const struct ast_sip_transport *transport, struct ast_str **buf) { @@ -499,7 +549,6 @@ static int transport_apply(const struct ast_sorcery *sorcery, void *obj) if (res == PJ_SUCCESS && (transport->tos || transport->cos)) { pj_sock_t sock; pj_qos_params qos_params; - sock = pjsip_udp_transport_get_socket(temp_state->state->transport); pj_sock_get_qos_params(sock, &qos_params); set_qos(transport, &qos_params); @@ -657,6 +706,11 @@ static int privkey_file_to_str(const void *obj, const intptr_t *args, char **buf static int transport_protocol_handler(const struct aco_option *opt, struct ast_variable *var, void *obj) { struct ast_sip_transport *transport = obj; + RAII_VAR(struct ast_sip_transport_state *, state, find_or_create_temporary_state(transport), ao2_cleanup); + + if (!state) { + return -1; + } if (!strcasecmp(var->value, "udp")) { transport->type = AST_TRANSPORT_UDP; @@ -672,6 +726,8 @@ static int transport_protocol_handler(const struct aco_option *opt, struct ast_v return -1; } + state->type = transport->type; + return 0; } @@ -1240,9 +1296,26 @@ struct ast_sip_transport_state *ast_sip_get_transport_state(const char *transpor return state->state; } +static int populate_transport_states(void *obj, void *arg, int flags) +{ + struct internal_state *state = obj; + struct ao2_container *container = arg; + + ao2_link(container, state->state); + + return CMP_MATCH; +} + struct ao2_container *ast_sip_get_transport_states(void) { - return ao2_container_clone(transport_states, 0); + struct ao2_container *states = ao2_container_alloc(DEFAULT_STATE_BUCKETS, transport_state_hash, transport_state_cmp); + + if (!states) { + return NULL; + } + + ao2_callback(transport_states, OBJ_NODATA | OBJ_MULTIPLE, populate_transport_states, states); + return states; } /*! \brief Initialize sorcery with transport support */ -- cgit v1.2.3