Changeset 9a579d2747d842eebf153211332159209d39ec23

Show
Ignore:
Timestamp:
05/18/12 14:01:48 (2 years ago)
Author:
Theo Schlossnagle <jesus@omniti.com>
git-committer:
Theo Schlossnagle <jesus@omniti.com> 1337349708 -0400
git-parent:

[0d98102c9b5f193cad2d082eb882d85193da1734]

git-author:
Theo Schlossnagle <jesus@omniti.com> 1337349708 -0400
Message:

The NTP checker is a bit too sensitive about its incoming data.
We have some machines that send duplicate UDP packets and
that causes the NTP control checker to freak out. This
provides a simplistic form of tolerance under those conditions.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/modules-lua/noit/module/ntp.lua

    r25a8df2 r9a579d2  
    157157    local f = { } 
    158158    local req_packet = make_ntp_control(req) 
     159    local error = nil 
    159160    s:send(req_packet) 
    160161 
     
    163164    local done = false 
    164165    repeat 
     166        local lerr = nil 
    165167        local rv, buf = s:recv(480) -- max packet 
    166168        local offset, count, cnt 
    167169        -- need at least a header 
    168         if buf:len() < 12 then return "short packet" end 
    169  
    170         f.hdr = buf:sub(1,12) 
    171         f.buf = buf:sub(13,buf:len()) 
    172         cnt, f.li_vn_mode, f.r_m_e_op, f.sequence, 
    173             f.status, f.associd, offset, count = string.unpack(f.hdr, '>bbHHHHH') 
    174  
    175         f.mode = band(f.li_vn_mode, 0x7) 
    176         f.version = band(rshift(f.li_vn_mode, 3), 0x7) 
    177         f.leap = band(rshift(f.li_vn_mode, 6), 0x3) 
    178         f.op = band(f.r_m_e_op, 0x1f) 
    179         f.is_more = band(f.r_m_e_op, 0x20) ~= 0 
    180         f.is_error = band(f.r_m_e_op, 0x40) ~= 0 
    181         f.is_response = band(f.r_m_e_op, 0x80) ~= 0 
    182  
    183         -- validate 
    184         if f.version > 4 or f.version < 1 then return "bad version" end 
    185         if f.mode ~= 6 then return "not a control packet" end 
    186         if not f.is_response then return "not a response packet" end 
    187         if req.sequence ~= f.sequence then return "sequence mismatch" end 
    188         if req.op ~= f.op then return "opcode mismatch " .. req.op .. " != " .. f.op  end 
    189         if f.is_error then 
    190             return "error: " 
    191                 .. bit.tohex(band(rshift(f.status, 8), 0xff), 2) 
     170        if buf:len() < 12 then lerr = "short packet" end 
     171        if lerr == nil then 
     172          f.hdr = buf:sub(1,12) 
     173          f.buf = buf:sub(13,buf:len()) 
     174          cnt, f.li_vn_mode, f.r_m_e_op, f.sequence, 
     175              f.status, f.associd, offset, count = string.unpack(f.hdr, '>bbHHHHH') 
     176 
     177          f.mode = band(f.li_vn_mode, 0x7) 
     178          f.version = band(rshift(f.li_vn_mode, 3), 0x7) 
     179          f.leap = band(rshift(f.li_vn_mode, 6), 0x3) 
     180          f.op = band(f.r_m_e_op, 0x1f) 
     181          f.is_more = band(f.r_m_e_op, 0x20) ~= 0 
     182          f.is_error = band(f.r_m_e_op, 0x40) ~= 0 
     183          f.is_response = band(f.r_m_e_op, 0x80) ~= 0 
     184 
     185          -- validate 
     186          if f.version > 4 or f.version < 1 then lerr = "bad version" end 
     187          if f.mode ~= 6 then lerr = "not a control packet" end 
     188          if not f.is_response then lerr = "not a response packet" end 
     189          if req.sequence ~= f.sequence then lerr = "sequence mismatch" end 
     190          if req.op ~= f.op then lerr = "opcode mismatch " .. req.op .. " != " .. f.op  end 
     191          if f.is_error then 
     192              return "error: " 
     193                  .. bit.tohex(band(rshift(f.status, 8), 0xff), 2) 
     194          end 
    192195        end 
    193         local expect = band(band(12 + count + 3, bnot(3)),0xffff) 
    194         -- must be aligned on a word boundary 
    195         if band(buf:len(), 3) ~= 0 then return "bad padding" end 
    196         if expect > buf:len() then 
    197             return "bad payload size " .. expect .. " vs. " .. buf:len() 
    198         end 
    199         if expect < buf:len() then 
     196 
     197        if lerr == nil then 
     198          local expect = band(band(12 + count + 3, bnot(3)),0xffff) 
     199          -- must be aligned on a word boundary 
     200          if band(buf:len(), 3) ~= 0 then lerr = "bad padding" end 
     201          if expect > buf:len() then 
     202            lerr = "bad payload size " .. expect .. " vs. " .. buf:len() 
     203          end 
     204          if expect < buf:len() then 
    200205            -- auth 
    201206            return "auth unsupported " .. expect .. " vs. " .. buf:len() 
     207          end 
    202208        end 
    203         if f.num_frags > 23 then return "too many fragments" end 
    204         if count < f.buf:len() then 
     209        if lerr == nil then 
     210          if f.num_frags > 23 then return "too many fragments" end 
     211          if count < f.buf:len() then 
    205212            f.buf = f.buf:sub(1,count) 
     213          end 
     214          f.offsets[offset] = f.buf 
     215          done = not f.is_more 
    206216        end 
    207         f.offsets[offset] = f.buf 
    208         done = not f.is_more 
     217        if lerr ~= nil then 
     218          noit.log("debug", "ntp error:%s\n", lerr) 
     219        end 
     220        error = lerr 
    209221    until done 
    210222 
    211223    f.data = '' 
    212224    for i, buf in pairs(f.offsets) do f.data = f.data .. buf end 
    213     return nil, f 
     225    return error, f 
    214226end 
    215227