Skip to content

Commit

Permalink
Release 1.6
Browse files Browse the repository at this point in the history
  • Loading branch information
David Fialho committed Nov 16, 2017
2 parents 3d6d1db + 5137eb4 commit a77098f
Show file tree
Hide file tree
Showing 62 changed files with 2,396 additions and 778 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
application.version=1.5
application.version=1.6
12 changes: 7 additions & 5 deletions src/main/kotlin/bgp/BGP.kt
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,14 @@ abstract class BaseBGP(val mrai: Time, routingTable: RoutingTable<BGPRoute>): Pr
}

/**
* Announces [node] as the destination.
* Makes [node] advertise a destination and sets [defaultRoute] as the default route to reach that destination.
* The default route is immediately exported if it becomes the selected route.
*
* @param node the node to advertise destination
* @param defaultRoute the default route to reach the destination
*/
override fun start(node: Node<BGPRoute>) {
val selfRoute = BGPRoute.self()
routingTable.update(node, selfRoute)
export(node)
override fun advertise(node: Node<BGPRoute>, defaultRoute: BGPRoute) {
process(node, node, defaultRoute)
}

/**
Expand Down
14 changes: 4 additions & 10 deletions src/main/kotlin/bgp/policies/interdomain/InterdomainExtenders.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,12 @@ import core.routing.Node
* @author David Fialho
*/

const val LOCAL_PREF_PEERPLUS: Int = 500000
const val LOCAL_PREF_PEERSTAR: Int = 400000
const val LOCAL_PREF_CUSTOMER: Int = 300000
const val LOCAL_PREF_PEER: Int = 200000
const val LOCAL_PREF_PROVIDER: Int = 100000

object CustomerExtender: Extender<BGPRoute> {

override fun extend(route: BGPRoute, sender: Node<BGPRoute>): BGPRoute {

return when {
route.localPref <= LOCAL_PREF_PEER || route.localPref == LOCAL_PREF_PEERSTAR -> BGPRoute.invalid()
route.localPref <= peerLocalPreference || route.localPref == peerstarLocalPreference -> BGPRoute.invalid()
else -> customerRoute(asPath = route.asPath.append(sender))
}
}
Expand All @@ -33,7 +27,7 @@ object PeerExtender: Extender<BGPRoute> {
override fun extend(route: BGPRoute, sender: Node<BGPRoute>): BGPRoute {

return when {
route.localPref <= LOCAL_PREF_PEER || route.localPref == LOCAL_PREF_PEERSTAR -> BGPRoute.invalid()
route.localPref <= peerLocalPreference || route.localPref == peerstarLocalPreference -> BGPRoute.invalid()
else -> peerRoute(asPath = route.asPath.append(sender))
}
}
Expand All @@ -57,7 +51,7 @@ object PeerplusExtender: Extender<BGPRoute> {
override fun extend(route: BGPRoute, sender: Node<BGPRoute>): BGPRoute {

return when {
route.localPref <= LOCAL_PREF_PEER || route.localPref == LOCAL_PREF_PEERSTAR -> BGPRoute.invalid()
route.localPref <= peerLocalPreference || route.localPref == peerstarLocalPreference -> BGPRoute.invalid()
else -> peerplusRoute(asPath = route.asPath.append(sender))
}
}
Expand All @@ -69,7 +63,7 @@ object PeerstarExtender: Extender<BGPRoute> {
override fun extend(route: BGPRoute, sender: Node<BGPRoute>): BGPRoute {

return when {
route.localPref <= LOCAL_PREF_PEER || route.localPref == LOCAL_PREF_PEERSTAR -> BGPRoute.invalid()
route.localPref <= peerLocalPreference || route.localPref == peerstarLocalPreference -> BGPRoute.invalid()
else -> peerstarRoute(asPath = route.asPath.append(sender))
}
}
Expand Down
19 changes: 14 additions & 5 deletions src/main/kotlin/bgp/policies/interdomain/Routes.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,41 @@ import core.routing.emptyPath
* This file contains methods to construct interdomain routes.
*/


// LOCAL-PREFs for each interdomain route
val peerplusLocalPreference: Int = 500000
val peerstarLocalPreference: Int = 400000
val customerLocalPreference: Int = 300000
val peerLocalPreference: Int = 200000
val providerLocalPreference: Int = 100000


/**
* Returns a peer+ route.
*/
fun peerplusRoute(siblingHops: Int = 0, asPath: Path = emptyPath())
= BGPRoute.with(localPref = LOCAL_PREF_PEERPLUS - siblingHops, asPath = asPath)
= BGPRoute.with(localPref = peerplusLocalPreference - siblingHops, asPath = asPath)

/**
* Returns a peer* route.
*/
fun peerstarRoute(siblingHops: Int = 0, asPath: Path = emptyPath())
= BGPRoute.with(localPref = LOCAL_PREF_PEERSTAR - siblingHops, asPath = asPath)
= BGPRoute.with(localPref = peerstarLocalPreference - siblingHops, asPath = asPath)

/**
* Returns a customer route.
*/
fun customerRoute(siblingHops: Int = 0, asPath: Path = emptyPath())
= BGPRoute.with(localPref = LOCAL_PREF_CUSTOMER - siblingHops, asPath = asPath)
= BGPRoute.with(localPref = customerLocalPreference - siblingHops, asPath = asPath)

/**
* Returns a peer route.
*/
fun peerRoute(siblingHops: Int = 0, asPath: Path = emptyPath())
= BGPRoute.with(localPref = LOCAL_PREF_PEER - siblingHops, asPath = asPath)
= BGPRoute.with(localPref = peerLocalPreference - siblingHops, asPath = asPath)

/**
* Returns a provider route.
*/
fun providerRoute(siblingHops: Int = 0, asPath: Path = emptyPath())
= BGPRoute.with(localPref = LOCAL_PREF_PROVIDER - siblingHops, asPath = asPath)
= BGPRoute.with(localPref = providerLocalPreference - siblingHops, asPath = asPath)
2 changes: 1 addition & 1 deletion src/main/kotlin/core/routing/Extender.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ package core.routing
* This function describes how each route elected by the head node of the link is transformed at the tail node.
* It describes both the export bgp.policies of the head node and the import bgp.policies of the tail node.
*
* TODO improve the documentation for extender
* TODO @doc - improve the documentation for extender
*/
interface Extender<R: Route> {

Expand Down
14 changes: 9 additions & 5 deletions src/main/kotlin/core/routing/Node.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package core.routing

import core.simulator.Advertiser
import core.simulator.notifications.BasicNotifier
import core.simulator.notifications.MessageReceivedNotification
import core.simulator.notifications.MessageSentNotification
Expand All @@ -20,7 +21,7 @@ typealias NodeID = Int
*
* @property id The ID of the node. This ID uniquely identifies it inside a topology
*/
class Node<R: Route>(val id: NodeID, val protocol: Protocol<R>) {
class Node<R : Route>(override val id: NodeID, val protocol: Protocol<R>) : Advertiser<R> {

/**
* Collection containing the in-neighbors of this node.
Expand All @@ -39,10 +40,13 @@ class Node<R: Route>(val id: NodeID, val protocol: Protocol<R>) {
}

/**
* Starts the protocol deployed by this node.
* This node advertises a destination according to the specification of the deployed protocol.
* It sets a default route for the destination. This route maybe sent to neighbors.
*
* @param defaultRoute the default route to set for the destination
*/
fun start() {
protocol.start(this)
override fun advertise(defaultRoute: R) {
protocol.advertise(this, defaultRoute)
}

/**
Expand Down Expand Up @@ -82,7 +86,7 @@ class Node<R: Route>(val id: NodeID, val protocol: Protocol<R>) {
/**
* Resets the node state.
*/
fun reset() {
override fun reset() {
protocol.reset()
inNeighbors.forEach { it.exporter.reset() }
}
Expand Down
7 changes: 5 additions & 2 deletions src/main/kotlin/core/routing/Protocol.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ interface Protocol<R: Route> {
fun addInNeighbor(neighbor: Neighbor<R>)

/**
* Starts this protocol.
* Makes [node] advertise a destination and sets [defaultRoute] as the default route to reach that destination.
*
* @param node the node to advertise destination
* @param defaultRoute the default route to reach the destination
*/
fun start(node: Node<R>)
fun advertise(node: Node<R>, defaultRoute: R)

/**
* Processes an incoming routing message.
Expand Down
18 changes: 18 additions & 0 deletions src/main/kotlin/core/simulator/AdvertiseEvent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package core.simulator

import core.routing.Route

/**
* Created on 09-11-2017
*
* @author David Fialho
*/
class AdvertiseEvent<R: Route>(private val advertiser: Advertiser<R>, private val route: R): Event {

/**
* Processes this event.
*/
override fun processIt() {
advertiser.advertise(route)
}
}
12 changes: 12 additions & 0 deletions src/main/kotlin/core/simulator/Advertisement.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package core.simulator

import core.routing.Route

/**
* Created on 08-11-2017
*
* @author David Fialho
*
* An advertisement is a data class that specifies the advertiser and the time at which it will/did take place.
*/
data class Advertisement<R: Route>(val advertiser: Advertiser<R>, val route: R, val time: Time = 0)
31 changes: 31 additions & 0 deletions src/main/kotlin/core/simulator/Advertiser.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package core.simulator

import core.routing.NodeID
import core.routing.Route

/**
* Created on 08-11-2017
*
* @author David Fialho
*
* An advertiser is some entity that can advertise destinations.
*/
interface Advertiser<in R: Route> {

/**
* Each advertiser is associated with a unique ID.
*/
val id: NodeID

/**
* Advertises some destination.
*
* @param defaultRoute the default route for the destination.
*/
fun advertise(defaultRoute: R)

/**
* Resets the state of the advertiser. This may be required before advertising.
*/
fun reset()
}
58 changes: 50 additions & 8 deletions src/main/kotlin/core/simulator/Engine.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package core.simulator

import core.routing.Node
import core.routing.Route
import core.routing.Topology
import core.simulator.notifications.BasicNotifier
import core.simulator.notifications.EndNotification
Expand Down Expand Up @@ -36,27 +36,60 @@ object Engine {
}

/**
* Runs the simulation for the given destination.
* Runs a simulation with a single advertisement.
*
* The scheduler is cleared before running the simulation.
*
* The threshold value determines the number of units of time the simulation should have terminated on. If this
* threshold is reached the simulation is interrupted immediately. If no threshold is specified then the
* simulator will run 'forever'.
*
* @param topology the topology used for the simulation
* @param destination the destination used for the simulation
* @param threshold a threshold value for the simulation
* @param topology the topology used for the simulation
* @param advertisement the single advertisement to start off the simulation
* @param threshold a threshold value for the simulation
* @return true if the simulation terminated before the specified threshold or false if otherwise.
*/
fun simulate(topology: Topology<*>, destination: Node<*>, threshold: Time = Int.MAX_VALUE): Boolean {
fun <R: Route> simulate(topology: Topology<R>, advertisement: Advertisement<R>,
threshold: Time = Int.MAX_VALUE): Boolean {
return simulate(topology, listOf(advertisement), threshold)
}

/**
* Runs a simulation with one or multiple advertisements.
*
* The scheduler is cleared before running the simulation.
*
* The threshold value determines the number of units of time the simulation should have terminated on. If this
* threshold is reached the simulation is interrupted immediately. If no threshold is specified then the
* simulator will run 'forever'.
*
* @param topology the topology used for the simulation
* @param advertisements a list containing all the advertisements to occur in the simulation
* @param threshold a threshold value for the simulation
* @return true if the simulation terminated before the specified threshold or false if otherwise
* @throws IllegalArgumentException if the advertisement plan is empty
*/
@Throws(IllegalArgumentException::class)
fun <R: Route> simulate(topology: Topology<*>, advertisements: List<Advertisement<R>>,
threshold: Time = Int.MAX_VALUE): Boolean {

if (advertisements.isEmpty()) {
throw IllegalArgumentException("a simulation requires at least one advertisement")
}

// Ensure the scheduler is completely clean before starting the simulation
scheduler.reset()

BasicNotifier.notifyStart(StartNotification(messageDelayGenerator.seed, topology))

// The simulation execution starts when the protocol of the destination is started
destination.start()
// Schedule advertisements specified in the strategy
for (advertisement in advertisements) {
scheduler.schedule(advertisement)
}

// Flag that will indicate whether or not the simulation finished before the threshold was reached
var terminatedBeforeThreshold = true

while (scheduler.hasEvents()) {
val event = scheduler.nextEvent()

Expand All @@ -72,6 +105,7 @@ object Engine {
event.processIt()
}

// Notify listeners the simulation ended
BasicNotifier.notifyEnd(EndNotification(topology))

return terminatedBeforeThreshold
Expand All @@ -92,6 +126,14 @@ object Engine {

}


/**
* Schedules an advertisement event.
*/
private fun <R: Route> Scheduler.schedule(advertisement: Advertisement<R>) {
schedule(AdvertiseEvent(advertisement.advertiser, advertisement.route), advertisement.time)
}

/**
* Cleaner way to access the simulation time.
*/
Expand Down
14 changes: 8 additions & 6 deletions src/main/kotlin/core/simulator/RandomDelayGenerator.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package core.simulator

import java.lang.System
import java.util.Random
import java.util.*

/**
* Created on 22-07-2017
Expand Down Expand Up @@ -31,14 +30,17 @@ private constructor(override val min: Time, override val max: Time, seed: Long):
* @param min the minimum delay value the generator will generate. Must be higher than 0
* @param max the maximum delay value the generator will generate. Must be higher than or equal to 'min'
* @param seed the seed used to generate the random delays. If none is provided it uses the system current time
* @throws IllegalStateException if 'max' is lower than 'min' or if 'min' is lower than 0.
* @throws IllegalArgumentException if 'max' is lower than 'min' or if 'min' is lower than 0.
*/
@Throws(IllegalStateException::class)
fun with(min: Time, max: Time, seed: Long = System.currentTimeMillis()): RandomDelayGenerator {

if (min < 0 || max < min) {
throw IllegalArgumentException("Maximum delay can not be lower than minimum and minimum must be a " +
"non-negative value")
if (min < 0) {
throw IllegalArgumentException("minimum must be a non-negative value, but was $min")
}

if (max < min) {
throw IllegalArgumentException("maximum delay can not be lower than minimum ($max < $min)")
}

return RandomDelayGenerator(min, max, seed)
Expand Down
12 changes: 12 additions & 0 deletions src/main/kotlin/io/AdvertisementInfo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io

import core.routing.NodeID
import core.routing.Route
import core.simulator.Time

/**
* Created on 14-11-2017
*
* @author David Fialho
*/
data class AdvertisementInfo<out R: Route>(val advertiserID: NodeID, val defaultRoute: R, val time: Time)
Loading

0 comments on commit a77098f

Please sign in to comment.