Forum Discussion

dan_19334's avatar
dan_19334
Icon for Nimbostratus rankNimbostratus
Jan 15, 2009

Match TCP::payload to Newline

How do you match the TCP::payload to a Newline?

 

 

I would like to load balance individual syslog messages across a pool of servers. The syslog client connects to the VIP and maintains a persistent TCP connection and sends many syslog messages, I would like to take each message and send to a different backend node.

 

 

This is the iRule I am using to perform this function but can't seem to figure out how to collect until a newline is read.

 

 

when CLIENT_ACCEPTED {

 

TCP::collect

 

}

 

 

when CLIENT_DATA {

 

if { [TCP::payload] contains "\x0D\x0A" } {}

 

if { [TCP::payload] contains "\r\n" } {

 

LB::detach

 

TCP::release

 

TCP::collect

 

}

 

}

 

 

 

Thanks,

 

-Dan

7 Replies

  • Cannot you activate LB datagram within the UDP profile to do this ?

     

     

    Otherwise if it's syslog you should be using UDP::payload instead of TCP
  • I would have thought looking for \x0D\x0A would have worked. Could you try \x0d\x0a as well? Else, you could try converting \x0D\x0A to binary and looking for that in the binary payload or (less efficiently?) converting the payload to hex using 'binary scan [TCP::payload] H* payload_hex' and then looking for 0d0a.

     

     

    If you do figure this out, could you reply? If I have a chance to test I'll do the same.

     

     

    Thanks,

     

    Aaron
  • This is using TCP via syslog-ng.

     

     

    I am not able to get inside of the If statement with either \x0D\x0A or \x0d\x0a. I also tried via this method of converting the payload to hex which didn't work either:

     

     

    when CLIENT_DATA {

     

    log local0. "In Client Data: [TCP::payload]"

     

    binary scan [TCP::payload] H* payload_hex

     

    log local0. "In Binary Data: $payload_hex"

     

    Also tried to match payload_hex to "\x0d\x0a"

     

    if { $payload_hex contains "0d0a" } {

     

    log local0. "XXXXXInside of IF"

     

    LB::detach

     

    TCP::release

     

    TCP::collect

     

    }

     

    }

     

     

    Not sure how to convert \x0d\x0a to binary, but the reverse did not work so I assume this would not either.

     

     

    Any other ideas? Do you think this is a bug or a irule logic issue?

     

     

    -Dan

     

  • What do you actually see in the hex payload? Maybe the client isn't using CR and LF?

    Here are two examples. One which converts \r\n to binary to check the binary payload and a second which converts the payload to hex to check for 0d0a:

      
      when CLIENT_ACCEPTED {   
         TCP::collect   
      }   
      when CLIENT_DATA {  
          save payload  
         set payload [TCP::payload]  
        
         log local0. "\$payload: $payload"  
        
         if {$payload contains [binary format a* "\r\n"]}{  
        
            log local0. "Found CRLF in binary payload!"  
         }  
        
          convert payload to HEX  
         binary scan $payload H* payload_hex  
        
         log local0. "\$payload_hex: $payload_hex"  
        
         if {$payload contains "0d0a"]}{  
        
            log local0. "Found CRLF in hex payload!"  
         }  
        
      }  
      

    : $payload: GET / HTTP/1.1 User-Agent: curl/7.16.3 (i686-pc-cygwin) libcurl/7.16.3 OpenSSL/0.9.8j zlib/1.2.3 libssh2/0.15-CVS Host: 10.42.2.100 Accept: */*

    : Found CRLF in binary payload!

    : $payload_hex: 474554202f20485454502f312e310d0a557365722d4167656e

    743a206375726c2f372e31362e332028693638362d70632d63

    796777696e29206c69626375726c2f372e31362e33204f7065

    6e53534c2f302e392e386a207a6c69622f312e322e33206c69

    62737368322f302e31352d4356530d0a486f73743a2031302e

    34322e322e3130300d0a4163636570743a202a2f2a0d0a0d0a

    : Found CRLF in hex payload!

    Aaron
  • Thanks Aaron, you where on the right track...syslog doesn't terminate it's messages with CRLF, only with LF (my bad).

     

     

    Converting to HEX helped figure this out, but now knowing this, it is not necessary to convert to HEX in the iRule.

     

     

    So, here is a working iRule to load balance syslog-ng messages to multiple nodes in a pool -- while maintaining a persistent TCP session with the client.

     

     

    when CLIENT_ACCEPTED {

     

    TCP::collect

     

    }

     

    when CLIENT_DATA {

     

    if { [TCP::payload] contains "\x0a" } {

     

    LB::detach

     

    TCP::release

     

    TCP::collect

     

    }

     

    }

     

     

    Also, with oneconnect enabled the TCP sessions are maintained to the backend nodes.

     

     

    Thanks Again!

     

    -Dan