From eb39a1a662fc2a061fa422ea201b90b654be6b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20H=C3=B6rberg?= Date: Sat, 10 Sep 2022 21:16:39 +0200 Subject: [PATCH] Create and free a nftables ctx per invokation Maybe helps with the memory leak we're seeing on some machines. --- src/nftables.cr | 26 ++++++++++++-------------- src/server-cli.cr | 5 ++--- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/nftables.cr b/src/nftables.cr index 9cba0e6..8c3991e 100644 --- a/src/nftables.cr +++ b/src/nftables.cr @@ -2,12 +2,12 @@ # Class to interact with nftables # Not linked to libnftables, but calls out to the `nft` binary class Nftables - def run_cmd(cmd : String) : Nil + def self.run_cmd(cmd : String) : Nil status = Process.run("nft", {cmd}, output: Process::Redirect::Inherit, error: Process::Redirect::Inherit) status.success? || raise Error.new("nftables command '#{cmd}' failed") end - def run_file(file : String) : Nil + def self.run_file(file : String) : Nil status = Process.run("nft", {"-f", file}, output: Process::Redirect::Inherit, error: Process::Redirect::Inherit) status.success? || raise Error.new("nftables file '#{file}' failed") end @@ -18,28 +18,26 @@ # Class to interact with nftables # All output is printed to stdout/stderr class Nftables - def initialize - @nft = LibNftables.nft_ctx_new(LibNftables::NFT_CTX_DEFAULT) - end - - def finalize - LibNftables.nft_ctx_free(@nft) - end - # Execute a nft command, eg. 'list ruleset' - def run_cmd(cmd : String) : Nil + def self.run_cmd(cmd : String) : Nil + nft = LibNftables.nft_ctx_new(LibNftables::NFT_CTX_DEFAULT) buf = Bytes.new(cmd.bytesize + 1) # null terminated string buf.copy_from(cmd.to_slice) - LibNftables.nft_run_cmd_from_buffer(@nft, buf).zero? || + LibNftables.nft_run_cmd_from_buffer(nft, buf).zero? || raise Error.new("nftables command '#{cmd}' failed") + ensure + LibNftables.nft_ctx_free(nft) if nft end # Execute a nft script in a file - def run_file(file : String) : Nil + def self.run_file(file : String) : Nil + nft = LibNftables.nft_ctx_new(LibNftables::NFT_CTX_DEFAULT) buf = Bytes.new(file.bytesize + 1) # null terminated string buf.copy_from(file.to_slice) - LibNftables.nft_run_cmd_from_filename(@nft, buf).zero? || + LibNftables.nft_run_cmd_from_filename(nft, buf).zero? || raise Error.new("nftables file '#{file}' failed") + ensure + LibNftables.nft_ctx_free(nft) if nft end class Error < Exception; end diff --git a/src/server-cli.cr b/src/server-cli.cr index 1ac744e..79a8bc4 100644 --- a/src/server-cli.cr +++ b/src/server-cli.cr @@ -9,9 +9,8 @@ begin puts "HMAC keys: #{c.hmac_keys.size}" if c.nftables_cmd.bytesize > 0 puts "nftables command: #{c.nftables_cmd}" - nft = Nftables.new - on_accept = ->(ip_str : String) { - nft.run_cmd sprintf(c.nftables_cmd, ip_str) + on_accept = ->(ip_str : String) : Nil { + Nftables.run_cmd sprintf(c.nftables_cmd, ip_str) } else puts "Open command: #{c.open_cmd}"