diff --git a/src/netcontroller/torcontrol/onionservice/__init__.py b/src/netcontroller/torcontrol/onionservice/__init__.py
index 87f786fe..02bab477 100644
--- a/src/netcontroller/torcontrol/onionservice/__init__.py
+++ b/src/netcontroller/torcontrol/onionservice/__init__.py
@@ -9,7 +9,7 @@ from utils.identifyhome import identify_home
from .servicecontrol import create_new_service, restore_service
-ONION_KEY_DATABASE_FILE = identify_home() + "torgossip-onion-address-keys.db"
+ONION_KEY_DATABASE_FILE = identify_home() + "onion-address-keys.db"
class OnionServiceTarget(NamedTuple):
@@ -17,27 +17,34 @@ class OnionServiceTarget(NamedTuple):
unix_socket_path: str
+class NoServices(ValueError):
+ pass
+
+
def load_services(controller):
db = SafeDB(ONION_KEY_DATABASE_FILE, protected=True)
- keys = db.keys()
+ keys = db.db_conn.keys()
+ keys.remove(b'enc')
+ restored = []
if not keys:
db.close()
- raise ValueError("No addresses to restore")
+ raise NoServices("No addresses to restore")
while keys:
# Not most pythonic but reduces mem usage as it runs
key = keys.pop()
- if len(len) > 3:
- try:
- service = unpackb(db.get(key))
- restore_service(
- controller, service['k'], service['p'],
- unix_socket=service['s'])
- except Exception as _: # noqa
- db.close()
- raise
+ try:
+ service = unpackb(db.get(key))
+ service_id = restore_service(
+ controller, service['k'], int(service['p']),
+ unix_socket=service['s'])[0]
+ restored.append((service_id, service['s']))
+ except Exception as _: # noqa
+ db.close()
+ raise
db.close()
+ return restored
def run_new_and_store_service(controller, target: OnionServiceTarget) -> bytes:
diff --git a/src/netcontroller/torcontrol/onionservice/servicecontrol.py b/src/netcontroller/torcontrol/onionservice/servicecontrol.py
index fbb31b7a..59678701 100644
--- a/src/netcontroller/torcontrol/onionservice/servicecontrol.py
+++ b/src/netcontroller/torcontrol/onionservice/servicecontrol.py
@@ -27,16 +27,18 @@ along with this program. If not, see .
def _add_ephemeral_service(
controller: 'Controller', virtual_port, target, key_content=None):
- key_type = "ED25519-V3"
+ key_type = "NEW"
if not key_content:
- key_type = "NEW"
+ key_content = "ED25519-V3"
+ else:
+ key_type = "ED25519-V3"
hs = controller.create_ephemeral_hidden_service(
{virtual_port: target},
key_type=key_type,
key_content=key_content,
- await_publication=True,
detached=True
)
+
return (hs.service_id, hs.private_key)
@@ -65,10 +67,15 @@ def restore_service(
bind_location: str = None):
if unix_socket and bind_location or (not unix_socket and not bind_location):
raise ValueError("Must pick unix socket or ip:port, and not both")
- key = base64.b64encode(key)
+
+ key = base64.b64encode(key).decode()
+
target = unix_socket
if bind_location:
target = bind_location
- return _add_ephemeral_service(controller, virtual_port, target, key)
+ if not target.startswith("unix:"):
+ target = "unix:" + target
+ return _add_ephemeral_service(
+ controller, virtual_port, target, key_content=key)
diff --git a/src/onionrcommands/daemonlaunch/__init__.py b/src/onionrcommands/daemonlaunch/__init__.py
index 7dc0e77c..b4f07b05 100755
--- a/src/onionrcommands/daemonlaunch/__init__.py
+++ b/src/onionrcommands/daemonlaunch/__init__.py
@@ -18,6 +18,7 @@ from deadsimplekv import DeadSimpleKV
import psutil
import config
+from netcontroller.torcontrol import onionservice, torcontroller
import onionrstatistics
from onionrstatistics import serializeddata
import apiservers
@@ -246,6 +247,13 @@ def daemon():
_setup_online_mode(use_existing_tor, net, security_level)
_show_info_messages()
+
+ with torcontroller.get_controller() as c:
+ try:
+ onionservice.load_services(c)
+ except onionservice.NoServices:
+ pass
+
logger.info(
"Onionr daemon is running under " + str(os.getpid()), terminal=True)
events.event('init', threaded=False, data=shared_state)
diff --git a/static-data/default-plugins/torgossip/client.py b/static-data/default-plugins/torgossip/client.py
index cdbe05d2..b55e5d8d 100644
--- a/static-data/default-plugins/torgossip/client.py
+++ b/static-data/default-plugins/torgossip/client.py
@@ -4,6 +4,7 @@ Torgossip client
Create streams to random peers
"""
+import sys
from base64 import b32encode
from os import path
from typing import TYPE_CHECKING
@@ -17,6 +18,9 @@ from netcontroller.torcontrol import torcontroller
if TYPE_CHECKING:
from .peerdb import TorGossipPeers
from stem.control import Controller
+sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
+
+from commands import GossipCommands
"""
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -31,6 +35,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
"""
+controller = torcontroller.get_controller()
def _add_bootstrap_peers(peer_db: 'TorGossipPeers'):
@@ -38,13 +43,18 @@ def _add_bootstrap_peers(peer_db: 'TorGossipPeers'):
with open(bootstap_peers, 'r') as bs_peers:
peers = bs_peers.split(',')
for peer in peers:
- if peer:
+ try:
+ peer_db.get(peer)
+ except KeyError:
+ pass
+ else:
+ continue
+ if peer and service_online_recently(controller, peer):
peer_db.add_peer(peer)
-def _client_pool(shared_state, controller: 'Controller'):
+def _client_pool(shared_state, socket_pool: dict):
peer_db: 'TorGossipPeers' = shared_state.get_by_string('TorGossipPeers')
- socket_pool = {}
socks_port = shared_state.get_by_string('NetController').socksPort
peers = peer_db.get_highest_score_peers(20)
@@ -61,20 +71,23 @@ def _client_pool(shared_state, controller: 'Controller'):
try:
socket_pool[peer] = s.connect(
(b32encode(peer).decode().lower() + ".onion", 2021))
+
except socket.GeneralProxyError:
s.close()
-
-def client_pool(shared_state):
- controller = torcontroller.get_controller()
- # Pass the stem Controller and then close it even if an exception raises
- try:
- _client_pool(shared_state, controller)
- except Exception:
- raise
- finally:
- # Calls before the above raise no matter what
- controller.close()
+def client_loop(shared_state, socket_pool):
+ while True:
+ if not socket_pool:
+ _client_pool(shared_state, socket_pool)
+
+
+def start_client(shared_state):
+ # add boot strap peers to db if we need peers
+ _add_bootstrap_peers(shared_state.get_by_string('TorGossipPeers'))
+ # create and fill pool of sockets to peers (over tor socks)
+ socket_pool = {}
+ _client_pool(shared_state, socket_pool)
+ client_loop(shared_state, socket_pool)
diff --git a/static-data/default-plugins/torgossip/clientfuncs/__init__.py b/static-data/default-plugins/torgossip/clientfuncs/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/static-data/default-plugins/torgossip/constants.py b/static-data/default-plugins/torgossip/constants.py
index 148eb8ed..7a9cad43 100644
--- a/static-data/default-plugins/torgossip/constants.py
+++ b/static-data/default-plugins/torgossip/constants.py
@@ -1,3 +1,4 @@
from utils.identifyhome import identify_home
SERVER_SOCKET = identify_home() + "torgossip.sock"
+HOSTNAME_FILE = identify_home() + "torgossip-hostname"
GOSSIP_PORT = 2020
\ No newline at end of file
diff --git a/static-data/default-plugins/torgossip/main.py b/static-data/default-plugins/torgossip/main.py
index 85482678..5d76d51b 100755
--- a/static-data/default-plugins/torgossip/main.py
+++ b/static-data/default-plugins/torgossip/main.py
@@ -3,14 +3,18 @@ Onionr - Private P2P Communication
Default plugin which allows users to encrypt/decrypt messages w/o using blocks
"""
-from inspect import trace
+from base64 import b32encode
import locale
+
+from netcontroller.torcontrol import torcontroller
locale.setlocale(locale.LC_ALL, '')
import sys
import os
import traceback
from threading import Thread
+from netcontroller.torcontrol import onionservice
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
+from constants import SERVER_SOCKET, GOSSIP_PORT, HOSTNAME_FILE
"""
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -44,5 +48,27 @@ def on_init(api, data=None):
shared_state.get(TorGossipPeers)
+ hs = ""
+
+ try:
+ with open(HOSTNAME_FILE, "rb") as f:
+ hs = f.read()
+ if not hs:
+ raise FileNotFoundError
+ except FileNotFoundError:
+ with torcontroller.get_controller() as c:
+
+ try:
+ hs = onionservice.run_new_and_store_service(
+ c, onionservice.OnionServiceTarget(
+ GOSSIP_PORT, SERVER_SOCKET))
+ except Exception:
+ print(traceback.format_exc())
+ raise
+
+ with open(HOSTNAME_FILE, "wb") as hf:
+ hf.write(hs)
+
+
Thread(target=start_server, daemon=True, args=[shared_state]).start()
diff --git a/static-data/default-plugins/torgossip/peerdb.py b/static-data/default-plugins/torgossip/peerdb.py
index e5562dbf..2f59a0c1 100644
--- a/static-data/default-plugins/torgossip/peerdb.py
+++ b/static-data/default-plugins/torgossip/peerdb.py
@@ -25,7 +25,6 @@ along with this program. If not, see .
"""
-
class TorGossipPeers: # name it this way to avoid collisions in SharedState
PACK_FORMAT = "qQ"
diff --git a/static-data/default-plugins/torgossip/server.py b/static-data/default-plugins/torgossip/server.py
index 19b9db3a..96673526 100644
--- a/static-data/default-plugins/torgossip/server.py
+++ b/static-data/default-plugins/torgossip/server.py
@@ -14,7 +14,7 @@ sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
from commands import GossipCommands # noqa
import commandhandlers
-from .constants import SERVER_SOCKET
+from constants import SERVER_SOCKET
"""
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by