Forum Discussion
Pavel_70776
Nimbostratus
Mar 02, 2012Balancing SMPP traffic based on recipient address
Hello,
we have an application sending SMS via SMPP and we need to balance the SMS messages based on recipient address to 2 different SMS Centres. SMS with recipient address starting 420 should go to SMSC1 and the rest of SMS's should go to SMSC2. Note that application creates one TCP session and throught this session sends multiple SMS, one SMS is in one TCP packet or more SMS can be placed in one TCP packet.
Thanks
36 Replies
- Michael_Yates
Nimbostratus
Hi Pavel,
Could you clarify what you are looking for a little more?
Did you want to direct the traffic to a specific location based on the Client's IP Address or the Destination IP Address? - Pavel_70776
Nimbostratus
Hi,
I'm looking for routing based on recipient or destination address, in SMPP protocol it means the telephone number. I thing this should require the layer 7 routing as the SMPP protocol is based on pairs of request/response PDUs (protocol data units, or packets) exchanged over OSI layer 4 (TCP session). Is it possible to create an iRule to do the required task?
I do not want to direct the traffic based on destination IP address. - Nat_Thirasuttakorn
Employee
Hi Pavel,
it is possible. however, there are a few tings to note
- this requires one new feature called message-based load balancing (which is not available in GUI)
- you may need to replay bind message to multiple servers (I assume application create TCP connection and send bind request) I am curious what kind of bind message application use, bind_transmitter?
what kind of SMPP message you are refering to, submit_sm? what SMPP version? what BIG-IP version you are using?
it would be great if you can provide packet trace of your SMPP traffic. (if it does not contain any sensitive data)
Nat - Pavel_70776
Nimbostratus
Hi Nat,
thanks for reply.
Application creates TCP connection and send bind_transiever. I need to route submit_sm messages from one application to more SMSC's. The submit_sm-resp and deliver_sm shall go from SMSC back to appl. Next, appl responses with deliver_sm-resp, which must go back to the SMSC previously sending deliver_sm.
We use SMPP v3.4
Pavel - Nat_Thirasuttakorn
Employee
Hi Pavel,
here is something that should work... (however, I didnt test 🙂 )
the idea is to decode submit_sm to find dest-addr
rewrite sequence number of request that was sent from SMSC (and rewrite it back to its original value in the _resp)
you may need to apply mblb profile to virtual: modify ltm virtual smpp profiles add {mblb}when CLIENT_ACCEPTED { set s_seq_idx 1 set first_bind_resp 1 set smsc1 10.10.10.1 set smsc2 10.10.10.2 TCP::collect } when CLIENT_DATA { while { [TCP::payload length] > 16 } { binary scan [TCP::payload] IH8IIa* len oper status seq p if { [TCP::payload length] < $len } { TCP::collect $len return } switch -glob $oper { 00000002 { set bind_message [TCP::payload $len] } 00000004 { submit_sm set p [string range $p [expr [string first \x00 $p]+1] end] binary scan $p cca* ston snpi p set p [string range $p [expr [string first \x00 $p]+1] end] binary scan $p ccA* dton dnpi p set dest [getfield $p \x00 1] if { $dest starts_with 420 } { use pool or node command pool [LB::server pool] member $smsc1 9000 } else { pool [LB::server pool] member $smsc2 9000 } } 8* { rewrite seq if { [info exists s_seq_map($seq)] } { set old_seq [lindex $s_seq_map($seq) 0] TCP::payload replace 12 4 [binary format I $s_seq_idx] set addr [lindex $s_seq_map($seq) 1] set port [lindex $s_seq_map($seq) 2] use pool or node command pool [LB::server pool] member $addr $port unset s_seq_map($seq) } } } TCP::release $len TCP::notify request } TCP::collect } when SERVER_CONNECTED { if { $first_bind_resp } { TCP::collect } else { TCP::collect -all TCP::respond $bind_message } } when SERVER_DATA { while { [TCP::payload length] > 16 } { binary scan [TCP::payload] IH8II len oper status seq if { [TCP::payload length] < $len } { TCP::collect $len return } switch -glob $oper { 0* { rewrite seq TCP::payload replace 12 4 [binary format I $s_seq_idx] set s_seq_map($s_seq_idx) "$seq [IP::remote_addr] [TCP::remote_port]" incr s_seq_idx } 80000002 { bind response if { $first_bind_resp } { set first_bind_resp 0 } else { TCP::payload replace 0 [TCP::payload length] "" set len 0 } } } TCP::release $len TCP::notify response } TCP::collect }
Nat - Nat_Thirasuttakorn
Employee
ummm... i think this linewhile { [TCP::payload length] > 16 } {
should bewhile { [TCP::payload length] >= 16 } { - Pavel_70776
Nimbostratus
Hi Nat,
I have been playing with the BIG-IP last few days and your iRule works fine. I did only small corrections.
Great job! Thanks a lot.
Next I have to do some more tests in our environment, mainly with fault tolerance.
Pavel - Nat_Thirasuttakorn
Employee
Hi Pavel,
Thanks for update.
Glad to hear that it works.
Looking forward to hear more test result.
Nat - Pavel_70776
Nimbostratus
Hi Nat,
iRule works fine, tested also for asynchronous SMPP transfer and for more clients.
Once again thank you.
Pavel - Nat_Thirasuttakorn
Employee
Hi Pavel,
This is cool. Thanks for letting me know.
I forgot to ask. :)
Last time you mentioned about a small correction that you fixes the iRule to make it works.
Could you let me know what are they?
Nat
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
