char *fingerprint = meshlink_get_fingerprint(mesh, (meshlink_node_t *)mesh->self);
const char *keys[] = {MESHLINK_MDNS_NAME_KEY, MESHLINK_MDNS_FINGERPRINT_KEY};
const char *values[] = {mesh->name, fingerprint};
- size_t size = prepare_packet(data, sizeof data, fingerprint, mesh->appname, "tcp", atoi(mesh->myport), 2, keys, values);
+ size_t size = prepare_packet(data, sizeof data, fingerprint, mesh->appname, "tcp", atoi(mesh->myport), 2, keys, values, false);
+ free(fingerprint);
switch(addr->address.sa.sa_family) {
case AF_INET:
uint16_t port = 0;
const char *keys[2] = {MESHLINK_MDNS_NAME_KEY, MESHLINK_MDNS_FINGERPRINT_KEY};
char *values[2] = {NULL, NULL};
+ bool response;
- if(parse_packet(buf, len, &name, mesh->appname, "tcp", &port, 2, keys, values)) {
+ if(parse_packet(buf, len, &name, mesh->appname, "tcp", &port, 2, keys, values, &response)) {
node_t *n = (node_t *)meshlink_get_node(mesh, values[0]);
if(n) {
logger(mesh, MESHLINK_INFO, "Node %s is part of the mesh network.\n", n->name);
+ if(!response && n != mesh->self) {
+ // Send a unicast response back
+ char *fingerprint = meshlink_get_fingerprint(mesh, (meshlink_node_t *)mesh->self);
+ const char *response_values[] = {mesh->name, fingerprint};
+ size_t size = prepare_packet(buf, sizeof(buf), fingerprint, mesh->appname, "tcp", atoi(mesh->myport), 2, keys, response_values, true);
+ sendto(io->fd, buf, size, MSG_DONTWAIT | MSG_NOSIGNAL, &sa.sa, sl);
+ free(fingerprint);
+ }
+
switch(sa.sa.sa_family) {
case AF_INET:
sa.in.sin_port = port;
static void netlink_io_handler(event_loop_t *loop, void *data, int flags) {
(void)flags;
+ (void)data;
static time_t prev_update;
meshlink_handle_t *mesh = loop->data;
#elif defined(RTM_NEWADDR)
static void pfroute_io_handler(event_loop_t *loop, void *data, int flags) {
(void)flags;
+ (void)data;
static time_t prev_update;
meshlink_handle_t *mesh = loop->data;
free(mesh->discovery.ifaces);
free(mesh->discovery.addresses);
+ mesh->discovery.ifaces = NULL;
+ mesh->discovery.addresses = NULL;
mesh->discovery.iface_count = 0;
mesh->discovery.address_count = 0;
}
}
-size_t prepare_packet(void *vdata, size_t size, const char *name, const char *protocol, const char *transport, uint16_t port, int nkeys, const char **keys, const char **values) {
+size_t prepare_packet(void *vdata, size_t size, const char *name, const char *protocol, const char *transport, uint16_t port, int nkeys, const char **keys, const char **values, bool response) {
// Create the request/response packet right now
uint8_t *data = vdata;
buf_t buf = {data, size};
// Header
buf_add_uint16(&buf, 0); // TX ID
- buf_add_uint16(&buf, 0); // flags
+ buf_add_uint16(&buf, response ? ntohs(1 << 15) : 0); // flags
buf_add_uint16(&buf, 1); // 1 question
buf_add_uint16(&buf, 1); // 1 answer RR
buf_add_uint16(&buf, 0); // 0 authority RRs
}
}
-bool parse_packet(const void *vdata, size_t size, char **name, const char *protocol, const char *transport, uint16_t *port, int nkeys, const char **keys, char **values) {
+bool parse_packet(const void *vdata, size_t size, char **name, const char *protocol, const char *transport, uint16_t *port, int nkeys, const char **keys, char **values, bool *response) {
const uint8_t *data = vdata;
cbuf_t buf = {data, size};
// Header
buf_check_uint16(&buf, 0); // TX ID
- buf_check_uint16(&buf, 0); // flags
+ uint16_t flags = buf_get_uint16(&buf); // flags
buf_check_uint16(&buf, 1); // 1 question
buf_check_uint16(&buf, 1); // 1 answer RR
buf_check_uint16(&buf, 0); // 0 authority RRs
buf_check_uint16(&buf, 2); // 1 checkitional RR
- if(buf.len == -1) {
+ if(buf.len == -1 || flags & ~ntohs(1 << 15)) {
return false;
}
+ *response = flags & ntohs(1 << 15);
+
// Question section: _protocol._transport.local PTR IN
buf_check_ulabel(&buf, protocol);
buf_check_ulabel(&buf, transport);
#include <stdint.h>
#include <unistd.h>
-size_t prepare_packet(void *buf, size_t size, const char *name, const char *protocol, const char *transport, uint16_t port, int nkeys, const char **keys, const char **values);
-bool parse_packet(const void *buf, size_t size, char **name, const char *protocol, const char *transport, uint16_t *port, int nkeys, const char **keys, char **values);
+size_t prepare_packet(void *buf, size_t size, const char *name, const char *protocol, const char *transport, uint16_t port, int nkeys, const char **keys, const char **values, bool response);
+bool parse_packet(const void *buf, size_t size, char **name, const char *protocol, const char *transport, uint16_t *port, int nkeys, const char **keys, char **values, bool *response);