gluon-packages/net/respondd/README.md

4.0 KiB

What is respondd?

Introduction

respondd is a server distributing information within a network.

For doing so, respondd spawns a udp socket (1001/udp) joining a multicast group. When a request is received, the information requested is transmitted to the requestor.

All information is oranized in a non-hierachical namespace. Each entry identifies a provider implemented in at least one C module. (eg statistics, nodeinfo, ...) - each request queries a specific provider. Each response is the merge-result of the output of all modules registered for the provider.

Some providers are implemented in /package/gluon-respondd.

Usage

TODO: Why is the port number included in the multicast group, too?

respondd [-p <port>] [-g <group> -i <if0> [-i <if1> ..]] [-d <dir>]
  -p <int>         port number to listen on
  -g <ip6>         multicast group, e.g. ff02::2:1001
  -i <string>      interface on which the group is joined
  -d <string>      data provider directory (default: current directory)
  -h               this help

Procotol

Request and response are encoded as utf8-strings. These strings are sent as UDP-Packets. Fragmentation is not supported - gzip-compression (for the response) is optional.

  • The request is the name for the provider - 'GET ' can be prepended for compression
  • The response is encoded as JSON. The structure is determined by the actual data.

Example

Requesting nodeinfo as implemented in the freifunk-gluon modules.

Request

nodeinfo

Response

"nodeinfo": {
  "software": {
    "autoupdater": {
      "branch": "stable",
      "enabled": true
    },
    "batman-adv": {
      "version": "2015.1",
      "compat": 15
    },
    "fastd": {
      "version": "v17",
      "enabled": false
    },
    "firmware": {
      "base": "gluon-v2016.1.5-8-gdeac14e",
      "release": "20160615"
    },
    "status-page": {
      "api": 1
    }
  },
  "network": {
    "addresses": [
      "fda0:cab1:e1e5:5116:eade:27ff:fe65:a5af",
      "fe80::eade:27ff:fe65:a5af",
      "2a03:2260:3011:1160:eade:27ff:fe65:a5af"
    ],
    "mesh": {
      "bat0": {
        "interfaces": {
          "wireless": [
            "ea:e3:29:65:a5:af",
            "ea:e3:28:65:a5:af"
          ],
          "other": [
            "ea:df:27:65:a5:af"
          ]
        }
      }
    },
    "mac": "e8:de:27:65:a5:af"
  },
  "location": {
    "latitude": 51.10727924,
    "longitude": 7.00933367
  },
  "owner": {
    "contact": "me@petabyteboy.de"
  },
  "system": {
    "site_code": "lln"
  },
  "node_id": "e8de2765a5af",
  "hostname": "PetaByteBoy",
  "hardware": {
    "model": "TP-Link TL-WDR3600 v1",
    "nproc": 1
  }
}

Implementing modules

respondd providers are C modules (shared objects). These modules should include <json-c/json.h> and <respondd.h>, the latter of which provides the following definitions:

    typedef struct json_object * (*respondd_provider)(void);

    struct respondd_provider_info {
            const char *request;
            const respondd_provider provider;
    };

    extern const struct respondd_provider_info respondd_providers[];

The module must define the array respondd_providers, e.g. like this:

    static struct json_object * respondd_provider_nodeinfo(void) {
            ...
    }

    static struct json_object * respondd_provider_statistics(void) {
            ...
    }

    const struct respondd_provider_info respondd_providers[] = {
            {"nodeinfo", respondd_provider_nodeinfo},
            {"statistics", respondd_provider_statistics},
            {}
    };

The array must be terminated with an empty entry. The provider for each request type must return a JSON-C JSON object. This JSON object must have exactly 1 reference, and all other memory must be freed by the provider before returning.

The JSON objects returned by different provider modules for the same request type are merged.