Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated IPv8 exit node script to use RustEndpoint #1266

Merged
merged 8 commits into from
Jan 24, 2024
6 changes: 4 additions & 2 deletions ipv8/attestation/wallet/primitives/cryptography_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ def generate_safe_prime(bit_length: int, backend: Backend = default_backend()) -
out = int(backend._ffi.string(generated_hex), 16)
# Cleanup the memory
backend._lib.OPENSSL_free(generated_hex)
backend._lib.BN_clear_free(generated)
backend._lib.BN_set_word(generated, 0)
backend._lib.BN_free(generated)
return out


Expand Down Expand Up @@ -59,5 +60,6 @@ def is_prime(number: int, backend: Backend = default_backend()) -> bool: # noqa
raise RuntimeError(msg)
result = backend._lib.BN_is_prime_ex(generated, backend._lib.BN_prime_checks_for_size(int(len(bhex_n) * 8)),
backend._ffi.NULL, backend._ffi.NULL)
backend._lib.BN_clear_free(generated)
backend._lib.BN_set_word(generated, 0)
backend._lib.BN_free(generated)
return result == 1
16 changes: 7 additions & 9 deletions ipv8/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,13 @@
],
'bootstrappers': [DISPERSY_BOOTSTRAPPER.copy()],
'initialize': {
'settings': {
'min_circuits': 1,
'max_circuits': 1,
'max_joined_circuits': 100,
'max_time': 10 * 60,
'max_time_inactive': 20,
'max_traffic': 250 * 1024 * 1024,
'dht_lookup_interval': 30
}
'min_circuits': 1,
'max_circuits': 1,
'max_joined_circuits': 100,
'max_time': 10 * 60,
'max_time_inactive': 20,
'max_traffic': 250 * 1024 * 1024,
'dht_lookup_interval': 30
},
'on_start': [
('build_tunnels', 1)
Expand Down
24 changes: 16 additions & 8 deletions ipv8/messaging/anonymization/community.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
from ...requestcache import RequestCache
from ...taskmanager import task
from ...types import Address
from ..interfaces.dispatcher.endpoint import DispatcherEndpoint
from ..interfaces.endpoint import Endpoint
from .caches import *
from .crypto import CryptoEndpoint, PythonCryptoEndpoint, TunnelCrypto
from .endpoint import TunnelEndpoint
Expand Down Expand Up @@ -101,7 +103,7 @@ class TunnelSettings(CommunitySettings):
# to flow over the circuit (i.e. bandwidth payouts to intermediate nodes in a circuit).
remove_tunnel_delay = 5

_peer_flags: Set[int]
_peer_flags: Set[int] = {PEER_FLAG_RELAY, PEER_FLAG_SPEED_TEST}

_max_relay_early = 8

Expand All @@ -120,7 +122,7 @@ def max_relay_early(self, value: int) -> None:
Set the maximum number of relay_early cells that are allowed to pass a relay.
"""
self._max_relay_early = value
if hasattr(self.endpoint, 'set_max_relay_early'):
if hasattr(self, 'endpoint') and hasattr(self.endpoint, 'set_max_relay_early'):
self.endpoint.set_max_relay_early(value)

@property
Expand All @@ -136,7 +138,7 @@ def peer_flags(self, value: Set[int]) -> None:
Set the peer flags.
"""
self._peer_flags = value
if hasattr(self.endpoint, 'set_peer_flags'):
if hasattr(self, 'endpoint') and hasattr(self.endpoint, 'set_peer_flags'):
self.endpoint.set_peer_flags(value)


Expand All @@ -153,7 +155,6 @@ def __init__(self, settings: TunnelSettings) -> None:
"""
Create a new TunnelCommunity.
"""
settings.peer_flags = {PEER_FLAG_RELAY, PEER_FLAG_SPEED_TEST}
self.settings = settings
self.dht_provider = settings.dht_provider

Expand Down Expand Up @@ -188,7 +189,14 @@ def __init__(self, settings: TunnelSettings) -> None:
self.crypto: TunnelCrypto = TunnelCrypto()
self.crypto.initialize(cast(LibNaCLSK, self.my_peer.key))

self.crypto_endpoint = self.endpoint if isinstance(self.endpoint,
# For now, the TunnelCommunity only supports IPv4 for control messages.
# Data packets can still be sent to IPv6 destinations.
if isinstance(self.endpoint, DispatcherEndpoint):
ipv4_endpoint = cast(Endpoint, self.endpoint.interfaces["UDPIPv4"])
else:
ipv4_endpoint = self.endpoint

self.crypto_endpoint = ipv4_endpoint if isinstance(ipv4_endpoint,
CryptoEndpoint) else PythonCryptoEndpoint(self.endpoint)
self.crypto_endpoint.setup_tunnels(self, self.settings)

Expand Down Expand Up @@ -781,12 +789,12 @@ def on_created(self, source_address: Address, payload: CreatedPayload, _: int |

self.logger.info("Got CREATED message forward as EXTENDED to origin.")

exit_socket = self.exit_sockets.pop(request.from_circuit_id, None)
if exit_socket is None:
if request.from_circuit_id not in self.exit_sockets:
self.logger.info("Created for unknown exit socket %s", request.from_circuit_id)
return
session_keys = self.exit_sockets[request.from_circuit_id].hop.keys
self.remove_exit_socket(request.from_circuit_id, remove_now=True)

session_keys = exit_socket.hop.keys
bw_relay = RelayRoute(request.from_circuit_id, Hop(request.peer, session_keys), BACKWARD)
fw_relay = RelayRoute(request.to_circuit_id, Hop(request.to_peer, session_keys), FORWARD)

Expand Down
2 changes: 1 addition & 1 deletion ipv8/messaging/anonymization/crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ def relay_cell(self, cell: CellPayload) -> None:
return

next_relay = self.relays[cell.circuit_id]
this_relay = self.relays[next_relay.circuit_id]

if cell.relay_early and next_relay.relay_early_count >= self.max_relay_early:
self.logger.warning('Dropping cell (too many relay_early cells)')
Expand All @@ -208,6 +207,7 @@ def relay_cell(self, cell: CellPayload) -> None:
try:
if next_relay.rendezvous_relay:
self.decrypt_cell(cell, FORWARD, next_relay.hop)
this_relay = self.relays[next_relay.circuit_id]
self.encrypt_cell(cell, BACKWARD, this_relay.hop)
cell.relay_early = False
else:
Expand Down
3 changes: 3 additions & 0 deletions ipv8/test/messaging/anonymization/test_community.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
CIRCUIT_STATE_EXTENDING,
PEER_FLAG_EXIT_BT,
PEER_FLAG_EXIT_IPV8,
PEER_FLAG_RELAY,
PEER_FLAG_SPEED_TEST,
)
from ....messaging.interfaces.udp.endpoint import DomainAddress, UDPEndpoint
Expand Down Expand Up @@ -74,6 +75,8 @@ def create_node(self, settings: CommunitySettings | None = None, create_dht: boo
tunnel_settings.min_circuits = 0
tunnel_settings.max_circuits = 0
tunnel_settings.remove_tunnel_delay = 0
# For some reason the exit flag set gets remembered across tests, so create a new set here
tunnel_settings.peer_flags = {PEER_FLAG_RELAY, PEER_FLAG_SPEED_TEST}
ipv8 = MockIPv8("curve25519", TunnelCommunity, settings=tunnel_settings)
# Then kill all automated circuit creation
ipv8.overlay.cancel_all_pending_tasks()
Expand Down
3 changes: 3 additions & 0 deletions ipv8/test/messaging/anonymization/test_hiddenservices.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
CIRCUIT_TYPE_DATA,
CIRCUIT_TYPE_IP_SEEDER,
PEER_FLAG_EXIT_BT,
PEER_FLAG_RELAY,
PEER_FLAG_SPEED_TEST,
PEER_SOURCE_DHT,
IntroductionPoint,
Expand Down Expand Up @@ -106,6 +107,8 @@ def create_node(self, settings: None = None, create_dht: bool = False, enable_st
tunnel_settings.min_circuits = 0
tunnel_settings.max_circuits = 0
tunnel_settings.remove_tunnel_delay = 0
# For some reason the exit flag set gets remembered across tests, so create a new set here
tunnel_settings.peer_flags = {PEER_FLAG_RELAY, PEER_FLAG_SPEED_TEST}
ipv8 = MockIPv8("curve25519", HiddenTunnelCommunity, settings=tunnel_settings)
ipv8.overlay.ipv8 = ipv8
ipv8.overlay.crypto_endpoint.setup_tunnels(ipv8.overlay, tunnel_settings)
Expand Down
4 changes: 2 additions & 2 deletions ipv8/test/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,15 +385,15 @@ def test_default_configuration(self) -> None:
[WalkerDefinition(Strategy.RandomWalk, 20, {'timeout': 3.0})],
[BootstrapperDefinition(Bootstrapper.DispersyBootstrapper,
DISPERSY_BOOTSTRAPPER['init'])],
{'settings': {
{
'min_circuits': 1,
'max_circuits': 1,
'max_joined_circuits': 100,
'max_time': 10 * 60,
'max_time_inactive': 20,
'max_traffic': 250 * 1024 * 1024,
'dht_lookup_interval': 30
}},
},
[('build_tunnels', 1)]) \
.add_overlay("DHTDiscoveryCommunity",
"anonymous id",
Expand Down
5 changes: 3 additions & 2 deletions ipv8_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,9 @@ def __init__(self, # noqa: C901, PLR0912
for overlay in configuration['overlays']:
overlay_class = _COMMUNITIES.get(overlay['class'], (extra_communities or {}).get(overlay['class']))
my_peer = self.keys[overlay['key']]
settings = overlay_class.settings_class(my_peer=my_peer, endpoint=self.endpoint, network=self.network,
**overlay['initialize'])
settings = overlay_class.settings_class(my_peer=my_peer, endpoint=self.endpoint, network=self.network)
for k, v in overlay['initialize'].items():
setattr(settings, k, v)
overlay_instance = overlay_class(settings)
self.overlays.append(overlay_instance)
for walker in overlay['walkers']:
Expand Down
16 changes: 12 additions & 4 deletions scripts/exitnode_ipv8_only_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

from ipv8.configuration import get_default_configuration
from ipv8.messaging.anonymization.tunnel import PEER_FLAG_EXIT_IPV8
from ipv8.messaging.interfaces.dispatcher.endpoint import INTERFACES
from ipv8.REST.rest_manager import RESTManager
from ipv8.util import run_forever
from ipv8_service import IPv8
Expand Down Expand Up @@ -71,10 +72,17 @@ async def start_ipv8(self, statedir: str | None, listen_port: int, statistics: b

for overlay in configuration['overlays']:
if overlay['class'] == 'HiddenTunnelCommunity':
overlay['initialize']['settings']['min_circuits'] = 0
overlay['initialize']['settings']['max_circuits'] = 0
overlay['initialize']['settings']['max_joined_circuits'] = 1000
overlay['initialize']['settings']['peer_flags'] = {PEER_FLAG_EXIT_IPV8}
overlay['initialize']['min_circuits'] = 0
overlay['initialize']['max_circuits'] = 0
overlay['initialize']['max_joined_circuits'] = 1000
overlay['initialize']['peer_flags'] = {PEER_FLAG_EXIT_IPV8}

try:
from ipv8_rust_tunnels.endpoint import RustEndpoint as UDPEndpoint
except ImportError:
from ipv8.messaging.interfaces.udp.endpoint import UDPEndpoint

INTERFACES["UDPIPv4"] = UDPEndpoint

print("Starting IPv8") # noqa: T201

Expand Down