⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nta_check.c

📁 this is simple sip stack.
💻 C
字号:
/* * This file is part of the Sofia-SIP package * * Copyright (C) 2005 Nokia Corporation. * * Contact: Pekka Pessi <pekka.pessi@nokia.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * *//**@CFILE nta.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 */#include "config.h"#include <sofia-sip/su_tagarg.h>#include <sofia-sip/sip_header.h>#include <sofia-sip/sip_status.h>#include <sofia-sip/sip_util.h>#include <sofia-sip/nta.h>/* ======================================================================== *//* Request validation *//** Check that all features UAC requires are also in 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, ...){  if (sip->sip_require) {    su_home_t home[1] = { SU_HOME_INIT(home) };    sip_unsupported_t *us;    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;    }  }  return 0;}/** Check that all features we require are also supported by UAC */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 (us) {    ta_list ta;    ta_start(ta, tag, value);    nta_incoming_treply(irq,			SIP_421_EXTENSION_REQUIRED,			SIPTAG_REQUIRE(require),			ta_tags(ta));    ta_end(ta);    su_home_deinit(home);    return 421;  }  return 0;}/** Check that we support the request method. */int nta_check_method(nta_incoming_t *irq,		     sip_t const *sip,		     sip_allow_t const *allow,		     tag_type_t tag, tag_value_t value, ...){  /* Check extensions */  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 (sip->sip_request->rq_method != sip_method_unknown)    nta_incoming_treply(irq,			status = SIP_405_METHOD_NOT_ALLOWED,			SIPTAG_ALLOW(allow),			ta_tags(ta));  else    nta_incoming_treply(irq,			status = SIP_501_NOT_IMPLEMENTED,			SIPTAG_ALLOW(allow),			ta_tags(ta));  ta_end(ta);  return status;}static char const application_sdp[] = "application/sdp";/* Check that we understand (session) content. */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, ...){  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;  if (cd == NULL || strcasecmp(cd->cd_type, "session") == 0) {    sip_accept_t const *ab = session_accepts;    char const *c_type;    if (c)      c_type = c->c_type;    else if (sip->sip_payload->pl_len > 3 &&	     strncasecmp(sip->sip_payload->pl_data, "v=0", 3) == 0)      /* Missing Content-Type, but it looks like SDP  */      c_type = application_sdp;    else      /* No chance */      ab = NULL, c_type = NULL;    for (; ab; ab = ab->ac_next) {      if (strcasecmp(c_type, ab->ac_type) == 0)	break;    }    if (ab)      acceptable_type = 1;  }  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[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);  return 415;}  /** Check that UAC accepts (application/sdp) */int nta_check_accept(nta_incoming_t *irq,		     sip_t const *sip,		     sip_accept_t const *acceptable,		     sip_accept_t const **return_acceptable,		     tag_type_t tag, tag_value_t value, ...){  ta_list ta;  sip_accept_t const *ac, *ab;  sip_method_t method;  if (!acceptable)    return 0;  if (sip->sip_request)    method = sip->sip_request->rq_method;  else /* if (sip->sip_cseq) */    method = sip->sip_cseq->cs_method;  /* Missing Accept header implies support for SDP in INVITE and OPTIONS   * (and PRACK and UPDATE?)    */  if (!sip->sip_accept && (method == sip_method_invite || 			   method == sip_method_options ||			   method == sip_method_prack ||			   method == sip_method_update)) {    for (ab = acceptable; ab; ab = ab->ac_next)      if (strcasecmp(application_sdp, ab->ac_type) == 0) {	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)      continue;    for (ab = acceptable; ab; ab = ab->ac_next)      if (strcasecmp(ac->ac_type, ab->ac_type) == 0) {	if (return_acceptable) *return_acceptable = ab;	return 0;      }  }  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.  * * 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. */int nta_check_session_expires(nta_incoming_t *irq,			      sip_t const *sip,			      sip_time_t my_min_se,			      tag_type_t tag, tag_value_t value, ...){  if ((sip->sip_min_se &&       sip->sip_session_expires->x_delta < sip->sip_min_se->min_delta)      || sip->sip_session_expires->x_delta < my_min_se) {    ta_list ta;    sip_min_se_t min_se[1];    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);    return 422;  }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -