comparison mod_firewall/mod_firewall.lua @ 2070:2356114ff505

mod_firewall: Optimize string match operations, string.find is faster than .match since no string is returned
author Kim Alvefur <zash@zash.se>
date Fri, 11 Mar 2016 18:13:53 +0100
parents 7dbde05b48a9
children d2ad556dcfb7
comparison
equal deleted inserted replaced
2069:cf9cd666ba00 2070:2356114ff505
164 elseif line:sub(-1,-1) == "\\" then 164 elseif line:sub(-1,-1) == "\\" then
165 line_hold = (line_hold or "")..line:sub(1,-2); 165 line_hold = (line_hold or "")..line:sub(1,-2);
166 end 166 end
167 line_no = line_no + 1; 167 line_no = line_no + 1;
168 168
169 if line_hold or line:match("^[#;]") then 169 if line_hold or line:find("^[#;]") then
170 -- No action; comment or partial line 170 -- No action; comment or partial line
171 elseif line == "" then 171 elseif line == "" then
172 if state == "rules" then 172 if state == "rules" then
173 return nil, ("Expected an action on line %d for preceding criteria") 173 return nil, ("Expected an action on line %d for preceding criteria")
174 :format(line_no); 174 :format(line_no);
175 end 175 end
176 state = nil; 176 state = nil;
177 elseif not(state) and line:match("^::") then 177 elseif not(state) and line:sub(1, 2) == "::" then
178 chain = line:gsub("^::%s*", ""); 178 chain = line:gsub("^::%s*", "");
179 local chain_info = chains[chain]; 179 local chain_info = chains[chain];
180 if not chain_info then 180 if not chain_info then
181 return nil, errmsg("Unknown chain: "..chain); 181 return nil, errmsg("Unknown chain: "..chain);
182 elseif chain_info.type ~= "event" then 182 elseif chain_info.type ~= "event" then
183 return nil, errmsg("Only event chains supported at the moment"); 183 return nil, errmsg("Only event chains supported at the moment");
184 end 184 end
185 ruleset[chain] = ruleset[chain] or {}; 185 ruleset[chain] = ruleset[chain] or {};
186 elseif not(state) and line:match("^%%") then -- Definition (zone, limit, etc.) 186 elseif not(state) and line:sub(1,1) == "%" then -- Definition (zone, limit, etc.)
187 local what, name = line:match("^%%%s*(%w+) +([^ :]+)"); 187 local what, name = line:match("^%%%s*(%w+) +([^ :]+)");
188 if not definition_handlers[what] then 188 if not definition_handlers[what] then
189 return nil, errmsg("Definition of unknown object: "..what); 189 return nil, errmsg("Definition of unknown object: "..what);
190 elseif not name or not idsafe(name) then 190 elseif not name or not idsafe(name) then
191 return nil, errmsg("Invalid "..what.." name"); 191 return nil, errmsg("Invalid "..what.." name");
192 end 192 end
193 193
194 local val = line:match(": ?(.*)$"); 194 local val = line:match(": ?(.*)$");
195 if not val and line:match(":<") then -- Read from file 195 if not val and line:find(":<") then -- Read from file
196 local fn = line:match(":< ?(.-)%s*$"); 196 local fn = line:match(":< ?(.-)%s*$");
197 if not fn then 197 if not fn then
198 return nil, errmsg("Unable to parse filename"); 198 return nil, errmsg("Unable to parse filename");
199 end 199 end
200 local f, err = io.open(fn); 200 local f, err = io.open(fn);
212 212
213 if not active_definitions[what] then 213 if not active_definitions[what] then
214 active_definitions[what] = {}; 214 active_definitions[what] = {};
215 end 215 end
216 active_definitions[what][name] = ret; 216 active_definitions[what][name] = ret;
217 elseif line:match("^[^%s:]+[%.=]") then 217 elseif line:find("^[^%s:]+[%.=]") then
218 -- Action 218 -- Action
219 if state == nil then 219 if state == nil then
220 -- This is a standalone action with no conditions 220 -- This is a standalone action with no conditions
221 rule = new_rule(ruleset, chain); 221 rule = new_rule(ruleset, chain);
222 end 222 end
245 rule = new_rule(ruleset, chain); 245 rule = new_rule(ruleset, chain);
246 end 246 end
247 -- Check standard modifiers for the condition (e.g. NOT) 247 -- Check standard modifiers for the condition (e.g. NOT)
248 local negated; 248 local negated;
249 local condition = line:match("^[^:=%.]*"); 249 local condition = line:match("^[^:=%.]*");
250 if condition:match("%f[%w]NOT%f[^%w]") then 250 if condition:find("%f[%w]NOT%f[^%w]") then
251 local s, e = condition:match("%f[%w]()NOT()%f[^%w]"); 251 local s, e = condition:match("%f[%w]()NOT()%f[^%w]");
252 condition = (condition:sub(1,s-1)..condition:sub(e+1, -1)):match("^%s*(.-)%s*$"); 252 condition = (condition:sub(1,s-1)..condition:sub(e+1, -1)):match("^%s*(.-)%s*$");
253 negated = true; 253 negated = true;
254 end 254 end
255 condition = condition:gsub(" ", "_"); 255 condition = condition:gsub(" ", "_");
279 local condition_uses = {}; 279 local condition_uses = {};
280 -- This inner loop assumes chain is an event-based, not a filter-based 280 -- This inner loop assumes chain is an event-based, not a filter-based
281 -- chain (filter-based will be added later) 281 -- chain (filter-based will be added later)
282 for _, rule in ipairs(rules) do 282 for _, rule in ipairs(rules) do
283 for _, condition in ipairs(rule.conditions) do 283 for _, condition in ipairs(rule.conditions) do
284 if condition:match("^not%(.+%)$") then 284 if condition:find("^not%(.+%)$") then
285 condition = condition:match("^not%((.+)%)$"); 285 condition = condition:match("^not%((.+)%)$");
286 end 286 end
287 condition_uses[condition] = (condition_uses[condition] or 0) + 1; 287 condition_uses[condition] = (condition_uses[condition] or 0) + 1;
288 end 288 end
289 end 289 end
374 local chain_definition = chains[chain]; 374 local chain_definition = chains[chain];
375 if chain_definition and chain_definition.type == "event" then 375 if chain_definition and chain_definition.type == "event" then
376 for _, event_name in ipairs(chain_definition) do 376 for _, event_name in ipairs(chain_definition) do
377 module:hook(event_name, handler, chain_definition.priority); 377 module:hook(event_name, handler, chain_definition.priority);
378 end 378 end
379 elseif not chain:match("^user/") then 379 elseif not chain:sub(1, 5) == "user/" then
380 module:log("warn", "Unknown chain %q", chain); 380 module:log("warn", "Unknown chain %q", chain);
381 end 381 end
382 module:hook("firewall/chains/"..chain, handler); 382 module:hook("firewall/chains/"..chain, handler);
383 end 383 end
384 end 384 end