def request_the_video_from_the_source(self): # {{{ Request the video using HTTP from the source node (Icecast). self.source_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if __debug__: try: print(self.source_socket.getsockname(), 'IMS: connecting to the source', self.source, '...') except Exception as e: pass # The behavior and return value for calling socket.socket.getsockname() on # an unconnected unbound socket is unspecified. # On UNIX, it returns an address ('0.0.0.0', 0), while on Windows it raises an obscure exception # "error: (10022, 'Invalid argument')" # I think we can avoid printing before connecting to the source to prevent errors in windows try: self.source_socket.connect(self.source) except socket.error as e: print("IMS: ", e) print(Color.red) print(self.source_socket.getsockname(), "\b: IMS: unable to connect to the source ", self.source) print(Color.none) self.source_socket.close() os._exit(1) if __debug__: print(self.source_socket.getsockname(), 'IMS: connected to', self.source) self.source_socket.sendall(self.GET_message.encode()) _print_(self.source_socket.getsockname(), 'IMS: GET_message =', self.GET_message)
def receive_the_header_size(self): # {{{ message = self.splitter_socket.recv(struct.calcsize("H")) value = struct.unpack("H", message)[0] self.header_size_in_chunks = socket.ntohs(value) _print_("header_size (in chunks) =", self.header_size_in_chunks)
def listen_to_the_team(self): # {{{ Create "team_socket" (UDP) for using the multicast channel self.team_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) try: self.team_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) except Exception as e: print(e) pass try: self.team_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) except Exception as e: print(e) pass self.team_socket.bind(("", self.mcast_port)) # self.team_socket.bind(('', self.SPLITTER_SOCKET.getsockname()[PORT])) mreq = struct.pack("4sl", socket.inet_aton(self.mcast_addr), socket.INADDR_ANY) self.team_socket.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) _print_("Listening to the mcast_channel =", (self.mcast_addr, self.mcast_port)) # This is the maximum time the peer will wait for a chunk # (from the splitter). self.team_socket.settimeout(1) if __debug__: print(self.team_socket.getsockname(), "\b.timeout = 1")
def receive_the_buffer_size(self): # {{{ message = self.splitter_socket.recv(struct.calcsize("H")) buffer_size = struct.unpack("H", message)[0] self.buffer_size = socket.ntohs(buffer_size) _print_("buffer_size =", self.buffer_size)
def send_the_header(self, peer_serve_socket): # {{{ _print_("IMS: Sending a header of", len(self.header), "bytes") try: peer_serve_socket.sendall(self.header) except: pass
def insert_peer(self, peer): # {{{ if peer not in self.peer_list: # Probar a quitar ----------------------------------------------------- #self.peer_list.insert(self.peer_number, peer) self.peer_list.append(peer) self.losses[peer] = 0 _print_("DBS: inserted peer", peer)
def __init__(self, peer): # {{{ sys.stdout.write(Color.yellow) _print_("Peer DBS (list)") sys.stdout.write(Color.none) _print_("DBS: max_chunk_debt =", self.MAX_CHUNK_DEBT)
def insert_peer(self, peer): # {{{ Splitter_DBS.insert_peer(self, peer) self.period[peer] = self.period_counter[peer] = 1 self.number_of_sent_chunks_per_peer[peer] = 0 #if __debug__: _print_("ACS: inserted", peer)
def receive_dsa_key(self): message = self.splitter_socket.recv(struct.calcsize("256s256s256s40s")) y, g, p, q = struct.unpack("256s256s256s40s", message) y = self.convert_to_long(y) g = self.convert_to_long(g) p = self.convert_to_long(p) q = self.convert_to_long(q) self.dsa_key = DSA.construct((y, g, p, q)) _print_("DSA key received")
def play_chunk(self, chunk): # {{{ try: self.player_socket.sendall(self.chunks[chunk % self.buffer_size]) except socket.error: # print(e) _print_("Player disconnected!") self.player_alive = False
def receive_my_endpoint(self): # {{{ message = self.splitter_socket.recv(struct.calcsize("4sH")) IP_addr, port = struct.unpack("4sH", message) # Ojo, !H ???? IP_addr = socket.inet_ntoa(IP_addr) port = socket.ntohs(port) self.me = (IP_addr, port) _print_("DBS: me =", self.me)
def receive_the_chunk_size(self): # {{{ # The size of the chunk in bytes. message = self.splitter_socket.recv(struct.calcsize("H")) chunk_size = struct.unpack("H", message)[0] self.chunk_size = socket.ntohs(chunk_size) _print_("chunk_size (bytes) =", self.chunk_size) self.message_format = "H" + str(self.chunk_size) + "s" if __debug__: print("message_format = ", self.message_format)
def request_the_video_from_the_source(self): # {{{ Request the video using HTTP from the source node (Icecast). self.source_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if __debug__: print(self.source_socket.getsockname(), 'IMS: connecting to the source', self.source, '...') self.source_socket.connect(self.source) if __debug__: print(self.source_socket.getsockname(), 'IMS: connected to', self.source) self.source_socket.sendall(self.GET_message.encode()) _print_(self.source_socket.getsockname(), 'IMS: GET_message =', self.GET_message)
def receive_the_number_of_peers(self): # {{{ self.debt = {} # Chunks debts per peer. self.peer_list = [] # The list of peers structure. sys.stdout.write(Color.green) _print_("DBS: Requesting the number of peers to", self.splitter_socket.getpeername()) self.number_of_peers = socket.ntohs(struct.unpack("H",self.splitter_socket.recv(struct.calcsize("H")))[0]) _print_("DBS: The size of the team is", self.number_of_peers, "(apart from me)") sys.stdout.write(Color.none)
def receive_the_list_of_peers(self): # {{{ self.debt = {} # Chunks debts per peer. self.peer_list = [] # The list of peers structure. sys.stdout.write(Color.green) _print_("DBS: Requesting", self.number_of_peers, "peers to", self.splitter_socket.getpeername()) #number_of_peers = socket.ntohs(struct.unpack("H",self.splitter_socket.recv(struct.calcsize("H")))[0]) #_print_("The size of the team is", number_of_peers, "(apart from me)") tmp = self.number_of_peers while tmp > 0: message = self.splitter_socket.recv(struct.calcsize("4sH")) IP_addr, port = struct.unpack("4sH", message) # Ojo, !H ???? IP_addr = socket.inet_ntoa(IP_addr) port = socket.ntohs(port) peer = (IP_addr, port) print("DBS: [hello] sent to", peer) self.say_hello(peer) if __debug__: _print_("DBS: [%5d]" % tmp, peer) else: _print_("DBS: {:.2%}\r".format((self.number_of_peers-tmp)/self.number_of_peers), end='') self.peer_list.append(peer) self.debt[peer] = 0 tmp -= 1 _print_("DBS: List of peers received") sys.stdout.write(Color.none)
def run(self): # {{{ self.receive_the_header() # {{{ A DBS splitter runs 4 threads. The main one and the # "handle_arrivals" thread are equivalent to the daemons used # by the IMS splitter. "moderate_the_team" and # "reset_counters_thread" are new. # }}} print(self.peer_connection_socket.getsockname(), "\b: DBS: waiting for the monitor peer ...") def _(): connection = self.peer_connection_socket.accept() incomming_peer = self.handle_a_peer_arrival(connection) #self.insert_peer(incomming_peer) # Notice that now, the # monitor peer is the # only one in the list of # peers. It is no # neccesary a delay. _() threading.Thread(target=self.handle_arrivals).start() threading.Thread(target=self.moderate_the_team).start() threading.Thread(target=self.reset_counters_thread).start() message_format = self.chunk_number_format \ + str(self.CHUNK_SIZE) + "s" #header_load_counter = 0 while self.alive: chunk = self.receive_chunk() try: peer = self.peer_list[self.peer_number] message = struct.pack(message_format, socket.htons(self.chunk_number), chunk) self.send_chunk(message, peer) self.destination_of_chunk[self.chunk_number % self.BUFFER_SIZE] = peer self.chunk_number = (self.chunk_number + 1) % common.MAX_CHUNK_NUMBER self.compute_next_peer_number(peer) if self.LOGGING: if self.peer_number == 0: self.CURRENT_ROUND += 1 message = "{0} {1} {2}".format(self.CURRENT_ROUND, len(self.peer_list), " ".join(map(lambda x: "{0}:{1}".format(x[0], x[1]), self.peer_list))) self.log_message(message) except IndexError: if __debug__: _print_("DBS: The monitor peer has died!")
def find_next_chunk(self): # {{{ # print (".") # counter = 0 chunk_number = (self.played_chunk + 1) % common.MAX_CHUNK_NUMBER while not self.received_flag[chunk_number % self.buffer_size]: sys.stdout.write(Color.cyan) _print_("lost chunk", chunk_number) sys.stdout.write(Color.none) chunk_number = (chunk_number + 1) % common.MAX_CHUNK_NUMBER # counter += 1 # if counter > self.buffer_size: # break return chunk_number
def __init__(self, peer): sys.stdout.write(Color.yellow) _print_("STrPe-DS Malicious Peer") sys.stdout.write(Color.none) threading.Thread.__init__(self) self.splitter_socket = peer.splitter_socket self.player_socket = peer.player_socket self.buffer_size = peer.buffer_size self.splitter = peer.splitter self.chunk_size = peer.chunk_size self.peer_list = peer.peer_list self.debt = peer.debt self.message_format = peer.message_format self.team_socket = peer.team_socket self.bad_peers = peer.bad_peers self.dsa_key = peer.dsa_key
def __init__(self, peer): # {{{ sys.stdout.write(Color.yellow) _print_("Monitor FNS") sys.stdout.write(Color.none) threading.Thread.__init__(self) self.splitter_socket = peer.splitter_socket self.player_socket = peer.player_socket self.buffer_size = peer.buffer_size self.chunk_format_string = peer.chunk_format_string self.splitter = peer.splitter self.chunk_size = peer.chunk_size self.peer_list = peer.peer_list self.debt = peer.debt
def __init__(self, peer): sys.stdout.write(Color.yellow) _print_("Trusted Peer") sys.stdout.write(Color.none) threading.Thread.__init__(self) self.splitter_socket = peer.splitter_socket self.player_socket = peer.player_socket self.buffer_size = peer.buffer_size self.splitter = peer.splitter self.chunk_size = peer.chunk_size self.peer_list = peer.peer_list self.debt = peer.debt self.message_format = peer.message_format self.team_socket = peer.team_socket self.next_sampled_index = 0 self.counter = 1
def __init__(self): # {{{ threading.Thread.__init__(self) sys.stdout.write(Color.yellow) _print_("Peer IMS") sys.stdout.write(Color.none) threading.Thread.__init__(self) _print_("Player port =", self.PLAYER_PORT) _print_("Splitter =", self.SPLITTER_ADDR) _print_("(Peer) port =", self.PORT)
def __init__(self, peer): # {{{ sys.stdout.write(Color.yellow) _print_("Peer DBS (list)") sys.stdout.write(Color.none) threading.Thread.__init__(self) self.splitter_socket = peer.splitter_socket self.player_socket = peer.player_socket self.buffer_size = peer.buffer_size #self.chunk_format_string = peer.message_format self.splitter = peer.splitter self.chunk_size = peer.chunk_size self.message_format = peer.message_format #self.extended_message_format = peer.message_format + "4sH" _print_("DBS: max_chunk_loss =", self.MAX_CHUNK_LOSS)
def __init__(self, peer): # {{{ #Peer_FNS.__init__(self, peer) sys.stdout.write(Color.yellow) _print_("Lossy Peer") sys.stdout.write(Color.none) threading.Thread.__init__(self) self.splitter_socket = peer.splitter_socket self.player_socket = peer.player_socket self.buffer_size = peer.buffer_size self.chunk_format_string = peer.chunk_format_string self.splitter = peer.splitter self.chunk_size = peer.chunk_size self.peer_list = peer.peer_list self.debt = peer.debt
def Run(self): print(Color.red, "RUN DEL SPLITTER STRPEDS", Color.none) self.receive_the_header() self.init_key() print(self.peer_connection_socket.getsockname(), "\b: STrPe-DS: waiting for the monitor peer ...") self.handle_a_peer_arrival(self.peer_connection_socket.accept()) threading.Thread(target=self.handle_arrivals).start() threading.Thread(target=self.moderate_the_team).start() threading.Thread(target=self.reset_counters_thread).start() threading.Thread(target=self.gather_bad_peers).start() message_format = self.chunk_number_format \ + str(self.CHUNK_SIZE) + "s" \ + str(self.DIGEST_SIZE) + "s" \ + str(self.DIGEST_SIZE) + "s" while self.alive: chunk = self.receive_chunk() try: peer = self.peer_list[self.peer_number] message = self.get_message(self.chunk_number, chunk, peer) self.send_chunk(message, peer) self.destination_of_chunk[self.chunk_number % self.BUFFER_SIZE] = peer self.chunk_number = (self.chunk_number + 1) % common.MAX_CHUNK_NUMBER self.compute_next_peer_number(peer) if self.peer_number == 0: self.on_round_beginning() if self.LOGGING: if self.peer_number == 0: self.CURRENT_ROUND += 1 message = "{0} {1} {2}".format(self.CURRENT_ROUND, len(self.peer_list), " ".join(map(lambda x: "{0}:{1}".format(x[0], x[1]), self.peer_list))) self.log_message(message) except IndexError: if __debug__: _print_("DBS: The monitor peer has died!")
def wait_for_the_player(self): # {{{ Setup "player_socket" and wait for the player self.player_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: # In Windows systems this call doesn't work! self.player_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) except Exception as e: _print_(e) pass self.player_socket.bind(("", self.PLAYER_PORT)) self.player_socket.listen(0) _print_("Waiting for the player at", self.player_socket.getsockname()) self.player_socket = self.player_socket.accept()[0] # self.player_socket.setblocking(0) _print_("The player is", self.player_socket.getpeername())
def wait_for_the_player(self): # {{{ Setup "player_socket" and wait for the player self.player_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: # In Windows systems this call doesn't work! self.player_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) except Exception as e: _print_(e) pass self.player_socket.bind(('', self.PLAYER_PORT)) self.player_socket.listen(0) _print_("Waiting for the player at", self.player_socket.getsockname()) self.player_socket = self.player_socket.accept()[0] #self.player_socket.setblocking(0) _print_("The player is", self.player_socket.getpeername())
def receive_the_list_of_peers_2(self): # {{{ # The monitor peer endpoints have already been received assert len(self.peer_list) == self.number_of_monitors sys.stdout.write(Color.green) _print_("NTS: Requesting the number of peers from splitter") sys.stdout.write(Color.none) # Add 1 as the monitor peer was already received message = self.splitter_socket.recv(struct.calcsize("H")) self.number_of_peers = socket.ntohs(struct.unpack("H", message)[0]) + self.number_of_monitors _print_("NTS: The size of the team is %d (apart from me)" % self.number_of_peers) # Skip the monitor peer for _ in range(self.number_of_peers - self.number_of_monitors): message = self.splitter_socket.recv(common.PEER_ID_LENGTH + struct.calcsize("4sHH")) peer_id = message[: common.PEER_ID_LENGTH] IP_addr, port, port_step = struct.unpack("4sHH", message[common.PEER_ID_LENGTH :]) # Ojo, !H IP_addr = socket.inet_ntoa(IP_addr) port = socket.ntohs(port) port_step = socket.ntohs(port_step) peer = (IP_addr, port) self.initial_peer_list.append(peer_id) # Try different probable ports for the existing peer probable_source_ports = [] if port_step > 0: number_of_ports = min((65536 - port) // port_step, common.MAX_PREDICTED_PORTS) probable_source_ports = list( range(port + port_step, port + (number_of_ports + 1) * port_step, port_step) ) self.say_hello(peer, probable_source_ports) if __debug__: print("NTS: [hello] sent to %s" % (peer,)) # Directly start packet sending self.hello_messages_event.set() sys.stdout.write(Color.green) _print_("NTS: List of peers received") sys.stdout.write(Color.none)
def receive_the_header(self): # {{{ header_size_in_bytes = self.header_size_in_chunks * self.chunk_size received = 0 data = "" while received < header_size_in_bytes: data = self.splitter_socket.recv(header_size_in_bytes - received) received += len(data) _print_("Percentage of header received = {:.2%}".format((1.0 * received) / header_size_in_bytes)) try: self.player_socket.sendall(data) except Exception as e: print(e) print("error sending data to the player") print("len(data) =", len(data)) time.sleep(1) _print_("received bytes:", received, "\r", end="") _print_("Received", received, "bytes of header")
def receive_the_header(self): # {{{ header_size_in_bytes = self.header_size_in_chunks * self.chunk_size received = 0 data = "" while received < header_size_in_bytes: data = self.splitter_socket.recv(header_size_in_bytes - received) received += len(data) _print_("Percentage of header received = {:.2%}".format( (1.0 * received) / header_size_in_bytes)) try: self.player_socket.sendall(data) except Exception as e: print(e) print("error sending data to the player") print("len(data) =", len(data)) time.sleep(1) _print_("received bytes:", received, "\r", end="") _print_("Received", received, "bytes of header")
def connect_to_the_splitter(self): # {{{ Setup "splitter" and "splitter_socket" # Nota: Ahora no reconvertimos de TCP a UDP! self.splitter_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.splitter = (self.SPLITTER_ADDR, self.SPLITTER_PORT) print("use_localhost=", self.USE_LOCALHOST) if self.USE_LOCALHOST: my_ip = '0.0.0.0' # Or '127.0.0.1' #my_ip = '127.0.0.1' else: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("gmail.com", 80)) #my_ip = socket.gethostbyname(socket.gethostname()) my_ip = s.getsockname()[0] s.close() _print_("Connecting to the splitter at", self.splitter, "from", my_ip) if self.PORT != 0: try: self.splitter_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) except Exception as e: print(e) pass sys.stdout.write(Color.purple) _print_("I'm using port the port", self.PORT) sys.stdout.write(Color.none) self.splitter_socket.bind((my_ip, self.PORT)) else: self.splitter_socket.bind((my_ip, 0)) try: self.splitter_socket.connect(self.splitter) except Exception as e: print(e) sys.exit("Sorry. Can't connect to the splitter at " + str(self.splitter)) _print_("Connected to the splitter at", self.splitter)
def connect_to_the_splitter(self): # {{{ Setup "splitter" and "splitter_socket" # Nota: Ahora no reconvertimos de TCP a UDP! self.splitter_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.splitter = (self.SPLITTER_ADDR, self.SPLITTER_PORT) print("use_localhost=", self.USE_LOCALHOST) if self.USE_LOCALHOST: my_ip = "0.0.0.0" # Or '127.0.0.1' # my_ip = '127.0.0.1' else: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(self.splitter) # my_ip = socket.gethostbyname(socket.gethostname()) my_ip = s.getsockname()[0] s.close() _print_("Connecting to the splitter at", self.splitter, "from", my_ip) if self.PORT != 0: try: self.splitter_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) except Exception as e: print(e) pass sys.stdout.write(Color.purple) _print_("I'm using port the port", self.PORT) sys.stdout.write(Color.none) self.splitter_socket.bind((my_ip, self.PORT)) else: self.splitter_socket.bind((my_ip, 0)) try: self.splitter_socket.connect(self.splitter) except Exception as e: print(e) sys.exit("Sorry. Can't connect to the splitter at " + str(self.splitter)) _print_("Connected to the splitter at", self.splitter)
def __init__(self): # {{{ colorama.init() try: colorama.init() except Exception: pass # }}} # {{{ Running in debug/release mode _print_("Running in", end=' ') if __debug__: print("debug mode") else: print("release mode") # }}} # {{{ Arguments handling parser = argparse.ArgumentParser( description= 'This is the splitter node of a P2PSP team. The splitter is in charge of defining the Set or Rules (SoR) that will control the team. By default, DBS (unicast transmissions) will be used.' ) #parser.add_argument('--splitter_addr', help='IP address to serve (TCP) the peers. (Default = "{}")'.format(Splitter_IMS.SPLITTER_ADDR)) <- no ahora parser.add_argument( '--buffer_size', help='size of the video buffer in blocks. Default = {}.'.format( Splitter_IMS.BUFFER_SIZE)) parser.add_argument( '--channel', help= 'Name of the channel served by the streaming source. Default = "{}".' .format(Splitter_IMS.CHANNEL)) parser.add_argument('--chunk_size', help='Chunk size in bytes. Default = {}.'.format( Splitter_IMS.CHUNK_SIZE)) parser.add_argument( '--header_size', help='Size of the header of the stream in chunks. Default = {}.'. format(Splitter_IMS.HEADER_SIZE)) parser.add_argument( '--max_chunk_loss', help= 'Maximum number of lost chunks for an unsupportive peer. Makes sense only in unicast mode. Default = {}.' .format(Splitter_DBS.MAX_CHUNK_LOSS)) parser.add_argument( '--max_number_of_monitor_peers', help= 'Maxium number of monitors in the team. The first connecting peers will automatically become monitors. Default = "{}".' .format(Splitter_DBS.MONITOR_NUMBER)) parser.add_argument( '--mcast_addr', help= 'IP multicast address used to serve the chunks. Makes sense only in multicast mode. Default = "{}".' .format(Splitter_IMS.MCAST_ADDR)) parser.add_argument( '--port', help='Port to serve the peers. Default = "{}".'.format( Splitter_IMS.PORT)) parser.add_argument( '--source_addr', help= 'IP address or hostname of the streaming server. Default = "{}".'. format(Splitter_IMS.SOURCE_ADDR)) parser.add_argument( '--source_port', help='Port where the streaming server is listening. Default = {}.'. format(Splitter_IMS.SOURCE_PORT)) parser.add_argument( "--IMS", action="store_true", help= "Uses the IP multicast infrastructure, if available. IMS mode is incompatible with ACS, LRS, DIS and NTS modes." ) parser.add_argument("--NTS", action="store_true", help="Enables NAT traversal.") parser.add_argument("--ACS", action="store_true", help="Enables Adaptive Chunk-rate.") parser.add_argument("--LRS", action="store_true", help="Enables Lost chunk Recovery.") parser.add_argument("--DIS", action="store_true", help="Enables Data Integrity check.") parser.add_argument('--strpe', nargs='+', type=str, help='Selects STrPe model for DIS') parser.add_argument('--strpeds', nargs='+', type=str, help='Selects STrPe-DS model for DIS') parser.add_argument( '--strpeds_majority_decision', help='Sets majority decision ratio for STrPe-DS model.') parser.add_argument( '--strpe_log', help='Logging STrPe & STrPe-DS specific data to file.') parser.add_argument( '--TTL', help='Time To Live of the multicast messages. Default = {}.'. format(Splitter_IMS.TTL)) try: argcomplete.autocomplete(parser) except Exception: pass args = parser.parse_args() #args = parser.parse_known_args()[0] if args.buffer_size: Splitter_IMS.BUFFER_SIZE = int(args.buffer_size) _print_("Buffer size =", Splitter_IMS.BUFFER_SIZE) if args.channel: Splitter_IMS.CHANNEL = args.channel _print_("Channel = \"" + Splitter_IMS.CHANNEL + "\"") if args.chunk_size: Splitter_IMS.CHUNK_SIZE = int(args.chunk_size) _print_("Chunk size =", Splitter_IMS.CHUNK_SIZE) if args.header_size: Splitter_IMS.HEADER_SIZE = int(args.header_size) _print_("Header size =", Splitter_IMS.HEADER_SIZE) if args.port: Splitter_IMS.PORT = int(args.port) _print_("Listening port =", Splitter_IMS.PORT) if args.source_addr: Splitter_IMS.SOURCE_ADDR = socket.gethostbyname(args.source_addr) _print_("Source address = ", Splitter_IMS.SOURCE_ADDR) if args.source_port: Splitter_IMS.SOURCE_PORT = int(args.source_port) _print_("Source port =", Splitter_IMS.SOURCE_PORT) if args.IMS: _print_("IP multicast (IMS) mode selected") if args.mcast_addr: Splitter_IMS.MCAST_ADDR = args.mcast_addr _print_("Multicast address =", Splitter_IMS.MCAST_ADDR) if args.TTL: Splitter_IMS.TTL = args.TTL _print_("Multicast TTL =", Splitter_IMS.TTL) splitter = Splitter_IMS() splitter.peer_list = [] # No peer_list is used in IMS. else: _print_("IP unicast mode selected") if args.max_chunk_loss: Splitter_DBS.MAX_CHUNK_LOSS = int(args.max_chunk_loss) _print_("Maximun chunk loss =", Splitter_DBS.MAX_CHUNK_LOSS) if args.max_number_of_monitor_peers: Splitter_DBS.MONITOR_NUMBER = int(args.monitor_number) _print_("Maximun number of monitor peers =", Splitter_DBS.MONITOR_NUMBER) splitter = Splitter_DBS() if args.NTS: from splitter_nts import Splitter_NTS splitter = Splitter_NTS(splitter) _print_("NTS enabled") if args.ACS: splitter = Splitter_ACS(splitter) _print_("ACS enabled") if args.LRS: from splitter_lrs import Splitter_LRS splitter = Splitter_LRS(splitter) _print_("LRS enabled") if args.DIS: from splitter_strpe import StrpeSplitter from splitter_strpeds import StrpeDsSplitter _print_("DIS enabled") if args.strpe: splitter = Splitter_strpe(splitter) print("strpe mode selected") for peer in args.strpe: splitter.add_trusted_peer(peer) if args.strpeds: splitter = StrpeSplitter(splitter) _print_("strpeds mode selected") for peer in args.strpeds: splitter.add_trusted_peer(peer) if args.strpeds_majority_decision: _print_("strpeds_majority_decision mode selected") splitter = Splitter_strpeds_majority_decision(splitter) splitter.setMajorityRatio( float(args.strpeds_majority_decision)) if args.strpe_log: splitter.LOGGING = True splitter.LOG_FILE = open(strpe_log, 'w', 0) #splitter = Splitter_ACS() # if (args.strpe): # splitter = self.init_strpe_splitter('strpe', args.strpe, args.strpe_log) # elif (args.strpeds): # splitter = self.init_strpe_splitter('strpeds', args.strpeds, args.strpe_log) # if args.strpeds_majority_decision: # splitter.setMajorityRatio(float(args.strpeds_majority_decision)) # else: # splitter = Splitter_LRS() # }}} # {{{ Run! splitter.start() # {{{ Prints information until keyboard interruption print(" | Received | Sent | Number losses/ losses") print( " Time | (kbps) | (kbps) | peers (peer) sents threshold period kbps" ) print( "---------+-----------+-----------+-----------------------------------..." ) last_sendto_counter = splitter.sendto_counter last_recvfrom_counter = splitter.recvfrom_counter while splitter.alive: try: time.sleep(1) chunks_sendto = splitter.sendto_counter - last_sendto_counter kbps_sendto = (chunks_sendto * splitter.CHUNK_SIZE * 8) / 1000 chunks_recvfrom = splitter.recvfrom_counter - last_recvfrom_counter kbps_recvfrom = (chunks_recvfrom * splitter.CHUNK_SIZE * 8) / 1000 last_sendto_counter = splitter.sendto_counter last_recvfrom_counter = splitter.recvfrom_counter sys.stdout.write(Color.none) _print_("|" + repr(kbps_recvfrom).rjust(10) + " |" + repr(kbps_sendto).rjust(10), end=" | ") #print('%5d' % splitter.chunk_number, end=' ') sys.stdout.write(Color.cyan) print(len(splitter.peer_list), end=' ') if not __debug__: counter = 0 for p in splitter.peer_list: if not __debug__: if counter > 10: break counter += 1 sys.stdout.write(Color.blue) print(p, end=' ') sys.stdout.write(Color.red) print(str('%3d' % splitter.losses[p]) + '/' + str('%3d' % chunks_sendto), splitter.MAX_CHUNK_LOSS, end=' ') if splitter is Splitter_ACS: try: sys.stdout.write(Color.yellow) print('%3d' % splitter.period[p], end=' ') sys.stdout.write(Color.purple) print(repr( (splitter.number_of_sent_chunks_per_peer[p] * splitter.CHUNK_SIZE * 8) / 1000).rjust(10), end=' ') splitter.number_of_sent_chunks_per_peer[p] = 0 except KeyError as e: print("!", e, "--") print(splitter.period[p]) pass sys.stdout.write(Color.none) print('', end=' ') print() except KeyboardInterrupt: print('Keyboard interrupt detected ... Exiting!') # Say to daemon threads that the work has been finished, splitter.alive = False # Wake up the "moderate_the_team" daemon, which is # waiting in a recvfrom(). if not args.IMS: splitter.say_goodbye(("127.0.0.1", splitter.PORT), splitter.team_socket) # Wake up the "handle_arrivals" daemon, which is waiting # in a accept(). sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(("127.0.0.1", splitter.PORT)) sock.recv(struct.calcsize("4sH")) # Multicast channel sock.recv(struct.calcsize("H")) # Header size sock.recv(struct.calcsize("H")) # Chunk size sock.recv(splitter.CHUNK_SIZE * splitter.HEADER_SIZE) # Header sock.recv(struct.calcsize("H")) # Buffer size if args.IMS: number_of_peers = 0 else: number_of_peers = socket.ntohs( struct.unpack("H", sock.recv(struct.calcsize("H")))[0]) print("Number of peers =", number_of_peers) # Receive the list while number_of_peers > 0: sock.recv(struct.calcsize("4sH")) number_of_peers -= 1 # Breaks this thread and returns to the parent process # (usually, the shell). break
def __init__(self): try: colorama.init() except Exception: pass _print_("Running in", end=' ') if __debug__: print("debug mode") else: print("release mode") peer = PeerSTRPEDS() parser = argparse.ArgumentParser(description='This is the peer node of a P2PSP team.') parser.add_argument('--enable_chunk_loss', help='Forces a lost of chunks') parser.add_argument('--max_chunk_debt', help='The maximun number of times that other peer can not send a chunk to this peer. Defaut = {}'.format(peer.max_chunk_debt)) parser.add_argument('--player_port', help='Port to communicate with the player. Default = {}'.format(peer.player_port)) parser.add_argument('--port_step', help='Source port step forced when behind a sequentially port allocating NAT (conflicts with --chunk_loss_period). Default = {}')#.format(Symsp_Peer.PORT_STEP)) parser.add_argument('--splitter_addr', help='IP address or hostname of the splitter. Default = {}.'.format(peer.splitter_addr)) parser.add_argument('--splitter_port', help='Listening port of the splitter. Default = {}.'.format(peer.splitter_port)) parser.add_argument('--port', help='Port to communicate with the peers. Default {} (the OS will chose it).'.format(peer.team_port)) parser.add_argument('--use_localhost', action="store_true", help='Forces the peer to use localhost instead of the IP of the adapter to connect to the splitter. Notice that in this case, peers that run outside of the host will not be able to communicate with this peer.') parser.add_argument('--malicious', action="store_true", help='Enables the malicious activity for peer.') parser.add_argument('--persistent', action="store_true", help='Forces the peer to send poisoned chunks to other peers.') parser.add_argument('--on_off_ratio', help='Enables on-off attack and sets ratio for on off (from 1 to 100)') parser.add_argument('--selective', nargs='+', type=str, help='Enables selective attack for given set of peers.') parser.add_argument('--bad_mouth', nargs='+', type=str, help='Enables Bad Mouth attack for given set of peers.') parser.add_argument('--trusted', action="store_true", help='Forces the peer to send hashes of chunks to splitter') parser.add_argument('--checkall', action="store_true", help='Forces the peer to send hashes of every chunks to splitter (works only with trusted option)') parser.add_argument('--strpeds', action="store_true", help='Enables STrPe-DS') parser.add_argument('--strpeds_log', help='Logging STrPe & STrPe-DS specific data to file.') parser.add_argument('--show_buffer', action="store_true", help='Shows the status of the buffer of chunks.') parser.add_argument('--monitor', action="store_true", help='Enables monitor') parser.add_argument('--mptr', help='Number of rounds attacking a peer individually before all attack mode.') try: argcomplete.autocomplete(parser) except Exception: pass args = parser.parse_args() if args.malicious: peer = MaliciousPeer(PeerSTRPEDS()) # {{{ Args handling and object instantiation if args.splitter_addr: peer.splitter_addr = socket.gethostbyname(args.splitter_addr) _print_('Splitter address =', peer.splitter_addr) if args.splitter_port: peer.splitter_port = int(args.splitter_port) _print_('Splitter port =', peer.splitter_port) if args.port: peer.team_port = int(args.port) _print_('(Peer) PORT =', peer.team_port) if args.player_port: peer.player_port = int(args.player_port) _print_('Listening port (player) =', peer.player_port) if args.max_chunk_debt: peer.max_chunk_debt = int(args.max_chunk_debt) _print_('Maximun chunk debt =', peer.max_chunk_debt) if args.use_localhost: peer.use_localhost = True _print_('Using localhost address') peer.WaitForThePlayer() peer.ConnectToTheSplitter() peer.ReceiveTheMcastEndpoint() peer.ReceiveTheHeaderSize() peer.ReceiveTheChunkSize() peer.ReceiveTheHeader() peer.ReceiveTheBufferSize() _print_("Using IP Multicast address =", peer.mcast_addr) if args.show_buffer: peer.show_buffer = True # A multicast address is always received, even for DBS peers. if peer.mcast_addr == "0.0.0.0": # {{{ IP unicast mode. peer.ListenToTheTeam() _print_("Peer DBS enabled") peer.ReceiveMyEndpoint() peer.ReceiveMagicFlags() #_print_("Magic flags =", bin(peer.magic_flags)) peer.ReceiveTheNumberOfPeers() _print_("Number of peers in the team (excluding me) =", peer.GetNumberOfPeers()) _print_("Am I a monitor peer? =", peer.AmIAMonitor()) peer.ReceiveTheListOfPeers() _print_("List of peers received") # After receiving the list of peers, the peer can check # whether is a monitor peer or not (only the first # arriving peers are monitors) if peer.AmIAMonitor(): #peer = Monitor_DBS(peer) _print_("Monitor DBS enabled") # The peer is a monitor. Now it's time to know the sets of rules that control this team. else: _print_("Peer DBS enabled") # The peer is a normal peer. Let's know the sets of rules that control this team. ''' if args.strpeds: peer = Peer_StrpeDs(peer) peer.receive_dsa_key() if args.malicious and not args.strpeds: # workaround for malicous strpeds peer peer = MaliciousPeer(peer) if args.persistent: peer.setPersistentAttack(True) if args.on_off_ratio: peer.setOnOffAttack(True, int(args.on_off_ratio)) if args.selective: peer.setSelectiveAttack(True, args.selective) ''' if args.malicious: peer.setChunkSize(peer.chunk_size) peer.firstMainTarget() if args.persistent: peer.setPersistentAttack(True) if args.on_off_ratio: peer.setOnOffAttack(True, int(args.on_off_ratio)) if args.selective: peer.setSelectiveAttack(True, args.selective) if args.bad_mouth: peer.setBadMouthAttack(True, args.bad_mouth) if args.mptr: peer.setMPTR(args.mptr) ''' if args.trusted: peer = TrustedPeer(peer) if args.checkall: peer.setCheckAll(True) ''' if args.strpeds_log != None: peer.SetLogging(True) peer.SetLogFile(args.strpeds_log) print(Color.red, "Receiving DSA Key", Color.none) peer.ReceiveDsaKey() # }}} else: # {{{ IP multicast mode peer.ListenToTheTeam() # }}} # }}} #print("Created new peer of type %s\n" % peer.__class__.__name__) # {{{ Run! peer.DisconnectFromTheSplitter() peer.BufferData() _print_("RUN") threading.Thread(target=peer.Run, args=()).start() print("threading!") self.console(peer)
def __init__(self): try: colorama.init() except Exception: pass _print_("Running in", end=' ') if __debug__: print("debug mode") else: print("release mode") # {{{ Args handling and object instantiation parser = argparse.ArgumentParser( description='This is the peer node of a P2PSP team.') parser.add_argument('--enable_chunk_loss', help='Forces a lost of chunks') parser.add_argument( '--max_chunk_debt', help= 'The maximun number of times that other peer can not send a chunk to this peer. Defaut = {}' .format(Peer_DBS.MAX_CHUNK_DEBT)) parser.add_argument( '--player_port', help='Port to communicate with the player. Default = {}'.format( Peer_IMS.PLAYER_PORT)) parser.add_argument( '--port_step', help= 'Source port step forced when behind a sequentially port allocating NAT (conflicts with --chunk_loss_period). Default = {}' .format(Symsp_Peer.PORT_STEP)) parser.add_argument( '--splitter_addr', help='IP address or hostname of the splitter. Default = {}.'. format(Peer_IMS.SPLITTER_ADDR)) parser.add_argument( '--splitter_port', help='Listening port of the splitter. Default = {}.'.format( Peer_IMS.SPLITTER_PORT)) parser.add_argument( '--port', help= 'Port to communicate with the peers. Default {} (the OS will chose it).' .format(Peer_IMS.PORT)) parser.add_argument( '--use_localhost', action="store_true", help= 'Forces the peer to use localhost instead of the IP of the adapter to connect to the splitter. Notice that in this case, peers that run outside of the host will not be able to communicate with this peer.' ) parser.add_argument('--malicious', action="store_true", help='Enables the malicious activity for peer.') parser.add_argument( '--persistent', action="store_true", help='Forces the peer to send poisoned chunks to other peers.') parser.add_argument( '--on_off_ratio', help= 'Enables on-off attack and sets ratio for on off (from 1 to 100)') parser.add_argument( '--selective', nargs='+', type=str, help='Enables selective attack for given set of peers.') parser.add_argument( '--bad_mouth', nargs='+', type=str, help='Enables Bad Mouth attack for given set of peers.') parser.add_argument( '--trusted', action="store_true", help='Forces the peer to send hashes of chunks to splitter') parser.add_argument( '--checkall', action="store_true", help= 'Forces the peer to send hashes of every chunks to splitter (works only with trusted option)' ) parser.add_argument('--strpeds', action="store_true", help='Enables STrPe-DS') parser.add_argument( '--strpe_log', help='Logging STrPe & STrPe-DS specific data to file.') parser.add_argument('--show_buffer', action="store_true", help='Shows the status of the buffer of chunks.') try: argcomplete.autocomplete(parser) except Exception: pass #args = parser.parse_known_args()[0] args = parser.parse_args() if args.splitter_addr: Peer_IMS.SPLITTER_ADDR = socket.gethostbyname(args.splitter_addr) _print_('Splitter address =', Peer_IMS.SPLITTER_ADDR) if args.splitter_port: Peer_IMS.SPLITTER_PORT = int(args.splitter_port) _print_('Splitter port =', Peer_IMS.SPLITTER_PORT) if args.port: Peer_IMS.PORT = int(args.port) _print_('(Peer) PORT =', Peer_IMS.PORT) if args.player_port: Peer_IMS.PLAYER_PORT = int(args.player_port) _print_('Listening port (player) =', Peer_IMS.PLAYER_PORT) if args.max_chunk_debt: Peer_DBS.MAX_CHUNK_DEBT = int(args.max_chunk_debt) _print_('Maximun chunk debt =', Peer_DBS.MAX_CHUNK_DEBT) if args.use_localhost: Peer_IMS.USE_LOCALHOST = True _print_('Using localhost address') peer = Peer_IMS() peer.wait_for_the_player() peer.connect_to_the_splitter() peer.receive_the_mcast_endpoint() peer.receive_the_header_size() peer.receive_the_chunk_size() peer.receive_the_header() peer.receive_the_buffer_size() _print_("Using IP Multicast address =", peer.mcast_addr) if args.show_buffer: Peer_IMS.SHOW_BUFFER = True # A multicast address is always received, even for DBS peers. if peer.mcast_addr == "0.0.0.0": # {{{ IP unicast mode. peer = Peer_DBS(peer) peer.receive_my_endpoint() peer.receive_the_number_of_peers() _print_("Number of peers in the team (excluding me) =", peer.number_of_peers) _print_("Am I a monitor peer? =", peer.am_i_a_monitor()) peer.listen_to_the_team() peer.receive_the_list_of_peers() _print_("List of peers received") peer.receive_magic_flags() _print_("Magic flags =", peer.magic_flags) # After receiving the list of peers, the peer can check # whether is a monitor peer or not (only the first # arriving peers are monitors) if peer.am_i_a_monitor(): from core.monitor_dbs import Monitor_DBS peer = Monitor_DBS(peer) _print_("Monitor DBS") # The peer is a monitor. Now it's time to know the sets of rules that control this team. if (peer.magic_flags & common.LRS): from core.monitor_lrs import Monitor_LRS peer = Monitor_LSR(peer) _print_("Monitor LRS") if (peer.magic_flags & common.NTS): from core.monitor_nts import Monitor_NTS peer = Monitor_NTS(peer) _print_("Monitor NTS") else: peer = Peer_DBS(peer) _print_("Peer DBS") # The peer is a normal peer. Let's know the sets of rules that control this team. if (peer.magic_flags & common.ACS): peer = Peer_ACR(peer) _print_("Peer ACS") if (peer.magic_flags & common.LRS): peer = Peer_LSR(peer) _print_("Peer LRS") if (peer.magic_flags & common.NTS): from peer_nts import Peer_NTS peer = Peeer_NTS(peer) _print_("Peer NTS") if args.enable_chunk_loss: if args.chunk_loss_period: Lossy_Peer.CHUNK_LOSS_PERIOD = int( args.chunk_loss_period) print('CHUNK_LOSS_PERIOD =', Lossy_Peer.CHUNK_LOSS_PERIOD) if int(args.chunk_loss_period) != 0: from lossy_peer import Lossy_Peer peer = Lossy_Peer(peer) if args.port_step: Symsp_Peer.PORT_STEP = int(args.port_step) print('PORT_STEP =', Symsp_Peer.PORT_STEP) if int(args.port_step) != 0: peer = Symsp_Peer(peer) if args.strpeds: from core.peer_strpeds import Peer_StrpeDs peer = Peer_StrpeDs(peer) peer.receive_dsa_key() if args.malicious and not args.strpeds: # workaround for malicous strpeds peer from core.malicious_peer import MaliciousPeer peer = MaliciousPeer(peer) if args.persistent: peer.setPersistentAttack(True) if args.on_off_ratio: peer.setOnOffAttack(True, int(args.on_off_ratio)) if args.selective: peer.setSelectiveAttack(True, args.selective) if args.malicious and args.strpeds: from core.peer_strpeds_malicious import Peer_StrpeDsMalicious peer = Peer_StrpeDsMalicious(peer) if args.persistent: peer.setPersistentAttack(True) if args.on_off_ratio: peer.setOnOffAttack(True, int(args.on_off_ratio)) if args.selective: peer.setSelectiveAttack(True, args.selective) if args.bad_mouth: peer.setBadMouthAttack(True, args.bad_mouth) if args.trusted: from core.trusted_peer import TrustedPeer peer = TrustedPeer(peer) if args.checkall: peer.setCheckAll(True) if args.strpe_log != None: peer.LOGGING = True peer.LOG_FILE = open(args.strpe_log, 'w', 0) # }}} else: # {{{ IP multicast mode peer.listen_to_the_team() # }}} # }}} # {{{ Run! peer.disconnect_from_the_splitter() peer.buffer_data() peer.start() print("+-----------------------------------------------------+") print("| Received = Received kbps, including retransmissions |") print("| Sent = Sent kbps |") print("| (Expected values are between parenthesis) |") print("------------------------------------------------------+") print() print( " Time | Received (Expected) | Sent (Expected) | Team description" ) print( "---------+-------------------------+--------------------------+-----------------..." ) last_chunk_number = peer.played_chunk if hasattr(peer, 'sendto_counter'): last_sendto_counter = 0 else: peer.sendto_counter = 0 last_sendto_counter = 0 if not hasattr(peer, 'peer_list'): peer.peer_list = [] last_recvfrom_counter = peer.recvfrom_counter while peer.player_alive: time.sleep(1) kbps_expected_recv = ((peer.played_chunk - last_chunk_number) * peer.chunk_size * 8) / 1000 last_chunk_number = peer.played_chunk kbps_recvfrom = ((peer.recvfrom_counter - last_recvfrom_counter) * peer.chunk_size * 8) / 1000 last_recvfrom_counter = peer.recvfrom_counter team_ratio = len(peer.peer_list) / (len(peer.peer_list) + 1.0) kbps_expected_sent = int(kbps_expected_recv * team_ratio) kbps_sendto = ((peer.sendto_counter - last_sendto_counter) * peer.chunk_size * 8) / 1000 last_sendto_counter = peer.sendto_counter try: if common.CONSOLE_MODE == False: from gi.repository import GObject try: from adapter import speed_adapter except ImportError as msg: pass GObject.idle_add(speed_adapter.update_widget, str(kbps_recvfrom) + ' kbps', str(kbps_sendto) + ' kbps', str(len(peer.peer_list) + 1)) except Exception as msg: pass if kbps_recvfrom > 0 and kbps_expected_recv > 0: nice = 100.0 / float( (float(kbps_expected_recv) / kbps_recvfrom) * (len(peer.peer_list) + 1)) else: nice = 0.0 _print_('|', end=Color.none) if kbps_expected_recv < kbps_recvfrom: sys.stdout.write(Color.red) elif kbps_expected_recv > kbps_recvfrom: sys.stdout.write(Color.green) print(repr(kbps_expected_recv).rjust(12), end=Color.none) print(('(' + repr(kbps_recvfrom) + ')').rjust(12), end=' | ') #print(("{:.1f}".format(nice)).rjust(6), end=' | ') #sys.stdout.write(Color.none) if kbps_expected_sent > kbps_sendto: sys.stdout.write(Color.red) elif kbps_expected_sent < kbps_sendto: sys.stdout.write(Color.green) print(repr(kbps_sendto).rjust(12), end=Color.none) print(('(' + repr(kbps_expected_sent) + ')').rjust(12), end=' | ') #sys.stdout.write(Color.none) #print(repr(nice).ljust(1)[:6], end=' ') print(len(peer.peer_list), end=' ') counter = 0 for p in peer.peer_list: if (counter < 5): print(p, end=' ') counter += 1 else: break print() try: if common.CONSOLE_MODE == False: GObject.idle_add(speed_adapter.update_widget, str(0) + ' kbps', str(0) + ' kbps', str(0)) except Exception as msg: pass
def _p_(*args, **kwargs): """Colorize the output.""" #sys.stdout.write(Common.DBS) _print_("DBS (malicious):", *args) sys.stdout.write(Color.none)
def __init__(self): try: colorama.init() except Exception: pass _print_("Running in", end=' ') if __debug__: print("debug mode") else: print("release mode") # {{{ Args handling and object instantiation parser = argparse.ArgumentParser(description='This is the peer node of a P2PSP team.') parser.add_argument('--enable_chunk_loss', help='Forces a lost of chunks') parser.add_argument('--max_chunk_debt', help='The maximun number of times that other peer can not send a chunk to this peer. Defaut = {}'.format(Peer_DBS.MAX_CHUNK_DEBT)) parser.add_argument('--player_port', help='Port to communicate with the player. Default = {}'.format(Peer_IMS.PLAYER_PORT)) parser.add_argument('--port_step', help='Source port step forced when behind a sequentially port allocating NAT (conflicts with --chunk_loss_period). Default = {}'.format(Symsp_Peer.PORT_STEP)) parser.add_argument('--splitter_addr', help='IP address or hostname of the splitter. Default = {}.'.format(Peer_IMS.SPLITTER_ADDR)) parser.add_argument('--splitter_port', help='Listening port of the splitter. Default = {}.'.format(Peer_IMS.SPLITTER_PORT)) parser.add_argument('--port', help='Port to communicate with the peers. Default {} (the OS will chose it).'.format(Peer_IMS.PORT)) parser.add_argument('--use_localhost', action="store_true", help='Forces the peer to use localhost instead of the IP of the adapter to connect to the splitter. Notice that in this case, peers that run outside of the host will not be able to communicate with this peer.') parser.add_argument('--malicious', action="store_true", help='Enables the malicious activity for peer.') parser.add_argument('--persistent', action="store_true", help='Forces the peer to send poisoned chunks to other peers.') parser.add_argument('--on_off_ratio', help='Enables on-off attack and sets ratio for on off (from 1 to 100)') parser.add_argument('--selective', nargs='+', type=str, help='Enables selective attack for given set of peers.') parser.add_argument('--bad_mouth', nargs='+', type=str, help='Enables Bad Mouth attack for given set of peers.') parser.add_argument('--trusted', action="store_true", help='Forces the peer to send hashes of chunks to splitter') parser.add_argument('--checkall', action="store_true", help='Forces the peer to send hashes of every chunks to splitter (works only with trusted option)') parser.add_argument('--strpeds', action="store_true", help='Enables STrPe-DS') parser.add_argument('--strpe_log', help='Logging STrPe & STrPe-DS specific data to file.') parser.add_argument('--show_buffer', action="store_true", help='Shows the status of the buffer of chunks.') try: argcomplete.autocomplete(parser) except Exception: pass #args = parser.parse_known_args()[0] args = parser.parse_args() if args.splitter_addr: Peer_IMS.SPLITTER_ADDR = socket.gethostbyname(args.splitter_addr) _print_('Splitter address =', Peer_IMS.SPLITTER_ADDR) if args.splitter_port: Peer_IMS.SPLITTER_PORT = int(args.splitter_port) _print_('Splitter port =', Peer_IMS.SPLITTER_PORT) if args.port: Peer_IMS.PORT = int(args.port) _print_('(Peer) PORT =', Peer_IMS.PORT) if args.player_port: Peer_IMS.PLAYER_PORT = int(args.player_port) _print_('Listening port (player) =', Peer_IMS.PLAYER_PORT) if args.max_chunk_debt: Peer_DBS.MAX_CHUNK_DEBT = int(args.max_chunk_debt) _print_('Maximun chunk debt =', Peer_DBS.MAX_CHUNK_DEBT) if args.use_localhost: Peer_IMS.USE_LOCALHOST = True _print_('Using localhost address') peer = Peer_IMS() peer.wait_for_the_player() peer.connect_to_the_splitter() peer.receive_the_mcast_endpoint() peer.receive_the_header_size() peer.receive_the_chunk_size() peer.receive_the_header() peer.receive_the_buffer_size() _print_("Using IP Multicast address =", peer.mcast_addr) if args.show_buffer: Peer_IMS.SHOW_BUFFER = True # A multicast address is always received, even for DBS peers. if peer.mcast_addr == "0.0.0.0": # {{{ IP unicast mode. peer = Peer_DBS(peer) peer.receive_my_endpoint() peer.receive_the_number_of_peers() _print_("Number of peers in the team (excluding me) =", peer.number_of_peers) _print_("Am I a monitor peer? =", peer.am_i_a_monitor()) peer.listen_to_the_team() peer.receive_the_list_of_peers() _print_("List of peers received") peer.receive_magic_flags() _print_("Magic flags =", peer.magic_flags) # After receiving the list of peers, the peer can check # whether is a monitor peer or not (only the first # arriving peers are monitors) if peer.am_i_a_monitor(): from core.monitor_dbs import Monitor_DBS peer = Monitor_DBS(peer) _print_("Monitor DBS") # The peer is a monitor. Now it's time to know the sets of rules that control this team. if (peer.magic_flags & common.LRS): from core.monitor_lrs import Monitor_LRS peer = Monitor_LSR(peer) _print_("Monitor LRS") if (peer.magic_flags & common.NTS): from core.monitor_nts import Monitor_NTS peer = Monitor_NTS(peer) _print_("Monitor NTS") else: peer = Peer_DBS(peer) _print_("Peer DBS") # The peer is a normal peer. Let's know the sets of rules that control this team. if (peer.magic_flags & common.ACS): peer = Peer_ACR(peer) _print_("Peer ACS") if (peer.magic_flags & common.LRS): peer = Peer_LSR(peer) _print_("Peer LRS") if (peer.magic_flags & common.NTS): from peer_nts import Peer_NTS peer = Peeer_NTS(peer) _print_("Peer NTS") if args.enable_chunk_loss: if args.chunk_loss_period: Lossy_Peer.CHUNK_LOSS_PERIOD = int(args.chunk_loss_period) print('CHUNK_LOSS_PERIOD =', Lossy_Peer.CHUNK_LOSS_PERIOD) if int(args.chunk_loss_period) != 0: from lossy_peer import Lossy_Peer peer = Lossy_Peer(peer) if args.port_step: Symsp_Peer.PORT_STEP = int(args.port_step) print('PORT_STEP =', Symsp_Peer.PORT_STEP) if int(args.port_step) != 0: peer = Symsp_Peer(peer) if args.strpeds: from core.peer_strpeds import Peer_StrpeDs peer = Peer_StrpeDs(peer) peer.receive_dsa_key() if args.malicious and not args.strpeds: # workaround for malicous strpeds peer from core.malicious_peer import MaliciousPeer peer = MaliciousPeer(peer) if args.persistent: peer.setPersistentAttack(True) if args.on_off_ratio: peer.setOnOffAttack(True, int(args.on_off_ratio)) if args.selective: peer.setSelectiveAttack(True, args.selective) if args.malicious and args.strpeds: from core.peer_strpeds_malicious import Peer_StrpeDsMalicious peer = Peer_StrpeDsMalicious(peer) if args.persistent: peer.setPersistentAttack(True) if args.on_off_ratio: peer.setOnOffAttack(True, int(args.on_off_ratio)) if args.selective: peer.setSelectiveAttack(True, args.selective) if args.bad_mouth: peer.setBadMouthAttack(True, args.bad_mouth) if args.trusted: from core.trusted_peer import TrustedPeer peer = TrustedPeer(peer) if args.checkall: peer.setCheckAll(True) if args.strpe_log != None: peer.LOGGING = True peer.LOG_FILE = open(args.strpe_log, 'w', 0) # }}} else: # {{{ IP multicast mode peer.listen_to_the_team() # }}} # }}} # {{{ Run! peer.disconnect_from_the_splitter() peer.buffer_data() peer.start() print("+-----------------------------------------------------+") print("| Received = Received kbps, including retransmissions |") print("| Sent = Sent kbps |") print("| (Expected values are between parenthesis) |") print("------------------------------------------------------+") print() print(" Time | Received (Expected) | Sent (Expected) | Team description") print("---------+-------------------------+--------------------------+-----------------...") last_chunk_number = peer.played_chunk if hasattr(peer, 'sendto_counter'): last_sendto_counter = 0 else: peer.sendto_counter = 0 last_sendto_counter = 0 if not hasattr(peer, 'peer_list'): peer.peer_list = [] last_recvfrom_counter = peer.recvfrom_counter while peer.player_alive: time.sleep(1) kbps_expected_recv = ((peer.played_chunk - last_chunk_number) * peer.chunk_size * 8) / 1000 last_chunk_number = peer.played_chunk kbps_recvfrom = ((peer.recvfrom_counter - last_recvfrom_counter) * peer.chunk_size * 8) / 1000 last_recvfrom_counter = peer.recvfrom_counter team_ratio = len(peer.peer_list) /(len(peer.peer_list) + 1.0) kbps_expected_sent = int(kbps_expected_recv*team_ratio) kbps_sendto = ((peer.sendto_counter - last_sendto_counter) * peer.chunk_size * 8) / 1000 last_sendto_counter = peer.sendto_counter try: if common.CONSOLE_MODE == False : from gi.repository import GObject try: from adapter import speed_adapter except ImportError as msg: pass GObject.idle_add(speed_adapter.update_widget,str(kbps_recvfrom) + ' kbps' ,str(kbps_sendto) + ' kbps' ,str(len(peer.peer_list)+1)) except Exception as msg: pass if kbps_recvfrom > 0 and kbps_expected_recv > 0: nice = 100.0/float((float(kbps_expected_recv)/kbps_recvfrom)*(len(peer.peer_list)+1)) else: nice = 0.0 _print_('|', end=Color.none) if kbps_expected_recv < kbps_recvfrom: sys.stdout.write(Color.red) elif kbps_expected_recv > kbps_recvfrom: sys.stdout.write(Color.green) print(repr(kbps_expected_recv).rjust(12), end=Color.none) print(('(' + repr(kbps_recvfrom) + ')').rjust(12), end=' | ') #print(("{:.1f}".format(nice)).rjust(6), end=' | ') #sys.stdout.write(Color.none) if kbps_expected_sent > kbps_sendto: sys.stdout.write(Color.red) elif kbps_expected_sent < kbps_sendto: sys.stdout.write(Color.green) print(repr(kbps_sendto).rjust(12), end=Color.none) print(('(' + repr(kbps_expected_sent) + ')').rjust(12), end=' | ') #sys.stdout.write(Color.none) #print(repr(nice).ljust(1)[:6], end=' ') print(len(peer.peer_list), end=' ') counter = 0 for p in peer.peer_list: if (counter < 5): print(p, end=' ') counter += 1 else: break print() try: if common.CONSOLE_MODE == False : GObject.idle_add(speed_adapter.update_widget,str(0)+' kbps',str(0)+' kbps',str(0)) except Exception as msg: pass
def print_the_module_name(self): # {{{ sys.stdout.write(Color.yellow) _print_("Lossy Peer") sys.stdout.write(Color.none)
def __init__(self): try: colorama.init() except Exception: pass _print_("Running in", end=' ') if __debug__: print("debug mode") else: print("release mode") # {{{ Args parsing and instantiation parser = argparse.ArgumentParser( description='This is the splitter node of a P2PSP team.') #parser.add_argument('--splitter_addr', help='IP address to serve (TCP) the peers. (Default = "{}")'.format(Splitter_IMS.SPLITTER_ADDR)) <- no ahora parser.add_argument( '--buffer_size', help='size of the video buffer in blocks. Default = {}.'.format( Splitter_IMS.BUFFER_SIZE)) parser.add_argument( '--channel', help= 'Name of the channel served by the streaming source. Default = "{}".' .format(Splitter_IMS.CHANNEL)) parser.add_argument('--chunk_size', help='Chunk size in bytes. Default = {}.'.format( Splitter_IMS.CHUNK_SIZE)) parser.add_argument( '--header_size', help='Size of the header of the stream in chunks. Default = {}.'. format(Splitter_IMS.HEADER_SIZE)) parser.add_argument( '--max_chunk_loss', help= 'Maximum number of lost chunks for an unsupportive peer. Makes sense only in unicast mode. Default = {}.' .format(Splitter_DBS.MAX_CHUNK_LOSS)) parser.add_argument( "--mcast", action="store_true", help="Uses the IP multicast infrastructure, if available.") parser.add_argument( '--mcast_addr', help= 'IP multicast address used to serve the chunks. Makes sense only in multicast mode. Default = "{}".' .format(Splitter_IMS.MCAST_ADDR)) parser.add_argument( '--port', help='Port to serve the peers. Default = "{}".'.format( Splitter_IMS.PORT)) parser.add_argument( '--source_host', help= 'IP address or hostname of the streaming server. Default = "{}".'. format(Splitter_IMS.SOURCE_ADDR)) parser.add_argument( '--source_port', help='Port where the streaming server is listening. Default = {}.'. format(Splitter_IMS.SOURCE_PORT)) args = parser.parse_args() #args = parser.parse_known_args()[0] if args.buffer_size: Splitter_IMS.BUFFER_SIZE = int(args.buffer_size) if args.channel: Splitter_IMS.CHANNEL = args.channel if args.chunk_size: Splitter_IMS.CHUNK_SIZE = int(args.chunk_size) if args.header_size: Splitter_IMS.HEADER_SIZE = int(args.header_size) if args.port: Splitter_IMS.PORT = int(args.port) if args.source_host: Splitter_IMS.SOURCE_ADDR = socket.gethostbyname(args.source_host) if args.source_port: Splitter_IMS.SOURCE_PORT = int(args.source_port) if args.mcast: print("IP multicast mode selected") if args.mcast_addr: Splitter_IMS.MCAST_ADDR = args.mcast_addr splitter = Splitter_IMS() splitter.peer_list = [] else: if args.max_chunk_loss: Splitter_DBS.MAX_CHUNK_LOSS = int(args.max_chunk_loss) #splitter = Splitter_DBS() #splitter = Splitter_FNS() #splitter = Splitter_ACS() splitter = Splitter_LRS() # }}} # {{{ Run! splitter.start() # {{{ Prints information until keyboard interruption print(" | Received | Sent | Number losses/ losses") print( " Time | (kbps) | (kbps) | peers (peer) sents threshold period kbps" ) print( "---------+----------+-----------+-----------------------------------..." ) last_sendto_counter = splitter.sendto_counter last_recvfrom_counter = splitter.recvfrom_counter while splitter.alive: try: time.sleep(1) chunks_sendto = splitter.sendto_counter - last_sendto_counter kbps_sendto = (chunks_sendto * splitter.CHUNK_SIZE * 8) / 1000 chunks_recvfrom = splitter.recvfrom_counter - last_recvfrom_counter kbps_recvfrom = (chunks_recvfrom * splitter.CHUNK_SIZE * 8) / 1000 last_sendto_counter = splitter.sendto_counter last_recvfrom_counter = splitter.recvfrom_counter sys.stdout.write(Color.none) _print_("|" + repr(kbps_recvfrom).rjust(10) + "|" + repr(kbps_sendto).rjust(10), end=" | ") #print('%5d' % splitter.chunk_number, end=' ') sys.stdout.write(Color.cyan) print(len(splitter.peer_list), end=' ') if not __debug__: counter = 0 for p in splitter.peer_list: if not __debug__: if counter > 10: break counter += 1 sys.stdout.write(Color.blue) print(p, end=' ') sys.stdout.write(Color.red) print(str('%3d' % splitter.losses[p]) + '/' + str('%3d' % chunks_sendto), splitter.MAX_CHUNK_LOSS, end=' ') try: sys.stdout.write(Color.yellow) print('%3d' % splitter.period[p], end=' ') sys.stdout.write(Color.purple) print(repr( (splitter.number_of_sent_chunks_per_peer[p] * splitter.CHUNK_SIZE * 8) / 1000).rjust(4), end=' ') splitter.number_of_sent_chunks_per_peer[p] = 0 except KeyError as e: print("!", e, "--") print(splitter.period[p]) pass sys.stdout.write(Color.none) print('', end=' ') print() except KeyboardInterrupt: print('Keyboard interrupt detected ... Exiting!') # Say to the daemon threads that the work has been finished, splitter.alive = False # Wake up the "moderate_the_team" daemon, which is waiting # in a cluster_sock.recvfrom(...). if not args.mcast: splitter.say_goodbye(("127.0.0.1", splitter.PORT), splitter.team_socket) # Wake up the "handle_arrivals" daemon, which is waiting # in a peer_connection_sock.accept(). sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(("127.0.0.1", splitter.PORT)) sock.recv(struct.calcsize("4sH")) # Multicast channel sock.recv(struct.calcsize("H")) # Header size sock.recv(struct.calcsize("H")) # Chunk size sock.recv(splitter.CHUNK_SIZE * splitter.HEADER_SIZE) # Header sock.recv(struct.calcsize("H")) # Buffer size if args.mcast: number_of_peers = 0 else: number_of_peers = socket.ntohs( struct.unpack("H", sock.recv(struct.calcsize("H")))[0]) print("Number of peers =", number_of_peers) # Receive the list while number_of_peers > 0: sock.recv(struct.calcsize("4sH")) number_of_peers -= 1 # Breaks this thread and returns to the parent process # (usually, the shell). break
# been arised. chunk_number = self.process_next_message() while chunk_number < 0: chunk_number = self.process_next_message() _p_(chunk_number) self.played_chunk = chunk_number _p_("First chunk to play", self.played_chunk) _p_(self.team_socket.getsockname(), "\b: buffering (\b", repr(100.0/self.buffer_size).rjust(4)) # Now, fill up to the half of the buffer. for x in range(int(self.buffer_size/2)): _print_("{:.2%}\r".format((1.0*x)/(self.buffer_size/2)), end='') <<<<<<< HEAD BUFFER_STATUS = int((100*x)/(self.buffer_size/2)+1) if common.CONSOLE_MODE == False : _print_(str(BUFFER_STATUS)) ======= BUFFER_STATUS = (100*x)/(self.buffer_size/2) +1 if Common.CONSOLE_MODE == False : >>>>>>> master GObject.idle_add(buffering_adapter.update_widget,BUFFER_STATUS) else: pass #print("!", end='') sys.stdout.flush() while self.process_next_message() < 0: pass print() latency = time.time() - start_time _p_('latency =', latency, 'seconds')
def __init__(self): # {{{ colorama.init() try: colorama.init() except Exception: pass # }}} # {{{ Running in debug/release mode _print_("Running in", end=' ') if __debug__: print("debug mode") else: print("release mode") # }}} splitter = SplitterSTRPEDS() # {{{ Arguments handling parser = argparse.ArgumentParser( description= 'This is the splitter node of a P2PSP team. The splitter is in charge of defining the Set or Rules (SoR) that will control the team. By default, DBS (unicast transmissions) will be used.' ) #parser.add_argument('--splitter_addr', help='IP address to serve (TCP) the peers. (Default = "{}")'.format(Splitter_IMS.SPLITTER_ADDR)) <- no ahora parser.add_argument( '--buffer_size', help='size of the video buffer in blocks. Default = {}.' ) #.format(Splitter_IMS.BUFFER_SIZE)) parser.add_argument( '--channel', help= 'Name of the channel served by the streaming source. Default = "{}".' ) #.format(Splitter_IMS.CHANNEL)) parser.add_argument('--chunk_size', help='Chunk size in bytes. Default = {}.' ) #.format(Splitter_IMS.CHUNK_SIZE)) parser.add_argument( '--header_size', help='Size of the header of the stream in chunks. Default = {}.' ) #.format(Splitter_IMS.HEADER_SIZE)) parser.add_argument( '--max_chunk_loss', help= 'Maximum number of lost chunks for an unsupportive peer. Makes sense only in unicast mode. Default = {}.' ) #.format(Splitter_DBS.MAX_CHUNK_LOSS)) parser.add_argument( '--max_number_of_monitor_peers', help= 'Maxium number of monitors in the team. The first connecting peers will automatically become monitors. Default = "{}".' ) #.format(Splitter_DBS.MONITOR_NUMBER)) parser.add_argument( '--mcast_addr', help= 'IP multicast address used to serve the chunks. Makes sense only in multicast mode. Default = "{}".' ) #.format(Splitter_IMS.MCAST_ADDR)) parser.add_argument('--port', help='Port to serve the peers. Default = "{}".' ) #.format(Splitter_IMS.PORT)) parser.add_argument( '--source_addr', help= 'IP address or hostname of the streaming server. Default = "{}".' ) #.format(Splitter_IMS.SOURCE_ADDR)) parser.add_argument( '--source_port', help='Port where the streaming server is listening. Default = {}.' ) #.format(Splitter_IMS.SOURCE_PORT)) parser.add_argument( '--p_mpl', help='Probabity Malicious peer leaves. Default = {}.') parser.add_argument( '--p_tpl', help='Probabity Trusted peer leaves. Default = {}.') #parser.add_argument("--IMS", action="store_true", help="Uses the IP multicast infrastructure, if available. IMS mode is incompatible with ACS, LRS, DIS and NTS modes.") parser.add_argument("--NTS", action="store_true", help="Enables NAT traversal.") #parser.add_argument("--ACS", action="store_true", help="Enables Adaptive Chunk-rate.") #parser.add_argument("--LRS", action="store_true", help="Enables Lost chunk Recovery.") #parser.add_argument("--DIS", action="store_true", help="Enables Data Integrity check.") #parser.add_argument('--strpe', nargs='+', type=str, help='Selects STrPe model for DIS') #parser.add_argument('--strpeds', nargs='+', type=str, help='Selects STrPe-DS model for DIS') #parser.add_argument('--strpeds_majority_decision', help='Sets majority decision ratio for STrPe-DS model.') parser.add_argument('--strpeds_log', help='Logging STrPe-DS specific data to file.') #parser.add_argument('--TTL', help='Time To Live of the multicast messages. Default = {}.')#.format(Splitter_IMS.TTL)) try: argcomplete.autocomplete(parser) except Exception: pass args = parser.parse_args() #args = parser.parse_known_args()[0] _print_("My IP address is =", socket.gethostbyname(socket.gethostname())) splitter.monitor_number = 1 if args.buffer_size: splitter.buffer_size = int(args.buffer_size) _print_("Buffer size =", str(splitter.buffer_size)) if args.channel: splitter.channel = args.channel _print_("Channel = \"" + str(splitter.channel) + "\"") if args.chunk_size: splitter.chunk_size = int(args.chunk_size) _print_("Chunk size =", str(splitter.chunk_size)) if args.header_size: splitter.header_size = int(args.header_size) _print_("Header size =", str(splitter.header_size)) if args.port: splitter.team_port = int(args.port) _print_("Listening port =", str(splitter.team_port)) if args.source_addr: splitter.source_addr = socket.gethostbyname(args.source_addr) _print_("Source address = ", str(splitter.source_addr)) if args.source_port: splitter.source_port = int(args.source_port) _print_("Source port =", str(splitter.source_port)) _print_("IP unicast mode selected") if args.max_chunk_loss: splitter.max_number_of_chunk_loss = int(args.max_chunk_loss) _print_("Maximun chunk loss =", str(splitter.max_number_of_chunk_loss)) if args.max_number_of_monitor_peers: splitter.max_number_of_monitors = int( args.max_number_of_monitor_peers) _print_("Maximun number of monitor peers =", str(splitter.max_number_of_monitors)) if args.strpeds_log != None: splitter.SetLogging(True) splitter.SetLogFile(args.strpeds_log) if args.p_mpl: splitter.p_mpl = int(args.p_mpl) _print_("P_MPL =", str(splitter.p_mpl)) if args.p_tpl: splitter.t_mpl = int(args.p_tpl) _print_("P_TPL =", str(splitter.p_tpl)) # {{{ Run! splitter.Start() # {{{ Prints information until keyboard interruption print(" | Received | Sent | Number losses/ losses") print( " Time | (kbps) | (kbps) | peers (peer) sents threshold period kbps" ) print( "---------+-----------+-----------+-----------------------------------..." ) last_sendto_counter = splitter.GetSendToCounter() last_recvfrom_counter = splitter.GetRecvFromCounter() while splitter.isAlive(): try: time.sleep(1) chunks_sendto = splitter.GetSendToCounter( ) - last_sendto_counter kbps_sendto = (chunks_sendto * splitter.chunk_size * 8) / 1000 chunks_recvfrom = splitter.GetRecvFromCounter( ) - last_recvfrom_counter kbps_recvfrom = (chunks_recvfrom * splitter.chunk_size * 8) / 1000 last_sendto_counter = splitter.GetSendToCounter() last_recvfrom_counter = splitter.GetRecvFromCounter() sys.stdout.write(Color.none) _print_("|" + repr(int(kbps_recvfrom)).rjust(10) + " |" + repr(int(kbps_sendto)).rjust(10), end=" | ") #print('%5d' % splitter.chunk_number, end=' ') sys.stdout.write(Color.cyan) print(len(splitter.GetPeerList()), end=' ') if not __debug__: counter = 0 for p in splitter.GetPeerList(): if not __debug__: if counter > 10: break counter += 1 sys.stdout.write(Color.blue) print(p, end=' ') sys.stdout.write(Color.red) #print(str('%3d' % splitter.GetLoss(p)) + '/' + str('%3d' % chunks_sendto), splitter.GetMaxChunkLoss(), end=' ') print() except KeyboardInterrupt: print('Keyboard interrupt detected ... Exiting!') # Say to daemon threads that the work has been finished, splitter.SetAlive(False) # Wake up the "moderate_the_team" daemon, which is # waiting in a recvfrom(). splitter.SayGoodbye() ''' if not args.IMS: #splitter.say_goodbye(("127.0.0.1", splitter.PORT), splitter.team_socket) splitter.team_socket.sendto(b'', ("127.0.0.1", splitter.PORT)) ''' # Wake up the "handle_arrivals" daemon, which is waiting # in an accept(). sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(("127.0.0.1", splitter.team_port)) sock.recv(struct.calcsize("4sH")) # Multicast channel sock.recv(struct.calcsize("H")) # Header size sock.recv(struct.calcsize("H")) # Chunk size sock.recv(splitter.CHUNK_SIZE * splitter.HEADER_SIZE) # Header sock.recv(struct.calcsize("H")) # Buffer size sock.recv(struct.calcsize("4sH")) # Endpoint sock.recv(struct.calcsize("B")) # Magic flags if args.IMS: number_of_peers = 0 else: number_of_peers = socket.ntohs( struct.unpack("H", sock.recv(struct.calcsize("H")))[0]) print("Number of peers =", number_of_peers) # Receive the list while number_of_peers > 0: sock.recv(struct.calcsize("4sH")) number_of_peers -= 1 # Breaks this thread and returns to the parent process # (usually, the shell). break
def _p_(*args, **kwargs): """Colorize the output.""" sys.stdout.write(Common.IMS_COLOR) _print_("IMS:", *args) sys.stdout.write(Color.none)
def buffer_data(self): # {{{ Buffering # {{{ The peer dies if the player disconnects. # }}} self.player_alive = True # {{{ The last chunk sent to the player. # }}} self.played_chunk = 0 # {{{ Counts the number of executions of the recvfrom() # function. # }}} self.recvfrom_counter = 0 # {{{ Label the chunks in the buffer as "received" or "not # received". # }}} self.received_flag = [] # {{{ The buffer of chunks is a structure that is used to delay # the playback of the chunks in order to accommodate the # network jittter. Two components are needed: (1) the "chunks" # buffer that stores the received chunks and (2) the # "received" buffer that stores if a chunk has been received # or not. Notice that each peer can use a different # buffer_size: the smaller the buffer size, the lower start-up # time, the higher chunk-loss ratio. However, for the sake of # simpliticy, all peers will use the same buffer size. self.chunks = [""]*self.buffer_size self.received_flag = [False]*self.buffer_size self.received_counter = 0 # }}} # Wall time (execution time plus waiting time). start_time = time.time() # We will send a chunk to the player when a new chunk is # received. Besides, those slots in the buffer that have not been # filled by a new chunk will not be send to the player. Moreover, # chunks can be delayed an unknown time. This means that (due to the # jitter) after chunk X, the chunk X+Y can be received (instead of the # chunk X+1). Alike, the chunk X-Y could follow the chunk X. Because # we implement the buffer as a circular queue, in order to minimize # the probability of a delayed chunk overwrites a new chunk that is # waiting for traveling the player, we wil fill only the half of the # circular queue. _p_(self.team_socket.getsockname(), "\b: buffering = 000.00%") sys.stdout.flush() # First chunk to be sent to the player. The # process_next_message() procedure returns the chunk number if # a packet has been received or -2 if a time-out exception has # been arised. chunk_number = self.process_next_message() while chunk_number < 0: chunk_number = self.process_next_message() _p_(chunk_number) self.played_chunk = chunk_number _p_("First chunk to play", self.played_chunk) _p_(self.team_socket.getsockname(), "\b: buffering (\b", repr(100.0/self.buffer_size).rjust(4)) # Now, fill up to the half of the buffer. for x in range(int(self.buffer_size/2)): _print_("{:.2%}\r".format((1.0*x)/(self.buffer_size/2)), end='')
def print_the_module_name(self): # {{{ sys.stdout.write(Color.red) _print_("Monitor DBS") sys.stdout.write(Color.none)
def process_next_message(self): # {{{ Now, receive and send. try: # {{{ Receive and send message, sender = self.receive_the_next_message() if len(message) == struct.calcsize(self.message_format): # {{{ A video chunk has been received chunk_number, chunk = self.unpack_message(message) self.chunks[chunk_number % self.buffer_size] = chunk self.received[chunk_number % self.buffer_size] = True if sender == self.splitter: # {{{ Send the previous chunk in burst sending # mode if the chunk has not been sent to all # the peers of the list of peers. # {{{ debug if __debug__: _print_("DBS:", self.team_socket.getsockname(), \ Color.red, "<-", Color.none, chunk_number, "-", sender) # }}} while( (self.receive_and_feed_counter < len(self.peer_list)) and (self.receive_and_feed_counter > 0) ): peer = self.peer_list[self.receive_and_feed_counter] self.team_socket.sendto(self.receive_and_feed_previous, peer) self.sendto_counter += 1 # {{{ debug if __debug__: print ("DBS:", self.team_socket.getsockname(), "-",\ socket.ntohs(struct.unpack(self.message_format, \ self.receive_and_feed_previous)[0]),\ Color.green, "->", Color.none, peer) # }}} self.debt[peer] += 1 if self.debt[peer] > self.MAX_CHUNK_LOSS: print (Color.red, "DBS:", peer, 'removed by unsupportive (' + str(self.debt[peer]) + ' lossess)', Color.none) del self.debt[peer] self.peer_list.remove(peer) self.receive_and_feed_counter += 1 self.receive_and_feed_counter = 0 self.receive_and_feed_previous = message # }}} else: # {{{ The sender is a peer # {{{ debug if __debug__: print ("DBS:", self.team_socket.getsockname(), \ Color.green, "<-", Color.none, chunk_number, "-", sender) # }}} if sender not in self.peer_list: # The peer is new self.peer_list.append(sender) self.debt[sender] = 0 print (Color.green, "DBS:", sender, 'added by chunk', \ chunk_number, Color.none) else: self.debt[sender] -= 1 # }}} # {{{ A new chunk has arrived and the # previous must be forwarded to next peer of the # list of peers. if ( self.receive_and_feed_counter < len(self.peer_list) and ( self.receive_and_feed_previous != '') ): # {{{ Send the previous chunk in congestion avoiding mode. peer = self.peer_list[self.receive_and_feed_counter] self.team_socket.sendto(self.receive_and_feed_previous, peer) self.sendto_counter += 1 self.debt[peer] += 1 if self.debt[peer] > self.MAX_CHUNK_LOSS: print (Color.red, "DBS:", peer, 'removed by unsupportive (' + str(self.debt[peer]) + ' lossess)', Color.none) del self.debt[peer] self.peer_list.remove(peer) # {{{ debug if __debug__: print ("DBS:", self.team_socket.getsockname(), "-", \ socket.ntohs(struct.unpack(self.message_format, self.receive_and_feed_previous)[0]),\ Color.green, "->", Color.none, peer) # }}} self.receive_and_feed_counter += 1 # }}} # }}} return chunk_number # }}} else: # {{{ A control chunk has been received print("DBS: Control received") if message == 'H': if sender not in self.peer_list: # The peer is new self.peer_list.append(sender) self.debt[sender] = 0 print (Color.green, "DBS:", sender, 'added by [hello]', Color.none) else: if sender in self.peer_list: sys.stdout.write(Color.red) print ("DBS:", self.team_socket.getsockname(), '\b: received "goodbye" from', sender) sys.stdout.write(Color.none) self.peer_list.remove(sender) del self.debt[sender] return -1 # }}} # }}} except socket.timeout: return -2
def __init__(self): # {{{ colorama.init() try: colorama.init() except Exception: pass # }}} # {{{ Running in debug/release mode _print_("Running in", end=' ') if __debug__: print("debug mode") else: print("release mode") # }}} splitter = SplitterSTRPEDS() # {{{ Arguments handling parser = argparse.ArgumentParser(description='This is the splitter node of a P2PSP team. The splitter is in charge of defining the Set or Rules (SoR) that will control the team. By default, DBS (unicast transmissions) will be used.') #parser.add_argument('--splitter_addr', help='IP address to serve (TCP) the peers. (Default = "{}")'.format(Splitter_IMS.SPLITTER_ADDR)) <- no ahora parser.add_argument('--buffer_size', help='size of the video buffer in blocks. Default = {}.')#.format(Splitter_IMS.BUFFER_SIZE)) parser.add_argument('--channel', help='Name of the channel served by the streaming source. Default = "{}".')#.format(Splitter_IMS.CHANNEL)) parser.add_argument('--chunk_size', help='Chunk size in bytes. Default = {}.')#.format(Splitter_IMS.CHUNK_SIZE)) parser.add_argument('--header_size', help='Size of the header of the stream in chunks. Default = {}.')#.format(Splitter_IMS.HEADER_SIZE)) parser.add_argument('--max_chunk_loss', help='Maximum number of lost chunks for an unsupportive peer. Makes sense only in unicast mode. Default = {}.')#.format(Splitter_DBS.MAX_CHUNK_LOSS)) parser.add_argument('--max_number_of_monitor_peers', help='Maxium number of monitors in the team. The first connecting peers will automatically become monitors. Default = "{}".')#.format(Splitter_DBS.MONITOR_NUMBER)) parser.add_argument('--mcast_addr', help='IP multicast address used to serve the chunks. Makes sense only in multicast mode. Default = "{}".')#.format(Splitter_IMS.MCAST_ADDR)) parser.add_argument('--port', help='Port to serve the peers. Default = "{}".')#.format(Splitter_IMS.PORT)) parser.add_argument('--source_addr', help='IP address or hostname of the streaming server. Default = "{}".')#.format(Splitter_IMS.SOURCE_ADDR)) parser.add_argument('--source_port', help='Port where the streaming server is listening. Default = {}.')#.format(Splitter_IMS.SOURCE_PORT)) parser.add_argument('--p_mpl', help='Probabity Malicious peer leaves. Default = {}.') parser.add_argument('--p_tpl', help='Probabity Trusted peer leaves. Default = {}.') #parser.add_argument("--IMS", action="store_true", help="Uses the IP multicast infrastructure, if available. IMS mode is incompatible with ACS, LRS, DIS and NTS modes.") parser.add_argument("--NTS", action="store_true", help="Enables NAT traversal.") #parser.add_argument("--ACS", action="store_true", help="Enables Adaptive Chunk-rate.") #parser.add_argument("--LRS", action="store_true", help="Enables Lost chunk Recovery.") #parser.add_argument("--DIS", action="store_true", help="Enables Data Integrity check.") #parser.add_argument('--strpe', nargs='+', type=str, help='Selects STrPe model for DIS') #parser.add_argument('--strpeds', nargs='+', type=str, help='Selects STrPe-DS model for DIS') #parser.add_argument('--strpeds_majority_decision', help='Sets majority decision ratio for STrPe-DS model.') parser.add_argument('--strpeds_log', help='Logging STrPe-DS specific data to file.') #parser.add_argument('--TTL', help='Time To Live of the multicast messages. Default = {}.')#.format(Splitter_IMS.TTL)) try: argcomplete.autocomplete(parser) except Exception: pass args = parser.parse_args() #args = parser.parse_known_args()[0] _print_("My IP address is =", socket.gethostbyname(socket.gethostname())) splitter.monitor_number = 1 if args.buffer_size: splitter.buffer_size = int(args.buffer_size) _print_("Buffer size =", str(splitter.buffer_size)) if args.channel: splitter.channel = args.channel _print_("Channel = \"" + str(splitter.channel) + "\"") if args.chunk_size: splitter.chunk_size = int(args.chunk_size) _print_("Chunk size =", str(splitter.chunk_size)) if args.header_size: splitter.header_size = int(args.header_size) _print_("Header size =", str(splitter.header_size)) if args.port: splitter.team_port = int(args.port) _print_("Listening port =", str(splitter.team_port)) if args.source_addr: splitter.source_addr = socket.gethostbyname(args.source_addr) _print_("Source address = ", str(splitter.source_addr)) if args.source_port: splitter.source_port = int(args.source_port) _print_("Source port =", str(splitter.source_port)) _print_("IP unicast mode selected") if args.max_chunk_loss: splitter.max_number_of_chunk_loss = int(args.max_chunk_loss) _print_("Maximun chunk loss =", str(splitter.max_number_of_chunk_loss)) if args.max_number_of_monitor_peers: splitter.max_number_of_monitors = int(args.max_number_of_monitor_peers) _print_("Maximun number of monitor peers =", str(splitter.max_number_of_monitors)) if args.strpeds_log != None: splitter.SetLogging(True) splitter.SetLogFile(args.strpeds_log) if args.p_mpl: splitter.p_mpl = int(args.p_mpl) _print_("P_MPL =", str(splitter.p_mpl)) if args.p_tpl: splitter.t_mpl = int(args.p_tpl) _print_("P_TPL =", str(splitter.p_tpl)) # {{{ Run! splitter.Start() while splitter.isAlive(): pass
def __init__(self): try: colorama.init() except Exception: pass _print_("Running in", end=' ') if __debug__: print("debug mode") else: print("release mode") # {{{ Args handling and object instantiation parser = argparse.ArgumentParser( description='This is the peer node of a P2PSP team.') parser.add_argument( '--chunk_loss_period', help= '0 -> no chunk loss, 1 -> lost all chunks, 2, lost half of the chunks ... Default = {}' .format(Lossy_Peer.CHUNK_LOSS_PERIOD)) parser.add_argument( '--max_chunk_loss', help= 'The maximun number of times that other peer can not send a chunk to this peer. Defaut = {}' .format(Peer_DBS.MAX_CHUNK_LOSS)) parser.add_argument( '--player_port', help='Port to communicate with the player. Default = {}'.format( Peer_IMS.PLAYER_PORT)) parser.add_argument( '--splitter_host', help='IP address or hostname of the splitter. Default = {}.'. format(Peer_IMS.SPLITTER_ADDR)) parser.add_argument( '--splitter_port', help='Listening port of the splitter. Default = {}.'.format( Peer_IMS.SPLITTER_PORT)) parser.add_argument( '--port', help= 'Port to communicate with the peers. Default {} (the OS will chose it).' .format(Peer_IMS.PORT)) parser.add_argument( '--use_localhost', action="store_true", help= 'Forces the peer to use localhost instead of the IP of the adapter to connect to the splitter.' ) #args = parser.parse_known_args()[0] args = parser.parse_args() if args.splitter_host: Peer_IMS.SPLITTER_ADDR = socket.gethostbyname(args.splitter_host) print('SPLITTER_ADDR =', Peer_IMS.SPLITTER_ADDR) if args.splitter_port: Peer_IMS.SPLITTER_PORT = int(args.splitter_port) print('SPLITTER_PORT =', Peer_IMS.SPLITTER_PORT) if args.port: Peer_IMS.PORT = int(args.port) print('(Peer) PORT =', Peer_IMS.PORT) if args.player_port: Peer_IMS.PLAYER_PORT = int(args.player_port) print('PLAYER_PORT =', Peer_IMS.PLAYER_PORT) if args.max_chunk_loss: Peer_DBS.MAX_CHUNK_LOSS = int(args.max_chunk_loss) print('MAX_CHUNK_LOSS =', Peer_DBS.MAX_CHUNK_LOSS) if args.use_localhost: Peer_IMS.USE_LOCALHOST = True print('Using localhost!') peer = Peer_IMS() peer.wait_for_the_player() peer.connect_to_the_splitter() peer.receive_the_mcast_endpoint() peer.receive_the_header_size() peer.receive_the_chunk_size() peer.receive_the_header() peer.receive_the_buffer_size() #peer.receive_configuration() _print_("IP Multicast address =", peer.mcast_addr) # A multicast address is always received, even for DBS peers. if peer.mcast_addr == "0.0.0.0": # {{{ This is an "unicast" peer. peer = Peer_DBS(peer) peer.receive_my_endpoint() peer.receive_the_number_of_peers() print("===============> number_of_peers =", peer.number_of_peers) print("===============> is_a_monitor =", peer.am_i_a_monitor()) peer.listen_to_the_team() peer.receive_the_list_of_peers() if peer.am_i_a_monitor(): #peer = Monitor_DBS(peer) #peer = Monitor_FNS(peer) peer = Monitor_LRS(peer) else: peer = Peer_FNS(peer) if args.chunk_loss_period: Lossy_Peer.CHUNK_LOSS_PERIOD = int(args.chunk_loss_period) print('CHUNK_LOSS_PERIOD =', Lossy_Peer.CHUNK_LOSS_PERIOD) if int(args.chunk_loss_period) != 0: peer = Lossy_Peer(peer) #peer.receive_my_endpoint() # }}} else: peer.listen_to_the_team() # }}} # {{{ Run! peer.disconnect_from_the_splitter() peer.buffer_data() peer.start() print("+-----------------------------------------------------+") print("| Received = Received kbps, including retransmissions |") print("| Sent = Sent kbps |") print("| (Expected values are between parenthesis) |") print("------------------------------------------------------+") print() print( " Time | Received (Expected) | Sent (Expected) | Team description" ) print( "---------+-------------------------+--------------------------+-----------------..." ) last_chunk_number = peer.played_chunk if hasattr(peer, 'sendto_counter'): last_sendto_counter = 0 else: peer.sendto_counter = 0 last_sendto_counter = 0 if not hasattr(peer, 'peer_list'): peer.peer_list = [] last_recvfrom_counter = peer.recvfrom_counter while peer.player_alive: time.sleep(1) kbps_expected_recv = ((peer.played_chunk - last_chunk_number) * peer.chunk_size * 8) / 1000 last_chunk_number = peer.played_chunk kbps_recvfrom = ((peer.recvfrom_counter - last_recvfrom_counter) * peer.chunk_size * 8) / 1000 last_recvfrom_counter = peer.recvfrom_counter team_ratio = len(peer.peer_list) / (len(peer.peer_list) + 1.0) kbps_expected_sent = int(kbps_expected_recv * team_ratio) kbps_sendto = ((peer.sendto_counter - last_sendto_counter) * peer.chunk_size * 8) / 1000 last_sendto_counter = peer.sendto_counter if kbps_recvfrom > 0 and kbps_expected_recv > 0: nice = 100.0 / float( (float(kbps_expected_recv) / kbps_recvfrom) * (len(peer.peer_list) + 1)) else: nice = 0.0 _print_('|', end=Color.none) if kbps_expected_recv < kbps_recvfrom: sys.stdout.write(Color.red) elif kbps_expected_recv > kbps_recvfrom: sys.stdout.write(Color.green) print(repr(kbps_expected_recv).rjust(12), end=Color.none) print(('(' + repr(kbps_recvfrom) + ')').rjust(12), end=' | ') #print(("{:.1f}".format(nice)).rjust(6), end=' | ') #sys.stdout.write(Color.none) if kbps_expected_sent > kbps_sendto: sys.stdout.write(Color.red) elif kbps_expected_sent < kbps_sendto: sys.stdout.write(Color.green) print(repr(kbps_sendto).rjust(12), end=Color.none) print(('(' + repr(kbps_expected_sent) + ')').rjust(12), end=' | ') #sys.stdout.write(Color.none) #print(repr(nice).ljust(1)[:6], end=' ') print(len(peer.peer_list), end=' ') counter = 0 for p in peer.peer_list: if (counter < 5): print(p, end=' ') counter += 1 else: break print()
def punish_peer(self, bad_peer, message = ""): if self.LOGGING: self.log_message("bad peer excluded {0}".format(bad_peer)) _print_("bad peer excluded: " + str(bad_peer) + "(" + message + ")") self.remove_peer(bad_peer)
def __init__(self): try: colorama.init() except Exception: pass _print_("Running in", end=' ') if __debug__: print("debug mode") else: print("release mode") # {{{ Args handling and object instantiation parser = argparse.ArgumentParser(description='This is the peer node of a P2PSP team.') parser.add_argument('--chunk_loss_period', help='0 -> no chunk loss, 1 -> lost all chunks, 2, lost half of the chunks ... Default = {}'.format(Lossy_Peer.CHUNK_LOSS_PERIOD)) parser.add_argument('--max_chunk_loss', help='The maximun number of times that other peer can not send a chunk to this peer. Defaut = {}'.format(Peer_DBS.MAX_CHUNK_LOSS)) parser.add_argument('--player_port', help='Port to communicate with the player. Default = {}'.format(Peer_IMS.PLAYER_PORT)) parser.add_argument('--splitter_host', help='IP address or hostname of the splitter. Default = {}.'.format(Peer_IMS.SPLITTER_ADDR)) parser.add_argument('--splitter_port', help='Listening port of the splitter. Default = {}.'.format(Peer_IMS.SPLITTER_PORT)) parser.add_argument('--port', help='Port to communicate with the peers. Default {} (the SO will chose it).'.format(Peer_IMS.PORT)) parser.add_argument('--use_localhost', action="store_true", help='Forces the peer to use localhost instead of the IP of the adapter to connect to the splitter.') #args = parser.parse_known_args()[0] args = parser.parse_args() if args.splitter_host: Peer_IMS.SPLITTER_ADDR = socket.gethostbyname(args.splitter_host) print ('SPLITTER_ADDR =', Peer_IMS.SPLITTER_ADDR) if args.splitter_port: Peer_IMS.SPLITTER_PORT = int(args.splitter_port) print ('SPLITTER_PORT =', Peer_IMS.SPLITTER_PORT) if args.port: Peer_IMS.PORT = int(args.port) print ('(Peer) PORT =', Peer_IMS.PORT) if args.player_port: Peer_IMS.PLAYER_PORT = int(args.player_port) print ('PLAYER_PORT =', Peer_IMS.PLAYER_PORT) if args.max_chunk_loss: Peer_DBS.MAX_CHUNK_LOSS = int(args.max_chunk_loss) print ('MAX_CHUNK_LOSS =', Peer_DBS.MAX_CHUNK_LOSS) if args.use_localhost: Peer_IMS.USE_LOCALHOST = True print('Using localhost!') peer = Peer_IMS() peer.wait_for_the_player() peer.connect_to_the_splitter() peer.receive_the_mcast_endpoint() peer.receive_the_header_size() peer.receive_the_chunk_size() peer.receive_the_header() peer.receive_the_buffer_size() #peer.receive_configuration() _print_("IP Multicast address =", peer.mcast_addr) # A multicast address is always received, even for DBS peers. if peer.mcast_addr == "0.0.0.0": # {{{ This is an "unicast" peer. peer = Peer_DBS(peer) peer.receive_my_endpoint() peer.receive_the_number_of_peers() print("===============> number_of_peers =", peer.number_of_peers) print(peer.am_i_a_monitor()) peer.listen_to_the_team() peer.receive_the_list_of_peers() if peer.am_i_a_monitor(): #peer = Monitor_DBS(peer) #peer = Monitor_FNS(peer) peer = Monitor_LRS(peer) else: peer = Peer_FNS(peer) if args.chunk_loss_period: Lossy_Peer.CHUNK_LOSS_PERIOD = int(args.chunk_loss_period) print('CHUNK_LOSS_PERIOD =', Lossy_Peer.CHUNK_LOSS_PERIOD) if int(args.chunk_loss_period) != 0: peer = Lossy_Peer(peer) #peer.receive_my_endpoint() # }}} else: peer.listen_to_the_team() # }}} # {{{ Run! peer.disconnect_from_the_splitter() peer.buffer_data() peer.start() print("+-----------------------------------------------------+") print("| Received = Received kbps, including retransmissions |") print("| Sent = Sent kbps |") print("| (Expected values are between parenthesis) |") print("------------------------------------------------------+") print() print(" Time | Received (Expected) | Sent (Expected) | Team description") print("---------+-------------------------+--------------------------+-----------------...") last_chunk_number = peer.played_chunk if hasattr(peer, 'sendto_counter'): last_sendto_counter = 0 else: peer.sendto_counter = 0 last_sendto_counter = 0 if not hasattr(peer, 'peer_list'): peer.peer_list = [] last_recvfrom_counter = peer.recvfrom_counter while peer.player_alive: time.sleep(1) kbps_expected_recv = ((peer.played_chunk - last_chunk_number) * peer.chunk_size * 8) / 1000 last_chunk_number = peer.played_chunk kbps_recvfrom = ((peer.recvfrom_counter - last_recvfrom_counter) * peer.chunk_size * 8) / 1000 last_recvfrom_counter = peer.recvfrom_counter team_ratio = len(peer.peer_list) /(len(peer.peer_list) + 1.0) kbps_expected_sent = int(kbps_expected_recv*team_ratio) kbps_sendto = ((peer.sendto_counter - last_sendto_counter) * peer.chunk_size * 8) / 1000 last_sendto_counter = peer.sendto_counter if kbps_recvfrom > 0 and kbps_expected_recv > 0: nice = 100.0/float((float(kbps_expected_recv)/kbps_recvfrom)*(len(peer.peer_list)+1)) else: nice = 0.0 _print_('|', end=Color.none) if kbps_expected_recv < kbps_recvfrom: sys.stdout.write(Color.red) elif kbps_expected_recv > kbps_recvfrom: sys.stdout.write(Color.green) print(repr(kbps_expected_recv).rjust(12), end=Color.none) print(('(' + repr(kbps_recvfrom) + ')').rjust(12), end=' | ') #print(("{:.1f}".format(nice)).rjust(6), end=' | ') #sys.stdout.write(Color.none) if kbps_expected_sent > kbps_sendto: sys.stdout.write(Color.red) elif kbps_expected_sent < kbps_sendto: sys.stdout.write(Color.green) print(repr(kbps_sendto).rjust(12), end=Color.none) print(('(' + repr(kbps_expected_sent) + ')').rjust(12), end=' | ') #sys.stdout.write(Color.none) #print(repr(nice).ljust(1)[:6], end=' ') print(len(peer.peer_list), end=' ') counter = 0 for p in peer.peer_list: if (counter < 5): print(p, end=' ') counter += 1 else: break print()
def __init__(self, peer): # {{{ sys.stdout.write(Color.yellow) _print_("Peer FNS") sys.stdout.write(Color.none)