Commit 5f77870e authored by Pekka Pessi's avatar Pekka Pessi
Browse files

nta_check.c: updated documentation.

darcs-hash:20060906063404-65a35-3b99efe900a0c23e29cdc6999532f0c4f118f1e7.gz
parent a43febca
......@@ -22,11 +22,11 @@
*
*/
/**@CFILE nta.c
/**@CFILE nta_check.c
* @brief Checks for features, MIME types, session timer.
*
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*
*
* @date Created: Wed Mar 8 16:35:05 EET 2006 ppessi
*/
......@@ -41,46 +41,82 @@
/* ======================================================================== */
/* Request validation */
/** Check that all features UAC requires are also in supported */
/**Check that we support all features which UAC requires.
*
* The list of supported features is compared with the list of features
* required by the UAC. If some features are not listed as supported, return
* 420. If @a irq is non-NULL, the 420 response message is sent to the
* client along with list of unsupported features in the @b Unsupported
* header, too.
*
* @param irq incoming transaction object (may be NULL).
* @param sip contents of the SIP message
* @param supported list of protocol features supported
* @param tag, value, ... optional list of tagged arguments used
* when responding to the transaction
*
* @return 0 if successful.
* 420 if any of the required features is not supported.
*/
int nta_check_required(nta_incoming_t *irq,
sip_t const *sip,
sip_supported_t const *supported,
tag_type_t tag, tag_value_t value, ...)
{
int status = 0;
if (sip->sip_require) {
su_home_t home[1] = { SU_HOME_INIT(home) };
su_home_t home[SU_HOME_AUTO_SIZE(512)];
sip_unsupported_t *us;
su_home_auto(home, sizeof home);
us = sip_has_unsupported(home, supported, sip->sip_require);
if (us) {
ta_list ta;
ta_start(ta, tag, value);
nta_incoming_treply(irq,
SIP_420_BAD_EXTENSION,
SIPTAG_UNSUPPORTED(us),
SIPTAG_SUPPORTED(supported),
ta_tags(ta));
ta_end(ta);
su_home_deinit(home);
return 420;
status = 420;
if (irq) {
ta_list ta;
ta_start(ta, tag, value);
nta_incoming_treply(irq,
SIP_420_BAD_EXTENSION,
SIPTAG_UNSUPPORTED(us),
SIPTAG_SUPPORTED(supported),
ta_tags(ta));
ta_end(ta);
}
}
su_home_deinit(home);
}
return 0;
return status;
}
/** Check that all features we require are also supported by UAC */
/** Check that UAC supports all the required features.
*
* The list of required features is compared with the features supported by
* the UAC. If some features are not supported, return 421. If @a irq is
* non-NULL, the 421 response message is sent to the client, too.
*
* @param irq incoming transaction object (may be NULL).
* @param sip contents of the SIP message
* @param require list of required protocol features
* @param tag, value, ... optional list of tagged arguments used
* when responding to the transaction
*
* @return 0 if successful.
* 421 if any of the required features is not supported.
*/
int nta_check_supported(nta_incoming_t *irq,
sip_t const *sip,
sip_require_t *require,
tag_type_t tag, tag_value_t value, ...)
{
su_home_t home[1] = { SU_HOME_INIT(home) };
sip_unsupported_t *us;
us = sip_has_unsupported(home, sip->sip_supported, require);
if (!sip_has_unsupported(NULL, sip->sip_supported, require))
return 0;
if (us) {
if (irq) {
ta_list ta;
ta_start(ta, tag, value);
nta_incoming_treply(irq,
......@@ -88,14 +124,28 @@ int nta_check_supported(nta_incoming_t *irq,
SIPTAG_REQUIRE(require),
ta_tags(ta));
ta_end(ta);
su_home_deinit(home);
return 421;
}
return 0;
return 421;
}
/** Check that we support the request method. */
/** Check that we allow the request method.
*
* The request-method is compared with the list of supported methods in @a
* allow. If match is found, 0 is is returned. Otherwise, if the
* request-method is well-known, 405 is returned. If the request-method is
* unknown, 501 is returned. If @a irq is non-NULL, the 405 or 501 response
* message is sent to the client, too.
*
* @param irq incoming transaction object (may be NULL).
* @param sip contents of the SIP message
* @param allow list of allowed methods
* @param tag, value, ... optional list of tagged arguments used
* when responding to the transaction
*
* @return 0 if successful, 405 is request-method is not allowed, 501 if
* request-method is unknown.
*/
int nta_check_method(nta_incoming_t *irq,
sip_t const *sip,
sip_allow_t const *allow,
......@@ -105,34 +155,62 @@ int nta_check_method(nta_incoming_t *irq,
char const *name = sip->sip_request->rq_method_name;
sip_param_t const *allowed;
int i = 0;
int status;
ta_list ta;
if (allow && (allowed = allow->k_items))
for (i = 0; allowed[i]; i++)
if (strcasecmp(name, allowed[i]) == 0)
return 0;
ta_start(ta, tag, value);
if (irq) {
ta_list ta;
ta_start(ta, tag, value);
if (sip->sip_request->rq_method != sip_method_unknown)
nta_incoming_treply(irq,
SIP_405_METHOD_NOT_ALLOWED,
SIPTAG_ALLOW(allow),
ta_tags(ta));
else
nta_incoming_treply(irq,
SIP_501_NOT_IMPLEMENTED,
SIPTAG_ALLOW(allow),
ta_tags(ta));
ta_end(ta);
}
if (sip->sip_request->rq_method != sip_method_unknown)
nta_incoming_treply(irq,
status = SIP_405_METHOD_NOT_ALLOWED,
SIPTAG_ALLOW(allow),
ta_tags(ta));
return 405;
else
nta_incoming_treply(irq,
status = SIP_501_NOT_IMPLEMENTED,
SIPTAG_ALLOW(allow),
ta_tags(ta));
ta_end(ta);
return status;
return 501;
}
static char const application_sdp[] = "application/sdp";
/* Check that we understand (session) content. */
int nta_check_session_content(nta_incoming_t *irq,
/** Check that we understand session content in the request.
*
* If there is no Content-Disposition header or the Content-Disposition
* header indicated "session", the message body and content-type is compared
* with the acceptable session content-types listed in @a session_accepts.
* (typically, @c "application/sdp"). If no match is found, a 415 is
* returned. If @a irq is non-NULL, the 415 response message is sent to the
* client, too.
*
* If the Content-Disposition header indicates something else but "session",
* and it does not contain "handling=optional" parameter, a 415 response is
* returned, too.
*
* Also, the Content-Encoding header is checked. If it is not empty
* (indicating no content-encoding), a 415 response is returned, too.
*
* @param irq incoming (server) transaction object (may be NULL).
* @param sip contents of the SIP message
* @param session_accepts list of acceptable content-types for "session"
* content disposition
* @param tag, value, ... optional list of tagged arguments used
* when responding to the transaction
*
* @return 0 if successful, 415 if content-type is not acceptable.
*/
int nta_check_session_content(nta_incoming_t *irq,
sip_t const *sip,
sip_accept_t const *session_accepts,
tag_type_t tag, tag_value_t value, ...)
......@@ -140,7 +218,6 @@ int nta_check_session_content(nta_incoming_t *irq,
sip_content_type_t const *c = sip->sip_content_type;
sip_content_disposition_t const *cd = sip->sip_content_disposition;
int acceptable_type = 0, acceptable_encoding = 0;
ta_list ta;
if (sip->sip_payload == NULL)
return 0;
......@@ -167,31 +244,50 @@ int nta_check_session_content(nta_incoming_t *irq,
if (ab)
acceptable_type = 1;
}
else if (cd->cd_optional)
else if (cd->cd_optional)
acceptable_type = 1;
/* Empty or missing Content-Encoding */
if (!sip->sip_content_encoding ||
!sip->sip_content_encoding->k_items ||
!sip->sip_content_encoding->k_items ||
!sip->sip_content_encoding->k_items[0] ||
!sip->sip_content_encoding->k_items[0][0])
acceptable_encoding = 1;
if (acceptable_type && acceptable_encoding)
return 0;
ta_start(ta, tag, value);
nta_incoming_treply(irq,
SIP_415_UNSUPPORTED_MEDIA,
SIPTAG_ACCEPT(session_accepts),
ta_tags(ta));
ta_end(ta);
if (irq) {
ta_list ta;
ta_start(ta, tag, value);
nta_incoming_treply(irq,
SIP_415_UNSUPPORTED_MEDIA,
SIPTAG_ACCEPT(session_accepts),
ta_tags(ta));
ta_end(ta);
}
return 415;
}
/** Check that UAC accepts (application/sdp) */
/**Check that UAC accepts one of listed MIME content-types.
*
* The list of acceptable content-types are compared with the acceptable
* content-types. If match is found, it is returned in @a return_acceptable.
* If no match is found, a 406 is returned. If @a irq is non-NULL, the 406
* response message is sent to the client, too.
*
* @param irq incoming transaction object (may be NULL).
* @param sip contents of the SIP message
* @param acceptable list of acceptable content types
* @param return_acceptable optional return-value parameter for
* matched content-type
* @param tag, value, ... optional list of tagged arguments used
* when responding to the transaction
*
* @return 406 if no content-type is acceptable by client, 0 if successful.
*/
int nta_check_accept(nta_incoming_t *irq,
sip_t const *sip,
sip_accept_t const *acceptable,
......@@ -211,9 +307,9 @@ int nta_check_accept(nta_incoming_t *irq,
method = sip->sip_cseq->cs_method;
/* Missing Accept header implies support for SDP in INVITE and OPTIONS
* (and PRACK and UPDATE?)
* (and PRACK and UPDATE?)
*/
if (!sip->sip_accept && (method == sip_method_invite ||
if (!sip->sip_accept && (method == sip_method_invite ||
method == sip_method_options ||
method == sip_method_prack ||
method == sip_method_update)) {
......@@ -222,7 +318,7 @@ int nta_check_accept(nta_incoming_t *irq,
if (return_acceptable) *return_acceptable = ab;
return 0;
}
}
}
for (ac = sip->sip_accept; ac; ac = ac->ac_next) {
if (sip_q_value(ac->ac_q) == 0 || !ac->ac_type)
......@@ -235,21 +331,31 @@ int nta_check_accept(nta_incoming_t *irq,
}
}
ta_start(ta, tag, value);
nta_incoming_treply(irq,
SIP_406_NOT_ACCEPTABLE,
SIPTAG_ACCEPT(acceptable),
ta_tags(ta));
ta_end(ta);
if (irq) {
ta_start(ta, tag, value);
nta_incoming_treply(irq,
SIP_406_NOT_ACCEPTABLE,
SIPTAG_ACCEPT(acceptable),
ta_tags(ta));
ta_end(ta);
}
return 406;
}
/**Check Session-Expires header.
/**Check Session-Expires header.
*
* If the proposed session-expiration time is smaller than Min-SE or our
* minimal session expiration time, respond with 422 containing our minimal
* session expiration time in Min-SE header.
*
* @param irq incoming transaction object (may be NULL).
* @param sip contents of the SIP message
* @param my_min_se minimal session expiration time in seconds
* @param tag, value, ... optional list of tagged arguments used
* when responding to the transaction
*
* @return 422 if session expiration time is too small, 0 when successful.
*/
int nta_check_session_expires(nta_incoming_t *irq,
sip_t const *sip,
......@@ -265,12 +371,15 @@ int nta_check_session_expires(nta_incoming_t *irq,
sip_min_se_init(min_se)->min_delta = my_min_se;
ta_start(ta, tag, value);
nta_incoming_treply(irq,
SIP_422_SESSION_TIMER_TOO_SMALL,
SIPTAG_MIN_SE(min_se),
ta_tags(ta));
ta_end(ta);
if (irq) {
ta_start(ta, tag, value);
nta_incoming_treply(irq,
SIP_422_SESSION_TIMER_TOO_SMALL,
SIPTAG_MIN_SE(min_se),
ta_tags(ta));
ta_end(ta);
}
return 422;
}
......
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