return *dq.ednsOptions;
});
- g_lua.registerFunction<vector<uint8_t>(DNSQuestion::*)(void)>("getTrailingData", [](const DNSQuestion& dq) {
- const uint8_t* message = reinterpret_cast<const uint8_t*>(dq.dh);
- const uint16_t length = getDNSPacketLength(reinterpret_cast<const char*>(message), dq.len);
- vector<uint8_t> tail(message + length, message + dq.len);
+ g_lua.registerFunction<std::string(DNSQuestion::*)(void)>("getTrailingData", [](const DNSQuestion& dq) {
+ const char* message = reinterpret_cast<const char*>(dq.dh);
+ const uint16_t messageLen = getDNSPacketLength(message, dq.len);
+ const std::string tail = std::string(message + messageLen, dq.len - messageLen);
return tail;
});
- g_lua.registerFunction<bool(DNSQuestion::*)(vector<pair<int, uint8_t>>)>("setTrailingData", [](DNSQuestion& dq, const vector<pair<int, uint8_t>>&data) {
- uint8_t* message = reinterpret_cast<uint8_t*>(dq.dh);
- const uint16_t length = getDNSPacketLength(reinterpret_cast<const char*>(message), dq.len);
- if(length + data.size() > dq.size) {
+ g_lua.registerFunction<bool(DNSQuestion::*)(std::string)>("setTrailingData", [](DNSQuestion& dq, const std::string& tail) {
+ char* message = reinterpret_cast<char*>(dq.dh);
+ const uint16_t messageLen = getDNSPacketLength(message, dq.len);
+ const uint16_t tailLen = tail.size();
+ if(messageLen + tailLen > dq.size) {
return false;
}
- /* Copy data from the Lua array, whose first index is 1 instead of 0. */
- dq.len = length + data.size();
- uint8_t* tail = message + length - 1;
- for(const auto& pair : data) {
- *(tail + pair.first) = pair.second;
+ /* Update length and copy data from the Lua string. */
+ dq.len = messageLen + tailLen;
+ if(tailLen > 0) {
+ tail.copy(message + messageLen, tailLen);
}
return true;
});
g_lua.registerFunction<void(DNSResponse::*)(std::function<uint32_t(uint8_t section, uint16_t qclass, uint16_t qtype, uint32_t ttl)> editFunc)>("editTTLs", [](const DNSResponse& dr, std::function<uint32_t(uint8_t section, uint16_t qclass, uint16_t qtype, uint32_t ttl)> editFunc) {
editDNSPacketTTL((char*) dr.dh, dr.len, editFunc);
});
- g_lua.registerFunction<vector<uint8_t>(DNSResponse::*)(void)>("getTrailingData", [](const DNSResponse& dq) {
- const uint8_t* message = reinterpret_cast<const uint8_t*>(dq.dh);
- const uint16_t length = getDNSPacketLength(reinterpret_cast<const char*>(message), dq.len);
- vector<uint8_t> tail(message + length, message + dq.len);
+ g_lua.registerFunction<std::string(DNSResponse::*)(void)>("getTrailingData", [](const DNSResponse& dq) {
+ const char* message = reinterpret_cast<const char*>(dq.dh);
+ const uint16_t messageLen = getDNSPacketLength(message, dq.len);
+ const std::string tail = std::string(message + messageLen, dq.len - messageLen);
return tail;
});
- g_lua.registerFunction<bool(DNSResponse::*)(vector<pair<int, uint8_t>>)>("setTrailingData", [](DNSResponse& dq, const vector<pair<int, uint8_t>>&data) {
- uint8_t* message = reinterpret_cast<uint8_t*>(dq.dh);
- const uint16_t length = getDNSPacketLength(reinterpret_cast<const char*>(message), dq.len);
- if(length + data.size() > dq.size) {
+ g_lua.registerFunction<bool(DNSResponse::*)(std::string)>("setTrailingData", [](DNSResponse& dq, const std::string& tail) {
+ char* message = reinterpret_cast<char*>(dq.dh);
+ const uint16_t messageLen = getDNSPacketLength(message, dq.len);
+ const uint16_t tailLen = tail.size();
+ if(messageLen + tailLen > dq.size) {
return false;
}
- /* Copy data from the Lua array, whose first index is 1 instead of 0. */
- dq.len = length + data.size();
- uint8_t* tail = message + length - 1;
- for(const auto& pair : data) {
- *(tail + pair.first) = pair.second;
+ /* Update length and copy data from the Lua string. */
+ dq.len = messageLen + tailLen;
+ if(tailLen > 0) {
+ tail.copy(message + messageLen, tailLen);
}
return true;
});
:returns: A table of tags, using strings as keys and values
- .. method:: DNSQuestion:getTrailingData() -> table
+ .. method:: DNSQuestion:getTrailingData() -> string
.. versionadded:: 1.4.0
Get all data following the DNS message.
- :returns: A list of 8-bit integers
+ :returns: The trailing data as a null-safe string
.. method:: DNSQuestion:sendTrap(reason)
:param table tags: A table of tags, using strings as keys and values
- .. method:: DNSQuestion:setTrailingData(bytes) -> bool
+ .. method:: DNSQuestion:setTrailingData(tail) -> bool
.. versionadded:: 1.4.0
Set the data following the DNS message, overwriting anything already present.
- :param table bytes: The new data as a list of 8-bit integers
+ :param string tail: The new data
:returns: true if the operation succeeded, false otherwise
.. _DNSResponse:
newServer{address="127.0.0.1:%s"}
function replaceTrailingData(dq)
- local success = dq:setTrailingData({65, 66, 67}) -- "ABC"
+ local success = dq:setTrailingData("ABC")
if not success then
return DNSAction.ServFail, ""
end
function fillBuffer(dq)
local available = dq.size - dq.len
- local tail = extendTableBy({}, available)
+ local tail = string.rep("A", available)
local success = dq:setTrailingData(tail)
if not success then
return DNSAction.ServFail, ""
function exceedBuffer(dq)
local available = dq.size - dq.len
- local tail = extendTableBy({}, available + 1)
+ local tail = string.rep("A", available + 1)
local success = dq:setTrailingData(tail)
if not success then
return DNSAction.ServFail, ""
return DNSAction.None, ""
end
addLuaAction("limited.trailing.tests.powerdns.com.", exceedBuffer)
-
- function extendTableBy(t, n)
- if n <= 1 then
- if n == 1 then
- t[#t + 1] = 0
- end
- return t
- end
-
- local lower = math.floor(n / 2)
- local upper = n - lower
- t = extendTableBy(t, lower)
- t = extendTableBy(t, upper)
- return t
- end
"""
@classmethod
def startResponders(cls):
addAction(AndRule({QNameRule("dropped.trailing.tests.powerdns.com."), TrailingDataRule()}), DropAction())
function removeTrailingData(dq)
- local success = dq:setTrailingData({})
+ local success = dq:setTrailingData("")
if not success then
return DNSAction.ServFail, ""
end
addLuaAction("removed.trailing.tests.powerdns.com.", removeTrailingData)
function reportTrailingData(dq)
- local tailBytes = dq:getTrailingData()
- local tailChars = string.char(unpack(tailBytes))
- return DNSAction.Spoof, "-" .. tailChars .. ".echoed.trailing.tests.powerdns.com."
+ local tail = dq:getTrailingData()
+ return DNSAction.Spoof, "-" .. tail .. ".echoed.trailing.tests.powerdns.com."
end
addLuaAction("echoed.trailing.tests.powerdns.com.", reportTrailingData)
function replaceTrailingData(dq)
- local success = dq:setTrailingData({65, 66, 67}) -- "ABC"
+ local success = dq:setTrailingData("ABC")
if not success then
return DNSAction.ServFail, ""
end