Forum Discussion

ShakeelRashid's avatar
ShakeelRashid
Icon for Nimbostratus rankNimbostratus
Mar 05, 2018

Non HTTP Traffic Stream Profile

Hi All,

 

I'm having a weird issue with a very simple stream profile I have attached to a VS. The profile looks for an occurrence of an IP address in the data and replaces it with its own VS IP address.

 

@172.xx.yy.zzz@10.xxx.yyy.zz@

 

We tried this out in our test environment and it worked fine, we now have an issue when transferring this configuration to live. We have an issue where the length of the IP addresses are different (i.e. replacement IP is one digit larger than the original IP in the data) and it ends up deleting 1 character from the end of the response data. The issue with this is that the reponse data is an Oracle connection string and deleting a closing bracket gives off an illegal address parameter and breaks everything. Is there a way to tell the LTM or Stream profile to preserve all other data and adjust the size of the response data accordingly? Any help from anyone is appreciated.

 

3 Replies

  • You have changed the content length but not updated the content-length header. Add an iRule with HTTP_RESPONSE_RELEASE event to update the content-length header to match the size of the HTTP::payload.

     

  • You can try with this code (not tested)

     

    when CLIENT_ACCEPTED {
        set collected_length 0
        set virtual_ip [IP::local_addr]
    }
    
    when SERVER_CONNECTED {
        TCP::collect
    }
    
    when SERVER_DATA {
        set tns_data [TCP::payload]
    
        if {[set host_start [string first "HOST" $tns_data ]] != -1} {
            set host_end [string first ")" $tns_data $host_start]
            set collected_length [expr {$collected_length + [TCP::payload length]}]
            TCP::payload replace $host_start $host_end "HOST=$virtual_ip)"
        }
        TCP::release
        if {$collected_length < 2048} {
            TCP::collect
        }
    }
  • The problem is TNS have header length value you have to update. Try this new version code:

     

    when CLIENT_ACCEPTED {
        set collected_length 0
        set virtual_ip [IP::local_addr]
    }
    
    when SERVER_CONNECTED {
        TCP::collect
    }
    
    when SERVER_DATA {
        set tns_data [TCP::payload]
         Detect if the response is a redirect
        if {[binary scan $tns_data SSccSSA* packet_length packet_checksum type reserved_byte header_checksum redirect_length redirect_data] == 7 && $type == 5} {
            if {[set host_start [string first "(HOST=" $redirect_data]] != -1 && [set host_end [string first ")" $redirect_data $host_start]] != -1} {
                set new_redirect_data [string replace $redirect_data $host_start $host_end "(HOST=$virtual_ip)"]
                set new_redirect_length [string length $new_redirect_data]
                TCP::payload replace 0 [TCP::payload length] [binary format SSccSSA* [expr {$new_redirect_length+10}] $packet_checksum $type $reserved_byte $header_checksum $new_redirect_length $new_redirect_data]
            }
        }
    
        TCP::release
        if {$collected_length < 2048} {
            TCP::collect
        }
    }