mirror of
https://github.com/craigerl/aprsd.git
synced 2025-11-20 15:13:32 -05:00
This patch adds basic ratelimiting to sending out AckPackets and non AckPackets. This provides a basic way to prevent aprsd from sending out packets as fast as possible, which isn't great for a bandwidth limited network. This patch also adds some keepalive checks to all threads in the threadslist as well as the network client objects (apris, kiss)
92 lines
2.4 KiB
Python
92 lines
2.4 KiB
Python
import json
|
|
import logging
|
|
|
|
from oslo_config import cfg
|
|
import rpyc
|
|
from rpyc.utils.authenticators import AuthenticationError
|
|
from rpyc.utils.server import ThreadPoolServer
|
|
|
|
from aprsd import conf # noqa: F401
|
|
from aprsd import packets, stats, threads
|
|
from aprsd.threads import log_monitor
|
|
|
|
|
|
CONF = cfg.CONF
|
|
LOG = logging.getLogger("APRSD")
|
|
|
|
|
|
def magic_word_authenticator(sock):
|
|
magic = sock.recv(len(CONF.rpc_settings.magic_word)).decode()
|
|
if magic != CONF.rpc_settings.magic_word:
|
|
raise AuthenticationError(f"wrong magic word {magic}")
|
|
return sock, None
|
|
|
|
|
|
class APRSDRPCThread(threads.APRSDThread):
|
|
def __init__(self):
|
|
super().__init__(name="RPCThread")
|
|
self.thread = ThreadPoolServer(
|
|
APRSDService,
|
|
port=CONF.rpc_settings.port,
|
|
protocol_config={"allow_public_attrs": True},
|
|
authenticator=magic_word_authenticator,
|
|
)
|
|
|
|
def stop(self):
|
|
if self.thread:
|
|
self.thread.close()
|
|
self.thread_stop = True
|
|
|
|
def loop(self):
|
|
# there is no loop as run is blocked
|
|
if self.thread and not self.thread_stop:
|
|
# This is a blocking call
|
|
self.thread.start()
|
|
|
|
|
|
@rpyc.service
|
|
class APRSDService(rpyc.Service):
|
|
def on_connect(self, conn):
|
|
# code that runs when a connection is created
|
|
# (to init the service, if needed)
|
|
LOG.info("Connected")
|
|
self._conn = conn
|
|
|
|
def on_disconnect(self, conn):
|
|
# code that runs after the connection has already closed
|
|
# (to finalize the service, if needed)
|
|
LOG.info("Disconnected")
|
|
self._conn = None
|
|
|
|
@rpyc.exposed
|
|
def get_stats(self):
|
|
stat = stats.APRSDStats()
|
|
stats_dict = stat.stats()
|
|
LOG.debug(stats_dict)
|
|
return json.dumps(stats_dict, indent=4, sort_keys=True, default=str)
|
|
|
|
@rpyc.exposed
|
|
def get_stats_obj(self):
|
|
return stats.APRSDStats()
|
|
|
|
@rpyc.exposed
|
|
def get_packet_list(self):
|
|
return packets.PacketList()
|
|
|
|
@rpyc.exposed
|
|
def get_packet_track(self):
|
|
return packets.PacketTrack()
|
|
|
|
@rpyc.exposed
|
|
def get_watch_list(self):
|
|
return packets.WatchList()
|
|
|
|
@rpyc.exposed
|
|
def get_seen_list(self):
|
|
return packets.SeenList()
|
|
|
|
@rpyc.exposed
|
|
def get_log_entries(self):
|
|
entries = log_monitor.LogEntries().get_all_and_purge()
|
|
return json.dumps(entries, default=str)
|