diff --git a/requirements.txt b/requirements.txt index 6e9873d..eb559c5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ peewee gunicorn arrow flask_wtf +git+https://github.com/cdiv1e12/py-levin diff --git a/xmrnodes/app.py b/xmrnodes/app.py index 4763954..844b797 100644 --- a/xmrnodes/app.py +++ b/xmrnodes/app.py @@ -10,7 +10,7 @@ from datetime import datetime, timedelta from flask import Flask, request, redirect from flask import render_template, flash, url_for from urllib.parse import urlparse -from xmrnodes.helpers import determine_crypto, is_onion, make_request +from xmrnodes.helpers import determine_crypto, is_onion, make_request, retrieve_peers from xmrnodes.forms import SubmitNode from xmrnodes.models import Node, HealthCheck from xmrnodes import config @@ -121,6 +121,11 @@ def check(): node.save() hc.save() +@app.cli.command("get_peers") +def get_peers(): + r = retrieve_peers() + print(r) + @app.cli.command("validate") def validate(): nodes = Node.select().where(Node.validated == False) diff --git a/xmrnodes/config.example.py b/xmrnodes/config.example.py index 116a24c..daa0ca7 100644 --- a/xmrnodes/config.example.py +++ b/xmrnodes/config.example.py @@ -4,3 +4,5 @@ SECRET_KEY = os.environ.get('SECRET_KEY', 'xxxx') DATA_DIR = os.environ.get('DATA_DIR', './data') TOR_HOST = os.environ.get('TOR_HOST', '127.0.0.1') TOR_PORT = os.environ.get('TOR_PORT', 9050) +NODE_HOST = os.environ.get('NODE_HOST', '127.0.0.1') +NODE_PORT = os.environ.get('NODE_PORT', 18080) diff --git a/xmrnodes/helpers.py b/xmrnodes/helpers.py index c065349..180f36f 100644 --- a/xmrnodes/helpers.py +++ b/xmrnodes/helpers.py @@ -1,3 +1,9 @@ +import sys +import socket +from levin.section import Section +from levin.bucket import Bucket +from levin.ctypes import * +from levin.constants import LEVIN_SIGNATURE from requests import get as r_get from xmrnodes import config @@ -47,3 +53,52 @@ def is_onion(url: str): return True else: return False + +def retrieve_peers(): + try: + sock = socket.socket() + sock.connect((config.NODE_HOST, config.NODE_PORT)) + except: + sys.stderr.write("unable to connect to %s:%d\n" % (config.NODE_HOST, config.NODE_PORT)) + sys.exit() + + bucket = Bucket.create_handshake_request() + + sock.send(bucket.header()) + sock.send(bucket.payload()) + + buckets = [] + peers = [] + + while 1: + buffer = sock.recv(8) + if not buffer: + sys.stderr.write("Invalid response; exiting\n") + break + + if not buffer.startswith(bytes(LEVIN_SIGNATURE)): + sys.stderr.write("Invalid response; exiting\n") + break + + bucket = Bucket.from_buffer(signature=buffer, sock=sock) + buckets.append(bucket) + + if bucket.command == 1001: + peers = bucket.get_peers() or [] + + for peer in peers: + try: + print('') + peers.append('http://{}:{}'.format( + peer['ip'].ip, peer['port'].value + )) + except: + pass + + sock.close() + break + + if peers: + return peers + else: + return None