Responding to a query

In this example for a request filter, we turn the request into a response and fill it out.

let pkt = context.packet;

let q = pkt.questions[0];

if (q.typeName === "A" && q.name === "foo.galliumdata.com") {

pkt.isQuery = false;

pkt.authoritative = true;
pkt.additionalRecords = [];

let ans = pkt.addAnswer("A");

ans.name = q.name;

ans.ipAddress = "";

context.result.response = pkt;


Note that you would typically filter for the type and the name in the filter's parameters.

We empty out additionalRecords because some DNS clients (like dig) add some options in it, and it would be an error to return those to the client.

Creating a generic answer from scratch

In this example, we create a new MX answer the hard way, by providing its byte content. It would be much easier to use addAnswer("MX"), of course, but this illustrate that you can create answer types that are not supported out of the box.

let ans = context.packet.addAnswer(""); // Create generic answer

ans.type = 15; // 15 = MX

ans.name = "galliumdata.com";

ans.data = [0,100,11,'g','a','l','l','i','u','m','d','a','t','a',3,'c','o','m',0];

The binary data follows the format for an MX answer:

  • two bytes for the preference (100)

  • a name whose components are prefixed with their length:

  • 11, which is the length of "galliumdata",

  • the 11 characters for "galliumdata"

  • 3, which is the length of "com",

  • the 3 characters for "com",

  • a zero to terminate.

Recording DNS queries in a Redis database

This requires that you have a Redis database, obviously. If you do not, you can start one with:

docker run --name gallium-redis -p 6379:6379 -d redis

You will also need to install the lettuce library, which is very easy:

In the Gallium Data app, go to the Libraries page (left nav)

⇨ Select the Find tab

⇨ In the Organization field, enter io.lettuce

⇨ In the Artifact field, enter lettuce-core

⇨ Click Find Libraries, and you should see a list of available versions.

⇨ Select version 6.1.2-RELEASE and add it to the repository.

⇨ Click Publish (at the top)

Note that publishing takes longer than usual (it might take 10-30 seconds). This is because Gallium Data has to download the lettuce library and its dependencies. This delay only happens the first time you install a new library.

Once that's done, create a JavaScript request filter with the following code:

if (!context.filterContext.redisAsync) {

const RedisClient = Java.type("io.lettuce.core.RedisClient");

const redisUrl = "redis://host.docker.internal:6379/0";

context.filterContext.redisAsync =



const q = context.packet.questions[0];

context.filterContext.redisAsync.incr(q.typeName + " " + q.name);

The screenshot shows some of the contents of the Redis database (using RedisInsight) after running this filter for a few minutes, with Gallium Data configured to be the default name server.

If you want to run RedisInsight, use something like:

docker run -d --name redis-insight -p 8001:8001 -v redisinsight:/db redislabs/redisinsight:latest

Open http://localhost:8001 and connect t