Forum Discussion

eooyc_209394's avatar
eooyc_209394
Icon for Nimbostratus rankNimbostratus
Jul 03, 2015

irule for SIP forward

we have an irule to forward SIP rule SIP-forward { when SIP_REQUEST_SEND { SIP::header insert "Record-Route" "" } when SIP_RESPONSE_SEND { if { [SIP::header "Record-Route"] ne "" }{ SIP::header remove "Record-Route" SIP::header insert "Record-Route" "" } } }

 

but now we have a new requirment that SIP_RESPONSE_SEND header has the following Route header , sip:xxxxxx.

 

we want to remove , could the following work? if { [SIP::header " Route"] ne "" }{ SIP::header remove "Route" "" }

 

4 Replies

  • The SIP::header remove method takes one of these two forms:

     

      SIP::header remove
      SIP::header remove 
    

     

    Thus, if you are attempting to remove a specific Route header, and there may be more than one, then the form you provide will unfortunately not work. You must iterate through the Route headers until you find the position of the header to remove. In 11.6, something like this might do it:

     

    set required_value ""
    for { set i 0 } { $i < [SIP::header count Route] } { incr i } {
        if { [SIP::header value Route $i] eq $required_value } {
            SIP::header remove Route $i
            break
        }
    }
    

     

    Before 11.6, this may do it:

     

    set required_value ""
    set i 0
    while { 1 } {
        switch [SIP::header value Route $i] {
            "" { 
                break 
            }
            $required_value {
                SIP::header remove Route $i
                break
            }
        }
    }
    

     

    I'm not sure whether the SIP::header sub-commands start at 0 or start at 1. If they start at 1, you'd have to adjust the code. And, I'll have to admit that I've not tested this, so ... good luck :).

  • Thank you for your reply. I just confirmed the route header is only one, not two. like this route , sip:xxxxxx

     

    not route route sip:xxxxxx

     

    whether your code work?

     

    also, we want to make the rule remove "," when only the sip:xxxxx contains special ip range. could you give me some suggestion? thank you very much.

     

  • Yes, I see now from RFC 3261 that the Route header is a comma-delimited list. The RFC is a bit ambiguous about spaces (i.e., route,route is clearly acceptable, but is route, route also acceptable?), so as a simplification, I'll assume whitespace is not permitted between list elements. I will also assume that the Route header is not repeated. If it is, then you'll have to mix-in the logic above. I assume that there can be more than one instance of the route you wish to remove. If that's not the case, the logic can be somewhat simplified. Finally, I use a Data Group (called dg-route-blocks-to-remove) to match IP addresses in the Route entries.

     

    when RULE_INIT {
        set static::srm_route_remove_data_group "dg-route-blocks-to-remove"
    }
    
    when SIP_REQUEST {
        set route_list [split [SIP::header Route] ,]
        for { set i 0 } { $i < [llength $route_list] } { incr i } {
            set ip [getfield [lindex $route_list $i] : 2]
            if { [class match $ip equals $static::srm_route_remove_data_group] } {
                lset route_list $i ""
            }
        }
    
         if you are using 11.6, you may substitute "SIP::header replace" here
        SIP::header remove Route
        SIP::header insert Route [join [lsearch -all -inline -not $route_list ""] ,]
    }
    

     

    I will once again admit that I have not tested this rule. Let me know if it bombs somehow.

  • I tested this and it works (the way I expect, at least). Here is an example tmsh command for creating the Data Group:

     

    tmsh create ltm data-group internal dg-route-blocks-to-remove \
      type ip records add { 10.10.210.0/24 { } 192.168.5.0/25 { } }
    

     

    Naturally, you would substitute your own set of netblocks.

    Do keep in mind that this mechanism will always move the Route header to the end of the message header set (in 11.6, using the SIP::header replace method avoids this).

    As an example, using the Data Group definition above, I sent the following SIP Request through a Virtual Server with the iRule above attached:

     

    REGISTER sips:ss2.biloxi.example.com SIP/2.0
    Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashd92
    From: Bob ;tag=ja743ks76zlflH
    To: Bob 
    Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com
    CSeq: 2 REGISTER
    Route: ,,,
    Content-Length: 0
    

     

    and this is the message that arrives at the Pool Member:

     

    REGISTER sips:ss2.biloxi.example.com SIP/2.0
    Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashd92
    From: Bob ;tag=ja743ks76zlflH
    To: Bob 
    Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com
    CSeq: 2 REGISTER
    Content-Length: 0
    Route: ,