diff --git a/proxywatchd.py b/proxywatchd.py index 7ee3b91..35bf621 100644 --- a/proxywatchd.py +++ b/proxywatchd.py @@ -13,6 +13,7 @@ import rocksock config = Config() _run_standalone = False +cached_dns = dict() class WorkerJob(): def __init__(self, proxy, proto, failcount, success_count, total_duration): @@ -24,7 +25,7 @@ class WorkerJob(): self.total_duration = total_duration def connect_socket(self): - srv = random.choice(config.servers).strip() + srvname = random.choice(config.servers).strip() protos = ['http', 'socks5', 'socks4'] if self.proto is None else [self.proto] server_port = 6697 if config.watchd.use_ssl else 6667 @@ -32,6 +33,31 @@ class WorkerJob(): for proto in protos: torhost = random.choice(config.torhosts) + srv = srvname + if proto == 'socks4': + # socks4 (without 4a) requires a raw ip address + # rocksock automatically resolves if needed, but it's more + # efficient to cache the result. + if srv in cached_dns: + srv = cached_dns[srvname] + if config.watchd.debug: + _log("using cached ip (%s) for %s (proxy: %s)"%(srv, srvname, self.proxy), "debug") + else: + dns_fail = False + try: + af, sa = rocksock.resolve(rocksock.RocksockHostinfo(srvname, server_port), want_v4=True) + if sa is not None: + cached_dns[srvname] = sa[0] + srv = sa[0] + else: dns_fail = True + except rocksock.RocksockException as e: + assert(e.get_errortype() == rocksock.RS_ET_GAI) + dns_fail = True + if dns_fail: + fail_inc = 0 + _log("could not resolve connection target %s"%srvname, "ERROR") + break + duration = time.time() proxies = [ rocksock.RocksockProxyFromURL('socks4://%s' % torhost), @@ -42,7 +68,7 @@ class WorkerJob(): sock = rocksock.Rocksock(host=srv, port=server_port, ssl=config.watchd.use_ssl, proxies=proxies, timeout=config.watchd.timeout) sock.connect() sock.send('%s\n' % random.choice(['NICK', 'USER', 'JOIN', 'MODE', 'PART', 'INVITE', 'KNOCK', 'WHOIS', 'WHO', 'NOTICE', 'PRIVMSG', 'PING', 'QUIT'])) - return sock, proto, duration, torhost, srv, 0 + return sock, proto, duration, torhost, srvname, 0 except rocksock.RocksockException as e: if config.watchd.debug: _log("proxy failed: %s://%s: %s"%(proto, self.proxy, e.get_errormessage()), 'debug') @@ -66,8 +92,9 @@ class WorkerJob(): _log("could not connect to proxy 0, sleep 5s", "ERROR") time.sleep(5) elif et == rocksock.RS_ET_GAI: + assert(0) fail_inc = 0 - _log("could not resolve connection target %s"%srv, "ERROR") + _log("could not resolve connection target %s"%srvname, "ERROR") break except KeyboardInterrupt as e: