Forum Discussion

Hongyuan__John_'s avatar
Hongyuan__John_
Icon for Nimbostratus rankNimbostratus
Sep 16, 2013

how to add an irule to change a=sendonly to a=sendrecv?

wonder if there is any way to have an irule to change re-invite with a=sendonly to a=sendrecv on the F5? we have issues for the SIP servers behind the F5 to hand a = sendonly.

 

Thanks.

 

John

 

3 Replies

  • sounds like a stream profile can help, have a look at it:

     

    http://support.f5.com/kb/en-us/solutions/public/8000/100/sol8115.html

     

    https://devcentral.f5.com/wiki/irules.stream.ashx

     

  • The iRule Wiki lists the funktion for SDP

     

    By now I only used these functions to read media information.

     

    But according to the wiki it should be possible, to manipulate them.

     

    For testing I would use a UDP profile with immediate timeout.

     

    Virtual servers will be required both on client and gateway side.

     

    I wrote the sample code below to verify SDP media information:

     

    when RULE_INIT {
         Create a list of SIP-headers to parse
    
        set ::headerlist1 [list "Via" "Route" "Record-Route" "Contact" "Path" "Service-Route"]
    }
    
    when CLIENT_ACCEPTED {
        set vip [IP::local_addr]
        set usr [IP::remote_addr]
    }
    
    when SIP_REQUEST {
       log local0. "persistence found for [SIP::header "Call-ID"] on: [lindex [persist lookup sip [SIP::header "Call-ID"]] 1]"
        if {[IP::local_addr] eq $usr} {
    
             Outgoing SIP request from SGC to client
    
            set mapping [list [IP::remote_addr] $vip]
    
             Loop through all predefined headers
    
            foreach header $::headerlist {
                set index 0
                while {[SIP::header $header $index] ne ""} {
    
                     Loop through all instances of each header
                     Insert a modified header and delete the previous one (shifted forward) afterwards
                    log local0. "$header $index BEFORE modification: [SIP::header $header $index]"
                    SIP::header insert $header [string map $mapping [SIP::header $header $index]] $index
                    log local0. "$header $index AFTER modification: [SIP::header $header $index]"
                    SIP::header remove $header [expr {$index + 1}]
                    incr index
                }
            }
        }
        log local0. "SDP media information: [SDP::media]"
        log local0. "SDP element \"v\": [SDP::field v]"
        log local0. "SDP element \"o\": [SDP::field o]"
        log local0. "SDP element \"s\": [SDP::field s]"
        log local0. "SDP element \"t\": [SDP::field t]"
        log local0. "SDP element \"m\": [SDP::field m]"
    
        if {(([SDP::field v] ne "") and ([SDP::field o] ne "") and ([SDP::field s] ne "") and ([SDP::field t] ne "") and ([SDP::field m] ne ""))} {
            log local0. "All required SDP fields recognized"
        }
    
        Log additional SDP fields
        Specify SDP field to log i.e. "x"
       set sdp_field "x"
       set index 0
       while {[SDP::field $sdp_field $index] ne ""} {
    
            Loop through all instances of specified SDP-field
           log local0. "SDP-field \"a\" $index: [SDP::field $sdp_field $index]"
           incr index
       }
    
    }
    
    when SIP_REQUEST_SEND {
    
        if {[IP::remote_addr] ne $usr} {
    
             Incoming SIP request from client to SGC after LB decission (SIP_REQUEST_SEND)
    
           set mapping [list $vip [IP::remote_addr]]
    
            set mapping [list "109.237.178.101" [IP::remote_addr]]
            set sgc "[IP::remote_addr]"
    
            SIP::uri [string map $mapping [SIP::uri]]
    
             Loop through all predefined headers
    
            foreach header $::headerlist {
                set index 0
                while {[SIP::header $header $index] ne ""} {
    
                     Loop through all instances of each header
                     Insert a modified header and delete the previous one (shifted forward) afterwards
    
                    log local0. "$header $index BEFORE modification: [SIP::header $header $index]"
                    SIP::header insert $header [string map $mapping [SIP::header $header $index]] $index
                    log local0. "$header $index AFTER modification: [SIP::header $header $index]"
                    SIP::header remove $header [expr {$index + 1}]
                    incr index
                }
            }
    
            log local0. "Methode: [SIP::method]; URI: [SIP::uri]; To-Header: [SIP::header "To"]"
            log local0. "Persist on: [domain [SIP::to] 3]; IP-Client: [IP::remote_addr]"
        }
    }
    
    when SIP_RESPONSE {
    
        if {[IP::local_addr] eq $usr} {
    
             Outgoing SIP response from SGC to client
    
            set mapping [list [IP::remote_addr] $vip]
    
             Loop through all predefined headers
    
            foreach header $::headerlist {
                set index 0
                while {[SIP::header $header $index] ne ""} {
    
                     Loop through all instances of each header
                     Insert a modified header and delete the previous one (shifted forward) afterwards
    
                    log local0. "$header $index BEFORE modification: [SIP::header $header $index]"
                    SIP::header insert $header [string map $mapping [SIP::header $header $index]] $index
                    log local0. "$header $index AFTER modification: [SIP::header $header $index]"
                    SIP::header remove $header [expr {$index + 1}]
                    incr index
                }
            }
        } else {
    
             Incoming SIP response from client to SGC
    
            set mapping [list $vip $sgc]
    
             Loop through all predefined headers
    
            foreach header $::headerlist {
                set index 0
                while {[SIP::header $header $index] ne ""} {
    
                     Loop through all instances of each header
                     Insert a modified header and delete the previous one (shifted forward) afterwards
    
                    log local0. "$header $index BEFORE modification: [SIP::header $header $index]"
                    SIP::header insert $header [string map $mapping [SIP::header $header $index]] $index
                    log local0. "$header $index AFTER modification: [SIP::header $header $index]"
                    SIP::header remove $header [expr {$index + 1}]
                    incr index
                }
            }
        }
    }
    

    Perhaps it will be required to replace the SDP information completely. Currently I don´t have my SIP enviroment deployed to provide some code for your specific requirement.