[asterisk-commits] mmichelson: branch group/rls r418113 - /team/group/rls/res/res_pjsip_pubsub.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Jul 7 10:26:29 CDT 2014
Author: mmichelson
Date: Mon Jul 7 10:26:23 2014
New Revision: 418113
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=418113
Log:
Add testing for whether a subscriber supports resource lists.
A subscriber that does not have a Supported: eventlist header
in its inbound SUBSCRIBE should not be able to subscribe
to resource lists. Such handling has now been added. Also a
unit test has been added to ensure that this behavior works
as expected.
Modified:
team/group/rls/res/res_pjsip_pubsub.c
Modified: team/group/rls/res/res_pjsip_pubsub.c
URL: http://svnview.digium.com/svn/asterisk/team/group/rls/res/res_pjsip_pubsub.c?view=diff&rev=418113&r1=418112&r2=418113
==============================================================================
--- team/group/rls/res/res_pjsip_pubsub.c (original)
+++ team/group/rls/res/res_pjsip_pubsub.c Mon Jul 7 10:26:23 2014
@@ -871,17 +871,20 @@
* \param handler The subscription handler for leaf nodes in the tree.
* \param resource The resource requested in the SUBSCRIBE request.
* \param tree The tree that is to be built.
+ * \param supports_lists Indicates if we should attempt to find a resource list or not.
*
* \retval 200-299 Successfully subscribed to at least one resource.
* \retval 300-699 Failure to subscribe to requested resource.
*/
static int build_resource_tree(struct ast_sip_endpoint *endpoint, const struct ast_sip_subscription_handler *handler,
- const char *resource, struct resource_tree *tree)
-{
- struct resource_list *list;
+ const char *resource, struct resource_tree *tree, int supports_lists)
+{
+ struct resource_list *list = NULL;
struct resources visited;
- list = retrieve_resource_list(resource, handler->event_name);
+ if (supports_lists) {
+ list = retrieve_resource_list(resource, handler->event_name);
+ }
if (!list) {
ast_debug(1, "Subscription to resource %s is not to a list\n", resource);
tree->root = tree_node_alloc(resource, NULL);
@@ -1082,6 +1085,35 @@
create_virtual_subscriptions(handler, endpoint, rdata, resource, generator, sub, tree->root);
return sub;
+}
+
+/*!
+ * \param Determine if SUBSCRIBE indicates support for RLS
+ *
+ * A SUBSCRIBE must have a Supported: eventlist header in order to
+ * allow for resource list subscriptions. Otherwise, we must interpret
+ * the inbound SUBSCRIBE as being for a single resource.
+ *
+ * \param rdata The inbound SUBSCRIBE request.
+ * \retval 1 The endpoint supports RLS
+ * \retval 0 The endpoint does not support RLS
+ */
+static int supports_resource_lists(pjsip_rx_data *rdata)
+{
+ pjsip_supported_hdr *supported;
+
+ supported = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_SUPPORTED, NULL);
+ if (supported) {
+ int i;
+
+ for (i = 0; i < supported->count; ++i) {
+ if (pj_strcmp2(&supported->values[i], "eventlist")) {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
}
@@ -1101,6 +1133,7 @@
struct resource_tree tree;
pjsip_expires_hdr *expires_header;
struct ast_sip_subscription_handler *handler;
+ int supports_lists;
/* If this subscription has already expired remove it */
if (ast_tvdiff_ms(persistence->expires, ast_tvnow()) <= 0) {
@@ -1156,11 +1189,13 @@
return 0;
}
+ supports_lists = supports_resource_lists(&rdata);
+
ast_sip_mod_data_set(rdata.tp_info.pool, rdata.endpt_info.mod_data,
pubsub_module.id, MOD_DATA_PERSISTENCE, persistence);
memset(&tree, 0, sizeof(tree));
- resp = build_resource_tree(endpoint, handler, resource, &tree);
+ resp = build_resource_tree(endpoint, handler, resource, &tree, supports_lists);
if (PJSIP_IS_STATUS_IN_CLASS(resp, 200)) {
sub = create_subscription_tree(handler, endpoint, &rdata, resource, generator, &tree);
sub->persistence = ao2_bump(persistence);
@@ -1833,6 +1868,7 @@
size_t resource_size;
int resp;
struct resource_tree tree;
+ int supports_lists;
endpoint = ast_pjsip_rdata_get_endpoint(rdata);
ast_assert(endpoint != NULL);
@@ -1888,8 +1924,10 @@
return PJ_TRUE;
}
+ supports_lists = supports_resource_lists(rdata);
+
memset(&tree, 0, sizeof(tree));
- resp = build_resource_tree(endpoint, handler, resource, &tree);
+ resp = build_resource_tree(endpoint, handler, resource, &tree, supports_lists);
if (!PJSIP_IS_STATUS_IN_CLASS(resp, 200)) {
pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, resp, NULL, NULL, NULL);
resource_tree_destroy(&tree);
@@ -2948,7 +2986,7 @@
}
tree = ast_calloc(1, sizeof(*tree));
- resp = build_resource_tree(NULL, &test_handler, "foo", tree);
+ resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1);
if (resp != 200) {
ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);
return AST_TEST_FAIL;
@@ -3012,7 +3050,7 @@
}
tree = ast_calloc(1, sizeof(*tree));
- resp = build_resource_tree(NULL, &test_handler, "foo", tree);
+ resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1);
if (resp != 200) {
ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);
return AST_TEST_FAIL;
@@ -3067,7 +3105,7 @@
}
tree = ast_calloc(1, sizeof(*tree));
- resp = build_resource_tree(NULL, &test_handler, "foo", tree);
+ resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1);
if (resp != 200) {
ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);
return AST_TEST_FAIL;
@@ -3130,7 +3168,7 @@
}
tree = ast_calloc(1, sizeof(*tree));
- resp = build_resource_tree(NULL, &test_handler, "foo", tree);
+ resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1);
if (resp != 200) {
ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);
return AST_TEST_FAIL;
@@ -3197,7 +3235,7 @@
}
tree = ast_calloc(1, sizeof(*tree));
- resp = build_resource_tree(NULL, &test_handler, "foo", tree);
+ resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1);
if (resp != 200) {
ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);
return AST_TEST_FAIL;
@@ -3263,7 +3301,7 @@
}
tree = ast_calloc(1, sizeof(*tree));
- resp = build_resource_tree(NULL, &test_handler, "herp", tree);
+ resp = build_resource_tree(NULL, &test_handler, "herp", tree, 1);
if (resp == 200) {
ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);
return AST_TEST_FAIL;
@@ -3304,7 +3342,7 @@
/* Since the test_handler is for event "test", this should not build a list, but
* instead result in a single resource being created, called "foo"
*/
- resp = build_resource_tree(NULL, &test_handler, "foo", tree);
+ resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1);
if (resp != 200) {
ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);
return AST_TEST_FAIL;
@@ -3320,8 +3358,68 @@
return AST_TEST_FAIL;
}
+ if (AST_VECTOR_SIZE(&tree->root->children) > 0) {
+ ast_test_status_update(test, "Tree root contains child nodes, but should not\n");
+ return AST_TEST_FAIL;
+ }
+
return AST_TEST_PASS;
}
+
+AST_TEST_DEFINE(lists_unsupported)
+{
+ RAII_VAR(struct resource_list *, list, NULL, cleanup_resource_list);
+ RAII_VAR(struct resource_tree *, tree, NULL, test_resource_tree_destroy);
+ const char *resources[] = {
+ "huey",
+ "dewey",
+ "louie",
+ };
+ int resp;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "lists_unsupported";
+ info->category = "/res/res_pjsip_pubsub/";
+ info->summary = "Ensure that subscription with no support for RLS subscribes to single resource";
+ info->description =
+ "Create a simple resource list. Ensure that building a resource tree when lists are unsupported results\n"
+ "not in subscribing to the created list but only to a single resource.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ list = create_resource_list(test, "foo", "test", resources, ARRAY_LEN(resources));
+ if (!list) {
+ return AST_TEST_FAIL;
+ }
+
+ tree = ast_calloc(1, sizeof(*tree));
+ resp = build_resource_tree(NULL, &test_handler, "foo", tree, 0);
+ if (resp != 200) {
+ ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);
+ return AST_TEST_FAIL;
+ }
+
+ if (!tree->root) {
+ ast_test_status_update(test, "Resource tree has no root\n");
+ return AST_TEST_FAIL;
+ }
+
+ if (strcmp(tree->root->resource, "foo")) {
+ ast_test_status_update(test, "Unexpected resource %s found in tree\n", tree->root->resource);
+ return AST_TEST_FAIL;
+ }
+
+ if (AST_VECTOR_SIZE(&tree->root->children) > 0) {
+ ast_test_status_update(test, "Tree root contains child nodes, but should not\n");
+ return AST_TEST_FAIL;
+ }
+
+ return AST_TEST_PASS;
+}
+
#endif
@@ -3406,6 +3504,7 @@
AST_TEST_REGISTER(duplicate_resource);
AST_TEST_REGISTER(loop);
AST_TEST_REGISTER(bad_event);
+ AST_TEST_REGISTER(lists_unsupported);
return AST_MODULE_LOAD_SUCCESS;
}
@@ -3427,6 +3526,7 @@
AST_TEST_UNREGISTER(duplicate_resource);
AST_TEST_UNREGISTER(loop);
AST_TEST_UNREGISTER(bad_event);
+ AST_TEST_UNREGISTER(lists_unsupported);
return 0;
}
More information about the asterisk-commits
mailing list