cancel
Showing results for 
Search instead for 
Did you mean: 

Implementing header a la mod_unique_id in trafficscript

SOLVED
riverbedjo
Contributor

Implementing header a la mod_unique_id in trafficscript

We are new to traffic script and just planning out our deployment of some Stingray devices. I'm looking to see if I can easily create and attach a unique ID in roughly the same way as mod_unique_id works on apache (see http://httpd.apache.org/docs/2.2/mod/mod_unique_id.html).

In apache they use the time, local I, pid and a counter local to the thread.

I don't mind how this is achieved, except that it must contain some uniqueness for the individual Stingray (a management IP address?) and some uniqueness for the request (pid, epoch and counter seem to make sense).

As such I imagine I'd be doing something like this:

$pid=sys.getpid();
$epoch=sys.time();
$counter=counter.increment(1)
$ip=request.getLocalIP();

$id= string.base64encode($epoch) . string.base64encode($ip) . string.base64encode($pid) . string.base64encode($counter);

http.removeHeader("UniqueId");


http.addHeader( "UniqueId", $id );

Except I don't think I can extract the counter like this. Is there already a built in way of generating a unique id that I'm missing, or is there some other way of better doing this?

1 ACCEPTED SOLUTION

Accepted Solutions
owen
Frequent Contributor

Re: Implementing header a la mod_unique_id in trafficscript

To identify the individual traffic manager you can use


$host = sys.hostname();


The counter functions can't return their value to TrafficScript, they are only visible through the activity monitor or via SNMP. It's not really practical to try and implement a counter using the global hash table (data.get() and data.set()) because of the race condition involved in reading the counter, incrementing it and writing it back to memory. The best approach is therefore to combine a random number with the time of the request; although there is a chance of a collision we can minimise this beyond reasonable expectations.


$random = math.random(0x7ffffffe);


Instead of sys.time() we can use


$epoch = sys.time.highres();


Which gives the time since epoch in microseconds, so there won't be many requests passing through with that particular value.

Concatonate these, hash the result and you can be pretty confident that every request will be uniquely identifiable.


$randomdata = http.getHeader( "User-Agent" ) .


    sys.hostname() .


    request.getRemoteIP() .


    sys.time.highres() .


    math.random( 0x7ffffffe );



$uid = string.hexEncode( string.hashMD5( $randomdata ) );


Here's a function you can call in any rule to get the unique ID (UID).  It stores the unique id in client-side cookie, and only generates one if it's missing:


sub getUID() {


  $c = http.getCookie( "Z-UID" );


  if( $c ) return $c;



  # Perhaps we've just set it, and the client has not recieved the response


  $c = connection.data.get( "Z-UID" );


  if( $c ) return $c;



  # Generate for the first time


  $randomdata = http.getHeader( "User-Agent" ) .


     sys.hostname() .


      request.getRemoteIP() .


      sys.time.highres() .


      math.random( 0x7ffffffe );


  $c = string.hexEncode( string.hashMD5( $randomdata ) );


  http.setResponseCookie( "Z-UID", $c );


  connection.data.set( "Z-UID", $c );


  return $c;


}


View solution in original post

3 REPLIES 3
owen
Frequent Contributor

Re: Implementing header a la mod_unique_id in trafficscript

To identify the individual traffic manager you can use


$host = sys.hostname();


The counter functions can't return their value to TrafficScript, they are only visible through the activity monitor or via SNMP. It's not really practical to try and implement a counter using the global hash table (data.get() and data.set()) because of the race condition involved in reading the counter, incrementing it and writing it back to memory. The best approach is therefore to combine a random number with the time of the request; although there is a chance of a collision we can minimise this beyond reasonable expectations.


$random = math.random(0x7ffffffe);


Instead of sys.time() we can use


$epoch = sys.time.highres();


Which gives the time since epoch in microseconds, so there won't be many requests passing through with that particular value.

Concatonate these, hash the result and you can be pretty confident that every request will be uniquely identifiable.


$randomdata = http.getHeader( "User-Agent" ) .


    sys.hostname() .


    request.getRemoteIP() .


    sys.time.highres() .


    math.random( 0x7ffffffe );



$uid = string.hexEncode( string.hashMD5( $randomdata ) );


Here's a function you can call in any rule to get the unique ID (UID).  It stores the unique id in client-side cookie, and only generates one if it's missing:


sub getUID() {


  $c = http.getCookie( "Z-UID" );


  if( $c ) return $c;



  # Perhaps we've just set it, and the client has not recieved the response


  $c = connection.data.get( "Z-UID" );


  if( $c ) return $c;



  # Generate for the first time


  $randomdata = http.getHeader( "User-Agent" ) .


     sys.hostname() .


      request.getRemoteIP() .


      sys.time.highres() .


      math.random( 0x7ffffffe );


  $c = string.hexEncode( string.hashMD5( $randomdata ) );


  http.setResponseCookie( "Z-UID", $c );


  connection.data.set( "Z-UID", $c );


  return $c;


}


hsiboy
New Contributor

Re: Implementing header a la mod_unique_id in trafficscript

Hi Owen,

i used the string.hashMD5( ) function and took the load balancer off air, apparently there is a memory leak.  

How can i check for memory leaks in the lab?

Stuart

jsteele
Pulser

Re: Implementing header a la mod_unique_id in trafficscript


stuart taylor wrote:


i used the string.hashMD5( ) function and took the load balancer off air, apparently there is a memory leak.  

This is a known issue in some versions of the traffic manager - it is not present in recent versions (9.6 onward).  Please contact Riverbed support if you need support on specific versions.