Passa al contenuto principale

4. Pseudocode Walk-Through

Questa pagina conserva variabili e funzioni: MAX_RATE, QPROTECT_ON, CRITICALqL_us, CRITICALqLSCORE_us, LG_AGING, qdelay, probNative, packet.uflow, qLscore, pick_bucket(), fill_bucket(), calcProbNative(), qprotect().

4.1. Input Parameters, Constants, and Variables

// Input Parameters
MAX_RATE; // Configured maximum sustained rate [b/s]
QPROTECT_ON; // Queue Protection is enabled [Default: TRUE]
CRITICALqL_us; // LL queue threshold delay [µs] Default: MAXTH_us
CRITICALqLSCORE_us;// The threshold queuing score [Default: 4000 µs]
LG_AGING; // The aging rate of the q'ing score [Default: 19]
// as log base 2 of the congestion-rate [lg(B/s)]

// Constants
AGING = pow(2, (LG_AGING-30) ) * T_RES;
CRITICALqL = CRITICALqL_us * 1000;
CRITICALqLSCORE = CRITICALqLSCORE_us * 1000/T_RES;
CRITICALqLPRODUCT = CRITICALqL * CRITICALqLSCORE;
qLSCORE_MAX = 5E9 / T_RES;
ATTEMPTS = 2;
BI_SIZE = 5;
NBUCKETS = pow(2, BI_SIZE);
MASK = NBUCKETS-1;
EXIT_SUCCESS = 0;
EXIT_SANCTION = 1;
MAX_FRAME_SIZE = 2000;
FLOOR = 2 * 8 * MAX_FRAME_SIZE * 10^9 / MAX_RATE;
struct bucket {
id; // identifier of flow using bucket
t_exp; // expiry time in units of T_RES
};
struct bucket buckets[NBUCKETS+1];

Le variabili pubbliche e di pacchetto importanti includono qdelay, probNative, packet, packet.size, packet.uflow e qdelayL(...). L'identificatore di flusso e normalmente una 5-tuple, oppure una 4-tuple per IPsec ESP che usa il Security Parameter Index (SPI).

4.2. qprotect()

qprotect(packet, ...) {
bckt_id;
qLscore;

qdelay = qL.qdelay(...);
probNative = calcProbNative(qdelay);

bckt_id = pick_bucket(packet.uflow);
qLscore = fill_bucket(buckets[bckt_id], packet.size, probNative);

if ( ( ( qdelay > CRITICALqL )
&& ( qdelay * qLscore > CRITICALqLPRODUCT ) )
|| ( qLscore >= qLSCORE_MAX ) )
return EXIT_SANCTION;
else
return EXIT_SUCCESS;
}

4.2.2. pick_bucket()

pick_bucket(uflw) {
h32 = hash32(uflw);
hsav = NBUCKETS;
now = get_time_now();
for (j=0; j<ATTEMPTS; j++) {
h = h32 & MASK;
if (buckets[h].id == uflw) {
if (buckets[h].t_exp <= now)
buckets[h].t_exp = now;
return h;
}
else if ((hsav == NBUCKETS) && (buckets[h].t_exp <= now)) {
hsav = h;
}
h32 >>= BI_SIZE;
}
if (hsav != NBUCKETS) {
buckets[hsav].t_exp = now;
} else {
if (buckets[hsav].t_exp <= now)
buckets[hsav].t_exp = now;
}
buckets[hsav].id = uflw;
return hsav;
}

Il bucket NBUCKETS aggiuntivo e il bucket "dregs" predefinito. Se ATTEMPTS=2 e BI_SIZE=5, ci sono 32 bucket non predefiniti.

4.2.3. fill_bucket()

fill_bucket(bckt_id, pkt_sz, probNative) {
now = get_time_now();
qLscore = min(buckets[bckt_id].t_exp - now
+ probNative * pkt_sz / AGING, qLSCORE_MAX);
buckets[bckt_id].t_exp = now + qLscore;
return qLscore;
}

4.2.4. calcProbNative()

calcProbNative(qdelay){
if ( qdelay >= MAXTH ) {
probNative = MAX_PROB;
} else if ( qdelay > MINTH ) {
probNative = MAX_PROB * (qdelay - MINTH)/RANGE;
} else {
probNative = 0;
}
return probNative;
}