Net.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import math
  2. import random
  3. import numpy
  4. from classes.Node import Node
  5. from classes.Client import Client
  6. import os
  7. class Network(object):
  8. def __init__(self, env, type, conf, loggers):
  9. self.env = env
  10. self.conf = conf
  11. self.topology = {}
  12. self.type = type
  13. self.loggers = loggers
  14. self.clients = [Client(env, conf, self, loggers = loggers, label=i) for i in range(int(conf["clients"]["number"]))]
  15. if type == "p2p":
  16. self.peers = [Node(env, conf, self, id="Peer%s" % i, loggers = loggers) for i in range(int(conf["clients"]["number"]))]
  17. self.topology["Type"] = "p2p"
  18. self.init_p2p()
  19. else:
  20. if type == "cascade":
  21. self.topology["Type"] = "cascade"
  22. self.mixnodes = [Node(env, conf, self, id="M%s" % i, loggers = loggers) for i in range(self.conf["network"]["cascade"]["cascade_len"])]
  23. self.init_cascade()
  24. elif type == "stratified":
  25. self.topology["Type"] = "stratified"
  26. num_mixnodes = int(self.conf["network"]["stratified"]["layers"]) * int(self.conf["network"]["stratified"]["layer_size"])
  27. self.mixnodes = [Node(env, conf, self, id="M%s" % i, loggers = loggers) for i in range(num_mixnodes)]
  28. self.init_stratified()
  29. elif type == "multi_cascade":
  30. self.topology["Type"] = "multi_cascade"
  31. num_mixnodes = int(self.conf["network"]["multi_cascade"]["cascade_len"]) * int(self.conf["network"]["multi_cascade"]["num_cascades"])
  32. self.mixnodes = [Node(env, conf, self, id="M%s" % i, loggers = loggers) for i in range(num_mixnodes)]
  33. self.init_multi_cascade()
  34. else:
  35. raise Exception("Didn't recognize the network type")
  36. print("Current topology: ", self.topology["Type"])
  37. # print("Batching yes/no: ", self.conf["mixnodes"]["batch"])
  38. def init_p2p(self):
  39. self.topology["peers"] = self.peers.copy()
  40. def init_cascade(self):
  41. self.topology["cascade"] = self.mixnodes.copy()
  42. def init_multi_cascade(self):
  43. num_cascades = int(self.conf["network"]["multi_cascade"]["num_cascades"])
  44. cascade_len = int(self.conf["network"]["multi_cascade"]["cascade_len"])
  45. ind_cascades = [self.mixnodes[x:x+cascade_len] for x in range(0, len(self.mixnodes), cascade_len)]
  46. self.topology["cascades"] = ind_cascades
  47. def init_stratified(self):
  48. num_layers = int(self.conf["network"]["stratified"]["layers"])
  49. mixes_per_layer = int(self.conf["network"]["stratified"]["layer_size"])
  50. layers = [self.mixnodes[i * mixes_per_layer:(i + 1) * mixes_per_layer] for i in range(0, num_layers)]
  51. self.topology["Layers"] = layers
  52. for i in range(0, num_layers - 1):
  53. for j in range(0, mixes_per_layer):
  54. self.topology[self.mixnodes[i * mixes_per_layer + j]] = layers[i + 1]
  55. def select_random_route(self):
  56. tmp_route = []
  57. if self.topology["Type"] == "stratified":
  58. tmp_route = [random.choice(L) for L in self.topology["Layers"]]
  59. elif self.topology["Type"] == "cascade":
  60. tmp_route = self.topology["cascade"].copy()
  61. elif self.topology["Type"] == "multi_cascade":
  62. tmp_route = random.choice(self.topology["cascades"])
  63. elif self.topology["Type"] == "p2p":
  64. length = self.conf["network"]["p2p"]["path_length"]
  65. tmp_route = random.sample(self.peers, length)
  66. return tmp_route
  67. def forward_packet(self, packet):
  68. ''' Function responsible for forwarding the packet, i.e.,
  69. checking what is the next hop of the packet and triggering the
  70. process_packet function by a particular node.
  71. Keyword arguments:
  72. packet - the packet to be forwarded.
  73. '''
  74. # TODO: If needed, some network delay can be added.
  75. yield self.env.timeout(0)
  76. # print(packet.current_node, packet.route, packet.dest)
  77. next_node = packet.route[packet.current_node + 1]
  78. packet.current_node += 1
  79. self.env.process(next_node.process_packet(packet))
  80. def __repr__(self):
  81. return "topology: " + str(self.topology)