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

📄 nua_stack.c

📁 Internet Phone, Chat, Conferencing
💻 C
📖 第 1 页 / 共 5 页
字号:
  else if (!sip->sip_organization && NH_PGET(nh, organization) &&	   sip_add_dup(msg, sip, (sip_header_t *)NH_PGET(nh, organization)) < 0)    msg_destroy(msg);  else if (!sip->sip_allow && NH_PGET(nh, allow) &&	   sip_add_dup(msg, sip, (sip_header_t*)NH_PGET(nh, allow)) < 0)    msg_destroy(msg);  else    return msg;  return NULL;}/* ======================================================================== *//* Generic processing */int nua_stack_process_unknown(nua_t *nua,			      nua_handle_t *nh,			      nta_incoming_t *irq,			      sip_t const *sip){  return 501;}intnua_stack_method(nua_t *nua, nua_handle_t *nh, nua_event_t e,		 tagi_t const *tags){  return UA_EVENT1(e, SIP_501_NOT_IMPLEMENTED);}/**Relay response message to the application. * * If handle has already been marked as destroyed by nua_handle_destroy(), * release the handle with nh_destroy(). */int nua_stack_process_response(nua_handle_t *nh,			       struct nua_client_request *cr,			       nta_outgoing_t *orq,			       sip_t const *sip,			       tag_type_t tag, tag_value_t value, ...){  msg_t *msg = nta_outgoing_getresponse(orq);  int status = sip->sip_status->st_status;  char const *phrase = sip->sip_status->st_phrase;  ta_list ta;  int final;  if (status >= 200 && status < 300)    nh_challenge(nh, sip);  /* Collect nextnonce */  if (nta_outgoing_method(orq) == sip_method_invite)    final = status >= 300;  else    final = status >= 200;  if (final) {    nua_creq_deinit(cr, orq);    if (cr->cr_usage && nh->nh_cr == cr) {      if ((status >= 300 && !cr->cr_usage->du_ready) ||	  cr->cr_usage->du_terminating)	nua_dialog_usage_remove(nh, nh->nh_ds, cr->cr_usage);    }    cr->cr_usage = NULL;  }  ta_start(ta, tag, value);  nua_stack_event(nh->nh_nua, nh, msg, cr->cr_event, status, phrase,	   ta_tags(ta));  if (final)    cr->cr_event = nua_i_error;  ta_end(ta);  return 0;}static inlineint can_redirect(sip_contact_t const *m, sip_method_t method){  if (m && m->m_url->url_host) {    enum url_type_e type = m->m_url->url_type;    return      type == url_sip ||      type == url_sips ||      (type == url_tel &&       (method == sip_method_invite || method == sip_method_message)) ||      (type == url_im && method == sip_method_message) ||      (type == url_pres && method == sip_method_subscribe);  }  return 0;}int nua_creq_restart_with(nua_handle_t *nh,			  struct nua_client_request *cr,			  nta_outgoing_t *orq,			  int status, char const *phrase,			  nua_creq_restart_f *f,			  TAG_LIST){  ta_list ta;  msg_t *msg = nta_outgoing_getresponse(orq);  nua_stack_event(nh->nh_nua, nh, msg, cr->cr_event, status, phrase,		  TAG_END());  nta_outgoing_destroy(orq);  if (f) {    ta_start(ta, tag, value);    f(nh, ta_args(ta));    ta_end(ta);  }  return 1;}/** Check response, return true if we can restart the request. * */int nua_creq_check_restart(nua_handle_t *nh,			   struct nua_client_request *cr,			   nta_outgoing_t *orq,			   sip_t const *sip,			   nua_creq_restart_f *f){  int status = sip->sip_status->st_status;  sip_method_t method = nta_outgoing_method(orq);  int removed = 0;  nua_dialog_usage_t *du = cr->cr_usage;  assert(f);  if (orq == cr->cr_orq)    removed = 1, cr->cr_orq = NULL;  cr->cr_restart = NULL;  if (cr->cr_msg == NULL || status < 200)    ;  else if (++cr->cr_retry_count > NH_PGET(nh, retry_count))    ;  else if (status == 302) {    if (can_redirect(sip->sip_contact, method)) {      return	nua_creq_restart_with(nh, cr, orq, 100, "Redirected",			      f, NUTAG_URL(sip->sip_contact->m_url),			      TAG_END());    }  }  else if (status == 423) {    sip_t *req = sip_object(cr->cr_msg);    unsigned my_expires = 0;    if (req->sip_expires)      my_expires = req->sip_expires->ex_delta;    if (sip->sip_min_expires &&	sip->sip_min_expires->me_delta > my_expires) {      sip_expires_t ex[1];      sip_expires_init(ex);      ex->ex_delta = sip->sip_min_expires->me_delta;      return	nua_creq_restart_with(nh, cr, orq,			      100, "Re-Negotiating Subscription Expiration",			      f, SIPTAG_EXPIRES(ex), TAG_END());    }  }  else if (method != sip_method_ack && method != sip_method_cancel &&	   ((status == 401 && sip->sip_www_authenticate) ||	    (status == 407 && sip->sip_proxy_authenticate)) &&	   nh_challenge(nh, sip) > 0) {    sip_t *rsip;    int done;    rsip = sip_object(cr->cr_msg);    /* XXX - check for instant restart */    done = auc_authorization(&nh->nh_auth, cr->cr_msg, (msg_pub_t*)rsip,			     rsip->sip_request->rq_method_name,			     rsip->sip_request->rq_url,			     rsip->sip_payload);    if (done > 0) {      return	nua_creq_restart_with(nh, cr, orq,			      100, "Request Authorized by Cache",			      f, TAG_END());    }    else if (done == 0) {      msg_t *msg = nta_outgoing_getresponse(orq);      nua_stack_event(nh->nh_nua, nh, msg, cr->cr_event,	       status, sip->sip_status->st_phrase, TAG_END());      nta_outgoing_destroy(orq);      if (du) {	du->du_pending = NULL;	du->du_refresh = 0;      }      /* Wait for nua_authenticate() */      cr->cr_restart = f;      return 1;    }    else {      SU_DEBUG_5(("nua(%p): auc_authorization failed\n", nh));    }  }#if HAVE_SOFIA_SMIME  else if (status == 493)     /* try detached signature */    ;#endif  else if (status == 422 && method == sip_method_invite) {    if (sip->sip_min_se && nh->nh_ss->ss_min_se < sip->sip_min_se->min_delta)      nh->nh_ss->ss_min_se = sip->sip_min_se->min_delta;    if (nh->nh_ss->ss_min_se > nh->nh_ss->ss_session_timer)      nh->nh_ss->ss_session_timer = nh->nh_ss->ss_min_se;    return      nua_creq_restart_with(nh, cr, orq,			    100, "Re-Negotiating Session Timer",			    f, TAG_END());  }  /* This was final response that cannot be restarted. */  if (removed)    cr->cr_orq = orq;  if (du) {    du->du_pending = NULL;    du->du_refresh = 0;  }  cr->cr_retry_count = 0;  if (cr->cr_msg)    msg_destroy(cr->cr_msg), cr->cr_msg = NULL;  return 0;}/** Restart a request */int nua_creq_restart(nua_handle_t *nh,		     struct nua_client_request *cr,		     nta_response_f *cb,		     tagi_t *tags){  msg_t *msg;  cr->cr_restart = NULL;  if (!cr->cr_msg)    return 0;  msg = nua_creq_msg(nh->nh_nua, nh, cr, 1, SIP_METHOD_UNKNOWN,		     TAG_NEXT(tags));  cr->cr_orq = nta_outgoing_mcreate(nh->nh_nua->nua_nta, cb, nh, NULL, msg,				    SIPTAG_END(), TAG_NEXT(tags));  if (!cr->cr_orq) {    msg_destroy(msg);    return 0;  }  return 1;}/* ======================================================================== *//* Authentication */voidnua_stack_authenticate(nua_t *nua, nua_handle_t *nh, nua_event_t e,		tagi_t const *tags){  int status = nh_authorize(nh, TAG_NEXT(tags));  if (status > 0) {    nua_creq_restart_f *restart = NULL;    nua_stack_event(nua, nh, NULL, e, SIP_200_OK, TAG_END());    if (nh->nh_cr->cr_restart) {      restart = nh->nh_cr->cr_restart;      nh->nh_cr->cr_restart = NULL;    }    else if (nh->nh_ss->ss_crequest->cr_restart) {      restart = nh->nh_ss->ss_crequest->cr_restart;      nh->nh_ss->ss_crequest->cr_restart = NULL;    }    if (restart)      restart(nh, (tagi_t *)tags);	/* Restart operation */  }  else if (status < 0) {    nua_stack_event(nua, nh, NULL, e, 500, "Cannot add credentials", TAG_END());  }  else {    nua_stack_event(nua, nh, NULL, e, 404, "No matching challenge", TAG_END());  }}/* ======================================================================== *//* * Process incoming requests */int nua_stack_process_request(nua_handle_t *nh,			      nta_leg_t *leg,			      nta_incoming_t *irq,			      sip_t const *sip){  nua_t *nua = nh->nh_nua;  sip_method_t method = sip->sip_request->rq_method;  sip_user_agent_t const *user_agent = NH_PGET(nh, user_agent);  sip_supported_t const *supported = NH_PGET(nh, supported);  sip_allow_t const *allow = NH_PGET(nh, allow);  enter;  nta_incoming_tag(irq, NULL);  if (nta_check_method(irq, sip, allow,		       SIPTAG_SUPPORTED(supported),		       SIPTAG_USER_AGENT(user_agent),		       TAG_END()))    return 405;  switch (sip->sip_request->rq_url->url_type) {  case url_sip:  case url_sips:  case url_im:  case url_pres:  case url_tel:    break;  default:    nta_incoming_treply(irq, SIP_416_UNSUPPORTED_URI,			SIPTAG_ALLOW(allow),			SIPTAG_SUPPORTED(supported),			SIPTAG_USER_AGENT(user_agent),			TAG_END());  }  if (nta_check_required(irq, sip, supported,			 SIPTAG_ALLOW(allow),			 SIPTAG_USER_AGENT(user_agent),			 TAG_END()))    return 420;  if (nh == nua->nua_dhandle) {    if (!sip->sip_to->a_tag)      ;    else if (method == sip_method_message && NH_PGET(nh, win_messenger_enable))      ;    else {      nta_incoming_treply(irq, 481, "Initial transaction with a To tag",			  TAG_END());      return 481;    }    nh = NULL;  }  if (sip->sip_timestamp)    nta_incoming_treply(irq, SIP_100_TRYING, TAG_END());  switch (method) {  case sip_method_invite:    return nua_stack_process_invite(nua, nh, irq, sip);  case sip_method_info:    if (nh) return nua_stack_process_info(nua, nh, irq, sip);    /*FALLTHROUGH*/  case sip_method_update:    if (nh) return nua_stack_process_update(nua, nh, irq, sip);    /*FALLTHROUGH*/  case sip_method_bye:    if (nh) return nua_stack_process_bye(nua, nh, irq, sip);    nta_incoming_treply(irq,			481, "Call Does Not Exist",			SIPTAG_ALLOW(allow),			SIPTAG_SUPPORTED(supported),			SIPTAG_USER_AGENT(user_agent),			TAG_END());    return 481;  case sip_method_message:    return nua_stack_process_message(nua, nh, irq, sip);  case sip_method_notify:    return nua_stack_process_notify(nua, nh, irq, sip);  case sip_method_subscribe:    return nua_stack_process_subsribe(nua, nh, irq, sip);  case sip_method_options:    return nua_stack_process_options(nua, nh, irq, sip);  case sip_method_refer:    return nua_stack_process_refer(nua, nh, irq, sip);  case sip_method_publish:    return nua_stack_process_publish(nua, nh, irq, sip);  case sip_method_ack:  case sip_method_cancel:    SU_DEBUG_1(("nua(%p): strange %s from <" URL_PRINT_FORMAT ">\n", nh,		sip->sip_request->rq_method_name,		URL_PRINT_ARGS(sip->sip_from->a_url)));    /* Send nua_i_error ? */    return 481;  default:    return nua_stack_process_unknown(nua, nh, irq, sip);  }}voidnua_stack_respond(nua_t *nua, nua_handle_t *nh,	   int status, char const *phrase, tagi_t const *tags){  struct nua_session_state *ss = nh->nh_ss;  nua_server_request_t *sr = ss->ss_srequest;  if (sr->sr_respond) {    sr->sr_respond(nua, nh, status, phrase, tags);  }#if 0  else if (nta_incoming_status(nh->nh_irq) < 200) {    int add_contact = 0;    sip_contact_t *m;    if (nta_incoming_url(nh->nh_irq)->url_type == url_sips &&	nua->nua_sips_contact)      m = nua->nua_sips_contact;    else      m = nua->nua_contact;    SU_DEBUG_1(("nua: anonymous response %u %s\n", status, phrase));    tl_gets(tags, NUTAG_ADD_CONTACT_REF(add_contact), TAG_END());    nta_incoming_treply(nh->nh_irq, status, phrase,			TAG_IF(add_contact, SIPTAG_CONTACT(m)),			TAG_NEXT(tags));    if (status >= 200)      nta_incoming_destroy(nh->nh_irq), nh->nh_irq = NULL;  }#endif  else if (ss->ss_srequest->sr_irq) {    nua_stack_event(nua, nh, NULL, nua_i_error,		    500, "Already Sent Final Response", TAG_END());  }  else {    nua_stack_event(nua, nh, NULL, nua_i_error,		    500, "Responding to a Non-Existing Request", TAG_END());  }}

⌨️ 快捷键说明

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