comparison mod_firewall/mod_firewall.lua @ 6534:5aeefc2251d4

mod_firewall: Load a script completely or not at all Previously it was possible that some chains would load, but others would not. This can be surprising (that a "half-loaded" state is possible) and hard to debug. This change makes it so that if some chains don't compile, the whole script will be treated as not loaded.
author Matthew Wild <mwild1@gmail.com>
date Wed, 06 May 2026 16:15:38 +0100
parents 0f61d13ebbde
children 82b6a03b9dfa
comparison
equal deleted inserted replaced
6533:0f61d13ebbde 6534:5aeefc2251d4
686 if not chain_functions then 686 if not chain_functions then
687 module:log("error", "Error compiling %s: %s", script, err or "unknown error"); 687 module:log("error", "Error compiling %s: %s", script, err or "unknown error");
688 return; 688 return;
689 end 689 end
690 690
691 local errs;
692
691 -- Loop through the chains in the script, and for each chain attach the compiled code to the 693 -- Loop through the chains in the script, and for each chain attach the compiled code to the
692 -- relevant events, keeping track in events_hooked so we can cleanly unload later 694 -- relevant events, keeping track in events_hooked so we can cleanly unload later
693 local events_hooked = {}; 695 local events_hooked = {};
694 for chain, handler_code in pairs(chain_functions) do 696 for chain, handler_code in pairs(chain_functions) do
695 local new_handler, err = compile_handler(handler_code, "mod_firewall::"..chain); 697 local new_handler, err = compile_handler(handler_code, "mod_firewall::"..chain);
696 if not new_handler then 698 if not new_handler then
697 module:log("error", "Compilation error for %s: %s", script, err); 699 module:log("error", "Compilation error for %s: %s", script, err);
700 errs = true;
701 break;
698 else 702 else
699 local chain_definition = chains[chain]; 703 local chain_definition = chains[chain];
700 if chain_definition and chain_definition.type == "event" then 704 if chain_definition and chain_definition.type == "event" then
701 local handler = new_handler(chain_definition.pass_return); 705 local handler = new_handler(chain_definition.pass_return);
702 for _, event_name in ipairs(chain_definition) do 706 for _, event_name in ipairs(chain_definition) do
708 end 712 end
709 local event_name, handler = "firewall/chains/"..chain, new_handler(false); 713 local event_name, handler = "firewall/chains/"..chain, new_handler(false);
710 events_hooked[event_name] = handler; 714 events_hooked[event_name] = handler;
711 module:hook(event_name, handler); 715 module:hook(event_name, handler);
712 end 716 end
717 end
718 if errs then
719 for event_name, event_handler in pairs(events_hooked) do
720 module:unhook(event_name, event_handler);
721 events_hooked[event_name] = nil;
722 end
723 return;
713 end 724 end
714 loaded_scripts[script] = { last_modified = last_modified, events_hooked = events_hooked }; 725 loaded_scripts[script] = { last_modified = last_modified, events_hooked = events_hooked };
715 module:log("debug", "Loaded %s", script); 726 module:log("debug", "Loaded %s", script);
716 return true; 727 return true;
717 end 728 end