Commit 01650270 authored by Pekka Pessi's avatar Pekka Pessi

sip: added k_bitmap to sip_allow_t. Added sip_is_allowed().

darcs-hash:20061213030728-65a35-67f83691c67ecbfe2fba9a6dc00cea52f02616e3.gz
parent 6600b56e
......@@ -72,22 +72,31 @@
*
* The #sip_allow_t is defined as follows:
* @code
* typedef struct msg_list_s
* typedef struct msg_allow_s
* {
* msg_common_t k_common[1]; // Common fragment info
* msg_list_t *k_next; // Link to next header
* msg_param_t *k_items; // List of items
* uint32_t k_bitmap; // Bitmap of allowed methods
* } sip_allow_t;
* @endcode
*
* @note The field @a k_bitmap was added in @VERSION_1_12_5.
*/
#define sip_allow_dup_xtra msg_list_dup_xtra
#define sip_allow_dup_one msg_list_dup_one
static msg_update_f sip_allow_update;
msg_hclass_t sip_allow_class[] =
SIP_HEADER_CLASS_LIST(allow, "Allow", "", list);
SIP_HEADER_CLASS(allow, "Allow", "", k_items, list, allow);
issize_t sip_allow_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
{
sip_allow_t *k = (sip_allow_t *)h;
return msg_commalist_d(home, &s, &k->k_items, msg_token_scan);
issize_t retval = msg_commalist_d(home, &s, &k->k_items, msg_token_scan);
msg_header_update_params(k->k_common, 0);
return retval;
}
issize_t sip_allow_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
......@@ -96,6 +105,45 @@ issize_t sip_allow_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
return msg_list_e(b, bsiz, h, f);
}
static int sip_allow_update(msg_common_t *h,
char const *name, isize_t namelen,
char const *value)
{
sip_allow_t *k = (sip_allow_t *)h;
if (name == NULL) {
k->k_bitmap = 0;
}
else {
sip_method_t method = sip_method_code(name);
if (method >= 0 && method < 32)
k->k_bitmap |= 1 << method;
}
return 0;
}
/** Return true if the method is listed in @Allow header. */
int sip_is_allowed(sip_allow_t const *allow,
sip_method_t method,
char const *name)
{
if (method < sip_method_unknown || !allow)
return 0;
if (sip_method_unknown < method && method < 32)
/* Well-known method */
return (allow->k_bitmap & (1 << method)) != 0;
if (method == sip_method_unknown &&
(allow->k_bitmap & (1 << sip_method_unknown)) == 0)
return 0;
return msg_header_find_item(allow->k_common, name) != NULL;
}
/* ====================================================================== */
/**@SIP_HEADER sip_proxy_require Proxy-Require Header
......
......@@ -139,7 +139,7 @@ typedef msg_payload_t sip_payload_t;
typedef struct sip_accept_s sip_accept_t;
typedef msg_accept_any_t sip_accept_encoding_t;
typedef msg_accept_any_t sip_accept_language_t;
typedef msg_list_t sip_allow_t;
typedef struct sip_allow_s sip_allow_t;
typedef struct msg_auth_info_s sip_authentication_info_t;
typedef struct msg_auth_s sip_authorization_t;
typedef struct sip_call_id_s sip_call_id_t;
......@@ -406,6 +406,20 @@ struct sip_accept_s
char const *ac_q; /**< Value of q parameter */
};
/**@ingroup sip_allow
* @brief Structure for @Allow header field.
*
* @NEW_1_12_5 (before used struct msg_list_s with @Allow).
*/
struct sip_allow_s
{
msg_common_t k_common[1]; /**< Common fragment info */
msg_list_t *k_next; /**< Link to next */
msg_param_t *k_items; /**< List of allowed items */
uint32_t k_bitmap; /**< Bitmap of allowed methods.
@NEW_1_12_5 */
};
/**@ingroup sip_authentication_info
* @brief Structure for @AuthenticationInfo header.
*
......
......@@ -345,6 +345,9 @@ int sip_has_supported(sip_supported_t const *support, char const *feature);
SOFIAPUBFUN
int sip_has_feature(msg_list_t const *supported, char const *feature);
SOFIAPUBFUN int sip_is_allowed(sip_allow_t const *allow,
sip_method_t method, char const *name);
/* ---------------------------------------------------------------------------
* Bitmasks for header classifications
*/
......
......@@ -1829,6 +1829,7 @@ static int test_sip_list_header(void)
"Allow: BYE\r\n"
"Allow: OPTIONS\r\n"
"Allow: MESSAGE\r\n"
"Allow: KUIK\r\n"
"Max-Forwards: 12\r\n"
"Content-Type: text/plain\r\n"
"\r\n"
......@@ -1839,11 +1840,43 @@ static int test_sip_list_header(void)
TEST_1(a->k_items);
TEST_1(a->k_next == NULL);
msg_destroy(msg), msg = NULL;
TEST_1(sip_is_allowed(a, SIP_METHOD_INVITE));
TEST_1(!sip_is_allowed(a, SIP_METHOD_PUBLISH));
TEST_1(sip_is_allowed(a, SIP_METHOD(KUIK)));
TEST_1(!sip_is_allowed(a, SIP_METHOD(kuik)));
TEST_1(a = sip_allow_make(home, ""));
TEST_S(sip_header_as_string(home, (void *)a), "");
TEST_1(a = sip_allow_make(home, "INVITE, PUBLISH"));
TEST_1(sip_is_allowed(a, SIP_METHOD_INVITE));
/* Test with list header */
TEST_1(msg_header_add_dup(msg, NULL, (msg_header_t *)a) == 0);
TEST_1(a = sip_allow_make(home, "MESSAGE, SUBSCRIBE"));
TEST_1(msg_header_add_dup(msg, NULL, (msg_header_t *)a) == 0);
TEST_1(msg_header_add_make(msg, NULL, sip_allow_class, "kuik") == 0);
TEST_1(a = sip->sip_allow);
TEST_1(a->k_items);
TEST_S(a->k_items[0], "INVITE");
TEST_S(a->k_items[1], "ACK");
TEST_S(a->k_items[2], "CANCEL");
TEST_S(a->k_items[3], "BYE");
TEST_S(a->k_items[4], "OPTIONS");
TEST_S(a->k_items[5], "MESSAGE");
TEST_S(a->k_items[6], "KUIK");
TEST_S(a->k_items[7], "PUBLISH");
TEST_S(a->k_items[8], "SUBSCRIBE");
TEST_S(a->k_items[9], "kuik");
TEST_P(a->k_items[10], NULL);
msg_destroy(msg), msg = NULL;
su_home_unref(home), home = NULL;
END();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment