def discover_existing_mcastport(ring1, timeout = 10): console_log.debug("Sniffing for packets to %s on %s (%s)" % (ring1.mcastaddr, ring1.name, ring1.ipv4_address)) console_log.debug("Sniffing for packets to %s on %s" % (ring1.mcastaddr, ring1.name)) networking.subscribe_multicast(ring1) cap = networking.start_cap(ring1, timeout / 10, "ip multicast and dst host %s and not src host %s" % (ring1.mcastaddr, ring1.ipv4_address)) # Stop the talker thread if it is running. _stop_talker_thread() ring1_original_mcast_port = ring1.mcastport def recv_packets(header, data): ring1.mcastport = networking.get_dport_from_packet(data) console_log.debug("Sniffed multicast traffic on %d" % ring1.mcastport) try: packet_count = 0 start_time = time.time() while packet_count < 1 and time.time() < start_time + timeout: try: packet_count += cap.dispatch(1, recv_packets) except Exception, e: raise RuntimeError("Error reading from the network: %s" % str(e)) # If we haven't seen anything yet, make sure we are blathering... if packet_count < 1: _start_talker_thread(ring1) console_log.debug("Finished after %d seconds, sniffed: %d" % (time.time() - start_time, packet_count))
def find_unused_port(ring0, timeout=10, batch_count=10000): from random import choice dest_addr = ring0.mcastaddr port_min = 32767 port_max = 65535 ports = range(port_min, port_max, 2) portrange_str = "%s-%s" % (port_min, port_max) firewall_control.add_rule( 0, "tcp", "find unused port", persist=False, address=ring0.mcastaddr ) try: networking.subscribe_multicast(ring0) console_log.info( "Sniffing for packets to %s on %s within port range %s" % (dest_addr, ring0.name, portrange_str) ) cap = networking.start_cap( ring0, timeout, "host %s and udp and portrange %s" % (dest_addr, portrange_str), ) def recv_packets(header, data): tgt_port = networking.get_dport_from_packet(data) try: ports.remove(tgt_port) except ValueError: # already removed pass packet_count = 0 start = time.time() while time.time() - start < timeout: try: packet_count += cap.dispatch(batch_count, recv_packets) except Exception as e: raise RuntimeError("Error reading from the network: %s" % str(e)) console_log.info( "Finished after %d seconds, sniffed: %d" % (time.time() - start, packet_count) ) finally: firewall_control.remove_rule( 0, "tcp", "find unused port", persist=False, address=ring0.mcastaddr ) return choice(ports)
def run(self): self.log.debug("Talker thread running") sock = networking.subscribe_multicast(self.interface) while not self._stop.is_set(): sock.sendto("%d\n\0" % self.interface.mcastport, (self.interface.mcastaddr, self.interface.mcastport)) self._stop.wait(0.25)