Mercurial > prosody-modules
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 |