From 5bea6c1b1cdfe7d9fc1f9b8f22f8df8d915e34d9 Mon Sep 17 00:00:00 2001 From: Corey Farrell <git@cfware.com> Date: Thu, 24 Jul 2014 17:47:29 +0000 Subject: [PATCH] chan_sip: complete upgrade to ao2 This change upgrades sip_registry and sip_subscription_mwi to astobj2. ASTERISK-24067 #close Reported by: Corey Farrell Review: https://reviewboard.asterisk.org/r/3759/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419438 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_sip.c | 473 ++++++++++++++++++++++--------------- channels/sip/include/sip.h | 10 +- 2 files changed, 291 insertions(+), 192 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 2a32971dce..3686692cab 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -825,7 +825,6 @@ static int can_parse_xml; static int speerobjs = 0; /*!< Static peers */ static int rpeerobjs = 0; /*!< Realtime peers */ static int apeerobjs = 0; /*!< Autocreated peer objects */ -static int regobjs = 0; /*!< Registry objects */ /*! @} */ static struct ast_flags global_flags[3] = {{0}}; /*!< global SIP_ flags */ @@ -885,9 +884,11 @@ static const struct _map_x_s referstatusstrings[] = { #ifdef LOW_MEMORY static const int HASH_PEER_SIZE = 17; static const int HASH_DIALOG_SIZE = 17; +static const int HASH_REGISTRY_SIZE = 17; #else static const int HASH_PEER_SIZE = 563; /*!< Size of peer hash table, prime number preferred! */ static const int HASH_DIALOG_SIZE = 563; +static const int HASH_REGISTRY_SIZE = 563; #endif static const struct { @@ -1003,15 +1004,11 @@ static struct sip_peer *bogus_peer; #define BOGUS_PEER_MD5SECRET "intentionally_invalid_md5_string" /*! \brief The register list: Other SIP proxies we register with and receive calls from */ -static struct ast_register_list { - ASTOBJ_CONTAINER_COMPONENTS(struct sip_registry); - int recheck; -} regl; +static struct ao2_container *registry_list; /*! \brief The MWI subscription list */ -static struct ast_subscription_mwi_list { - ASTOBJ_CONTAINER_COMPONENTS(struct sip_subscription_mwi); -} submwil; +static struct ao2_container *subscription_mwi_list; + static int temp_pvt_init(void *); static void temp_pvt_cleanup(void *); @@ -1181,7 +1178,6 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer, int cache_only); /* Misc dialog routines */ static int __sip_autodestruct(const void *data); -static void *registry_unref(struct sip_registry *reg, char *tag); static int update_call_counter(struct sip_pvt *fup, int event); static int auto_congest(const void *arg); static struct sip_pvt *find_call(struct sip_request *req, struct ast_sockaddr *addr, const int intended_method); @@ -1369,7 +1365,7 @@ static char *sip_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli /*--- Internal UA client handling (outbound registrations) */ static void ast_sip_ouraddrfor(const struct ast_sockaddr *them, struct ast_sockaddr *us, struct sip_pvt *p); -static void sip_registry_destroy(struct sip_registry *reg); +static void sip_registry_destroy(void *reg); static int sip_register(const char *value, int lineno); static const char *regstate2str(enum sipregistrystate regstate) attribute_const; static int sip_reregister(const void *data); @@ -1503,7 +1499,7 @@ static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *i /*!--- SIP MWI Subscription support */ static int sip_subscribe_mwi(const char *value, int lineno); -static void sip_subscribe_mwi_destroy(struct sip_subscription_mwi *mwi); +static void sip_subscribe_mwi_destroy(void *data); static void sip_send_all_mwi_subscriptions(void); static int sip_subscribe_mwi_do(const void *data); static int __sip_subscribe_mwi_do(struct sip_subscription_mwi *mwi); @@ -3466,7 +3462,7 @@ void dialog_unlink_all(struct sip_pvt *dialog) if (dialog->registry->call == dialog) { dialog->registry->call = dialog_unref(dialog->registry->call, "nulling out the registry's call dialog field in unlink_all"); } - dialog->registry = registry_unref(dialog->registry, "delete dialog->registry"); + ao2_t_replace(dialog->registry, NULL, "delete dialog->registry"); } if (dialog->stateid != -1) { ast_extension_state_del(dialog->stateid, cb_extensionstate); @@ -3516,20 +3512,6 @@ void dialog_unlink_all(struct sip_pvt *dialog) dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time"); } -void *registry_unref(struct sip_registry *reg, char *tag) -{ - ast_debug(3, "SIP Registry %s: refcount now %u\n", reg->hostname, reg->refcount - 1); - ASTOBJ_UNREF(reg, sip_registry_destroy); - return NULL; -} - -/*! \brief Add object reference to SIP registry */ -static struct sip_registry *registry_addref(struct sip_registry *reg, char *tag) -{ - ast_debug(3, "SIP Registry %s: refcount now %u\n", reg->hostname, reg->refcount + 1); - return ASTOBJ_REF(reg); /* Add pointer to registry in packet */ -} - static void append_history_full(struct sip_pvt *p, const char *fmt, ...) __attribute__((format(printf, 2, 3))); @@ -6513,15 +6495,16 @@ static int sip_call(struct ast_channel *ast, const char *dest, int timeout) /*! \brief Destroy registry object Objects created with the register= statement in static configuration */ -static void sip_registry_destroy(struct sip_registry *reg) +static void sip_registry_destroy(void *obj) { + struct sip_registry *reg = obj; /* Really delete */ ast_debug(3, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); if (reg->call) { /* Clear registry before destroying to ensure we don't get reentered trying to grab the registry lock */ - reg->call->registry = registry_unref(reg->call->registry, "destroy reg->call->registry"); + ao2_t_replace(reg->call->registry, NULL, "destroy reg->call->registry"); ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); dialog_unlink_all(reg->call); reg->call = dialog_unref(reg->call, "unref reg->call"); @@ -6531,21 +6514,19 @@ static void sip_registry_destroy(struct sip_registry *reg) AST_SCHED_DEL(sched, reg->timeout); ast_string_field_free_memory(reg); - ast_atomic_fetchadd_int(®objs, -1); - ast_free(reg); } /*! \brief Destroy MWI subscription object */ -static void sip_subscribe_mwi_destroy(struct sip_subscription_mwi *mwi) +static void sip_subscribe_mwi_destroy(void *data) { + struct sip_subscription_mwi *mwi = data; if (mwi->call) { mwi->call->mwi = NULL; - sip_destroy(mwi->call); + mwi->call = dialog_unref(mwi->call, "sip_subscription_mwi destruction"); } AST_SCHED_DEL(sched, mwi->resub); ast_string_field_free_memory(mwi); - ast_free(mwi); } /*! \brief Destroy SDP media offer list */ @@ -6605,7 +6586,7 @@ void __sip_destroy(struct sip_pvt *p, int lockowner, int lockdialoglist) if (p->registry) { if (p->registry->call == p) p->registry->call = dialog_unref(p->registry->call, "nulling out the registry's call dialog field in unlink_all"); - p->registry = registry_unref(p->registry, "delete p->registry"); + ao2_t_replace(p->registry, NULL, "delete p->registry"); } if (p->mwi) { @@ -9541,18 +9522,27 @@ static struct sip_pvt *find_call(struct sip_request *req, struct ast_sockaddr *a /*! \brief create sip_registry object from register=> line in sip.conf and link into reg container */ static int sip_register(const char *value, int lineno) { - struct sip_registry *reg, *tmp; + struct sip_registry *reg; + + reg = ao2_t_find(registry_list, value, OBJ_SEARCH_KEY, "check for existing registry"); + if (reg) { + ao2_t_ref(reg, -1, "throw away found registry"); + return 0; + } - if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) { + if (!(reg = ao2_t_alloc(sizeof(*reg), sip_registry_destroy, "allocate a registry struct"))) { ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); return -1; } - ASTOBJ_INIT(reg); + if (ast_string_field_init(reg, 256)) { + ao2_t_ref(reg, -1, "failed to string_field_init, drop reg"); + return -1; + } - ast_copy_string(reg->name, value, sizeof(reg->name)); + ast_string_field_set(reg, configvalue, value); if (sip_parse_register_line(reg, default_expiry, value, lineno)) { - registry_unref(reg, "failure to parse, unref the reg pointer"); + ao2_t_ref(reg, -1, "failure to parse, unref the reg pointer"); return -1; } @@ -9561,16 +9551,8 @@ static int sip_register(const char *value, int lineno) reg->refresh = reg->expiry = reg->configured_expiry = default_expiry; } - /* Add the new registry entry to the list, but only if it isn't already there */ - if ((tmp = ASTOBJ_CONTAINER_FIND(®l, reg->name))) { - registry_unref(tmp, "throw away found registry"); - } else { - ast_atomic_fetchadd_int(®objs, 1); - ASTOBJ_CONTAINER_LINK(®l, reg); - } - - /* release the reference given by ASTOBJ_INIT. The container has another reference */ - registry_unref(reg, "unref the reg pointer"); + ao2_t_link(registry_list, reg, "link reg to registry_list"); + ao2_t_ref(reg, -1, "unref the reg pointer"); return 0; } @@ -9622,11 +9604,15 @@ static int sip_subscribe_mwi(const char *value, int lineno) } } - if (!(mwi = ast_calloc_with_stringfields(1, struct sip_subscription_mwi, 256))) { + if (!(mwi = ao2_t_alloc(sizeof(*mwi), sip_subscribe_mwi_destroy, "allocate an mwi struct"))) { + return -1; + } + + if (ast_string_field_init(mwi, 256)) { + ao2_t_ref(mwi, -1, "failed to string_field_init, drop mwi"); return -1; } - ASTOBJ_INIT(mwi); ast_string_field_set(mwi, username, username); if (secret) { ast_string_field_set(mwi, secret, secret); @@ -9640,8 +9626,8 @@ static int sip_subscribe_mwi(const char *value, int lineno) mwi->portno = portnum; mwi->transport = transport; - ASTOBJ_CONTAINER_LINK(&submwil, mwi); - ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy); + ao2_t_link(subscription_mwi_list, mwi, "link new mwi object"); + ao2_t_ref(mwi, -1, "unref to match ao2_t_alloc"); return 0; } @@ -14498,7 +14484,7 @@ static int sip_subscribe_mwi_do(const void *data) mwi->resub = -1; __sip_subscribe_mwi_do(mwi); - ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy); + ao2_t_ref(mwi, -1, "unref mwi to balance ast_sched_add"); return 0; } @@ -14575,14 +14561,13 @@ static int __sip_subscribe_mwi_do(struct sip_subscription_mwi *mwi) /* If we have no DNS manager let's do a lookup */ if (!mwi->dnsmgr) { char transport[MAXHOSTNAMELEN]; - struct sip_subscription_mwi *saved; snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(mwi->transport), get_srv_protocol(mwi->transport)); mwi->us.ss.ss_family = get_address_family_filter(mwi->transport); /* Filter address family */ - saved = ASTOBJ_REF(mwi); - ast_dnsmgr_lookup_cb(mwi->hostname, &mwi->us, &mwi->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_mwi, saved); + ao2_t_ref(mwi, +1, "dnsmgr reference to mwi"); + ast_dnsmgr_lookup_cb(mwi->hostname, &mwi->us, &mwi->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_mwi, mwi); if (!mwi->dnsmgr) { - ASTOBJ_UNREF(saved, sip_subscribe_mwi_destroy); /* dnsmgr disabled, remove reference */ + ao2_t_ref(mwi, -1, "dnsmgr disabled, remove reference"); } } @@ -14645,7 +14630,7 @@ static int __sip_subscribe_mwi_do(struct sip_subscription_mwi *mwi) ast_set_flag(&mwi->call->flags[0], SIP_OUTGOING); /* Associate the call with us */ - mwi->call->mwi = ASTOBJ_REF(mwi); + mwi->call->mwi = ao2_t_bump(mwi, "Reference mwi from it's call"); mwi->call->subscribed = MWI_NOTIFICATION; @@ -15348,7 +15333,7 @@ static int sip_reregister(const void *data) r->expire = -1; r->expiry = r->configured_expiry; __sip_do_register(r); - registry_unref(r, "unref the re-register scheduled event"); + ao2_t_ref(r, -1, "unref the re-register scheduled event"); return 0; } @@ -15402,9 +15387,7 @@ static int sip_reg_timeout(const void *data) /* decouple the two objects */ /* p->registry == r, so r has 2 refs, and the unref won't take the object away */ - if (p->registry) { - p->registry = registry_unref(p->registry, "p->registry unreffed"); - } + ao2_t_replace(p->registry, NULL, "p->registry unreffed"); r->call = dialog_unref(r->call, "unrefing r->call"); } /* If we have a limit, stop registration and give up */ @@ -15421,7 +15404,7 @@ static int sip_reg_timeout(const void *data) ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); } sip_publish_registry(r->username, r->hostname, regstate2str(r->regstate)); - registry_unref(r, "unreffing registry_unref r"); + ao2_t_ref(r, -1, "unreffing registry_unref r"); return 0; } @@ -15472,11 +15455,11 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char * * or peer NULL. Since we're only concerned with its existence, we're not going to * bother getting a ref to the proxy*/ if (!obproxy_get(r->call, peer)) { - registry_addref(r, "add reg ref for dnsmgr"); + ao2_t_ref(r, +1, "add reg ref for dnsmgr"); ast_dnsmgr_lookup_cb(peer ? peer->tohost : r->hostname, &r->us, &r->dnsmgr, sip_cfg.srvlookup ? transport : NULL, on_dns_update_registry, r); if (!r->dnsmgr) { /*dnsmgr refresh disabled, no reference added! */ - registry_unref(r, "remove reg ref, dnsmgr disabled"); + ao2_t_ref(r, -1, "remove reg ref, dnsmgr disabled"); } } if (peer) { @@ -15540,12 +15523,12 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char * p = dialog_unref(p, "unref dialog after unlink_all"); if (r->timeout > -1) { AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r, - registry_unref(_data, "del for REPLACE of registry ptr"), - registry_unref(r, "object ptr dec when SCHED_REPLACE add failed"), - registry_addref(r,"add for REPLACE registry ptr")); + ao2_t_ref(_data, -1, "del for REPLACE of registry ptr"), + ao2_t_ref(r, -1, "object ptr dec when SCHED_REPLACE add failed"), + ao2_t_ref(r, +1, "add for REPLACE registry ptr")); ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); } else { - r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, registry_addref(r, "add for REPLACE registry ptr")); + r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, ao2_t_bump(r, "add for REPLACE registry ptr")); ast_log(LOG_WARNING, "Probably a DNS error for registration to %s@%s, trying REGISTER again (after %d seconds)\n", r->username, r->hostname, global_reg_timeout); } r->regattempts++; @@ -15569,7 +15552,7 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char * ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ r->call = dialog_ref(p, "copying dialog into registry r->call"); /* Save pointer to SIP dialog */ - p->registry = registry_addref(r, "transmit_register: addref to p->registry in transmit_register"); /* Add pointer to registry in packet */ + p->registry = ao2_t_bump(r, "transmit_register: addref to p->registry in transmit_register"); /* Add pointer to registry in packet */ if (!ast_strlen_zero(r->secret)) { /* Secret (password) */ ast_string_field_set(p, peersecret, r->secret); } @@ -15615,9 +15598,9 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char * ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); } AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r, - registry_unref(_data,"reg ptr unrefed from del in SCHED_REPLACE"), - registry_unref(r,"reg ptr unrefed from add failure in SCHED_REPLACE"), - registry_addref(r,"reg ptr reffed from add in SCHED_REPLACE")); + ao2_t_ref(_data, -1, "reg ptr unrefed from del in SCHED_REPLACE"), + ao2_t_ref(r, -1, "reg ptr unrefed from add failure in SCHED_REPLACE"), + ao2_t_ref(r, +1, "reg ptr reffed from add in SCHED_REPLACE")); ast_debug(1, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); } @@ -18837,7 +18820,7 @@ static enum check_auth_result check_user_full(struct sip_pvt *p, struct sip_requ } /*! \brief Find user - If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced + If we get a match, this will add a reference pointer to the user object, that needs to be unreferenced */ static int check_user(struct sip_pvt *p, struct sip_request *req, int sipmethod, const char *uri, enum xmittype reliable, struct ast_sockaddr *addr) { @@ -19329,14 +19312,18 @@ static int manager_show_registry(struct mansession *s, const struct message *m) const char *id = astman_get_header(m, "ActionID"); char idtext[256] = ""; int total = 0; + struct ao2_iterator iter; + struct sip_registry *iterator; if (!ast_strlen_zero(id)) snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); astman_send_listack(s, m, "Registrations will follow", "start"); - ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { - ASTOBJ_RDLOCK(iterator); + iter = ao2_iterator_init(registry_list, 0); + while ((iterator = ao2_t_iterator_next(&iter, "manager_show_registry iter"))) { + ao2_lock(iterator); + astman_append(s, "Event: RegistryEntry\r\n" "%s" @@ -19358,9 +19345,12 @@ static int manager_show_registry(struct mansession *s, const struct message *m) iterator->refresh, regstate2str(iterator->regstate), (long) iterator->regtime.tv_sec); - ASTOBJ_UNLOCK(iterator); + + ao2_unlock(iterator); + ao2_t_ref(iterator, -1, "manager_show_registry iter"); total++; - } while(0)); + } + ao2_iterator_destroy(&iter); astman_append(s, "Event: RegistrationsComplete\r\n" @@ -19677,7 +19667,8 @@ static int dialog_dump_func(void *userobj, void *arg, int flags) /*! \brief List all allocated SIP Objects (realtime or static) */ static char *sip_show_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - char tmp[256]; + struct sip_registry *reg; + struct ao2_iterator iter; switch (cmd) { case CLI_INIT: @@ -19696,8 +19687,17 @@ static char *sip_show_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_a ao2_t_callback(peers, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers"); ast_cli(a->fd, "-= Peer objects by IP =-\n\n"); ao2_t_callback(peers_by_ip, OBJ_NODATA, peer_dump_func, a, "initiate ao2_callback to dump peers_by_ip"); - ast_cli(a->fd, "-= Registry objects: %d =-\n\n", regobjs); - ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), ®l); + + iter = ao2_iterator_init(registry_list, 0); + ast_cli(a->fd, "-= Registry objects: %d =-\n\n", ao2_container_count(registry_list)); + while ((reg = ao2_t_iterator_next(&iter, "sip_show_objects iter"))) { + ao2_lock(reg); + ast_cli(a->fd, "name: %s\n", reg->configvalue); + ao2_unlock(reg); + ao2_t_ref(reg, -1, "sip_show_objects iter"); + } + ao2_iterator_destroy(&iter); + ast_cli(a->fd, "-= Dialog objects:\n\n"); ao2_t_callback(dialogs, OBJ_NODATA, dialog_dump_func, a, "initiate ao2_callback to dump dialogs"); return CLI_SUCCESS; @@ -20757,6 +20757,8 @@ static char *sip_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_ char tmpdat[256]; struct ast_tm tm; int counter = 0; + struct ao2_iterator iter; + struct sip_registry *iterator; switch (cmd) { case CLI_INIT: @@ -20773,8 +20775,10 @@ static char *sip_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_ return CLI_SHOWUSAGE; ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Refresh", "State", "Reg.Time"); - ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { - ASTOBJ_RDLOCK(iterator); + iter = ao2_iterator_init(registry_list, 0); + while ((iterator = ao2_t_iterator_next(&iter, "sip_show_registry iter"))) { + ao2_lock(iterator); + snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); snprintf(user, sizeof(user), "%s", iterator->username); if (!ast_strlen_zero(iterator->regdomain)) { @@ -20789,9 +20793,13 @@ static char *sip_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_ } else tmpdat[0] = '\0'; ast_cli(a->fd, FORMAT, host, (iterator->dnsmgr) ? "Y" : "N", user, iterator->refresh, regstate2str(iterator->regstate), tmpdat); - ASTOBJ_UNLOCK(iterator); + + ao2_unlock(iterator); + ao2_t_ref(iterator, -1, "sip_show_registry iter"); counter++; - } while(0)); + } + ao2_iterator_destroy(&iter); + ast_cli(a->fd, "%d SIP registrations.\n", counter); return CLI_SUCCESS; #undef FORMAT @@ -21171,6 +21179,8 @@ static char *sip_show_mwi(struct ast_cli_entry *e, int cmd, struct ast_cli_args { #define FORMAT "%-30.30s %-12.12s %-10.10s %-10.10s\n" char host[80]; + struct ao2_iterator iter; + struct sip_subscription_mwi *iterator; switch (cmd) { case CLI_INIT: @@ -21185,12 +21195,15 @@ static char *sip_show_mwi(struct ast_cli_entry *e, int cmd, struct ast_cli_args ast_cli(a->fd, FORMAT, "Host", "Username", "Mailbox", "Subscribed"); - ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { - ASTOBJ_RDLOCK(iterator); + iter = ao2_iterator_init(subscription_mwi_list, 0); + while ((iterator = ao2_t_iterator_next(&iter, "sip_show_mwi iter"))) { + ao2_lock(iterator); snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); ast_cli(a->fd, FORMAT, host, iterator->username, iterator->mailbox, AST_CLI_YESNO(iterator->subscribed)); - ASTOBJ_UNLOCK(iterator); - } while(0)); + ao2_unlock(iterator); + ao2_t_ref(iterator, -1, "sip_show_mwi iter"); + } + ao2_iterator_destroy(&iter); return CLI_SUCCESS; #undef FORMAT @@ -23546,8 +23559,8 @@ static void handle_response_subscribe(struct sip_pvt *p, int resp, const char *r p->options = NULL; } p->mwi->subscribed = 1; - if ((p->mwi->resub = ast_sched_add(sched, mwi_expiry * 1000, sip_subscribe_mwi_do, ASTOBJ_REF(p->mwi))) < 0) { - ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); + if ((p->mwi->resub = ast_sched_add(sched, mwi_expiry * 1000, sip_subscribe_mwi_do, ao2_t_bump(p->mwi, "mwi ast_sched_add"))) < 0) { + ao2_t_ref(p->mwi, -1, "mwi ast_sched_add < 0"); } break; case 401: @@ -23556,7 +23569,7 @@ static void handle_response_subscribe(struct sip_pvt *p, int resp, const char *r if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_SUBSCRIBE, 0)) { ast_log(LOG_NOTICE, "Failed to authenticate on SUBSCRIBE to '%s'\n", sip_get_header(&p->initreq, "From")); p->mwi->call = NULL; - ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); + ao2_t_ref(p->mwi, -1, "failed to authenticate SUBSCRIBE"); pvt_set_needdestroy(p, "failed to authenticate SUBSCRIBE"); } break; @@ -23564,27 +23577,27 @@ static void handle_response_subscribe(struct sip_pvt *p, int resp, const char *r transmit_response_with_date(p, "200 OK", req); ast_log(LOG_WARNING, "Authentication failed while trying to subscribe for MWI.\n"); p->mwi->call = NULL; - ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); + ao2_t_ref(p->mwi, -1, "received 403 response"); pvt_set_needdestroy(p, "received 403 response"); sip_alreadygone(p); break; case 404: ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that a mailbox may not have been configured.\n"); p->mwi->call = NULL; - ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); + ao2_t_ref(p->mwi, -1, "received 404 response"); pvt_set_needdestroy(p, "received 404 response"); break; case 481: ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side said that our dialog did not exist.\n"); p->mwi->call = NULL; - ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); + ao2_t_ref(p->mwi, -1, "received 481 response"); pvt_set_needdestroy(p, "received 481 response"); break; case 500: case 501: ast_log(LOG_WARNING, "Subscription failed for MWI. The remote side may have suffered a heart attack.\n"); p->mwi->call = NULL; - ASTOBJ_UNREF(p->mwi, sip_subscribe_mwi_destroy); + ao2_t_ref(p->mwi, -1, "received 500/501 response"); pvt_set_needdestroy(p, "received 500/501 response"); break; } @@ -23715,7 +23728,7 @@ static int handle_response_register(struct sip_pvt *p, int resp, const char *res break; } ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); - AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 403")); + AST_SCHED_DEL_UNREF(sched, r->timeout, ao2_t_ref(r, -1, "reg ptr unref from handle_response_register 403")); r->regstate = REG_STATE_NOAUTH; sip_publish_registry(r->username, r->hostname, regstate2str(r->regstate)); pvt_set_needdestroy(p, "received 403 response"); @@ -23727,7 +23740,7 @@ static int handle_response_register(struct sip_pvt *p, int resp, const char *res r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 404"); r->regstate = REG_STATE_REJECTED; sip_publish_registry(r->username, r->hostname, regstate2str(r->regstate)); - AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 404")); + AST_SCHED_DEL_UNREF(sched, r->timeout, ao2_t_ref(r, -1, "reg ptr unref from handle_response_register 404")); break; case 407: /* Proxy auth */ if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) { @@ -23746,7 +23759,7 @@ static int handle_response_register(struct sip_pvt *p, int resp, const char *res case 423: /* Interval too brief */ r->expiry = atoi(sip_get_header(req, "Min-Expires")); ast_log(LOG_WARNING, "Got 423 Interval too brief for service %s@%s, minimum is %d seconds\n", p->registry->username, p->registry->hostname, r->expiry); - AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 423")); + AST_SCHED_DEL_UNREF(sched, r->timeout, ao2_t_ref(r, -1, "reg ptr unref from handle_response_register 423")); if (r->call) { r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 423"); pvt_set_needdestroy(p, "received 423 response"); @@ -23768,7 +23781,7 @@ static int handle_response_register(struct sip_pvt *p, int resp, const char *res r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 479"); r->regstate = REG_STATE_REJECTED; sip_publish_registry(r->username, r->hostname, regstate2str(r->regstate)); - AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 479")); + AST_SCHED_DEL_UNREF(sched, r->timeout, ao2_t_ref(r, -1, "reg ptr unref from handle_response_register 479")); break; case 200: /* 200 OK */ if (!r) { @@ -23785,10 +23798,10 @@ static int handle_response_register(struct sip_pvt *p, int resp, const char *res if (r->timeout > -1) { ast_debug(1, "Cancelling timeout %d\n", r->timeout); } - AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 200")); + AST_SCHED_DEL_UNREF(sched, r->timeout, ao2_t_ref(r, -1, "reg ptr unref from handle_response_register 200")); if (r->call) r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 200"); - p->registry = registry_unref(p->registry, "unref registry entry p->registry"); + ao2_t_replace(p->registry, NULL, "unref registry entry p->registry"); /* destroy dialog now to avoid interference with next register */ pvt_set_needdestroy(p, "Registration successfull"); @@ -23840,9 +23853,9 @@ static int handle_response_register(struct sip_pvt *p, int resp, const char *res /* Schedule re-registration before we expire */ AST_SCHED_REPLACE_UNREF(r->expire, sched, expires_ms, sip_reregister, r, - registry_unref(_data,"unref in REPLACE del fail"), - registry_unref(r,"unref in REPLACE add fail"), - registry_addref(r,"The Addition side of REPLACE")); + ao2_t_ref(_data, -1, "unref in REPLACE del fail"), + ao2_t_ref(r, -1, "unref in REPLACE add fail"), + ao2_t_ref(r, +1, "The Addition side of REPLACE")); } return 1; } @@ -31147,29 +31160,36 @@ static void display_nat_warning(const char *cat, int reason, struct ast_flags *f static void cleanup_all_regs(void) { - /* First, destroy all outstanding registry calls */ - /* This is needed, since otherwise active registry entries will not be destroyed */ - ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { /* regl is locked */ - ASTOBJ_WRLOCK(iterator); /* now regl is locked, and the object is also locked */ - if (iterator->call) { - ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); - /* This will also remove references to the registry */ - dialog_unlink_all(iterator->call); - iterator->call = dialog_unref(iterator->call, "remove iterator->call from registry traversal"); - } - if (iterator->expire > -1) { - AST_SCHED_DEL_UNREF(sched, iterator->expire, registry_unref(iterator, "reg ptr unref from reload config")); - } - if (iterator->timeout > -1) { - AST_SCHED_DEL_UNREF(sched, iterator->timeout, registry_unref(iterator, "reg ptr unref from reload config")); - } - if (iterator->dnsmgr) { - ast_dnsmgr_release(iterator->dnsmgr); - iterator->dnsmgr = NULL; - registry_unref(iterator, "reg ptr unref from dnsmgr"); - } - ASTOBJ_UNLOCK(iterator); - } while(0)); + struct ao2_iterator iter; + struct sip_registry *iterator; + /* First, destroy all outstanding registry calls */ + /* This is needed, since otherwise active registry entries will not be destroyed */ + iter = ao2_iterator_init(registry_list, 0); + while ((iterator = ao2_t_iterator_next(&iter, "cleanup_all_regs iter"))) { + ao2_lock(iterator); + + if (iterator->call) { + ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); + /* This will also remove references to the registry */ + dialog_unlink_all(iterator->call); + iterator->call = dialog_unref(iterator->call, "remove iterator->call from registry traversal"); + } + if (iterator->expire > -1) { + AST_SCHED_DEL_UNREF(sched, iterator->expire, ao2_t_ref(iterator, -1, "reg ptr unref from reload config")); + } + if (iterator->timeout > -1) { + AST_SCHED_DEL_UNREF(sched, iterator->timeout, ao2_t_ref(iterator, -1, "reg ptr unref from reload config")); + } + if (iterator->dnsmgr) { + ast_dnsmgr_release(iterator->dnsmgr); + iterator->dnsmgr = NULL; + ao2_t_ref(iterator, -1, "reg ptr unref from dnsmgr"); + } + + ao2_unlock(iterator); + ao2_t_ref(iterator, -1, "cleanup_all_regs iter"); + } + ao2_iterator_destroy(&iter); } /*! \brief Re-read SIP.conf config file @@ -31253,10 +31273,8 @@ static int reload_config(enum channelreloadreason reason) } ast_mutex_unlock(&authl_lock); - cleanup_all_regs(); - /* Then, actually destroy users and registry */ - ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); + cleanup_all_regs(); ast_debug(4, "--------------- Done destroying registry list\n"); ao2_t_callback(peers, OBJ_NODATA, peer_markall_func, NULL, "callback to mark all peers"); } @@ -32923,39 +32941,50 @@ static void sip_send_all_registers(void) { int ms; int regspacing; - if (!regobjs) { + struct ao2_iterator iter; + struct sip_registry *iterator; + + if (!ao2_container_count(registry_list)) { return; } - regspacing = default_expiry * 1000/regobjs; + regspacing = default_expiry * 1000 / ao2_container_count(registry_list); if (regspacing > 100) { regspacing = 100; } ms = regspacing; - ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { - ASTOBJ_WRLOCK(iterator); + + iter = ao2_iterator_init(registry_list, 0); + while ((iterator = ao2_t_iterator_next(&iter, "sip_send_all_registers iter"))) { + ao2_lock(iterator); ms += regspacing; AST_SCHED_REPLACE_UNREF(iterator->expire, sched, ms, sip_reregister, iterator, - registry_unref(_data, "REPLACE sched del decs the refcount"), - registry_unref(iterator, "REPLACE sched add failure decs the refcount"), - registry_addref(iterator, "REPLACE sched add incs the refcount")); - ASTOBJ_UNLOCK(iterator); - } while (0) - ); + ao2_t_ref(_data, -1, "REPLACE sched del decs the refcount"), + ao2_t_ref(iterator, -1, "REPLACE sched add failure decs the refcount"), + ao2_t_ref(iterator, +1, "REPLACE sched add incs the refcount")); + ao2_unlock(iterator); + ao2_t_ref(iterator, -1, "sip_send_all_registers iter"); + } + ao2_iterator_destroy(&iter); } /*! \brief Send all MWI subscriptions */ static void sip_send_all_mwi_subscriptions(void) { - ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { - struct sip_subscription_mwi *saved; - ASTOBJ_WRLOCK(iterator); + struct ao2_iterator iter; + struct sip_subscription_mwi *iterator; + + iter = ao2_iterator_init(subscription_mwi_list, 0); + while ((iterator = ao2_t_iterator_next(&iter, "sip_send_all_mwi_subscriptions iter"))) { + ao2_lock(iterator); AST_SCHED_DEL(sched, iterator->resub); - saved = ASTOBJ_REF(iterator); - if ((iterator->resub = ast_sched_add(sched, 1, sip_subscribe_mwi_do, saved)) < 0) { - ASTOBJ_UNREF(saved, sip_subscribe_mwi_destroy); + ao2_t_ref(iterator, +1, "mwi added to schedule"); + if ((iterator->resub = ast_sched_add(sched, 1, sip_subscribe_mwi_do, iterator)) < 0) { + ao2_t_ref(iterator, -1, "mwi failed to schedule"); } - ASTOBJ_UNLOCK(iterator); - } while (0)); + ao2_unlock(iterator); + ao2_t_ref(iterator, -1, "sip_send_all_mwi_subscriptions iter"); + } + ao2_iterator_destroy(&iter); } static int process_crypto(struct sip_pvt *p, struct ast_rtp_instance *rtp, struct ast_sdp_srtp **srtp, const char *a) @@ -33272,6 +33301,53 @@ static int dialog_cmp_cb(void *obj, void *arg, int flags) return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH | CMP_STOP : 0; } + +static int registry_hash_cb(const void *obj, const int flags) +{ + const struct sip_registry *object; + const char *key; + + switch (flags & OBJ_SEARCH_MASK) { + case OBJ_SEARCH_KEY: + key = obj; + break; + case OBJ_SEARCH_OBJECT: + object = obj; + key = object->configvalue; + break; + default: + /* Hash can only work on something with a full key. */ + ast_assert(0); + return 0; + } + return ast_str_hash(key); +} + +static int registry_cmp_cb(void *obj, void *arg, int flags) +{ + const struct sip_registry *object_left = obj; + const struct sip_registry *object_right = arg; + const char *right_key = arg; + int cmp; + + switch (flags & OBJ_SEARCH_MASK) { + case OBJ_SEARCH_OBJECT: + right_key = object_right->configvalue; + /* Fall through */ + case OBJ_SEARCH_KEY: + cmp = strcmp(object_left->configvalue, right_key); + break; + default: + cmp = 0; + break; + } + if (cmp) { + return 0; + } + return CMP_MATCH; +} + + /*! \brief SIP Cli commands definition */ static struct ast_cli_entry cli_sip[] = { AST_CLI_DEFINE(sip_show_channels, "List active SIP channels or subscriptions"), @@ -33318,6 +33394,8 @@ static void sip_unregister_tests(void) #ifdef TEST_FRAMEWORK AST_TEST_DEFINE(test_sip_mwi_subscribe_parse) { + struct ao2_iterator iter; + struct sip_subscription_mwi *iterator; int found = 0; enum ast_test_result_state res = AST_TEST_PASS; const char *mwi1 = "1234@mysipprovider.com/1234"; @@ -33344,8 +33422,10 @@ AST_TEST_DEFINE(test_sip_mwi_subscribe_parse) } else { found = 0; res = AST_TEST_FAIL; - ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { - ASTOBJ_WRLOCK(iterator); + + iter = ao2_iterator_init(subscription_mwi_list, 0); + while ((iterator = ao2_t_iterator_next(&iter, "test_sip_mwi_subscribe_parse mwi1"))) { + ao2_lock(iterator); if ( !strcmp(iterator->hostname, "mysipprovider.com") && !strcmp(iterator->username, "1234") && @@ -33356,8 +33436,10 @@ AST_TEST_DEFINE(test_sip_mwi_subscribe_parse) found = 1; res = AST_TEST_PASS; } - ASTOBJ_UNLOCK(iterator); - } while(0)); + ao2_unlock(iterator); + ao2_t_ref(iterator, -1, "test_sip_mwi_subscribe_parse mwi1"); + } + ao2_iterator_destroy(&iter); if (!found) { ast_test_status_update(test, "sip_subscribe_mwi test 1 failed\n"); } @@ -33368,8 +33450,10 @@ AST_TEST_DEFINE(test_sip_mwi_subscribe_parse) } else { found = 0; res = AST_TEST_FAIL; - ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { - ASTOBJ_WRLOCK(iterator); + + iter = ao2_iterator_init(subscription_mwi_list, 0); + while ((iterator = ao2_t_iterator_next(&iter, "test_sip_mwi_subscribe_parse mwi2"))) { + ao2_lock(iterator); if ( !strcmp(iterator->hostname, "mysipprovider.com") && !strcmp(iterator->username, "1234") && @@ -33380,8 +33464,10 @@ AST_TEST_DEFINE(test_sip_mwi_subscribe_parse) found = 1; res = AST_TEST_PASS; } - ASTOBJ_UNLOCK(iterator); - } while(0)); + ao2_unlock(iterator); + ao2_t_ref(iterator, -1, "test_sip_mwi_subscribe_parse mwi2"); + } + ao2_iterator_destroy(&iter); if (!found) { ast_test_status_update(test, "sip_subscribe_mwi test 2 failed\n"); } @@ -33392,8 +33478,10 @@ AST_TEST_DEFINE(test_sip_mwi_subscribe_parse) } else { found = 0; res = AST_TEST_FAIL; - ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { - ASTOBJ_WRLOCK(iterator); + + iter = ao2_iterator_init(subscription_mwi_list, 0); + while ((iterator = ao2_t_iterator_next(&iter, "test_sip_mwi_subscribe_parse mwi3"))) { + ao2_lock(iterator); if ( !strcmp(iterator->hostname, "mysipprovider.com") && !strcmp(iterator->username, "1234") && @@ -33404,8 +33492,10 @@ AST_TEST_DEFINE(test_sip_mwi_subscribe_parse) found = 1; res = AST_TEST_PASS; } - ASTOBJ_UNLOCK(iterator); - } while(0)); + ao2_unlock(iterator); + ao2_t_ref(iterator, -1, "test_sip_mwi_subscribe_parse mwi3"); + } + ao2_iterator_destroy(&iter); if (!found) { ast_test_status_update(test, "sip_subscribe_mwi test 3 failed\n"); } @@ -33416,8 +33506,10 @@ AST_TEST_DEFINE(test_sip_mwi_subscribe_parse) } else { found = 0; res = AST_TEST_FAIL; - ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { - ASTOBJ_WRLOCK(iterator); + + iter = ao2_iterator_init(subscription_mwi_list, 0); + while ((iterator = ao2_t_iterator_next(&iter, "test_sip_mwi_subscribe_parse mwi4"))) { + ao2_lock(iterator); if ( !strcmp(iterator->hostname, "mysipprovider.com") && !strcmp(iterator->username, "1234") && @@ -33428,8 +33520,10 @@ AST_TEST_DEFINE(test_sip_mwi_subscribe_parse) found = 1; res = AST_TEST_PASS; } - ASTOBJ_UNLOCK(iterator); - } while(0)); + ao2_unlock(iterator); + ao2_t_ref(iterator, -1, "test_sip_mwi_subscribe_parse mwi4"); + } + ao2_iterator_destroy(&iter); if (!found) { ast_test_status_update(test, "sip_subscribe_mwi test 4 failed\n"); } @@ -33440,8 +33534,10 @@ AST_TEST_DEFINE(test_sip_mwi_subscribe_parse) } else { found = 0; res = AST_TEST_FAIL; - ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { - ASTOBJ_WRLOCK(iterator); + + iter = ao2_iterator_init(subscription_mwi_list, 0); + while ((iterator = ao2_t_iterator_next(&iter, "test_sip_mwi_subscribe_parse mwi4"))) { + ao2_lock(iterator); if ( !strcmp(iterator->hostname, "mysipprovider.com") && !strcmp(iterator->username, "1234") && @@ -33452,8 +33548,10 @@ AST_TEST_DEFINE(test_sip_mwi_subscribe_parse) found = 1; res = AST_TEST_PASS; } - ASTOBJ_UNLOCK(iterator); - } while(0)); + ao2_unlock(iterator); + ao2_t_ref(iterator, -1, "test_sip_mwi_subscribe_parse mwi4"); + } + ao2_iterator_destroy(&iter); if (!found) { ast_test_status_update(test, "sip_subscribe_mwi test 5 failed\n"); } @@ -34289,8 +34387,9 @@ static int load_module(void) } ast_format_cap_append_by_type(sip_tech.capabilities, AST_MEDIA_TYPE_AUDIO); - ASTOBJ_CONTAINER_INIT(®l); /* Registry object list -- not searched for anything */ - ASTOBJ_CONTAINER_INIT(&submwil); /* MWI subscription object list */ + registry_list = ao2_t_container_alloc(HASH_REGISTRY_SIZE, registry_hash_cb, registry_cmp_cb, "allocate registry_list"); + subscription_mwi_list = ao2_t_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, + AO2_CONTAINER_ALLOC_OPT_INSERT_BEGIN, NULL, NULL, "allocate subscription_mwi_list"); if (!(sched = ast_sched_context_create())) { ast_log(LOG_ERROR, "Unable to create scheduler context\n"); @@ -34564,20 +34663,26 @@ static int unload_module(void) ast_free(default_tls_cfg.capath); cleanup_all_regs(); - ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); - ASTOBJ_CONTAINER_DESTROY(®l); + ao2_cleanup(registry_list); - ASTOBJ_CONTAINER_TRAVERSE(&submwil, 1, do { - ASTOBJ_WRLOCK(iterator); - if (iterator->dnsmgr) { - ast_dnsmgr_release(iterator->dnsmgr); - iterator->dnsmgr = NULL; - ASTOBJ_UNREF(iterator, sip_subscribe_mwi_destroy); + { + struct ao2_iterator iter; + struct sip_subscription_mwi *iterator; + + iter = ao2_iterator_init(subscription_mwi_list, 0); + while ((iterator = ao2_t_iterator_next(&iter, "unload_module iter"))) { + ao2_lock(iterator); + if (iterator->dnsmgr) { + ast_dnsmgr_release(iterator->dnsmgr); + iterator->dnsmgr = NULL; + ao2_t_ref(iterator, -1, "dnsmgr release"); + } + ao2_unlock(iterator); + ao2_t_ref(iterator, -1, "unload_module iter"); } - ASTOBJ_UNLOCK(iterator); - } while(0)); - ASTOBJ_CONTAINER_DESTROYALL(&submwil, sip_subscribe_mwi_destroy); - ASTOBJ_CONTAINER_DESTROY(&submwil); + ao2_iterator_destroy(&iter); + } + ao2_cleanup(subscription_mwi_list); /* * Wait awhile for the TCP/TLS thread container to become empty. diff --git a/channels/sip/include/sip.h b/channels/sip/include/sip.h index 8ce63ee9d4..68c2ee8605 100644 --- a/channels/sip/include/sip.h +++ b/channels/sip/include/sip.h @@ -31,7 +31,6 @@ #include "asterisk/test.h" #include "asterisk/channel.h" #include "asterisk/app.h" -#include "asterisk/astobj.h" #include "asterisk/indications.h" #include "asterisk/security_events.h" #include "asterisk/features.h" @@ -1292,7 +1291,7 @@ struct sip_peer { unsigned short rt_fromcontact:1;/*!< copy fromcontact from realtime */ unsigned short host_dynamic:1; /*!< Dynamic Peers register with Asterisk */ unsigned short selfdestruct:1; /*!< Automatic peers need to destruct themselves */ - unsigned short the_mark:1; /*!< moved out of ASTOBJ into struct proper; That which bears the_mark should be deleted! */ + unsigned short the_mark:1; /*!< That which bears the_mark should be deleted! */ unsigned short autoframing:1; /*!< Whether to use our local configuration for frame sizes (off) * or respect the other endpoint's request for frame sizes (on) * for incoming calls @@ -1371,12 +1370,10 @@ struct sip_peer { * or once the previously completed registration one expires). * The registration can be in one of many states, though at the moment * the handling is a bit mixed. - * - * \todo Convert this to astobj2 */ struct sip_registry { - ASTOBJ_COMPONENTS_FULL(struct sip_registry, 80, 1); AST_DECLARE_STRING_FIELDS( + AST_STRING_FIELD(configvalue);/*!< register string from config */ AST_STRING_FIELD(callid); /*!< Global Call-ID */ AST_STRING_FIELD(realm); /*!< Authorization realm */ AST_STRING_FIELD(nonce); /*!< Authorization nonce */ @@ -1431,11 +1428,8 @@ struct sip_threadinfo { /*! * \brief Definition of an MWI subscription to another server - * - * \todo Convert this to astobj2. */ struct sip_subscription_mwi { - ASTOBJ_COMPONENTS_FULL(struct sip_subscription_mwi,1,1); AST_DECLARE_STRING_FIELDS( AST_STRING_FIELD(username); /*!< Who we are sending the subscription as */ AST_STRING_FIELD(authuser); /*!< Who we *authenticate* as */ -- GitLab