Exemplo n.º 1
0
/** Create a new outbound object */
outbound_t *
outbound_new(outbound_owner_t *owner,
	     outbound_owner_vtable const *owner_methods,
	     su_root_t *root,
	     nta_agent_t *agent,
	     char const *instance)
{
  outbound_t *ob;

  if (!owner || !owner_methods || !root || !agent)
    return NULL;

  ob = su_home_clone((su_home_t *)owner, sizeof *ob);

  if (ob) {
    su_md5_t md5[1];
    uint8_t digest[SU_MD5_DIGEST_SIZE];
    su_guid_t guid[1];

    ob->ob_owner = owner;
    ob->ob_oo = owner_methods;
    ob->ob_root = root;
    ob->ob_nta = agent;

    if (instance)
      ob->ob_instance =
	su_sprintf(ob->ob_home, "+sip.instance=\"<%s>\"", instance);
    ob->ob_reg_id = 0;

    outbound_peer_info(ob, NULL);

    /* Generate a random cookie (used as Call-ID) for us */
    su_md5_init(md5);
    su_guid_generate(guid);
    if (instance)
      su_md5_update(md5, (void *)instance, strlen(instance));
    su_md5_update(md5, (void *)guid, sizeof guid);
    su_md5_digest(md5, digest);
    token64_e(ob->ob_cookie, sizeof ob->ob_cookie, digest, sizeof digest);

    if (instance && !ob->ob_instance)
      su_home_unref(ob->ob_home), ob = NULL;
  }

  return ob;
}
Exemplo n.º 2
0
static int nua_notify_client_init_etag(nua_client_request_t *cr,
				       msg_t *msg, sip_t *sip,
				       tagi_t const *tags)
{
#if SU_HAVE_EXPERIMENTAL
  nua_handle_t *nh = cr->cr_owner;
  struct notifier_usage *nu = nua_dialog_usage_private(cr->cr_usage);
  nua_server_request_t *sr;

  if (nu->nu_tag)
    su_free(nh->nh_home, nu->nu_tag), nu->nu_tag = NULL;
    nu->nu_no_body = 0;

  if (sip->sip_etag) {
    nu->nu_appl_etags = 1;
    nu->nu_tag = su_strdup(nh->nh_home, sip->sip_etag->g_string);
  }
  else if (!nu->nu_appl_etags && nu->nu_etags) {
    su_md5_t md5[1];
    unsigned char digest[SU_MD5_DIGEST_SIZE];
    sip_payload_t pl[1] = { SIP_PAYLOAD_INIT() };
    char token[2 * 16];

    su_md5_init(md5);

    if (sip->sip_payload) *pl = *sip->sip_payload;

    if (pl->pl_len)
      su_md5_update(md5, pl->pl_data, pl->pl_len);
    su_md5_update(md5, &pl->pl_len, sizeof(pl->pl_len));

    if (sip->sip_content_type)
      su_md5_striupdate(md5, sip->sip_content_type->c_type);

    su_md5_digest(md5, digest);
    token64_e(token, sizeof token, digest, sizeof digest);
    token[(sizeof token) - 1] = '\0';
    nu->nu_tag = su_strdup(nh->nh_home, token);
  }

  if (!nu->nu_requested || !nu->nu_tag)
    return 0;

  /* Check if SUBSCRIBE had matching suppression */
  for (sr = nh->nh_ds->ds_sr; sr; sr = sr->sr_next)
    if (sr->sr_usage == cr->cr_usage && sr->sr_method == sip_method_subscribe)
      break;

  if (sr) {
    sip_t const *sip = sr->sr_request.sip;

    sip_suppress_body_if_match_t *sbim;
    sip_suppress_notify_if_match_t *snim;

    if (cr->cr_usage->du_ready) {
      snim = sip_suppress_notify_if_match(sip);

      if (snim && su_casematch(snim->snim_tag, nu->nu_tag)) {
	if (nu->nu_requested > nu->nu_expires)
	  nu->nu_expires = nu->nu_requested;
	nu->nu_requested = 0;
	return nua_client_return(cr, 202, "NOTIFY Suppressed", msg);
      }
    }

    sbim = sip_suppress_body_if_match(sip);
    if (sbim && su_casematch(sbim->sbim_tag, nu->nu_tag))
      nu->nu_no_body = 1;
  }
#endif

  return 0;
}