Пример #1
0
def ifAccountThread():
    """Runs as a thread to account from traffic on an interface"""
    global _accountingInfo, _runIfAccount, nas_id, nas_ip
    global radius_update_interval, radius_acct_server, radius_auth_server

    try:
        # Is interface accounting enabled
        enabled = config_getboolean("accounting", "enabled", True)
        if not enabled:
            log_info("Interface accounting disabled.")
            return
        _runIfAccount = True

        # What interval shall we check hosts at
        check_interval = config_get("accounting", "check_interval", DEFAULT_CHECK_INTERVAL)
        radius_update_interval = config_getint("accounting", "update_interval", DEFAULT_UPDATE_INTERVAL)

        # Initialise the interface list
        default_user_file = "%s/accounting_users" % os.path.dirname(DEFAULT_CONFFILE)
        user_file = config_get("accounting", "user_file", default_user_file)
        if not os.path.exists(user_file):
            log_error("Interface accounting disabled. No user file: %s" % user_file)
            _runIfAccount = False
            return

        # Initialise the RADIUS connection
        try:
            dummy0 = getInterfaces(returnOne="dummy0")[0]
            dummy0ip = dummy0["address"].split("/")[0]
        except:
            log_error("Could not determine host loopback address!", sys.exc_info())
            dummy0ip = "127.0.0.1"
        acct_server = config_get("accounting", "acct_server", "radius")
        acct_secret = config_get_required("accounting", "acct_secret")
        auth_server = config_get("accounting", "auth_server", "radius")
        auth_secret = config_get_required("accounting", "auth_secret")
        nas_id = config_get("accounting", "nas_id", getFQDN())
        nas_ip = config_get("accounting", "nas_ip", dummy0ip)
        radius_acct_server = Client(server=acct_server, secret=acct_secret, dict=Dictionary(RADIUS_DICTIONARY))
        radius_auth_server = Client(server=auth_server, secret=auth_secret, dict=Dictionary(RADIUS_DICTIONARY))
        # FreeRADIUS at least auths based on IP address, make sure our
        # packets come from the right place
        radius_acct_server.bind((nas_ip, 0))
        radius_auth_server.bind((nas_ip, 0))

        # Read and parse the user file
        parseUserFile(user_file)

        # Initialise interface state
        initialiseInterfaceState()

        # Loop forever reading byte counters as appropriate
        while _runIfAccount:
            # wait a bit before checking
            time.sleep(check_interval)
            # Send any queued packets
            processRADIUSQueue()
            # Try and re-authenticate any dead interfaces
            for ifname, iface in _accountingInfo.items():
                if iface["authenticated"]:
                    continue
                age = time.time() - iface["last_auth_check"]
                if age > radius_update_interval:
                    doRADIUSAuthentication(ifname)
            # Update traffic details
            updateTrafficCounters()
            # Generate interim-updates
            processInterimUpdates()

    except:
        (etype, value, tb) = sys.exc_info()
        log_error("Exception in interface accounting thread! - %s" % value, (etype, value, tb))

    log_info("Exiting interface accounting thread")
Пример #2
0
    def getLength(self, from_interface):
        """Returns the length in metres of the link from the named interface

        If there are multiple peer interfaces on the link, the length returned
        is the length to the most distance interface.

        The length is calculated using the great circle distance based on the
        GPS co-ordinates of the two sites where the host containing the
        interface is located. If GPS information is not available for either
        end the link is set to a default value of 20000m. The default value
        can be modified via the default_link_length configuration file 
        parameter
        """
        session = getSessionE(self._session_id)
        orig = None
        orig_lat = 0
        orig_long = 0
        peers = []
        length = 0

        # Get the default link length
        default_link_length = config_getint("network", "default_link_length", DEFAULT_LINK_LENGTH)
        if default_link_length < MIN_DEFAULT_LINK_LENGTH:
            log_error("Invalid default link length! Must be > %sm" % MIN_DEFAULT_LINK_LENGTH)
            default_link_length = DEFAULT_LINK_LENGTH

        # Select the interface co-ordinates for all interfaces on this link
        res = session.query("SELECT * FROM interface_gpslocation WHERE " "link_id=%s", (self.link_id))
        if len(res) < 2:
            return default_link_length

        for iface in res:
            # No GPS co-ords available
            if iface["gps_lat"] <= 0 or iface["gps_long"] <= 0:
                return default_link_length
            this_lat = iface["gps_lat"]
            this_long = iface["gps_long"]
            if iface["interface_id"] == from_interface:
                try:
                    orig = nav.GeoPoint()
                    orig.set_latitude_dec(this_lat)
                    orig.set_longitude_dec(this_long)
                except:
                    log_warn("Invalid co-ordinates for interface %s" % from_interface, sys.exc_info())
                    return default_link_length
            else:
                peers.append((this_lat, this_long))
            if orig is not None:
                # Calculate distance
                while peers != []:
                    lat, long = peers.pop()
                    try:
                        peer = nav.GeoPoint()
                        peer.set_latitude_dec(lat)
                        peer.set_longitude_dec(long)
                    except:
                        log_warn("Invalid co-ordinates for interface", sys.exc_info())
                        return default_link_length
                    # Round the length up to the nearest integer and convert
                    # to metres
                    plength = int(ceil(orig.get_distance_to(peer) * 1000))
                    if plength > length:
                        length = plength

        # Check that at least one distance was calculated
        if length == 0:
            length = default_link_length
        return length