mirror of
https://github.com/r4sas/py-i2phosts
synced 2025-01-09 22:38:08 +00:00
ca831b2d45
Many hosts are not resolved with first lookup b32->b64, but if we query 2nd time, host can be resolved. Because of this, some registered hosts may be never seen while they actually up!
110 lines
3.2 KiB
Python
Executable File
110 lines
3.2 KiB
Python
Executable File
#!/usr/bin/python
|
|
|
|
import os
|
|
import sys
|
|
import argparse
|
|
import datetime
|
|
import configobj
|
|
import socket
|
|
import time
|
|
|
|
# parse command line options
|
|
parser = argparse.ArgumentParser(
|
|
description='Hosts checker for py-i2phosts.',
|
|
epilog='Report bugs to http://zzz.i2p/topics/733')
|
|
parser.add_argument('-d', '--debug', action='store_true',
|
|
help='set loglevel to debug and write messages to stdout'),
|
|
parser.add_argument('-v', '--verbose', action='store_true',
|
|
help='set loglevel to info and write messages to stdout'),
|
|
parser.add_argument('-c', '--config', default='/etc/py-i2phosts/checker.conf', dest='config_file',
|
|
help='config file to use')
|
|
args = parser.parse_args()
|
|
|
|
# read config
|
|
spec = '''
|
|
log_file = string(default='/var/log/py-i2phosts/master.log')
|
|
log_level = option('debug', 'info', 'warning', 'error', 'critical', default='info')
|
|
lookup_retries = integer(1, 20, default=2)
|
|
'''
|
|
spec = spec.split('\n')
|
|
config = configobj.ConfigObj(args.config_file, configspec=spec)
|
|
if 'include' in config:
|
|
config_included = configobj.ConfigObj(config['include'])
|
|
config.merge(config_included)
|
|
|
|
# django setup
|
|
DJANGO_SETTINGS_MODULE = 'pyi2phosts.settings'
|
|
if 'DJANGO_PROJECT_PATH' in config:
|
|
DJANGO_PROJECT_PATH = config['DJANGO_PROJECT_PATH']
|
|
else:
|
|
DJANGO_PROJECT_PATH = os.path.dirname(sys.argv[0]) + '/..'
|
|
sys.path.insert(1, DJANGO_PROJECT_PATH)
|
|
os.environ['DJANGO_SETTINGS_MODULE'] = DJANGO_SETTINGS_MODULE
|
|
from pyi2phosts.postkey.models import i2phost
|
|
from pyi2phosts.lib.utils import get_logger
|
|
from pyi2phosts.lib.utils import validate_config
|
|
from pyi2phosts.lib.utils import get_b32
|
|
|
|
# validate config
|
|
validate_config(config)
|
|
|
|
# configure logger
|
|
if args.debug == True:
|
|
log_level = 'debug'
|
|
log_file = None
|
|
elif args.verbose == True:
|
|
log_level = 'info'
|
|
log_file = None
|
|
else:
|
|
log_level = config['log_level']
|
|
log_file = config['log_file']
|
|
log = get_logger(filename=log_file, log_level=log_level)
|
|
|
|
# determine BOB interface address
|
|
if 'bob_addr' in config:
|
|
bob_addr = config['bob_addr']
|
|
else:
|
|
log.warning('BOB address isn\'t specified in config, falling back to localhost')
|
|
bob_addr = '127.0.0.1:2827'
|
|
|
|
# split bob_addr to ip and port
|
|
bob_ip, bob_port = bob_addr.split(':')
|
|
|
|
# connect to BOB
|
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
try:
|
|
s.connect((bob_ip, int(bob_port)))
|
|
# just receive BOB's greeting
|
|
time.sleep(1)
|
|
data = s.recv(512)
|
|
# make file object
|
|
f = s.makefile('r')
|
|
except socket.error, e:
|
|
log.error('failed to connect to BOB: %s', e)
|
|
sys.exit(1)
|
|
|
|
all_hosts = i2phost.objects.all().order_by('-activated', '-last_seen')
|
|
log.info('starting check')
|
|
for host in all_hosts:
|
|
log.debug('%s: testing...', host.name)
|
|
# get b32 address from full dest key
|
|
dest = host.b64hash
|
|
b32dest = get_b32(dest)
|
|
# do name lookup query with b32 address
|
|
# it success only if host is alive
|
|
for i in range(config['lookup_retries']):
|
|
s.send('lookup %s\n' % b32dest)
|
|
data = f.readline().rstrip('\n')
|
|
if data == 'ERROR Address Not found.':
|
|
log.debug('%s: unable to resolve, try: %s', host.name, i)
|
|
elif data == 'OK ' + host.b64hash:
|
|
log.info('alive host: %s', host.name)
|
|
# update lastseen timestamp
|
|
host.last_seen = datetime.datetime.utcnow()
|
|
host.save()
|
|
break
|
|
else:
|
|
log.warning('unexpected reply: %s', data)
|
|
s.close()
|
|
log.info('check finished')
|