[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Problems with errormodel



> We are trying to insert an error model into our simulation based on Mr
> Haobo Yu's contribution to this mailing list (last one in february).
> 
> However, we cannot make it work properly. The simulator drops packets,
> but after it has dropped the first one it drop all the rest.
> 
> We tried to use the following:
> 
> $ns add-duplex-lossy-link $n0 $n1 50
> 
> It seems that it doesn't matter what the rate parameter (here it's 50) is...

Which version of ns are you using? If you are using ns daily snapshot
after March 17, the meaning of rate in ErrorModel has been changed. Before
that, it means the average number of packets between two consecutive
drops. After that, rate means the percentage of dropped packets. So if
it's the latter case, setting rate to 50 will drop all packets. To correct
this problem, you can use the attached codes. They are what I'm currently
using in my simulations with the current ns.

Please let me know if there's problems.

- Haobo


#----------------------------------------------------------------------
# Lossy link stuff
#----------------------------------------------------------------------

#
# insert an ErrorModel between the queue and the link
# a pkt still go thru the queue and may be dropped there, then the 
# loss introduced by the ErrorModel is purely the effect of the link
#
# Must be inserted *RIGHT AFTER* the deqT_ (if present) or queue_, because
# nam can only visualize a packet drop if and only if it is on the link or 
# in the queue
#
SimpleLink instproc add-loss { ns em } {
	$self instvar queue_ head_ link_ isLossy_ deqT_ lossModule_

	if [info exists deqT_] {
		$em target [$deqT_ target]
		$deqT_ target $em
	} else {
		$em target [$queue_ target]
		$queue_ target $em
	}

	set isLossy_ 1
	set lossModule_ $em
}

SimpleLink instproc is-lossy {} {
	$self instvar isLossy_ lossModule_
	if [info exists isLossy_] {
		return [$lossModule_ set enable_]
	} else {
		return 0
	}
}

SimpleLink instproc has-loss-module {} {
	$self instvar isLossy_
	if [info exists isLossy_] {
		return 1
	} else {
		return 0
	}
}

SimpleLink instproc enable-loss {} {
	$self instvar isLossy_ lossModule_

	if ![info exists isLossy_] {
		return
	}
	$lossModule_ set enable_ 1
}

SimpleLink instproc change-loss-rate { rate } {
	$self instvar lossModule_
	if [info exists lossModule_] {
		$lossModule_ set rate_ $rate
	}
}

SimpleLink instproc disable-loss {} {
	$self instvar isLossy_ lossModule_

	if ![info exists isLossy_] {
		return
	}
	$lossModule_ set enable_ 0
}

SimpleLink instproc remove-loss {} {
	$self instvar isLossy_ queue_ head_ deqT_

	if ![info exists isLossy_] {
		return;
	}

	# changed!
	#	set em [$head_ target]
	#	if { [$head_ info class] == "networkinterface" } {
	#		$head_ target [$em target]
	#	} else {
	#		set head_ [$em target]
	#	}

	if [info exists deqT_] {
		set em [$deqT_ target]
		$deqT_ target [$em target]
	} else {
		set em [$queue_ target]
		$queue_ target [$em target]
	}

	set drp [$em drop-target]

	[Simulator instance] instvar alltrace_

	if [info exists alltrace_] {
		set pos [lsearch -glob $alltrace_ $drp]
		if {$pos == -1} {
			$self instvar fromNode_ toNode_
			error "No drop trace $drp for lossy link
([$fromNode_ id]:[$toNode_ id]), all trace = $alltrace_"
		} else {
			set alltrace_ [lreplace $alltrace_ $pos $pos]
			puts "Drop trace object $drp deleted"
		}
		delete $drp
	}

	delete $em
	unset isLossy_
}

#
# following is the correct separation between link and simulator
# simulator should set everything which is related to its variables,
# then pass everything else to link
#
Simulator instproc insert-loss { n1 n2 rate } {
	$self instvar nullAgent_ 
	$self instvar link_ 

	# if the link already has a loss module, enable it
	set lnk $link_([$n1 id]:[$n2 id])
	if [$lnk has-loss-module] {
		$lnk enable-loss
#		puts "Link ([$n1 id]:[$n2 id]) loss enabled"
		return
	}

	# XXX
	# Semantics of ErrorModel::rate_ is changed!!! Now it means 
	# the means number of packets between two consecutive losses!
	# If a random var is given to the error model, rate_ is ignored.
	set tmp [new RandomVariable/Uniform]
	$tmp set min_ 0.0
	$tmp set max_ 1.0
	set em [new ErrorModel]
	$em unit pkt
	$em set rate_ $rate
	$em ranvar $tmp
	$em drop-target $nullAgent_

	set trace [$self get-ns-traceall]
	if {$trace != ""} {
		set drpT [$self create-trace Drop $trace $n1 $n2]
		set trace [$self get-nam-traceall]
		if {$trace != ""} {
			$drpT namattach $trace
		}
		$drpT target [$em drop-target]
		$em drop-target $drpT
	} else {
		set trace [$self get-nam-traceall]
		if {$trace != ""} {
			set drpT [$self create-trace Drop $trace $n1 $n2
nam]
			$drpT target [$em drop-target]
			$em drop-target $drpT
		}
	}

	$lnk add-loss $self $em
#	puts "Lossy link ([$n1 id]:[$n2 id]) added"
}

# should eventually rename to diable instead of remove
Simulator instproc remove-loss { n1 n2 } {
	$self instvar link_
#	$link_([$n1 id]:[$n2 id]) remove-loss
	$link_([$n1 id]:[$n2 id]) disable-loss
	puts "Link ([$n1 id]:[$n2 id]) no longer lossy"
}

Simulator instproc add-duplex-lossy-link { n1 n2 rate } {
	$self insert-loss $n1 $n2 $rate
	$self insert-loss $n2 $n1 $rate
}

Simulator instproc remove-duplex-lossy-link { n1 n2 } {
	$self remove-loss $n1 $n2
	$self remove-loss $n2 $n1
}

#
# change all duplex link to lossy link
#
Simulator instproc duplex-lossy-link { n1 n2 bw delay type {rate 0.1} } {
	$ns duplex-link $n1 $n2 $bw $delay $type

	# we may add some ranvar and ratio here so only some percentage of 
	# the links are lossy, and these lossy links are chosen randomly
	$self add-duplex-lossy-link $n1 $n2 $rate
}

Simulator instproc duplex-lossy-link-of-interfaces { n1 n2 bw delay type
{rate 0.1} } {
	$ns duplex-lossy-link-of-interfaces $n1 $n2 $bw $delay $type
	$self add-duplex-lossy-link $n1 $n2 $rate
}

Simulator instproc is-lossy { src dst } {
	$self instvar link_
	return [$link_([$src id]:[$dst id]) is-lossy]
}

SessionSim instproc insert-loss { n1 n2 rate} {
	$self instvar loss_ link_
	$self instvar nullAgent_ 

	set from [$n1 id]
	set to [$n2 id]

	# if the link already has a loss module, enable it
	if [info exists loss_($from:$to)] {
		$loss_($from:$to) enable
#		puts "Link ([$n1 id]:[$n2 id]) loss enabled"
		return
	}

	set tmp [new RandomVariable/Uniform]
	$tmp set min_ 0.0
	$tmp set max_ 1.0
	set em [new ErrorModelRandomSRMErrorModel]
	$em unit pkt
	$em ranvar $tmp_
	$em set rate_ $rate ;# 10% loss => rate = 0.1
	$em drop-target $nullAgent_

	set trace [$self get-nam-traceall]
	if {$trace != ""} {
		set drpT [$self create-trace Drop $trace $n1 $n2 nam]
		$drpT target [$em drop-target]
		$em drop-target $drpT
	}

	if [info exists link_($from:$to)] {
		set loss_($from:$to) $em
	}
	puts "Lossy link ([$n1 id]:[$n2 id]) added"

}

SessionSim instproc is-lossy { src dst } {
	$self instvar loss_

	set from [$src id]
	set to [$dst id]
	return [info exists loss_($from:$to)]
}

# should eventually rename to diable instead of remove
SessionSim instproc remove-loss { n1 n2 } {
	$self instvar loss_

	set from [$n1 id]
	set to [$n2 id]
	if [info exists loss_($from:$to)] {
		$loss_($from:$to) disable
	}
	puts "Link ([$n1 id]:[$n2 id]) no longer lossy"
}