Exemple #1
0
    def _active_get_mapping(self):
        # Anly working on A record now
        if ((self._active_timer != None) and
            (self._active_timer.is_alive())):
                return
        try:
            results = resolver.query(self.rule, 'A')
            ttl = results.ttl

            self._active_timer = Timer(ttl, self._active_get_mapping_expired)
            self._active_timer.start()
            new_active_results = []
        
            # These two reduce churn: only adds things that weren't there from the 
            # previous pass, only deletes things that aren't there from this pass.
        
            # Add new addresses
            for addr in results:
                new_active_results.append(addr)
                if addr not in self._active_results:
                    print "adding addr: " + str(addr)
                    self.add_rule_cb(ipv4_src=str(addr), eth_type=ether.ETH_TYPE_IP)
                    self.add_rule_cb(ipv4_dst=str(addr), eth_type=ether.ETH_TYPE_IP)

            # Remove old addresses
            for addr in self._active_results:
                if addr not in results:
                    self.remove_rule_cb(ipv4_src=str(addr), eth_type=ether.ETH_TYPE_IP)
                    self.remove_rule_cb(ipv4_dst=str(addr), eth_type=ether.ETH_TYPE_IP)
            self._active_results = new_active_results
        except (resolver.NoAnswer, exception.Timeout, resolver.NXDOMAIN):
            self.logger.info("Could not query for " + self.rule + ". Trying again in 30 seconds.")
            self._active_timer = Timer(30, self._active_get_mapping_expired)
            self._active_timer.start()
            self._active_results = []
Exemple #2
0
class DNSMetadataEntry(MetadataEntry):
    def __init__(self, data_source, engine, rule, add_rule_cb, remove_rule_cb):
        super(DNSMetadataEntry, self).__init__(data_source, engine, rule)
        
        self.register_callbacks(add_rule_cb, remove_rule_cb)
        self.data_source.set_new_callback(self.handle_new_entry_callback)
        if ACTIVE_MAPPING == True:
            self._active_timer = None
            self._active_results = []
            self._active_get_mapping()
                

    def handle_expiration_callback(self, addr, entry):
        self.logger.info("DNSMetadataEntry.handle_expiration_callback(): called with " + addr)
        #need to remove the rules that was generated by the particular DNSEntry
        #TODO
        self.remove_rule_cb(ipv4_src=str(addr), eth_type=ether.ETH_TYPE_IP)
        self.remove_rule_cb(ipv4_dst=str(addr), eth_type=ether.ETH_TYPE_IP)

    def handle_new_entry_callback(self, addr, entry):
        self.logger.info("DNSMetadataEntry.handle_new_entry_callback(): called with " + addr)
        for name in entry.names:
            if name == self.rule:
                self.add_rule_cb(ipv4_src=str(addr), eth_type=ether.ETH_TYPE_IP)
                self.add_rule_cb(ipv4_dst=str(addr), eth_type=ether.ETH_TYPE_IP)
                self.logger.debug("    New rule for " + name)
                entry.register_timeout_callback(self.handle_expiration_callback)

    def _active_get_mapping_expired(self):
        #self.logger.debug("_active_get_mapping_expired() called " + str(self._active_timer.is_alive()))
        self._active_timer.cancel()
        self._active_get_mapping()

    def _active_get_mapping(self):
        # Anly working on A record now
        if ((self._active_timer != None) and
            (self._active_timer.is_alive())):
                return
        try:
            results = resolver.query(self.rule, 'A')
            ttl = results.ttl

            self._active_timer = Timer(ttl, self._active_get_mapping_expired)
            self._active_timer.start()
            new_active_results = []
        
            # These two reduce churn: only adds things that weren't there from the 
            # previous pass, only deletes things that aren't there from this pass.
        
            # Add new addresses
            for addr in results:
                new_active_results.append(addr)
                if addr not in self._active_results:
                    print "adding addr: " + str(addr)
                    self.add_rule_cb(ipv4_src=str(addr), eth_type=ether.ETH_TYPE_IP)
                    self.add_rule_cb(ipv4_dst=str(addr), eth_type=ether.ETH_TYPE_IP)

            # Remove old addresses
            for addr in self._active_results:
                if addr not in results:
                    self.remove_rule_cb(ipv4_src=str(addr), eth_type=ether.ETH_TYPE_IP)
                    self.remove_rule_cb(ipv4_dst=str(addr), eth_type=ether.ETH_TYPE_IP)
            self._active_results = new_active_results
        except (resolver.NoAnswer, exception.Timeout, resolver.NXDOMAIN):
            self.logger.info("Could not query for " + self.rule + ". Trying again in 30 seconds.")
            self._active_timer = Timer(30, self._active_get_mapping_expired)
            self._active_timer.start()
            self._active_results = []
 def _set_and_start_timer(self):
     time_to_go = self.expiry - datetime.now()
     self.timer = Timer(time_to_go.total_seconds(), self._call_callbacks)
     self.timer.start()
class DNSClassifierEntry:
    def __init__(self, IP, names, classification, ttl, expiry=None):
        self.IP = IP
        self.names = names
        self.classification = classification
        self.ttl = ttl
        if expiry is datetime:
            self.expiry = expiry
        else:
            self.expiry = datetime.now() + timedelta(seconds=ttl)

        # callbacks! 
        self.timeout_callbacks = []
        self.timer = None

    def __del__(self):
        if self.timer is not None:
            self.timer.cancel()
    
    def print_entry(self, offset=""):
        names_str = ""
        for name in self.names:
            names_str = names_str + name + " "
        if (self.is_expired()):
            expired = "Expired"
        else:
            expired = "Not expired"

        print offset + self.IP
        print offset + names_str
        print offset + str(self.ttl)
        print offset + self.classification
        print offset + str(self.expiry)
        print offset + expired

    def is_expired(self, expiry=None):
        if expiry is datetime:
            expiration_time = expiry
        else:
            expiration_time = datetime.now()

        return self.expiry < expiration_time
    
    def update_expiry(self, ttl):
        self.ttl = ttl
        self.expiry = datetime.now() + timedelta(seconds=ttl)
        if self.timer is not None:
            self.timer.cancel()
            self._set_and_start_timer()
    
    def register_timeout_callback(self, func):
        if func not in self.timeout_callbacks:
            self.timeout_callbacks.append(func) 
        if self.timer is None and not self.is_expired():
            self._set_and_start_timer()

    def _call_callbacks(self):
        # This is called when it expires.
        for cb in self.timeout_callbacks:
            cb(self.IP, self)

    def _set_and_start_timer(self):
        time_to_go = self.expiry - datetime.now()
        self.timer = Timer(time_to_go.total_seconds(), self._call_callbacks)
        self.timer.start()