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

📄 nua_register.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 5 页
字号:
  nua->nua_nw_changed = snc;  return 0;}intnua_stack_init_registrations(nua_t *nua){  /* Create initial identities: peer-to-peer, public, sips */  nua_registration_t **nr_list = &nua->nua_registrations, **nr_next;  nua_handle_t **nh_list;  nua_handle_t *dnh = nua->nua_dhandle;  sip_via_t const *v;  /* Remove existing, local address based registrations and count the     rest */  while (nr_list && *nr_list) {    nr_next = &(*nr_list)->nr_next;    if ((*nr_list)->nr_default == 1) {      nua_registration_remove(*nr_list);      /* memset(*nr_list, 170, sizeof(**nr_list)); */      /* XXX - free, too */    }    nr_list = nr_next;  }  nr_list = &nua->nua_registrations;  v = nta_agent_public_via(nua->nua_nta);  if (v) {    nua_registration_from_via(nr_list, dnh, v, 1);  }  v = nta_agent_via(nua->nua_nta);  if (v) {    nua_registration_from_via(nr_list, dnh, v, 0);  }  else {    sip_via_t v[2];    sip_via_init(v)->v_next = v + 1;    v[0].v_protocol = sip_transport_udp;    v[0].v_host = "addr.is.invalid.";    sip_via_init(v + 1);    v[1].v_protocol = sip_transport_tcp;    v[1].v_host = "addr.is.invalid.";    nua_registration_from_via(nr_list, dnh, v, 0);  }  /* Go through all the registrations and set to refresh almost     immediately */  nh_list = &nua->nua_handles;  for (; *nh_list; nh_list = &(*nh_list)->nh_next) {    nua_dialog_state_t *ds;    nua_dialog_usage_t *du;    ds = (*nh_list)->nh_ds;    du = ds->ds_usage;    if (ds->ds_has_register == 1 && du->du_class->usage_refresh) {      nua_dialog_usage_refresh(*nh_list, ds, du, 1);    }  }  nta_agent_bind_tport_update(nua->nua_nta, (nta_update_magic_t *)nua, nua_stack_tport_update);  return 0;}int nua_registration_from_via(nua_registration_t **list,			      nua_handle_t *nh,			      sip_via_t const *via,			      int public){  su_home_t *home = nh->nh_home;  sip_via_t *v, *pair, /* v2[2], */ *vias, **vv, **prev;  nua_registration_t *nr = NULL, **next;  su_home_t autohome[SU_HOME_AUTO_SIZE(1024)];  int nr_items = 0;  vias = sip_via_copy(su_home_auto(autohome, sizeof autohome), via);  for (; *list; list = &(*list)->nr_next)    ++nr_items;  next = list;  for (vv = &vias; (v = *vv);) {    char const *protocol;    sip_contact_t *contact;    sip_via_t v2[2];    *vv = v->v_next, v->v_next = NULL, pair = NULL;    if (v->v_protocol == sip_transport_tcp)      protocol = sip_transport_udp;    else if (v->v_protocol == sip_transport_udp)      protocol = sip_transport_tcp;    else      protocol = NULL;    if (protocol) {      /* Try to pair vias if we have both udp and tcp */      for (prev = vv; *prev; prev = &(*prev)->v_next) {        if (strcasecmp(protocol, (*prev)->v_protocol))          continue;        if (strcasecmp(v->v_host, (*prev)->v_host))          continue;        if (str0cmp(v->v_port, (*prev)->v_port))          continue;        break;      }      if (*prev) {        pair = *prev; *prev = pair->v_next; pair->v_next = NULL;      }    }    /* if more than one candidate, ignore local entries */    if (v && (*vv || nr_items > 0) && 	host_is_local(v->v_host)) {      SU_DEBUG_9(("nua_register: ignoring contact candidate %s:%s.\n", 		  v->v_host, v->v_port ? v->v_port : ""));      continue;    }         nr = su_zalloc(home, sizeof *nr);    if (!nr)      break;    v2[0] = *v;    if (pair)      /* Don't use protocol if we have both udp and tcp */      protocol = NULL, v2[0].v_next = &v2[1], v2[1] = *pair;    else      protocol = via->v_protocol, v2[0].v_next = NULL;    v2[1].v_next = NULL;    contact = nua_handle_contact_by_via(nh, home, 0, v2, protocol, NULL);    v = sip_via_dup(home, v2);    if (!contact || !v) {      su_free(home, nr);      break;    }    nr->nr_ready = 1, nr->nr_default = 1, nr->nr_public = public;    nr->nr_secure = contact->m_url->url_type == url_sips;    nr->nr_contact = contact;    *nr->nr_dcontact = *contact, nr->nr_dcontact->m_params = NULL;    nr->nr_via = v;    nr->nr_ip4 = host_is_ip4_address(contact->m_url->url_host);    nr->nr_ip6 = !nr->nr_ip4 && host_is_ip6_reference(contact->m_url->url_host);    SU_DEBUG_9(("nua_register: Adding contact URL '%s' to list.\n", contact->m_url->url_host));    ++nr_items;    nr->nr_next = *next, nr->nr_prev = next; *next = nr, next = &nr->nr_next;    nr->nr_list = list;  }  su_home_deinit(autohome);  return 0;}staticvoid nua_stack_tport_update(nua_t *nua, nta_agent_t *nta){#if 0  nua_registration_t *default_oc;  nua_registration_t const *defaults = nua->nua_registrations;  sip_via_t *via = nta_agent_via(nta);  default_oc = outbound_by_aor(defaults, NULL, 1);  if (default_oc) {    assert(default_oc->nr_via);    outbound_contacts_from_via(default_oc,				       via,				       via->v_next);    /* refresh_register(nua_handle_t *nh, nua_dialog_usage_t *du, sip_time_t now); */  }#endif  return;}nua_registration_t *nua_registration_by_aor(nua_registration_t const *list,					    sip_from_t const *aor,					    url_t const *remote_uri,					    int only_default){  sip_from_t *alt_aor = NULL, _alt_aor[1];  int sips_aor = aor && aor->a_url->url_type == url_sips;  int sips_uri = remote_uri && remote_uri->url_type == url_sips;  nua_registration_t const *nr, *public = NULL, *any = NULL;  nua_registration_t const *registered = NULL;  nua_registration_t const *namewise = NULL, *sipswise = NULL;  int ip4 = remote_uri && host_is_ip4_address(remote_uri->url_host);  int ip6 = remote_uri && host_is_ip6_reference(remote_uri->url_host);  if (only_default || aor == NULL) {    /* Ignore AoR, select only by remote_uri */    for (nr = list; nr; nr = nr->nr_next) {      if (!nr->nr_ready)	continue;      if (only_default && !nr->nr_default)	continue;      if (nr->nr_ip4 && ip6)	continue;      if (nr->nr_ip6 && ip4)	continue;      if (sips_uri ? nr->nr_secure : !nr->nr_secure) 	return (nua_registration_t *)nr;      if (!registered && nr->nr_aor)	registered = nr;      if (!public && nr->nr_public)	public = nr;      if (!any)	any = nr;    }    if (registered)      return (nua_registration_t *)registered;    if (public)      return (nua_registration_t *)public;    if (any)      return (nua_registration_t *)any;    return NULL;  }  if (!sips_aor && aor) {    alt_aor = memcpy(_alt_aor, aor, sizeof _alt_aor);    alt_aor->a_url->url_type = url_sips;    alt_aor->a_url->url_scheme = "sips";  }  for (nr = list; nr; nr = nr->nr_next) {    if (!nr->nr_ready || !nr->nr_contact)      continue;    if (nr->nr_aor) {      if (aor && url_cmp(nr->nr_aor->a_url, aor->a_url) == 0)	return (nua_registration_t *)nr;      if (!namewise && alt_aor && url_cmp(nr->nr_aor->a_url, aor->a_url) == 0)	namewise = nr;    }    if (!sipswise && ((sips_aor || sips_uri) ? 		      nr->nr_secure : !nr->nr_secure))      sipswise = nr;    if (!registered)      registered = nr;    if (!public && nr->nr_public)      public = nr;    if (!any)      any = nr;  }  if (namewise)    return (nua_registration_t *)namewise;  if (sipswise)    return (nua_registration_t *)sipswise;  if (registered)    return (nua_registration_t *)registered;      /* XXX -      should we do some policing whether sips_aor or sips_uri can be used     with sip contact?  */  if (public)    return (nua_registration_t *)public;  if (any)    return (nua_registration_t *)any;  return NULL;}nua_registration_t *nua_registration_for_request(nua_registration_t const *list, sip_t const *sip){  sip_from_t const *aor;  url_t *uri;  aor = sip->sip_from;  uri = sip->sip_request->rq_url;  return nua_registration_by_aor(list, aor, uri, 0);}nua_registration_t *nua_registration_for_response(nua_registration_t const *list, 			      sip_t const *sip,			      sip_record_route_t const *record_route,			      sip_contact_t const *remote_contact){  nua_registration_t *nr;  sip_to_t const *aor = NULL;  url_t const *uri = NULL;  if (sip)    aor = sip->sip_to;    if (record_route)    uri = record_route->r_url;  else if (sip && sip->sip_record_route)    uri = sip->sip_record_route->r_url;  else if (remote_contact)    uri = remote_contact->m_url;  else if (sip && sip->sip_from)    uri = sip->sip_from->a_url;  nr = nua_registration_by_aor(list, aor, uri, 0);  return nr;}/** Return Contact usable in dialogs */sip_contact_t const *nua_registration_contact(nua_registration_t const *nr){  if (nr->nr_by_stack && nr->nr_ob) {    sip_contact_t const *m = outbound_dialog_contact(nr->nr_ob);    if (m)      return m;  }  if (nr->nr_contact)    return nr->nr_dcontact;  else    return NULL;}/** Return initial route. */sip_route_t const *nua_registration_route(nua_registration_t const *nr){  return nr ? nr->nr_route : NULL;}sip_contact_t const *nua_stack_get_contact(nua_registration_t const *nr){  nr = nua_registration_by_aor(nr, NULL, NULL, 1);  return nr && nr->nr_contact ? nr->nr_dcontact : NULL;}/** Add a Contact (and Route) header to request */int nua_registration_add_contact_to_request(nua_handle_t *nh,					    msg_t *msg,					    sip_t *sip,					    int add_contact,					    int add_service_route){  nua_registration_t *nr = NULL;  if (!add_contact && !add_service_route)    return 0;  if (nh == NULL || msg == NULL)    return -1;  if (sip == NULL)    sip = sip_object(msg);  if (nr == NULL)    nr = nua_registration_for_request(nh->nh_nua->nua_registrations, sip);  return nua_registration_add_contact_and_route(nh, nr, msg, sip, 						add_contact, 						add_service_route);}/** Add a Contact header to response. * * @param nh * @param msg response message * @param sip headers in response message * @param record_route record-route from request * @param remote_contact Contact from request */int nua_registration_add_contact_to_response(nua_handle_t *nh,					     msg_t *msg,					     sip_t *sip,					     sip_record_route_t const *record_route,					     sip_contact_t const *remote_contact){  nua_registration_t *nr = NULL;  if (sip == NULL)    sip = sip_object(msg);  if (nh == NULL || msg == NULL || sip == NULL)    return -1;  if (nr == NULL)    nr = nua_registration_for_response(nh->nh_nua->nua_registrations, sip,				       record_route, remote_contact);  return nua_registration_add_contact_and_route(nh, nr, msg, sip, 						1,						0);}/** Add a Contact (and Route) header to request */static int nua_registration_add_contact_and_route(nua_handle_t *nh,					   nua_registration_t *nr,					   msg_t *msg,					   sip_t *sip,					   int add_contact,					   int add_service_route){  if (nr == NULL)    return -1;  if (add_contact) {    sip_contact_t const *m = NULL;    char const *m_display;

⌨️ 快捷键说明

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