diff --git a/docker/netrave-protohandler/config_manager.rb b/docker/netrave-protohandler/config_manager.rb new file mode 100644 index 0000000..4ee8a41 --- /dev/null +++ b/docker/netrave-protohandler/config_manager.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require 'json' +require 'singleton' + +module ProtoConfig + class ConfigManager + include Singleton + + attr_reader :recently_connected_time, :listen_ip, :listen_port, :db_type, :db_params, :db_username, :db_password + + def initialize + # Initialize with default settings + @recently_connected_time = 120 # default value + @listen_ip = '0.0.0.0' # default value + @listen_port = 3080 # default value + @db_type = 'sqlite' + @db_params = { username: nil, password: nil } # default value + + # Check if the config file exists in the current working directory + config_path = 'config.json' + create_default_config(config_path) unless File.exist?(config_path) + + load_config(config_path) + end + + def create_default_config(config_path) + default_config = { + 'recently_connected_time' => @recently_connected_time, + 'listen_ip' => @listen_ip, + 'listen_port' => @listen_port, + 'db_type' => @db_type, + 'db_params' => @db_params, + 'db_username' => @db_username, + 'db_password' => @db_password + } + File.write(config_path, JSON.pretty_generate(default_config)) + end + + def load_config(config_path) + # Load configuration from a JSON file + config_data = JSON.parse(File.read(config_path)) + + @recently_connected_time = config_data['recently_connected_time'] if config_data['recently_connected_time'] + @listen_ip = config_data['listen_ip'] if config_data['listen_ip'] + @listen_port = config_data['listen_port'] if config_data['listen_port'] + @db_type = config_data['db_type'] if config_data['db_type'] + @db_params = config_data['db_params'] if config_data['db_params'] + rescue StandardError => e + puts "Failed to load configuration: #{e.message}" + end + end +end diff --git a/docker/netrave-protohandler/db/database_manager_factory.rb b/docker/netrave-protohandler/db/database_manager_factory.rb new file mode 100644 index 0000000..a8b3ecf --- /dev/null +++ b/docker/netrave-protohandler/db/database_manager_factory.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +# The 'factory' that constructs the constructors for our various database managers +class DatabaseManagerFactory + def self.create(db_type, username: nil, password: nil) + db_manager = Object.new + case db_type + when 'sqlite_memory' + db_manager.extend(SQLiteMemoryManager) + when 'sqlite_flatfile' + db_manager.extend(SQLiteFlatFileManager) + when 'mysql' + db_manager.extend(MySQLManager) + when 'postgres' + db_manager.extend(PostgresManager) + when 'mongodb' + db_manager.extend(MongoDBManager) + else + raise "Unknown database type: #{db_type}" + end + + # Initialize the database manager with username and password if they exist + db_manager.initialize(username, password) if db_manager.respond_to?(:initialize) + + db_manager + end +end diff --git a/docker/netrave-protohandler/db/dbmanager_module.rb b/docker/netrave-protohandler/db/dbmanager_module.rb new file mode 100644 index 0000000..5712601 --- /dev/null +++ b/docker/netrave-protohandler/db/dbmanager_module.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +# CRUD operations for Database modularity +module DatabaseManager + def initialize_db(username = nil, password = nil); end + + def insert(table, data) + raise NotImplementedError, 'This method is defined in a mixin and must be overridden' + end + + def query(table, condition) + raise NotImplementedError, 'This method is defined in a mixin and must be overridden' + end + + def update(table, query, update) + raise NotImplementedError, 'This method is defined in a mixin and must be overridden' + end + + def delete(table, query) + raise NotImplementedError, 'This method is defined in a mixin and must be overridden' + end +end diff --git a/docker/netrave-protohandler/db/mongodb_module.rb b/docker/netrave-protohandler/db/mongodb_module.rb new file mode 100644 index 0000000..e208c78 --- /dev/null +++ b/docker/netrave-protohandler/db/mongodb_module.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'mongo' +require_relative 'dbmanager_module' + +module MongoDBManager + include DatabaseManager + + def initialize_db(username = nil, password = nil) + credentials = username && password ? { user: username, password: password } : {} + @client = Mongo::Client.new(['127.0.0.1:27017'], { database: 'my_db' }.merge(credentials)) + end + + def insert(table, data) + @client[table].insert_one(data) + end + + def query(table, condition) + @client[table].find(condition).to_a + end + + def update(table, query, update) + @client[table].find_one_and_update(query, { '$set' => update }) + end + + def delete(table, query) + @client[table].find_one_and_delete(query) + end +end diff --git a/docker/netrave-protohandler/db/mysqldb_module.rb b/docker/netrave-protohandler/db/mysqldb_module.rb new file mode 100644 index 0000000..06adcef --- /dev/null +++ b/docker/netrave-protohandler/db/mysqldb_module.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'sequel' + +module MySQLManager + include DatabaseManager + + def initialize_db + @db = Sequel.connect(adapter: 'mysql2', host: 'localhost', database: 'my_db', user: 'user', password: 'password') + # ... setup tables + end + + # ... implement CRUD operations +end diff --git a/docker/netrave-protohandler/db/postgre_module.rb b/docker/netrave-protohandler/db/postgre_module.rb new file mode 100644 index 0000000..7be796f --- /dev/null +++ b/docker/netrave-protohandler/db/postgre_module.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'sequel' + +module PostgresManager + include DatabaseManager + + def initialize_db + @db = Sequel.connect(adapter: 'postgres', host: 'localhost', database: 'my_db', user: 'user', password: 'password') + # ... setup tables + end + + # ... implement CRUD operations +end diff --git a/docker/netrave-protohandler/db/protohandler_dbmanager.rb b/docker/netrave-protohandler/db/protohandler_dbmanager.rb new file mode 100644 index 0000000..4ab1814 --- /dev/null +++ b/docker/netrave-protohandler/db/protohandler_dbmanager.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'sequel' + +class ProtohandlerDBManager + attr_reader :db + + def initialize + setup_database + end + + def setup_database + @db = Sequel.sqlite # In-memory database + + create_processors_table unless table_exists?(:processors) + create_orchestrators_table unless table_exists?(:orchestrators) + create_blacklist_table unless table_exists?(:blacklist) + end + + def table_exists?(table_name) + @db.table_exists?(table_name) + end + + def create_processors_table + @db.create_table :processors do + primary_key :proto_handler_id + String :uuid + String :domain + Integer :port + end + end + + def create_orchestrators_table + @db.create_table :orchestrators do + primary_key :id + String :domain + Integer :port + end + end + + def create_blacklist_table + @db.create_table :blacklist do + primary_key :id + String :uuid + end + end +end diff --git a/docker/netrave-protohandler/db/sqliteflatfile_module.rb b/docker/netrave-protohandler/db/sqliteflatfile_module.rb new file mode 100644 index 0000000..6cef61b --- /dev/null +++ b/docker/netrave-protohandler/db/sqliteflatfile_module.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'sequel' + +module SQLiteFlatFileManager + include DatabaseManager + + def initialize_db + @db = Sequel.sqlite('my_database.db') + # ... setup tables + end + + # ... implement CRUD operations +end diff --git a/docker/netrave-protohandler/db/sqlitememory_module.rb b/docker/netrave-protohandler/db/sqlitememory_module.rb new file mode 100644 index 0000000..92e7f13 --- /dev/null +++ b/docker/netrave-protohandler/db/sqlitememory_module.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'sequel' + +module SQLiteMemoryManager + include DatabaseManager + + def initialize_db + @db = Sequel.sqlite + # ... setup tables + end + + # ... implement CRUD operations +end diff --git a/docker/netrave-protohandler/netrave_protohandler.rb b/docker/netrave-protohandler/netrave_protohandler.rb index 1d8f643..6802889 100644 --- a/docker/netrave-protohandler/netrave_protohandler.rb +++ b/docker/netrave-protohandler/netrave_protohandler.rb @@ -2,42 +2,30 @@ require 'socket' require 'async' -require 'sequel' require 'openssl' require 'securerandom' +require_relative 'db/protohandler_dbmanager' -# Set up the database -DB = Sequel.sqlite # In-memory database +# main class for the protocol handler server +class ProtoServer + attr_reader :listen_ip, :listen_port, :db_manager -# Create processors table -DB.create_table :processors do - primary_key :proto_handler_id - String :uuid - String :domain - Integer :port + def initialize(listen_ip, listen_port) + @listen_ip = listen_ip + @listen_port = listen_port + @db_manager = ProtohandlerDBManager.new + end end -# Create orchestrators table -DB.create_table :orchestrators do - primary_key :id - String :domain - Integer :port -end +# Initialize server with config +config = ServerConfig.new('0.0.0.0', 3080) +server = TCPServer.new(config.listen_ip, config.listen_port) -# Create blacklist table -DB.create_table :blacklist do - primary_key :id - String :uuid -end - -processors = DB[:processors] -orchestrators = DB[:orchestrators] -blacklist = DB[:blacklist] - -listen_ip = ENV['LISTEN_IP'] || '0.0.0.0' -listen_port = ENV['LISTEN_PORT'] || 3080 - -server = TCPServer.new(listen_ip, listen_port) +# Initialize database tables +db_manager = config.db_manager +processors = db_manager.db[:processors] +orchestrators = db_manager.db[:orchestrators] +blacklist = db_manager.db[:blacklist] # This hash will store the recently connected UUIDs with their last validation timestamp recently_connected = {} @@ -58,21 +46,37 @@ def create_socket(ip, port) # rubocop:disable Metrics/MethodLength end end -def handle_input(line, processors, orchestrators, blacklist, recently_connected) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity +# Check if the UUID is blacklisted +def blacklisted?(uuid, blacklist) + blacklist.where(uuid:).count.positive? +end + +# Validate if the UUID has recently connected +def recently_connected?(uuid, recently_connected) + recently_connected[uuid] && Time.now - recently_connected[uuid] < 120 +end + +# Handle unregistered UUIDs +def handle_unregistered_uuid(uuid, processors, blacklist) + if uuid.nil? || processors.where(uuid:).count.zero? + blacklist.insert(uuid:) + return 'ERROR Unrecognized UUID' + end + nil +end + +def handle_input(line, processors, orchestrators, blacklist, recently_connected) command, *args = line.split uuid = args.shift if command != 'REGISTER' - # Check if the UUID is blacklisted - return 'TERMINATE' if blacklist.where(uuid:).count.positive? + return 'TERMINATE' if blacklisted?(uuid, blacklist) - # Check if the UUID is in the recently connected cache - if recently_connected[uuid] && Time.now - recently_connected[uuid] < 120 + if recently_connected?(uuid, recently_connected) # UUID is recently connected and within 2 minutes, no need to re-validate - elsif command != 'REGISTER' && (uuid.nil? || processors.where(uuid:).count.zero?) - # UUID is not recently connected or is invalid, add to blacklist - blacklist.insert(uuid:) - return 'ERROR Unrecognized UUID' else + unregistered_response = handle_unregistered_uuid(uuid, processors, blacklist) + return unregistered_response if unregistered_response + # UUID is valid, update the recently connected cache recently_connected[uuid] = Time.now end @@ -108,6 +112,7 @@ def register_orchestrator(line, orchestrators) puts "Orchestrator registered with domain: #{domain}, port: #{port}" end +# Main Async loop Async do loop do Async::Task.new do @@ -120,7 +125,7 @@ Async do register_orchestrator(line, orchestrators) else # Here we handle each line of input from the client - handle_input(line, processors, blacklist, recently_connected) + handle_input(line, processors, orchestrators, blacklist, recently_connected) end ensure # This code will be executed when the fiber is finished, regardless of whether an exception was raised diff --git a/docker/netrave-protohandler/npeph b/docker/netrave-protohandler/npeph new file mode 100644 index 0000000..a3853f6 --- /dev/null +++ b/docker/netrave-protohandler/npeph @@ -0,0 +1,18 @@ +#!/usr/bin/env ruby + +# frozen_string_literal: true + +require_relative 'config_manager' + +# Initialize the ConfigManager +config = ProtoConfig::ConfigManager.instance + +# Your logic to start the Protocol Handler goes here +# For example, you could initialize your server with the IP and port from the config +# Or pass the recently_connected_time to your connection handling logic + +puts "NETRAVE Packet Exchange Protocol Handler (NPEPH) is starting..." +puts "Listening on #{config.listen_ip}:#{config.listen_port}" +puts "Recently connected time threshold: #{config.recently_connected_time} seconds" + +# Your server initialization and start logic here diff --git a/lib/pkg/sumdb/sum.golang.org/latest b/lib/pkg/sumdb/sum.golang.org/latest index 5749fc7..80155c4 100644 --- a/lib/pkg/sumdb/sum.golang.org/latest +++ b/lib/pkg/sumdb/sum.golang.org/latest @@ -1,5 +1,5 @@ go.sum database tree -18982882 -5hq5RwlCLIiagi6hZScdHlumu5XIpITikSz2+tAr9LA= +19688221 +k58/ugqvqq6DqYjvo1m1COmAGb067rn6gQNOPDdtELg= -— sum.golang.org Az3grhw2ZJlhe/saIZhYrbHraYSRxzcFocBkNuDAACA6cT3QTOA1P1fa+rhYfXNq2KVoROv5wGw5Y/2naw4QGoEoYAE= +— sum.golang.org Az3grhYRJ7p1GIdTipHl5Sqe55vwSI8JugOEHx10umcUxmC5CFJxCpjrU3SFPAnm1YuxAZ3TqifbpfWXZncfjYtidgY=