ProSBC leg and session IDs when redirecting a call with 3xx using "Process call routing

Hello

When redirecting a call with 3xx using ProSBC – “Process call routing”, the C-leg (created due to 3xx redirection) has the same h323-conf-id as the A-leg and B-leg.
Shouldn’t it be different?

Reference documentation:


RADIUS – IETF Parameters

RADIUS IETF param name Description
h323-conf-id Unique call identifier for the two initial legs (incoming and outgoing) – 128-bit integer formatted as xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx.
h323-incoming-conf-id Contains the original h323-conf-id in case of call transfer for subsequent outgoing legs – 128-bit integer formatted as xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx.
Acct-Session-Id Refers to @{SessionId} of the original legs for this call in case of a call transfer. The transfer target leg has a different @{SessionId}, but can be linked with the original call legs through @{OriginalSessionId}.
Telcob-Other-Leg-Id Integer that represents the other LegID bridged for this call.

Routing Scripts – Parameter Mapping

Reference documentation:

Script parameter name Comment Our Comment
leg_id Leg ID Unique to the system? Relation with text variables and RADIUS attributes?
session_id Session ID Unique across systems? Relation with text variables and RADIUS attributes?
original_session_id Original Session ID (before call transfer or redirections) Unique across systems? Relation with text variables and RADIUS attributes?

Test Results and Observations

We tested ProSBC 3xx using “Process call routing” with RADIUS enabled.
The Access-Request from the B-leg arrived with the same leg_id as the A-leg.

Question

In this case is it possible, via configuration or Ruby scripting, to change the B-leg leg_id so that it differs from the A-leg?

This is required because:

  • A-leg must be charged to the A-leg client
  • The redirected call (B/C-leg) must be charged to the B-leg client, not the A-leg client

Our Test Results

Leg Tipo G9-LegId (= leg_id) h323-conf-id h323-incoming-conf-id Acct-Session-Id Telcob-Other-Leg-Id NAP Calling Called Redirecting
a_leg Access-Request 2525443219 (0x96873493) 96873493 00000000 0200dfb4 6942f0b5 96873493 00000000 0200dfb4 6942f0b5 A 221451045 211450097
b_leg Access-Request 2525443219 (0x96873493) 96873493 00000000 0200dfb4 6942f0b5 96873493 00000000 0200dfb4 6942f0b5 B 221451045 969570105 211450097
b_leg Acct-Stop 96873493 00000000 0200dfb4 6942f0b5 96873493 00000000 0200dfb4 6942f0b5 0x168734cf 2525443219 (0x96873493) B 221451045 211450097
c_leg Acct-Start 96873493 00000000 0200dfb4 6942f0b5 96873493 00000000 0200dfb4 6942f0b5 0x16873513 2525443219 (0x96873493) C 221451045 969570105 211450097
a_leg Acct-Start 96873493 00000000 0200dfb4 6942f0b5 96873493 00000000 0200dfb4 6942f0b5 0x96873493 377959631 (0x168734cf) A 221451045 211450097
c_leg Acct-Stop 96873493 00000000 0200dfb4 6942f0b5 96873493 00000000 0200dfb4 6942f0b5 0x16873513 2525443219 (0x96873493) C 221451045 969570105 211450097
a_leg Acct-Stop 96873493 00000000 0200dfb4 6942f0b5 96873493 00000000 0200dfb4 6942f0b5 0x96873493 377959631 (0x168734cf) A 221451045 211450097

Hello Dcosta,

Thanks for the post and the detailed observation.

Looking at our RADIUS IETF parameter definitions, the C-leg (transfer target) is intended to have a unique @SessionId while maintaining a link to the original call via attributes like h323-incoming-conf-id. It appears that when “Process call routing” is used for 3xx, the ProSBC may be incorrectly reusing the initial h323-conf-id for the new leg.

Next Steps & Investigation: We need to investigate the root cause to determine if this behavior is a bug or a configuration limitation.

  • Potential Scripting Solution: It may be possible to resolve this via a scripting solution. By intercepting the call during the 3xx redirect, you could manually set params[:radius_attributes][:"h323-conf-id"] to a new value. This would force the RADIUS server to recognize a new session ID for billing while maintaining the original ID in the h323-incoming-conf-id field for your traces.

  • Validation: I am performing further in-house testing this week to validate this behavior.

I will follow up shortly with a more definitive answer and, if applicable, a sample script once testing is complete.

-Support

Hello Dcosta,

We have tested with both versions 3.1.135.7 and 3.3.12.53 and see the same behavior. Please confirm what version you are currently running.

Thanks

Hello Dave,

We are using version 3.3.11.67.
On 2. Software Release Status - Forum ProSBC the latest is 3.3.11.67. How can we get version 3.3.12.53 ?

Thanks

Hello Dcosta,

Thank you!

ToolPack version 3.3.12.53 is now released!

Let me know if you have any questions.

I am still not certain we can fix this problem with scripting, I need to consult with my team. Probably won’t get back to you with an answer till after Christmas.

Happy Holidays

-Support

Hello Dcosta,

It appears we may be able to provide a fix via scripting. Let me link you to an older forum post and our documentation regarding the supported script parameters.

Add A-Leg Call-ID as X-CID on B-Leg - 6. Advanced Routing / Routing Scripts - Forum ProSBC

I am working on testing this out in our lab, but thought with your experince you might want to have a look and testing too.

Let me know if you have any questions.

-Support

Hello Dave,

Have you been able to take the test?

I looked at the post you link but I didn’t get your point of view, it talks about SIP headers, not radius, and the call_id I found on Routing_Script_Parameter_Mapping_Table is the SIP call ID (sip_call_id).

In the past I already have tested the leg_id, session_id, original_session_id without success.
Example of my script filling Authorization attributes:
auth[“G9-LegId”] = call [:leg_id]
log_trace 3, “G9: LOGTRACE-DC : leg_id: #{ call[:leg_id].inspect }”
auth[“h323-conf-id”] = call [:session_id]
log_trace 3, “G9: LOGTRACE-DC : session_id: #{ call[:session_id].inspect }”
auth[“h323-incoming-conf-id”] = call [:original_session_id]
log_trace 3, “G9: LOGTRACE-DC : OriginalSessionId: #{ call[:original_session_id].inspect }”

Can you please en-light me with your workaround idea?

Thanks,
David Costa

Hi David,

I have been off-site training, and have not had time to look at this yet. I will have a look and get back to you sometime next week.

-Support

Hi David,

Let’s break this down together. I can’t provide scripting services as you know, because this falls under the lines of professional services. I am happy to point the way and provide help as you need it.

What we can do with scripting:

  • We can detect a redirect scenario
  • We detect a new outbound leg
  • Modify - params[:radius_attributes]
    Generate new ID"s per leg for RADIUS packets only

We can’t do:

  • Change the internal ProSBC call object
  • Prevent ProSBC from initially reusing the conf-id
  • rewrite historical accounting already sent to RADIUS

We want to override the RADIUS attributes before the accounting packet is sent

Please take some time and review our sip_header_params.rb. This is where we want to put our scripting filter.

The filter runs per leg and has access to:

  • params
  • params [:radius_attributes]
  • call direction and routing state

High-level logic:

  1. Detect redirect-generated leg
  2. Read original h323-conf-id
  3. Generate a new conf-id
  4. Overwrite RADIUS attributes

I can post a sample script for you, but I still need time to test it. Hopefully, this will point you in the right direction.

-Support

Hold up Dave. I think I am wrong. I just managed to run a quick test script and it appears to me the radius parameters are still not available at the after filter stage. I am surprised.

|9th, 09:24:39.806 SER : HARepositoryClient: CTBCAFServiceHARepositoryAutoClient::SetParam: Can't change mun32PeriodicPollingDelayMs after initialization
 |9th, 09:24:39.806 Successfully reloaded configuration
 |9th, 09:24:39.807 SER : CmMgmtClient: SendReloadDone cfg=5 Success Msg=
 |9th, 09:24:40.697 SER : OnReloadConfig result Ack cfg=5
 |9th, 10:22:53.918 ROUT: CONTACT_FILTER: before_filter EXECUTED
 |9th, 10:22:53.918 ROUT: CONTACT_FILTER: raw Contact=''
 |9th, 10:22:53.918 ROUT: CONTACT_FILTER: sip_method=''
 |9th, 10:22:53.920 ROUT: CONTACT_REWRITE: OutCall[0] nap=NAP_SIP_50 Contact set to '<sip:prosbctg@10.50.60.100:5060>'
 |9th, 10:22:53.920 ROUT: RadiusConfIdTest: params[:radius_attributes] is NIL (not available at this stage?)
 |9th, 10:22:53.922 CMC : TbCmcLibGenerateNewEntityId: Initial EntityId set to 0x20F679F2 tbcmc_lib_entity.c:161
 |9th, 10:23:51.347 CLI : Received signal 14 (SIGALRM), code 128, errno 0, from pid 0, uid 0. Not quitting.

You can see clearly here. I am not completely done with testing, but this is why I didn’t want to give you the test script just yet.

More to follow after I can finish more testing this week and talk more with my team.

-Support

Hi David,

I managed to finish up my testing today. This is what I can tell you conclusively.

The ProSBC does not allow modifying the built-in SessionId (h323-conf-id) via scripting, it does support generating custom accounting attributes. If you are able to use a custom attribute for billing correlation, we can generate a unique per-leg session identifier during routing and include it in both RADIUS and CDRs. This provides full per-leg uniqueness without modifying core SBC behavior.

I have tested it, but not sure if you can configure your RADIUS to accept unique accounting attributes.

Cheers,
Support

Hi Dave,

Not as is but with some refactor on our Radius code, I believe we can.
On our ruby script we fill Radius Authentication avpairs. But on accounting we use ProSBC native radius accounting.
Radius Authentication
auth[“G9-LegId”] = call [:leg_id]
auth[“h323-conf-id”] = call [:session_id]
auth[“h323-incoming-conf-id”] = call [:original_session_id]
On Radius authorization we already use the CustomCdrValue
params [:bridge] [:CustomCdrValue] = “LegId=” + call [:leg_id]
params [:bridge] [:CustomCdrValue] += “;RubyAuthorizationTime=” + Time.new.to_f.to_s
if auth [:“G9-AuthorizationTime”] != nil
params [:bridge] [:CustomCdrValue] += “;PerlAuthorizationTime=” + auth [:“G9-AuthorizationTime”]
end

Let me know how we can generate an unique value at Authentication moment and also use it to correlate the Radius accounting between call legs.

Thanks,

David Costa

Hi David,

Here is a sample script. Are you familiar with our scripting? You need to use this as a filter script to validate how to create your own unique_session_id for RADIUS.

#
# test_session_id.rb
#
# Purpose:
#   Proof-of-concept ScriptAttribute for per-leg accounting
#

module TestSessionId

  def init_test_session_id(params)
    log_trace :always, "TestSessionId filter loaded"
  end

  def test_session_id(params)
    # Generate a simple per-leg value
    params[:bridge][:TestSessionId] = "TEST-#{Time.now.to_i}"

    log_trace :always,
      "TestSessionId: set ScriptAttribute TestSessionId=#{params[:bridge][:TestSessionId]}"

    params
  end

end


Use this as a filter script. You need to add the script params and include commands in our main simple_routing_sbc.rb. If you are not familiar with our scripting, please check online documentation here. Routing Scripts

My testing output:

|10th, 07:35:47.211 ROUT: CONTACT_FILTER: before_filter EXECUTED
 |10th, 07:35:47.211 ROUT: CONTACT_FILTER: raw Contact=''
 |10th, 07:35:47.211 ROUT: CONTACT_FILTER: sip_method=''
 |10th, 07:35:47.213 ROUT: CONTACT_REWRITE: OutCall[0] nap=NAP_SIP_50 Contact set to '<sip:prosbctg@10.50.60.100:5060>'
 |10th, 07:35:47.213 ROUT: RadiusConfIdTest: params[:radius_attributes] is NIL (not available at this stage?)
 |10th, 07:35:47.213 ROUT: ParamsDump: params.class=ScriptParams
 |10th, 07:35:47.213 ROUT: ParamsDump: params.keys=N/A
 |10th, 07:35:47.213 ROUT: ParamsDump: params[:call].class=Call
 |10th, 07:35:47.213 ROUT: ParamsDump: call.keys=N/A
 |10th, 07:35:47.213 ROUT: ParamsDump: params[:routes].class=Array
 |10th, 07:35:47.213 ROUT: ParamsDump: routes[0].keys=["disabled", "forward_sip_domain", "forward_sip_parameters", "nap", "remapped_nap", "route_name"]
 |10th, 07:35:47.213 ROUT: ParamsDump: params[:out_calls].class=Array
 |10th, 07:35:47.213 ROUT: ParamsDump: out_calls[0].keys=N/A
 |10th, 07:35:47.213 ROUT: ParamsDump: params[:bridge].class=Hash
 |10th, 07:35:47.213 ROUT: ParamsDump: bridge.keys=["reason"]
 |10th, 07:35:47.213 ROUT: TestSessionId: set ScriptAttribute TestSessionId=TEST-1770708947

Cheers,
Support

Hi Dave,

params [:bridge] [:CustomCdrValue]

And the radius accounting I get it from CustomCdrValue?

CustomCdrValue is the only value I can set for Radius CDRs?

Thanks,

David Costa

Hi David,

I am not sure I understand the question, do you want to create multiple custom values? If you can clarify, I will do my best to help.

Thanks,
Support

Hi Dave,

We already use Telcob-CustomCdrValue on our TMG and when we need to pass more than one value, we concatenate them into Telcob-CustomCdrValue. That’s OK and work just fine.

I was just checking if there was any change on radius params. From what I see on documentation no.

Thanks,

David Costa

Hi David,

Nope, there are no new hardcoded changes for RADIUS params. One other idea to explore is creating and importing a custom RADIUS dictionary. I am not sure this will make things easier for you or not.

Example:

VENDOR          TelcoBridges            12345
ATTRIBUTE       TB-Custom-Leg-ID        101     string
ATTRIBUTE       TB-Custom-Session-ID    102     string

I have not tested this, but I believe once the custom dictionary is imported, the script can treat your newly created attributes like native ones. As long as this is being done in logical order in your scripting.

Needs to be tested. :slight_smile:

Cheers,
Dave