Forum Discussion
karmacoma_49245
Nimbostratus
Jul 10, 2008iRule disconnects the client when switch from one server to another
Hi guys
We are newbies when writing iRules and I'm afraid we need some help. Our iRule is supposed to assign a different LDAP server depending on a subscriber id.
Let's say we have two OpenLDAP DBs and we have to route the traffic to one or the other. If we receive a search for DB1 the iRule routes it properly and the transaction is finished.
If then we receive a new message for DB2 the iRule sends it to the DB2. Note we have set the OpenLDAP so there is no need for a bind to be sent before a search for example is sent.
The problem we are having is that when a new search for DB2 is coming into the F5 while the F5 has still not closed the previous LDAP dialogue towards the DB1, we get a TCP reset towards both sides of the F5 leading into disconnection of the client and affecting performance.
We think we may need to buffer the messages until the previous dialogue is finished so that no message is lost and no reset is sent however we don't know hot to do so, any ideas???
Another possible solution could be to reject the incoming messages while a previous message is processed but we have try with no success.
Here is our iRule
rule ldapProxy {
when RULE_INIT {
Define default ldap server and port
set ::ldapPool Internal_Pool
set ::ldapPort 389
Turn on debugging
set ::debug 1
Define a lookup table for debugging
array set ::msg_types {
0 "bind request"
1 "bind response"
2 "unbind request"
3 "search request"
4 "search response"
6 "modify request"
7 "modify response"
8 "add request"
9 "add response"
10 "delete request"
11 "delete response"
12 "modifydn request"
13 "modifydn response"
14 "compare request"
15 "compare response"
16 "abandon request"
23 "extended request"
24 "extended response"
}
}
when CLIENT_ACCEPTED {
TCP::collect
}
when CLIENT_DATA {
Grab the current payload collected
set payload [TCP::payload]
set SUBSID [findstr $payload "MSISDN=" 7 6 ]
if {$SUBSID>=491700 and $SUBSID < 491706 } {
set NODE "172.80.121.30"
} elseif {$SUBSID>= 491723 and $SUBSID < 491724 } {
set NODE "172.80.121.31"
} else {
}
Pull the first 2 bytes.
binary scan $payload H2c ber_t ber_len
The first byte is the tag signifying an LDAP message,
Always is hex 30, if that is not so reject
if { $ber_t ne "30" } {
reject
return
}
The second byte is one of two values:
a) The length of the packet minus the above
defining byte and the length byte
OR
b) an octet describing how many subsequent bytes
hold the packet length
In either case the message type (what we are after)
follows the message id field which too can be a variable
number of bytes.
set len_bytes 0
if { [expr [expr ($ber_len + 0x100) % 0x100] & 128] > 0 } {
set len_bytes [expr [expr ($ber_len + 0x100) % 0x100] & 127]
}
How many bytes is the message id
binary scan $payload x[expr 3 + $len_bytes]c msgid_bytes
The message type is then 4 bytes + number length bytes + number of
message id bytes offset.
binary scan $payload x[expr 4 + $len_bytes + $msgid_bytes]c msgtype
msgtype - BER encoded value, bits 1-5 are the actual
type, 6 is the data type, 7-8 are the data class
Here we only care about the lower 5 bits
set msgtype [expr $msgtype & 31]
if {$::debug and
[catch {
log local0. "message type is: $::msg_types($msgtype) $msgtype"
}
]
} {
log local0. "Bad message type: $msgtype"
reject
}
Each connection should start with a bind request
if { $msgtype == 0 } {
if {$::debug} {log local0. "Bind Request with: $::ldapPool"}
pool $::ldapPool
} elseif {[string compare [LB::server addr] $NODE] -- 0}{
if {$::debug} {log local0. "Sending to node : $NODE"}
LB::detach
node $NODE $::ldapPort
}
TCP::release
TCP::collect
}
}
thanks a lot in advance!
7 Replies
- karmacoma_49245
Nimbostratus
Hi nmenant
thanks a lot for such a fast reply!
we are continuously checking the ltm with tail -f but we don't get any TCL error. We just know there has been a reset when the client sends a new bind towards the servers (through the F5, of course) but nothing else.
Regards O. - Nicolas_Menant
Employee
Hi,
i just read the iRule and since i'm not a master in LDAP protocol it seems nice except maybe the LB::detach in CLIENT_DATA. Never tried this one but since you seem to do this when you want to move on the other LDAP server that may be the problem.
May it be possible for you to do the following:
Add some troubleshooting log commands always everywhere in your iRule so that we can follow step by step what is happening in your iRule.
Then do your test and please print us your output of /var/log/ltm.
It may help newbie like me to help you !
Regards
N. - karmacoma_49245
Nimbostratus
Hi nmenant
it seems that is not the problem, see what happens when we remove the detach
Jul 10 12:04:30 tmm tmm[1664]: Rule ldapproxy_system3_detach_test : message type is: search request 3
Jul 10 12:04:30 tmm tmm[1664]: Rule ldapproxy_system3_detach_test : message type is: search request 3
Jul 10 12:04:55 tmm tmm[1664]: Rule ldapproxy_system3_detach_test : message type is: search request 3
Jul 10 12:04:55 tmm tmm[1664]: Rule ldapproxy_system3_detach_test : Sending to node : 172.80.121.31
Jul 10 12:04:55 tmm tmm[1664]: 01220001:3: TCL error: ldapproxy_system3_detach_test - Address in use (line 1) invoked from within "node $NODE $::ldapPort"
it looks like we are trying to set up a connection towards a node using an address which already exists....
thanks
k. - Nicolas_Menant
Employee
Hi,
it seems to be a known issue when using pool or node command for udp traffic within CLIENT_ACCEPTED event. For what the support says, it shouldn't interrupt UDP traffic but maybe you should open a support case.
F5 reference number to this issue is CR69801.
HTH
N. - karmacoma_49245
Nimbostratus
Hi nmenant!
Maybe I'm much more newbie than I thought. I have tried to look for the C69801 case but couldn't find it either in the Cases or in the F5 Knowledge Base. Could you please let me know where I can find it ?
On the other hand we are not using UDP, just TCP so it may not apply.
Thanks
Oscar - karmacoma_49245
Nimbostratus
Hi nmenant!
here is a little drawing of what it is happening at TCP level. This is the sequence when it is successful:Ldap ClientVIPF5Server1Server2 ============================= LDap Search -----------------> TCP(SYN) -----------> TCP(ACK) <--------------- TCP(FIN/ACK) ---------------------------> TCP(SYN/ACK) <----------- TCP(ACK) ------------> Ldap Search ------------> TCP(FIN(ACK) <--------------------------- TCP(ACK) -----------------------------> TCP(ACK) <---------------------------- ::::::::::::::::::::::::::: ::::::::::::::::::::::::::::
On the other hand this is the sequence when it fails:Ldap ClientVIPF5Server1Server2 ============================= LDap Search -----------------> TCP(SYN) -----------------------------> TCP(ACK) <--------------- TCP(FIN/ACK) ---------> LDap Search -----------------> ****** TCP(ACK) <--------------- TCP(RST/ACK) <--------------- TCP(SYN/ACK) <--------------------------- TCP(RST) --------------------------> TCP(FIN/ACK) <------------ TCP(ACK) ------------->
as you can see there is an incoming search for the second server ongoning when a search for the first one comes in. The F5 hasn't finished the reconnection and sends resets to both sides (client and server).
This is what we want to avoid (in particular the RST to the client). We have already tried to modify the tcp profile settings but no success. We are thinking about two iRules, one for server one and another one for server two.
We are not sure about how to handle this but we will try. The other possibility would be to try buffering but looks more complicated and we don't even know how to start.
Any other alternatives or ideas on how to implement this?
Thanks a lot in any case! - karmacoma_49245
Nimbostratus
hey guys
any ideas?
thanks!
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects