From 4754ed45b607e82450a5e31fea1da3ba61433b04 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Mar 2021 08:54:12 +0100 Subject: Adding upstream version 1.1.0+debian. Signed-off-by: Daniel Baumann --- src/output/dnscli.lua | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 src/output/dnscli.lua (limited to 'src/output/dnscli.lua') diff --git a/src/output/dnscli.lua b/src/output/dnscli.lua new file mode 100644 index 0000000..bfdaf36 --- /dev/null +++ b/src/output/dnscli.lua @@ -0,0 +1,187 @@ +-- Copyright (c) 2018-2021, OARC, Inc. +-- All rights reserved. +-- +-- This file is part of dnsjit. +-- +-- dnsjit is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- dnsjit is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with dnsjit. If not, see . + +-- dnsjit.output.dnscli +-- DNS aware UDP/TCP/TLS client +-- local dnscli = require("dnsjit.output.dnscli") +-- .SS UDP Receiver Chain +-- local output = dnscli.new(dnscli.UDP) +-- output:connect("127.0.0.1", "53") +-- input:receiver(output) +-- .SS TCP Nonblocking +-- local output = dnscli.new(dnscli.TCP + dnscli.NONBLOCKING) +-- output:send(object) +-- +-- The DNS client can a +-- .I core.object.dns +-- or a +-- .I core.object.payload +-- object via the receiver interface or using +-- .I send() +-- and send it as DNS query after which it can receive the response by using +-- the producer interface. +-- If the object being sent is a +-- .I core.object.dns +-- then it will look at +-- .I includes_dnslen +-- attribute and depending on the protocol it will disregard, include or send +-- the DNS length as an extra packet. +-- If the object being sent is a +-- .I core.object.payload +-- then no special handling will be done and it will be sent as is. +-- When receiving responses the producer interface will generate +-- .I core.object.payload +-- objects which may include the DNS length depending on the protocol used and +-- must be handled by the caller. +-- .SS MODES +-- These transport modes and options are available when creating a new Dnscli +-- output. +-- .TP +-- UDP +-- Create an output using UDP. +-- .TP +-- TCP +-- Create an output using TCP. +-- .TP +-- TLS +-- Create an output using TCP and encrypt it with TLS. +-- .TP +-- NONBLOCKING +-- Make the client nonblocking, see +-- .I send() +-- and +-- .IR produce() . +module(...,package.seeall) + +require("dnsjit.output.dnscli_h") +local ffi = require("ffi") +local C = ffi.C + +local t_name = "output_dnscli_t" +local output_dnscli_t = ffi.typeof(t_name) +local Dnscli = { + NONBLOCKING = 0x1, + UDP = 0x10, + TCP = 0x20, + TLS = 0x30, +} + +-- Create a new Dnscli output. +function Dnscli.new(mode) + local self = { + obj = output_dnscli_t(), + } + C.output_dnscli_init(self.obj, mode) + ffi.gc(self.obj, C.output_dnscli_destroy) + return setmetatable(self, { __index = Dnscli }) +end + +-- Set or return the timeout used for sending and reciving, must be used before +-- .IR connect() . +function Dnscli:timeout(seconds, nanoseconds) + if seconds == nil and nanoseconds == nil then + return self.obj.timeout + end + if nanoseconds == nil then + nanoseconds = 0 + end + self.obj.timeout.sec = seconds + self.obj.timeout.nsec = nanoseconds +end + +-- Connect to the +-- .I host +-- and +-- .I port +-- and return 0 if successful. +function Dnscli:connect(host, port) + return C.output_dnscli_connect(self.obj, host, port) +end + +-- Return if nonblocking mode is on (true) or off (false). +function Dnscli:nonblocking() + if self.obj.nonblocking == 1 then + return true + end + return false +end + +-- Send an object and optionally continue sending after +-- .I sent +-- bytes. +-- Unlike the receive interface this function lets you know if the sending was +-- successful or not which might be needed on nonblocking connections. +-- Returns -2 on error, -1 if interrupted, timed out or unable to send due to +-- nonblocking, or the number of bytes sent. +-- .B Note +-- the counters for sent, received, errors and timeouts are not affected by +-- this function. +function Dnscli:send(object, sent) + if sent == nil then + sent = 0 + end + return C.output_dnscli_send(self.obj, object, sent) +end + +-- Return the C functions and context for receiving objects, these objects +-- will be sent. +function Dnscli:receive() + return C.output_dnscli_receiver(self.obj), self.obj +end + +-- Return the C functions and context for producing objects, these objects +-- are received. +-- If nonblocking mode is enabled the producer will return a payload object +-- with length zero if there was nothing to receive. +-- If nonblocking mode is disabled the producer will wait for data and if +-- timed out (see +-- .IR timeout ) +-- it will return a payload object with length zero. +-- The producer returns nil on error. +function Dnscli:produce() + return C.output_dnscli_producer(self.obj), self.obj +end + +-- Return the number of "packets" sent, actually the number of completely sent +-- payloads. +function Dnscli:packets() + return tonumber(self.obj.pkts) +end + +-- Return the number of "packets" received, actually the number of successful +-- calls to +-- .IR recvfrom (2) +-- that returned data. +function Dnscli:received() + return tonumber(self.obj.pkts_recv) +end + +-- Return the number of errors when sending or receiving. +function Dnscli:errors() + return tonumber(self.obj.errs) +end + +-- Return the number of timeouts when sending or receiving. +function Dnscli:timeouts() + return tonumber(self.obj.timeouts) +end + +-- core.object.dns (3), +-- core.object.payload (3), +-- core.timespec (3) +return Dnscli -- cgit v1.2.3