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 |
