added unix transport for testing

This commit is contained in:
Kevin F 2022-06-26 14:43:16 -05:00
parent b25e376349
commit 64a88118bd
7 changed files with 197 additions and 2 deletions

View File

@ -20,8 +20,8 @@ def do_announce():
except AttributeError:
pass
sock = announce_peer.get_socket(12)
sock.sendall(
command_to_byte(GossipCommands.ANNOUNCE) + our_transport_address)
sock.sendall(command_to_byte(GossipCommands.ANNOUNCE))
sock.sendall(our_transport_address)
if int.from_bytes(sock.recv(1), 'big') != 1:
logger.warn(
f"Could not announce with {announce_peer.transport_address}")

View File

@ -0,0 +1,25 @@
import config
import logger
from gossip.server import gossip_server_socket_file
from unixpeer import UnixPeer
def on_announce_rec(api, data=None):
announced: str = data['address']
try:
announced = announced.decode('utf-8')
except AttributeError:
pass
announced = announced.strip()
if announced == gossip_server_socket_file:
logger.warn(
"Received announcement for our unix node, which shouldn't happen",
terminal=True)
return
logger.info(f"Peer {announced} announced to us.", terminal=True)
data['callback'](UnixPeer(announced))

View File

@ -0,0 +1,68 @@
import shelve
from threading import Thread
from time import sleep
import os
import dbm
import traceback
from typing import Callable
from gossip.server import gossip_server_socket_file
from gossip.peer import Peer
from gossip.peerset import gossip_peer_set
from utils.identifyhome import identify_home
import logger
import config
from unixpeer import UnixPeer
from unixfilepaths import peer_database_file
bootstrap_file = f'{os.path.dirname(os.path.realpath(__file__))}/bootstrap.txt'
def load_existing_peers(callback: Callable):
"""Load peers saved to disk"""
peer_address: str = ''
# the peers here are saved on clean shutdown
with shelve.open(peer_database_file, 'r') as unix_peer_db:
peer_address: str = unix_peer_db.nextkey()
while peer_address:
Thread(
target=callback,
args=[unix_peer_db[peer_address]],
name=f'{peer_address} connection attempt',
daemon=True).start()
def on_bootstrap(api, data):
callback_func = data['callback']
try:
load_existing_peers(callback_func)
except dbm.error:
try:
with open(bootstrap_file, 'r') as bootstrap_file_obj:
bootstrap_nodes = set(bootstrap_file_obj.read().split(','))
except FileNotFoundError:
bootstrap_nodes = set()
except Exception as e:
logger.warn(traceback.format_exc(), terminal=True)
return
else:
return
while not os.path.exists(gossip_server_socket_file):
sleep(0.1)
for address in bootstrap_nodes:
if address == gossip_server_socket_file or not address:
continue
# Tell the gossip logic that this peer is ready to connect
# it will add it to data['peer_set'] if it responds to ping
Thread(
target=callback_func,
args=[UnixPeer(address)],
daemon=True).start()

View File

@ -0,0 +1 @@
/dev/shm/onionr655223043/gossip-server.sock

View File

@ -0,0 +1,71 @@
"""Onionr - Private P2P Communication.
Unix transport plugin. Intended for testing Onionr networks using IPC
"""
import sys
import os
import locale
from time import sleep
import traceback
from typing import Set, TYPE_CHECKING
from threading import Thread
import stem
from stem.control import Controller
import logger
from utils import readstatic
import config
from filepaths import gossip_server_socket_file
from gossip.peer import Peer
locale.setlocale(locale.LC_ALL, '')
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
# import after path insert
from unixpeer import UnixPeer
from bootstrap import on_bootstrap
from announce import on_announce_rec
#from shutdown import on_shutdown_event
"""
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
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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 <https://www.gnu.org/licenses/>.
"""
plugin_name = 'unixtransport'
PLUGIN_VERSION = '0.0.0'
def on_init(api, data=None):
logger.info(
f"Unix Transport Plugin v{PLUGIN_VERSION} enabled", terminal=True)
logger.info(
f"Peers can connect to {gossip_server_socket_file}", terminal=True)
def on_get_our_transport(api, data=None):
callback_func = data['callback']
for_peer = data['peer']
if data['peer'].__class__ == UnixPeer:
callback_func(for_peer, gossip_server_socket_file)
def on_gossip_start(api, data: Set[Peer] = None):
# We don't do gossip logic
return

View File

@ -0,0 +1,2 @@
from utils.identifyhome import identify_home
peer_database_file = f'{identify_home()}/unix-peers'

View File

@ -0,0 +1,28 @@
from os.path import exists
from socket import AF_UNIX, SOCK_STREAM, socket
class UnixPeer:
def __init__(self, socket_file):
if not exists(socket_file):
raise FileExistsError("No such file " + socket_file)
self.transport_address = socket_file
def get_socket(self, connect_timeout) -> socket:
s = socket(AF_UNIX, SOCK_STREAM)
#s.settimeout(connect_timeout)
s.connect(self.transport_address)
return s
def __hash__(self):
return hash(self.transport_address)
def __eq__(self, other):
try:
return self.transport_address == other.transport_address
except AttributeError:
return False