Forum Discussion

Anjlica_110059's avatar
Anjlica_110059
Icon for Nimbostratus rankNimbostratus
Aug 09, 2007

iRule closes connection

I modified the original question after I realised CLIENT_CONNECTED is not the right state to use inthe iRule when no connections exist.

 

------------------------------------------------

 

 

Hi,

 

We just introduced this iRule to persist incoming packets based on source ip and port.

 

 

Our call flow:

 

Client 1 ---> opens TCP connection with F5 ---> Round Robbing between sever 1 and server 2.

 

 

Onec conenctions are set up, then we want F5 to start using an iRule -

 

 

when CLIENT_ACCEPTED {

 

set src_ip_and_port [[IP::client_addr] ":" [TCP::client_port] ]

 

if { $src_ip_and_port != "" } {

 

persist uie $src_ip_and_port

 

}

 

}

 

 

When the client initially sets up new connections, there is no connection already set up so the F5 closes the incoming connections. Is there a state that we can use so that F5 bypasses this iRule when brand new connections are being set up?

 

 

 

7 Replies

  • In general, it's a good idea to check the /var/log/ltm file for TCL errors and iRule logging. You can do this via the GUI in system >> logs >> local traffic or by accessing the command line and tailing the file (tail -f /var/log/ltm).

     

     

    The reason you're getting resets to the client with that rule is that you're executing the client IP and port as a command. If you remove the outer pair of braces from your set command you should see the request go through.

     

     

    Try this for example:

     

     

    set src_ip_and_port "[IP::client_addr]:[TCP::client_port]"

     

    log local0. "\$src_ip_and_port: $src_ip_and_port"

     

     

    Out of curiosity, is there a reason you're trying to persist on the client IP and client port? Depending on the protocol/application, the client port could be selected and changed arbitrarily.

     

     

    Aaron
  • Our application opens tcp connections to the servers in the pool when ti is started. Once the tcp connection is established, it does a "log in" to the servers using a userid/passwd - same userid/passwd to all servers. The client hen stays logged in and sends requests on those exising connections(same ip and src port). So we want the F5 to send the requests(PSH,ACK) to the same server where this source port was initially set up at.

     

    Connection set up:

     

    Client ---> F5 ---> server 1(source port 1)

     

    Client ---> F5 ---> server 2(source port 2)

     

    Sending Requests -

     

    Now requests sent from client on src port 1 must always be sent to server 1, not server 2.

     

  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    That will happen naturally, in following with standard TCP mechanics: Once the connection is established, LTM keeps track of which server was selected, and all packets belonging to that connection will be sent there.

     

     

    You'd only need to apply a persistence scheme to make sure NEW connections from the same client follow the initial connection.

     

     

    HTH

     

    /deb
  • I am geeting closer. Here is a draft:

     

    so basically the client sends a PSH,ACK it sends a string "LOGIN:userid:passwd" in the tcp paylod.

     

    We don't want the iRule to be implemented if the client is doing an initial login.

     

    So I am looking at first six octets - LOGIN to determine whether to use the iRule or not.

     

     

    when CLIENT_ACCEPTED {

     

    set payload_string = [TCP::collect 6]

     

    log local0. "\$payload_string"

     

    if (payload_string contains "LOGIN")

     

    {

     

    }

     

    else

     

    {

     

    set src_ip_and_port [[IP::client_addr] ":" [TCP::client_port] ]

     

    if { $src_ip_and_port != "" } {

     

    persist uie $src_ip_and_port

     

    }

     

    }

     

    }

     

    }
  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    Still won't work without the changes hoolio recommended.

     

     

    Even then, your iRule either isn't necessary or else it won't accomplish your goal.

     

     

    It's not necessary if the application server opens and uses a single TCP connection: Packets from that connection will already always be sent to the same pool member.

     

     

    Or else it won't accomplish the goal: If the client opens multiple TCP connections that all need to go to the same server, the source port will change for each new connection. Since you're including the port in your persistence key, when it changes, your iRule will not be able to associate a new connection from the same client with the old persistence record.Our call flow:

     

    Client 1 ---> opens TCP connection with F5 ---> Round Robbing between sever 1 and server 2.If you're seeing transactions from the same client on different servers, that means the client is opening up more than one TCP connection, and you'll need to persist on source address only or find another persistence token to use.

     

     

    You might want to just try the built-in source address persistence and see if that works for you.

     

     

    HTH

     

    /deb
  • Here is the set up we have -

    There are several servers each listening on multiple ports.Several client machines run the client application.

    Client application is started.

    Client opens x number of sockets using a VIP and port.

    We want number of new sockets opened to be round robbin load balanced between diff. servers and ports.

    The client logs into each server and starts sending requests(PSH,ACK) over existing connections.

    So if client has an existign connection with server x port y, then we want that request to go to that server and port combination.

    Since we have several client machines connecting to same set of servers, we cannot use source ip address persistence.

    We almost got to a point where the script seem to follow the right path(we are still printintg out to logs to see if the right event gets triggered):
    when CLIENT_ACCEPTED { 
      TCP::collect 6
     log local0. "HERE 1"
    }
    when CLIENT_DATA {            
      set payload_string [TCP::payload]
      log local0. "data [TCP::payload]"                           
      if {$payload_string contains "LOGIN"} {
        pool mypool
        log local0. "new"                       
      } else {
        log local0. "HERE 2"
        set src_ip_and_port [TCP::client_port]   
        log local0. "src port <$src_ip_and_port>"
        if { $src_ip_and_port != "" } {
          log local0. "persist" 
        } else {
          log local0. "error1"
        }
      }
      TCP::release
    }
  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    Well, the problem is still that a source port cannot be re-used by the client to connect to the same server until a network-significant amount of time has passed, so your rule really won't do anything at all but create persistence records that will never be followed.

     

     

    You don't have a persist statement in the latest version of your rule, so it's really not doing anything but sending traffic to mypool if the loging string is seen & the default pool otherwise.

     

     

    Have you tested with no rule and no persistence at all?

     

     

    /deb