A Traffic Script for load baancing MS Terminal Services when the Session Broker service is being used as discussed here.
This will parse the x.224 RDP Routing Token that is handed back by the Terminal Server when the user has a brokered session still running on a different host. When the Stingray Traffic Manager gets one of these x.224 Routing tokens, it will honour it and send the client to the appropriate server in the Terminal Server Pool.
There is a very good description of how MS Terminal Services uses the x.224 header here.
I have tested it pretty thouroughly in my AWS EC2 lab environment, but I am pretty keen for any feedback from anyone using it.
# Traffic Script for load balancing Microsoft Terminal Services Farms.
# This configuration requires the TS Farm to be set up using a server with the
# session broker role installed. See MS TechNet article for details of how
# to set this up: http:technet.microsoft.com/en-us/library/cc772418.aspx
# Note, in this configuration, you will not need to set up Round Robin DNS,
# instead, just point the farm name DNS entry at the Traffic Group IP you
# bind to the Virtual Server on the Stingray.
# NB: this configuration requires you to create a Persistence Class of
# "Named Node session persistence" and bind it to the pool. Put the name of
# your persistence pool into the "myPersistenceProfile" variable below
##########################################
$myPersistenceProfile = "tslb_namedNode";#
##########################################
### NOTHING TO EDIT BELOW THIS LINE
##########################################
# Check to see if this is a new connection or traffic from an existing flow
if (!connection.data.get("first_run")) {
# Read TPKT Header, 4 bytes
$tpkt_head = request.get(4);
$tpkt_head = string.skip($tpkt_head, 2);
# Bytes 3/4 are High/Low header length bits
$rest_head = string.bytesToInt($tpkt_head) - 4;
$total = $tpkt_head;
if ($rest_head > 0) {
# Read in rest of header
$header = request.get(string.bytesToInt($total));
string.skip($header, 13);
$pos = string.find($header, string.hexdecode("0D0A"));
if ($pos > 0) {
$poss_token = string.left($header, $pos);
if (string.regexmatch($poss_token, "[C|c]ookie:\\s(msts|mstshash)=(.+)$")) {
$kval = $1;
$vval = $2;
# We have a cookie to parse
if ($kval == "mstshash") {
# If we have an mstshash cookie, let the session be load balanced normally.
} else if ($kval == "msts" && string.regexmatch($vval, "^(\\d+)\\.(\\d+)\\.\\d+$")) {
log.info("ip: ".$1);
log.info("port: ".$2);
# Here we parse the captured "msts=" cookie to extract the back end node info to route the connection
$ip = string.bytesToDotted(string.reverse(string.intToBytes($1, 4)));
$port = string.bytesToInt(string.reverse(string.intToBytes($2, 2)));
$node = $ip.
":".$port; # NB: not IPv6 safe
connection.setPersistence($myPersistenceProfile);
connection.setPersistenceNode($node);
} else {
log.info("discard");
connection.discard();
}
}
}
}
# Set the connection run flag to prevent us from running this rule again on traffic from the same flow
connection.data.set("first_run", "yes");
}
Hi Jason,
So in addition of using the IP based session persistence enabled and Windows Remote Desktop Session Host 2008 R2 (Terminal Server), do we need to import the script above somewhere into the SteelApp ?
Depending on how you have set up your RDP, importing this rule into Traffic Manager may help to provide more inteligent persistence for your RDP services. The article above also links to the Microsoft support site for their guidance on how to set up.
I suggest you contact your local support SE to determine the best way to setup in your environment - and they can also look at the other queries you raise elsewhere?