Beispiel #1
0
static void sas_log_tx_msg(pjsip_tx_data *tdata)
{
  // For outgoing messages always use the trail identified in the module data
  SAS::TrailId trail = get_trail(tdata);

  if (trail != 0)
  {
    // Log the message event.
    SAS::Event event(trail, SASEvent::TX_SIP_MSG, 1u);
    event.add_static_param(pjsip_transport_get_type_from_flag(tdata->tp_info.transport->flag));
    event.add_static_param(tdata->tp_info.dst_port);
    event.add_var_param(tdata->tp_info.dst_name);
    event.add_var_param((int)(tdata->buf.cur - tdata->buf.start), tdata->buf.start);
    SAS::report_event(event);
  }
  else
  {
    LOG_ERROR("Transmitting message with no SAS trail identifier\n%.*s",
              (int)(tdata->buf.cur - tdata->buf.start),
              tdata->buf.start);
  }
}
static void sas_log_tx_msg(pjsip_tx_data *tdata)
{
  // For outgoing messages always use the trail identified in the module data
  SAS::TrailId trail = get_trail(tdata);

  if (trail == DONT_LOG_TO_SAS)
  {
    TRC_DEBUG("Skipping SAS logging for OPTIONS response");
    return;
  }
  else if (trail != 0)
  {
    // Raise SAS markers on initial requests only - responses in the same
    // transaction will have the same trail ID so don't need additional markers
    if (tdata->msg->type == PJSIP_REQUEST_MSG)
    {
      PJUtils::report_sas_to_from_markers(trail, tdata->msg);

      PJUtils::mark_sas_call_branch_ids(trail, NULL, tdata->msg);
    }

    // Log the message event.
    SAS::Event event(trail, SASEvent::TX_SIP_MSG, 0);
    event.add_static_param(pjsip_transport_get_type_from_flag(tdata->tp_info.transport->flag));
    event.add_static_param(tdata->tp_info.dst_port);
    event.add_var_param(tdata->tp_info.dst_name);
    event.add_compressed_param((int)(tdata->buf.cur - tdata->buf.start),
                               tdata->buf.start,
                               &SASEvent::PROFILE_SIP);
    SAS::report_event(event);
  }
  else
  {
    TRC_ERROR("Transmitting message with no SAS trail identifier\n%.*s",
              (int)(tdata->buf.cur - tdata->buf.start),
              tdata->buf.start);
  }
}
Beispiel #3
0
static void sas_log_rx_msg(pjsip_rx_data* rdata)
{
  SAS::TrailId trail = 0;

  if (rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG)
  {
    // Message is a response, so try to correlate to an existing UAC
    // transaction using the top-most Via header.
    pj_str_t key;
    pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAC,
                         &rdata->msg_info.cseq->method, rdata);
    pjsip_transaction* tsx = pjsip_tsx_layer_find_tsx(&key, PJ_TRUE);
    if (tsx)
    {
      // Found the UAC transaction, so get the trail if there is one.
      trail = get_trail(tsx);

      // Unlock tsx because it is locked in find_tsx()
      pj_grp_lock_release(tsx->grp_lock);
    }
  }
  else if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD)
  {
    // Message is an ACK, so try to correlate it to the existing UAS
    // transaction using the top-most Via header.
    pj_str_t key;
    pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_UAS_ROLE,
                         &rdata->msg_info.cseq->method, rdata);
    pjsip_transaction* tsx = pjsip_tsx_layer_find_tsx(&key, PJ_TRUE);
    if (tsx)
    {
      // Found the UAS transaction, so get the trail if there is one.
      trail = get_trail(tsx);

      // Unlock tsx because it is locked in find_tsx()
      pj_grp_lock_release(tsx->grp_lock);
    }
  }
  else if (rdata->msg_info.msg->line.req.method.id == PJSIP_CANCEL_METHOD)
  {
    // Message is a CANCEL request chasing an INVITE, so we want to try to
    // correlate it to the INVITE trail for the purposes of SAS tracing.
    pj_str_t key;
    pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_UAS_ROLE,
                         pjsip_get_invite_method(), rdata);
    pjsip_transaction* tsx = pjsip_tsx_layer_find_tsx(&key, PJ_TRUE);
    if (tsx)
    {
      // Found the INVITE UAS transaction, so get the trail if there is one.
      trail = get_trail(tsx);

      // Unlock tsx because it is locked in find_tsx()
      pj_grp_lock_release(tsx->grp_lock);
    }
  }

  if (trail == 0)
  {
    // The message doesn't correlate to an existing trail, so create a new
    // one.
    trail = SAS::new_trail(1u);
  }

  // Store the trail in the message as it gets passed up the stack.
  set_trail(rdata, trail);

  // Log the message event.
  SAS::Event event(trail, SASEvent::RX_SIP_MSG, 1u);
  event.add_static_param(pjsip_transport_get_type_from_flag(rdata->tp_info.transport->flag));
  event.add_static_param(rdata->pkt_info.src_port);
  event.add_var_param(rdata->pkt_info.src_name);
  event.add_var_param(rdata->msg_info.len, rdata->msg_info.msg_buf);
  SAS::report_event(event);
}
// LCOV_EXCL_START - can't meaningfully test SAS in UT
static void sas_log_rx_msg(pjsip_rx_data* rdata)
{
  bool first_message_in_trail = false;
  SAS::TrailId trail = 0;

  // Look for the SAS Trail ID for the corresponding transaction object.
  //
  // Note that we are NOT locking the transaction object before we fetch the
  // trail ID from it.  This is deliberate - we cannot get a group lock from
  // this routine as we may already have obtained the IO lock (which is lower
  // in the locking hierarchy) higher up the stack.
  // (e.g. from ioqueue_common_abs::ioqueue_dispatch_read_event) and grabbing
  // the group lock here may cause us to deadlock with a thread using the locks
  // in the right order.
  //
  // This is safe for the following reasons
  // - The transaction objects are only ever invalidated by the current thread
  //   (i.e. the transport thread), so we don't need to worry about the tsx
  //   pointers being invalid.
  // - In principle, the trail IDs (which are 64 bit numbers stored as void*s
  //   since thats the format of the generic PJSIP user data area) might be
  //   being written to as we are reading them, thereby invalidating them.
  //   However, the chances of this happening are exceedingly remote and, if it
  //   ever happened, the worst that could happen is that the trail ID would be
  //   invalid and the log we're about to make unreachable by SAS.  This is
  //   assumed to be sufficiently low impact as to be ignorable for practical
  //   purposes.
  if (rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG)
  {
    // Message is a response, so try to correlate to an existing UAC
    // transaction using the top-most Via header.
    pj_str_t key;
    pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAC,
                         &rdata->msg_info.cseq->method, rdata);
    pjsip_transaction* tsx = pjsip_tsx_layer_find_tsx(&key, PJ_FALSE);
    if (tsx)
    {
      // Found the UAC transaction, so get the trail if there is one.
      trail = get_trail(tsx);
    }
  }
  else if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD)
  {
    // Message is an ACK, so try to correlate it to the existing UAS
    // transaction using the top-most Via header.
    pj_str_t key;
    pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_UAS_ROLE,
                         &rdata->msg_info.cseq->method, rdata);
    pjsip_transaction* tsx = pjsip_tsx_layer_find_tsx(&key, PJ_FALSE);
    if (tsx)
    {
      // Found the UAS transaction, so get the trail if there is one.
      trail = get_trail(tsx);
    }
  }
  else if (rdata->msg_info.msg->line.req.method.id == PJSIP_CANCEL_METHOD)
  {
    // Message is a CANCEL request chasing an INVITE, so we want to try to
    // correlate it to the INVITE trail for the purposes of SAS tracing.
    pj_str_t key;
    pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_UAS_ROLE,
                         pjsip_get_invite_method(), rdata);
    pjsip_transaction* tsx = pjsip_tsx_layer_find_tsx(&key, PJ_FALSE);
    if (tsx)
    {
      // Found the INVITE UAS transaction, so get the trail if there is one.
      trail = get_trail(tsx);
    }
  }
  else if ((rdata->msg_info.msg->line.req.method.id == PJSIP_OPTIONS_METHOD) &&
           (URIClassifier::classify_uri(rdata->msg_info.msg->line.req.uri) == NODE_LOCAL_SIP_URI))
  {
    // This is an OPTIONS poll directed at this node. Don't log it to SAS, and set the trail ID to a sentinel value so we don't log the response either.
    TRC_DEBUG("Skipping SAS logging for OPTIONS request");
    set_trail(rdata, DONT_LOG_TO_SAS);
    return;
  }

  if (trail == 0)
  {
    // The message doesn't correlate to an existing trail, so create a new
    // one.

    // If SAS::new_trail returns 0 or DONT_LOG_TO_SAS, keep going.
    while ((trail == 0) || (trail == DONT_LOG_TO_SAS))
    {
      trail = SAS::new_trail(1u);
    }
    first_message_in_trail = true;
  }

  // Store the trail in the message as it gets passed up the stack.
  set_trail(rdata, trail);

  // Raise SAS markers on the first message in a trail only - subsequent
  // messages with the same trail ID don't need additional markers
  if (first_message_in_trail)
  {
    PJUtils::report_sas_to_from_markers(trail, rdata->msg_info.msg);

    pjsip_cid_hdr* cid = (pjsip_cid_hdr*)rdata->msg_info.cid;

    PJUtils::mark_sas_call_branch_ids(trail, cid, rdata->msg_info.msg);
  }

  // Log the message event.
  SAS::Event event(trail, SASEvent::RX_SIP_MSG, 0);
  event.add_static_param(pjsip_transport_get_type_from_flag(rdata->tp_info.transport->flag));
  event.add_static_param(rdata->pkt_info.src_port);
  event.add_var_param(rdata->pkt_info.src_name);
  event.add_compressed_param(rdata->msg_info.len, rdata->msg_info.msg_buf, &SASEvent::PROFILE_SIP);
  SAS::report_event(event);
}