Asynchronous processingΒΆ

Since 1.8.0, dnsdist has the ability to process queries and responses in an asynchronous way, suspending them to continue processing other queries and responses, while we are waiting for an external event to occur.

This is done by calling the DNSQuestion:suspend() method on a query or a response to pause it, then later the getAsynchronousObject() to retrieve it before resuming via AsynchronousObject:resume().

A timeout must be supplied when pausing a query or a response, to prevent paused objects from piling up, consuming memory. When the timeout expires, the suspended object is automatically retrieved and resumes its processing where it was left.

Asynchronous processing of queries and responses

The following code shows a very simple example that forwards queries and responses to an external component over a unix network socket, and resumes them when it gets an answer from the external component.

  local asyncID = 0
  local asyncResponderEndpoint = newNetworkEndpoint('/path/to/unix/network/socket/remote/endpoint')
  local listener = newNetworkListener()
  listener:addUnixListeningEndpoint('/path/to/unix/network/socket/local/endpoint', 0, gotAsyncResponse)
  listener:start()

  function gotAsyncResponse(endpointID, message, from)
    local queryID = tonumber(message)
    local asyncObject = getAsynchronousObject(asyncID, queryID)
    local dq = asyncObject:getDQ()
    dq:setTag(filteringTagName, filteringTagValue)
    asyncObject:resume()
  end

  function passQueryToAsyncFilter(dq)
    local timeout = 500 -- 500 ms
    local buffer = dq:getContent()
    local id = dq.dh:getID()
    dq:suspend(asyncID, id, timeout)
    asyncResponderEndpoint:send(buffer)
    return DNSAction.Allow
  end

function passResponseToAsyncFilter(dr)
    local timeout = 500 -- 500 ms
    local buffer = dr:getContent()
    local id = dr.dh:getID()
    dr:suspend(asyncID, id, timeout)
    asyncResponderEndpoint:send(buffer)
    return DNSResponseAction.Allow
  end

  addAction(AllRule(), LuaAction(passQueryToAsyncFilter))
  addCacheHitResponseAction(AllRule(), LuaResponseAction(passResponseToAsyncFilter))
  addResponseAction(AllRule(), LuaResponseAction(passResponseToAsyncFilter))