123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- import math
- import random
- import numpy
- from classes.Node import Node
- from classes.Client import Client
- import os
- class Network(object):
- def __init__(self, env, type, conf, loggers):
- self.env = env
- self.conf = conf
- self.topology = {}
- self.type = type
- self.loggers = loggers
- self.clients = [Client(env, conf, self, loggers = loggers, label=i) for i in range(int(conf["clients"]["number"]))]
- if type == "p2p":
- self.peers = [Node(env, conf, self, id="Peer%s" % i, loggers = loggers) for i in range(int(conf["clients"]["number"]))]
- self.topology["Type"] = "p2p"
- self.init_p2p()
- else:
- if type == "cascade":
- self.topology["Type"] = "cascade"
- self.mixnodes = [Node(env, conf, self, id="M%s" % i, loggers = loggers) for i in range(self.conf["network"]["cascade"]["cascade_len"])]
- self.init_cascade()
- elif type == "stratified":
- self.topology["Type"] = "stratified"
- num_mixnodes = int(self.conf["network"]["stratified"]["layers"]) * int(self.conf["network"]["stratified"]["layer_size"])
- self.mixnodes = [Node(env, conf, self, id="M%s" % i, loggers = loggers) for i in range(num_mixnodes)]
- self.init_stratified()
- elif type == "multi_cascade":
- self.topology["Type"] = "multi_cascade"
- num_mixnodes = int(self.conf["network"]["multi_cascade"]["cascade_len"]) * int(self.conf["network"]["multi_cascade"]["num_cascades"])
- self.mixnodes = [Node(env, conf, self, id="M%s" % i, loggers = loggers) for i in range(num_mixnodes)]
- self.init_multi_cascade()
- else:
- raise Exception("Didn't recognize the network type")
- print("Current topology: ", self.topology["Type"])
- # print("Batching yes/no: ", self.conf["mixnodes"]["batch"])
- def init_p2p(self):
- self.topology["peers"] = self.peers.copy()
- def init_cascade(self):
- self.topology["cascade"] = self.mixnodes.copy()
- def init_multi_cascade(self):
- num_cascades = int(self.conf["network"]["multi_cascade"]["num_cascades"])
- cascade_len = int(self.conf["network"]["multi_cascade"]["cascade_len"])
- ind_cascades = [self.mixnodes[x:x+cascade_len] for x in range(0, len(self.mixnodes), cascade_len)]
- self.topology["cascades"] = ind_cascades
- def init_stratified(self):
- num_layers = int(self.conf["network"]["stratified"]["layers"])
- mixes_per_layer = int(self.conf["network"]["stratified"]["layer_size"])
- layers = [self.mixnodes[i * mixes_per_layer:(i + 1) * mixes_per_layer] for i in range(0, num_layers)]
- self.topology["Layers"] = layers
- for i in range(0, num_layers - 1):
- for j in range(0, mixes_per_layer):
- self.topology[self.mixnodes[i * mixes_per_layer + j]] = layers[i + 1]
- def select_random_route(self):
- tmp_route = []
- if self.topology["Type"] == "stratified":
- tmp_route = [random.choice(L) for L in self.topology["Layers"]]
- elif self.topology["Type"] == "cascade":
- tmp_route = self.topology["cascade"].copy()
- elif self.topology["Type"] == "multi_cascade":
- tmp_route = random.choice(self.topology["cascades"])
- elif self.topology["Type"] == "p2p":
- length = self.conf["network"]["p2p"]["path_length"]
- tmp_route = random.sample(self.peers, length)
- return tmp_route
- def forward_packet(self, packet):
- ''' Function responsible for forwarding the packet, i.e.,
- checking what is the next hop of the packet and triggering the
- process_packet function by a particular node.
- Keyword arguments:
- packet - the packet to be forwarded.
- '''
- # TODO: If needed, some network delay can be added.
- yield self.env.timeout(0)
- # print(packet.current_node, packet.route, packet.dest)
- next_node = packet.route[packet.current_node + 1]
- packet.current_node += 1
- self.env.process(next_node.process_packet(packet))
- def __repr__(self):
- return "topology: " + str(self.topology)
|