143
143
if sys.version_info < (3, 2):
144
144
configparser.Configparser = configparser.SafeConfigParser
147
147
stored_state_file = "clients.pickle"
149
149
log = logging.getLogger(os.path.basename(sys.argv[0]))
961
961
# key_id() and fingerprint() functions
962
962
client["key_id"] = (section.get("key_id", "").upper()
963
963
.replace(" ", ""))
964
client["fingerprint"] = (section.get("fingerprint",
964
client["fingerprint"] = (section["fingerprint"].upper()
966
965
.replace(" ", ""))
967
if not (client["key_id"] or client["fingerprint"]):
968
log.error("Skipping client %s without key_id or"
969
" fingerprint", client_name)
970
del settings[client_name]
972
966
if "secret" in section:
973
967
client["secret"] = codecs.decode(section["secret"]
974
968
.encode("utf-8"),
1079
1074
def __del__(self):
1082
def init_checker(self, randomize_start=False):
1083
# Schedule a new checker to be started a randomly selected
1084
# time (a fraction of 'interval') from now. This spreads out
1085
# the startup of checkers over time when the server is
1077
def init_checker(self):
1078
# Schedule a new checker to be started an 'interval' from now,
1079
# and every interval from then on.
1087
1080
if self.checker_initiator_tag is not None:
1088
1081
GLib.source_remove(self.checker_initiator_tag)
1089
interval_milliseconds = int(self.interval.total_seconds()
1092
delay_milliseconds = random.randrange(
1093
interval_milliseconds + 1)
1095
delay_milliseconds = interval_milliseconds
1096
1082
self.checker_initiator_tag = GLib.timeout_add(
1097
delay_milliseconds, self.start_checker, randomize_start)
1098
delay = datetime.timedelta(0, 0, 0, delay_milliseconds)
1099
# A checker might take up to an 'interval' of time, so we can
1100
# expire at the soonest one interval after a checker was
1101
# started. Since the initial checker is delayed, the expire
1102
# time might have to be extended.
1103
now = datetime.datetime.utcnow()
1104
self.expires = now + delay + self.interval
1105
# Schedule a disable() at expire time
1083
random.randrange(int(self.interval.total_seconds() * 1000
1086
# Schedule a disable() when 'timeout' has passed
1106
1087
if self.disable_initiator_tag is not None:
1107
1088
GLib.source_remove(self.disable_initiator_tag)
1108
1089
self.disable_initiator_tag = GLib.timeout_add(
1109
int((self.expires - now).total_seconds() * 1000),
1090
int(self.timeout.total_seconds() * 1000), self.disable)
1091
# Also start a new checker *right now*.
1092
self.start_checker()
1112
1094
def checker_callback(self, source, condition, connection,
1156
1138
def need_approval(self):
1157
1139
self.last_approval_request = datetime.datetime.utcnow()
1159
def start_checker(self, start_was_randomized=False):
1141
def start_checker(self):
1160
1142
"""Start a new checker subprocess if one is not running.
1162
1144
If a checker already exists, leave it running and do
1212
1194
GLib.IOChannel.unix_new(pipe[0].fileno()),
1213
1195
GLib.PRIORITY_DEFAULT, GLib.IO_IN,
1214
1196
self.checker_callback, pipe[0], command)
1215
if start_was_randomized:
1216
# We were started after a random delay; Schedule a new
1217
# checker to be started an 'interval' from now, and every
1218
# interval from then on.
1219
now = datetime.datetime.utcnow()
1220
self.checker_initiator_tag = GLib.timeout_add(
1221
int(self.interval.total_seconds() * 1000),
1223
self.expires = max(self.expires, now + self.interval)
1224
# Don't start a new checker again after same random delay
1226
1197
# Re-run this periodically if run by GLib.timeout_add