[Home]

Summary:ASTERISK-22619: [patch] Session-ID header support for chan_sip
Reporter:Ben Smithurst (bensmithurst)Labels:
Date Opened:2013-10-01 05:19:33Date Closed:2013-10-25 09:46:57
Priority:MinorRegression?No
Status:Closed/CompleteComponents:Channels/chan_sip/NewFeature
Versions:11.5.1 Frequency of
Occurrence
Related
Issues:
Environment:Attachments:( 0) session-id-trunk.diff
Description:This patch adds support for the {{Session-ID}} header (as described at http://tools.ietf.org/html/draft-kaplan-dispatch-session-id-03) in Asterisk.  That is to say, if an incoming {{INVITE}} has such a header, it will be copied onto outgoing calls initiated from that incoming call.

This is useful for some network monitoring appliances (we use Palladion, which makes use of the header, to track call flow better).

We have primarily tested this with 11.5.1 but the patch also applies to trunk.
Comments:By: Rusty Newton (rnewton) 2013-10-17 19:15:22.667-0500

Thanks. Let us know about any testing with trunk, as new features generally only go into trunk.

By: Matt Jordan (mjordan) 2013-10-25 09:46:46.638-0500

I have a number of issues both with the implementation of this patch, as well as the need for it.

# Per the linked draft RFC, the Session-ID header is simply supposed to be a unique ID that persists across B2BUAs. If all we cared about was whether or not the Session-ID header persisted across a call, then this can most likely be done completely in the dialplan. Something like the following would take the Session-ID header out of a channel and apply it to the outbound call leg:
{noformat}
same => n,Set(__my_session_id=${SIP_HEADER(Session-ID)})
same => n,Dial(SIP/foo,,b(default^apply_session_header^1))
...

exten => apply_session_header,1,NoOp()
same => n,SIPAddHeader(Session-ID:${__my_session_id})
same => n,Return()
...
{noformat}
Generating a new Session-ID could be done if the inbound call did not have a session ID. Note that this does *not* meet the intent of the RFC, but essentially does what your patch does: copy a Session-ID header from an inbound call leg to an outbound call leg.
# Unfortunately, simply copying the Session-ID header doesn't meet the intent of the RFC. From Section 3, Overview of Operation:
{quote}
  The general concept is that the UAC generating an out-of-dialog
  request generates a new, pseudo-random, unique value which remains
  constant for the duration of the transaction, any dialog created
  from that request, or for a registration.
{quote}
There's a lot more to the Session-ID RFC then simply pushing an inbound Session-ID to an outbound request - which is what currently occurs. You currently add a session ID in {{transmit_invite}}, {{transmit_request}}, and {{transmit_request_with_auth}}. That doesn't take care of the following points:
# The header isn't added in responses, which must be done:
{quote}
The UAC and UAS then reflect this header field value in all messages for the duration of the dialog.
{quote}
# Because the Session-ID isn't persisted in the SIP pvt structure, we have no protection against a message in a dialog changing the Session-ID. That is, if we receive a Session-ID from a UAC and we send the Session-ID to a UAS, nothing prevents either party from updating the Session-ID and corrupting it during the dialog. That breaks the intent of the RFC, which is that the B2BUA should persist the Session-ID one it has been established during the dialog.
# We don't generate a Session-ID for messages originating from Asterisk. From Section 4.2:
{quote}
  The rules for when a UAC generates a new Session-ID value are
  similar as those for Call-ID value: a UAC supporting this document's
  mechanism MUST generate a new unique Session-ID value whenever it
  generates an out-of-dialog request, or for a new Registration.
{quote}
In fact, we violate most of Section 4.2 with this patch. There are explicit rules about when a new Session ID should be generated when Asterisk is acting as a UAC that this patch does not implement.
# This patch does not implement the UAS behavior correctly either - Asterisk can act as a UAS when it does not generate an outbound call. In Section 4.3:
{quote}
  If an out-of-dialog request is received without a Session-ID header
  field, the UAS SHOULD generate a new one for subsequent use in the
  transaction and dialog, as defined for a UAC, and use the same value
  in all responses and upstream in-dialog requests for the same
  dialog.
{quote}
We do not generate a Session-ID header in this patch.
# When Asterisk is acting as the B2BUA, the behavior implemented here is incomplete.
## When Asterisk is acting as a B2BUA, it does not generate a Session-ID if it did not receive one on the inbound call leg. While this is a MAY, it should be implemented, as the functionality is rather incomplete without it.
{quote}
  If an out-of-dialog request is received by a B2BUA compliant with
  this document, and the request does *not* contain a Session-ID
  header field, the B2BUA MAY generate a new one.  The new Session-ID
  value MUST be calculated based on the received Call-ID of the
  received request, even if the B2BUA uses a different Call-ID value
  for requests generated on its other "side(s)".  It MUST then insert
  it in any requests or responses it generates, as if it had actually
  received the new Session-ID from the UAC, following the rules
  previously defined for a B2BUA.  This allows for a B2BUA to provide
  a migration to Session-ID deployment, on behalf of upstream nodes
  that do not yet support it.
{quote}
## Section 4.5.2 is not implemented, as we do not insert the header into responses, nor do we check the presence of the Session-ID header in responses.
{quote}
4.5.2     B2BUA Insertion of Saved Session-ID

  If a Session-ID was received in an out-of-dialog request, or the
  B2BUA locally generated one because none existed, the B2BUA SHOULD
  insert the same Session-ID field into all responses and upstream in-
  dialog requests if and only if a Session-ID is not already in them.
  This allows for a B2BUA to provide a migration to Session-ID
  deployment, on behalf of downstream nodes that do not yet support
  it.
{quote}

I haven't even tried to figure out what all should be done in transfer scenarios.

In general, this patch is incomplete. The way it is currently implemented and the functionality is does provide could be replicated using standard dialplan constructs. To do the RFC properly, however, is a substantial amount of additional work that should be done before this patch is considered for inclusion.

As such, for now, I'm closing this issue as "Incomplete". If you'd like to provide a full patch that implements this functionality, please let a bug marshal know in #asterisk-bugs or simply comment on this issue after uploading the patch and we'd be happy to reopen it for you.

Thanks!