def main(): syslog.syslog(syslog.LOG_ERR, 'starting captiveportal background process') # handle to ipfw, arp and the config ipfw = IPFW() arp = ARP() cnf = Config() while True: try: # construct objects db = DB() # update accounting info db.update_accounting_info(ipfw.list_accounting_info()) # process sessions per zone arp.reload() cpzones = cnf.get_zones() for zoneid in cpzones: registered_addresses = ipfw.list_table(zoneid) registered_add_accounting = ipfw.list_accounting_info() expected_clients = db.list_clients(zoneid) # handle connected clients, timeouts, address changes, etc. for db_client in expected_clients: # fetch ip address (or network) from database cpnet = db_client['ipAddress'].strip() # there are different reasons why a session should be removed, check for all reasons and # use the same method for the actual removal drop_session = False # todo, static ip and addresses shouldn't be affected by the timeout rules below. # check if hardtimeout is set and overrun for this session if 'hardtimeout' in cpzones[zoneid] and str(cpzones[zoneid]['hardtimeout']).isdigit(): # hardtimeout should be set and we should have collected some session data from the client if int(cpzones[zoneid]['hardtimeout']) > 0 and float(db_client['startTime']) > 0: if (time.time() - float(db_client['startTime'])) / 60 > int(cpzones[zoneid]['hardtimeout']): drop_session = True # check if idletimeout is set and overrun for this session if 'idletimeout' in cpzones[zoneid] and str(cpzones[zoneid]['idletimeout']).isdigit(): # idletimeout should be set and we should have collected some session data from the client if int(cpzones[zoneid]['idletimeout']) > 0 and float(db_client['last_accessed']) > 0: if (time.time() - float(db_client['last_accessed'])) / 60 > int(cpzones[zoneid]['idletimeout']): drop_session = True # check session, if it should be active, validate its properties if not drop_session: # registered client, but not active according to ipfw (after reboot) if cpnet not in registered_addresses: ipfw.add_to_table(zoneid, cpnet) # is accounting rule still available? need to reapply after reload / reboot if cpnet not in registered_add_accounting and db_client['ipAddress'] not in registered_add_accounting: ipfw.add_accounting(cpnet) else: # remove session db.del_client(zoneid, db_client['sessionId']) ipfw.delete_from_table(zoneid, cpnet) ipfw.del_accounting(cpnet) # cleanup, destruct del db # sleep time.sleep(5) except KeyboardInterrupt: break except SystemExit: break except: syslog.syslog(syslog.LOG_ERR, traceback.format_exc())