aboutsummaryrefslogtreecommitdiffstats
path: root/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h
diff options
context:
space:
mode:
authorLuca Muscariello <lumuscar@cisco.com>2022-03-30 22:29:28 +0200
committerMauro Sardara <msardara@cisco.com>2022-03-31 19:51:47 +0200
commitc46e5df56b67bb8ea7a068d39324c640084ead2b (patch)
treeeddeb17785938e09bc42eec98ee09b8a28846de6 /ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h
parent18fa668f25d3cc5463417ce7df6637e31578e898 (diff)
feat: boostrap hicn 22.02
The current patch provides several new features, improvements, bug fixes and also complete rewrite of entire components. - lib The hicn packet parser has been improved with a new packet format fully based on UDP. The TCP header is still temporarily supported but the UDP header will replace completely the new hicn packet format. Improvements have been made to make sure every packet parsing operation is made via this library. The current new header can be used as header between the payload and the UDP header or as trailer in the UDP surplus area to be tested when UDP options will start to be used. - hicn-light The portable packet forwarder has been completely rewritten from scratch with the twofold objective to improve performance and code size but also to drop dependencies such as libparc which is now removed by the current implementation. - hicn control the control library is the agent that is used to program the packet forwarders via their binary API. This component has benefited from significant improvements in terms of interaction model which is now event driven and more robust to failures. - VPP plugin has been updated to support VPP 22.02 - transport Major improvement have been made to the RTC protocol, to the support of IO modules and to the security sub system. Signed manifests are the default data authenticity and integrity framework. Confidentiality can be enabled by sharing the encryption key to the prod/cons layer. The library has been tested with group key based applications such as broadcast/multicast and real-time on-line meetings with trusted server keys or MLS. - testing Unit testing has been introduced using GoogleTest. One third of the code base is covered by unit testing with priority on critical features. Functional testing has also been introduce using Docker, linux bridging and Robot Framework to define test with Less Code techniques to facilitate the extension of the coverage. Co-authored-by: Mauro Sardara <msardara@cisco.com> Co-authored-by: Jordan Augé <jordan.auge+fdio@cisco.com> Co-authored-by: Michele Papalini <micpapal@cisco.com> Co-authored-by: Angelo Mantellini <manangel@cisco.com> Co-authored-by: Jacques Samain <jsamain@cisco.com> Co-authored-by: Olivier Roques <oroques+fdio@cisco.com> Co-authored-by: Enrico Loparco <eloparco@cisco.com> Co-authored-by: Giulio Grassi <gigrassi@cisco.com> Change-Id: I75d0ef70f86d921e3ef503c99271216ff583c215 Signed-off-by: Luca Muscariello <muscariello@ieee.org> Signed-off-by: Mauro Sardara <msardara@cisco.com>
Diffstat (limited to 'ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h')
-rw-r--r--ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h950
1 files changed, 459 insertions, 491 deletions
diff --git a/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h b/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h
index ff04b5d72..4b8e7a7f4 100644
--- a/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h
+++ b/ctrl/facemgr/src/interfaces/bonjour/mdns/mdns.h
@@ -7,7 +7,8 @@
*
* https://github.com/mjansson/mdns
*
- * This library is put in the public domain; you can redistribute it and/or modify it without any restrictions.
+ * This library is put in the public domain; you can redistribute it and/or
+ * modify it without any restrictions.
*
*/
@@ -31,76 +32,73 @@
#define MDNS_INVALID_POS ((size_t)-1)
-#define MDNS_STRING_CONST(s) (s), (sizeof((s))-1)
+#define MDNS_STRING_CONST(s) (s), (sizeof((s)) - 1)
#define MDNS_STRING_FORMAT(s) (int)((s).length), s.str
enum mdns_record_type {
- MDNS_RECORDTYPE_IGNORE = 0,
- //Address
- MDNS_RECORDTYPE_A = 1,
- //Domain Name pointer
- MDNS_RECORDTYPE_PTR = 12,
- //Arbitrary text string
- MDNS_RECORDTYPE_TXT = 16,
- //IP6 Address [Thomson]
- MDNS_RECORDTYPE_AAAA = 28,
- //Server Selection [RFC2782]
- MDNS_RECORDTYPE_SRV = 33
+ MDNS_RECORDTYPE_IGNORE = 0,
+ // Address
+ MDNS_RECORDTYPE_A = 1,
+ // Domain Name pointer
+ MDNS_RECORDTYPE_PTR = 12,
+ // Arbitrary text string
+ MDNS_RECORDTYPE_TXT = 16,
+ // IP6 Address [Thomson]
+ MDNS_RECORDTYPE_AAAA = 28,
+ // Server Selection [RFC2782]
+ MDNS_RECORDTYPE_SRV = 33
};
enum mdns_entry_type {
- MDNS_ENTRYTYPE_ANSWER = 1,
- MDNS_ENTRYTYPE_AUTHORITY = 2,
- MDNS_ENTRYTYPE_ADDITIONAL = 3
+ MDNS_ENTRYTYPE_ANSWER = 1,
+ MDNS_ENTRYTYPE_AUTHORITY = 2,
+ MDNS_ENTRYTYPE_ADDITIONAL = 3
};
-enum mdns_class {
- MDNS_CLASS_IN = 1
-};
+enum mdns_class { MDNS_CLASS_IN = 1 };
-typedef enum mdns_record_type mdns_record_type_t;
-typedef enum mdns_entry_type mdns_entry_type_t;
-typedef enum mdns_class mdns_class_t;
+typedef enum mdns_record_type mdns_record_type_t;
+typedef enum mdns_entry_type mdns_entry_type_t;
+typedef enum mdns_class mdns_class_t;
-typedef int (* mdns_record_callback_fn)(const struct sockaddr* from,
- mdns_entry_type_t entry, uint16_t type,
- uint16_t rclass, uint32_t ttl,
- const void* data, size_t size, size_t offset, size_t length,
- void* user_data);
+typedef int (*mdns_record_callback_fn)(const struct sockaddr* from,
+ mdns_entry_type_t entry, uint16_t type,
+ uint16_t rclass, uint32_t ttl,
+ const void* data, size_t size,
+ size_t offset, size_t length,
+ void* user_data);
-typedef struct mdns_string_t mdns_string_t;
-typedef struct mdns_string_pair_t mdns_string_pair_t;
-typedef struct mdns_record_srv_t mdns_record_srv_t;
-typedef struct mdns_record_txt_t mdns_record_txt_t;
+typedef struct mdns_string_t mdns_string_t;
+typedef struct mdns_string_pair_t mdns_string_pair_t;
+typedef struct mdns_record_srv_t mdns_record_srv_t;
+typedef struct mdns_record_txt_t mdns_record_txt_t;
struct mdns_string_t {
- const char* str;
- size_t length;
+ const char* str;
+ size_t length;
};
struct mdns_string_pair_t {
- size_t offset;
- size_t length;
- int ref;
+ size_t offset;
+ size_t length;
+ int ref;
};
struct mdns_record_srv_t {
- uint16_t priority;
- uint16_t weight;
- uint16_t port;
- mdns_string_t name;
+ uint16_t priority;
+ uint16_t weight;
+ uint16_t port;
+ mdns_string_t name;
};
struct mdns_record_txt_t {
- mdns_string_t key;
- mdns_string_t value;
+ mdns_string_t key;
+ mdns_string_t value;
};
-static int
-mdns_socket_open_ipv4(void);
+static int mdns_socket_open_ipv4(void);
-static int
-mdns_socket_setup_ipv4(int sock);
+static int mdns_socket_setup_ipv4(int sock);
#if 0
static int
@@ -112,8 +110,7 @@ static int
mdns_socket_setup_ipv6(int sock);
#endif
-static void
-mdns_socket_close(int sock);
+static void mdns_socket_close(int sock);
#if 0
static int
@@ -125,21 +122,18 @@ mdns_discovery_recv(int sock, void* buffer, size_t capacity,
mdns_record_callback_fn callback, void* user_data);
#endif
-static int
-mdns_query_send(int sock, mdns_record_type_t type, const char* name, size_t length,
- void* buffer, size_t capacity);
+static int mdns_query_send(int sock, mdns_record_type_t type, const char* name,
+ size_t length, void* buffer, size_t capacity);
-static size_t
-mdns_query_recv(int sock, void* buffer, size_t capacity,
- mdns_record_callback_fn callback, void* user_data,
- uint8_t one_shot);
+static size_t mdns_query_recv(int sock, void* buffer, size_t capacity,
+ mdns_record_callback_fn callback, void* user_data,
+ uint8_t one_shot);
-static mdns_string_t
-mdns_string_extract(const void* buffer, size_t size, size_t* offset,
- char* str, size_t capacity);
+static mdns_string_t mdns_string_extract(const void* buffer, size_t size,
+ size_t* offset, char* str,
+ size_t capacity);
-static int
-mdns_string_skip(const void* buffer, size_t size, size_t* offset);
+static int mdns_string_skip(const void* buffer, size_t size, size_t* offset);
#if 0
static int
@@ -147,78 +141,80 @@ mdns_string_equal(const void* buffer_lhs, size_t size_lhs, size_t* ofs_lhs,
const void* buffer_rhs, size_t size_rhs, size_t* ofs_rhs);
#endif
-static void*
-mdns_string_make(void* data, size_t capacity, const char* name, size_t length);
+static void* mdns_string_make(void* data, size_t capacity, const char* name,
+ size_t length);
-static mdns_string_t
-mdns_record_parse_ptr(const void* buffer, size_t size, size_t offset, size_t length,
- char* strbuffer, size_t capacity);
+static mdns_string_t mdns_record_parse_ptr(const void* buffer, size_t size,
+ size_t offset, size_t length,
+ char* strbuffer, size_t capacity);
-static mdns_record_srv_t
-mdns_record_parse_srv(const void* buffer, size_t size, size_t offset, size_t length,
- char* strbuffer, size_t capacity);
+static mdns_record_srv_t mdns_record_parse_srv(const void* buffer, size_t size,
+ size_t offset, size_t length,
+ char* strbuffer,
+ size_t capacity);
-static struct sockaddr_in*
-mdns_record_parse_a(const void* buffer, size_t size, size_t offset, size_t length,
- struct sockaddr_in* addr);
+static struct sockaddr_in* mdns_record_parse_a(const void* buffer, size_t size,
+ size_t offset, size_t length,
+ struct sockaddr_in* addr);
-static struct sockaddr_in6*
-mdns_record_parse_aaaa(const void* buffer, size_t size, size_t offset, size_t length,
- struct sockaddr_in6* addr);
+static struct sockaddr_in6* mdns_record_parse_aaaa(const void* buffer,
+ size_t size, size_t offset,
+ size_t length,
+ struct sockaddr_in6* addr);
-static size_t
-mdns_record_parse_txt(const void* buffer, size_t size, size_t offset, size_t length,
- mdns_record_txt_t* records, size_t capacity);
+static size_t mdns_record_parse_txt(const void* buffer, size_t size,
+ size_t offset, size_t length,
+ mdns_record_txt_t* records,
+ size_t capacity);
// Implementations
-static int
-mdns_socket_open_ipv4(void) {
- int sock = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (sock < 0)
- return -1;
- if (mdns_socket_setup_ipv4(sock)) {
- mdns_socket_close(sock);
- return -1;
- }
- return sock;
+static int mdns_socket_open_ipv4(void) {
+ int sock = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (sock < 0) return -1;
+ if (mdns_socket_setup_ipv4(sock)) {
+ mdns_socket_close(sock);
+ return -1;
+ }
+ return sock;
}
-static int
-mdns_socket_setup_ipv4(int sock) {
- struct sockaddr_in saddr;
- memset(&saddr, 0, sizeof(saddr));
- saddr.sin_family = AF_INET;
- saddr.sin_addr.s_addr = INADDR_ANY;
+static int mdns_socket_setup_ipv4(int sock) {
+ struct sockaddr_in saddr;
+ memset(&saddr, 0, sizeof(saddr));
+ saddr.sin_family = AF_INET;
+ saddr.sin_addr.s_addr = INADDR_ANY;
#ifdef __APPLE__
- saddr.sin_len = sizeof(saddr);
+ saddr.sin_len = sizeof(saddr);
#endif
- if (bind(sock, (struct sockaddr*)&saddr, sizeof(saddr)))
- return -1;
+ if (bind(sock, (struct sockaddr*)&saddr, sizeof(saddr))) return -1;
#ifdef _WIN32
- unsigned long param = 1;
- ioctlsocket(sock, FIONBIO, &param);
+ unsigned long param = 1;
+ ioctlsocket(sock, FIONBIO, &param);
#else
- const int flags = fcntl(sock, F_GETFL, 0);
- fcntl(sock, F_SETFL, flags | O_NONBLOCK);
+ const int flags = fcntl(sock, F_GETFL, 0);
+ fcntl(sock, F_SETFL, flags | O_NONBLOCK);
#endif
- unsigned char ttl = 1;
- unsigned char loopback = 1;
- struct ip_mreq req;
+ unsigned char ttl = 1;
+ unsigned char loopback = 1;
+ struct ip_mreq req;
- setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl, sizeof(ttl));
- setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&loopback, sizeof(loopback));
+ setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl,
+ sizeof(ttl));
+ setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&loopback,
+ sizeof(loopback));
- memset(&req, 0, sizeof(req));
- req.imr_multiaddr.s_addr = htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U));
- req.imr_interface.s_addr = INADDR_ANY;
- if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&req, sizeof(req)))
- return -1;
+ memset(&req, 0, sizeof(req));
+ req.imr_multiaddr.s_addr =
+ htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U));
+ req.imr_interface.s_addr = INADDR_ANY;
+ if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&req, sizeof(req)))
+ return -1;
- return 0;
+ return 0;
}
#if 0
@@ -274,67 +270,58 @@ mdns_socket_setup_ipv6(int sock) {
}
#endif
-static void
-mdns_socket_close(int sock) {
+static void mdns_socket_close(int sock) {
#ifdef _WIN32
- closesocket(sock);
+ closesocket(sock);
#else
- close(sock);
+ close(sock);
#endif
}
-static int
-mdns_is_string_ref(uint8_t val) {
- return (0xC0 == (val & 0xC0));
-}
+static int mdns_is_string_ref(uint8_t val) { return (0xC0 == (val & 0xC0)); }
-static mdns_string_pair_t
-mdns_get_next_substring(const void* rawdata, size_t size, size_t offset) {
- const uint8_t* buffer = rawdata;
- mdns_string_pair_t pair = {MDNS_INVALID_POS, 0, 0};
- if (!buffer[offset]) {
- pair.offset = offset;
- return pair;
- }
- if (mdns_is_string_ref(buffer[offset])) {
- if (size < offset + 2)
- return pair;
+static mdns_string_pair_t mdns_get_next_substring(const void* rawdata,
+ size_t size, size_t offset) {
+ const uint8_t* buffer = rawdata;
+ mdns_string_pair_t pair = {MDNS_INVALID_POS, 0, 0};
+ if (!buffer[offset]) {
+ pair.offset = offset;
+ return pair;
+ }
+ if (mdns_is_string_ref(buffer[offset])) {
+ if (size < offset + 2) return pair;
- offset = (((size_t)(0x3f & buffer[offset]) << 8) | (size_t)buffer[offset + 1]);
- if (offset >= size)
- return pair;
+ offset =
+ (((size_t)(0x3f & buffer[offset]) << 8) | (size_t)buffer[offset + 1]);
+ if (offset >= size) return pair;
- pair.ref = 1;
- }
+ pair.ref = 1;
+ }
- size_t length = (size_t)buffer[offset++];
- if (size < offset + length)
- return pair;
+ size_t length = (size_t)buffer[offset++];
+ if (size < offset + length) return pair;
- pair.offset = offset;
- pair.length = length;
+ pair.offset = offset;
+ pair.length = length;
- return pair;
+ return pair;
}
-static int
-mdns_string_skip(const void* buffer, size_t size, size_t* offset) {
- size_t cur = *offset;
- mdns_string_pair_t substr;
- do {
- substr = mdns_get_next_substring(buffer, size, cur);
- if (substr.offset == MDNS_INVALID_POS)
- return 0;
- if (substr.ref) {
- *offset = cur + 2;
- return 1;
- }
- cur = substr.offset + substr.length;
- }
- while (substr.length);
-
- *offset = cur + 1;
- return 1;
+static int mdns_string_skip(const void* buffer, size_t size, size_t* offset) {
+ size_t cur = *offset;
+ mdns_string_pair_t substr;
+ do {
+ substr = mdns_get_next_substring(buffer, size, cur);
+ if (substr.offset == MDNS_INVALID_POS) return 0;
+ if (substr.ref) {
+ *offset = cur + 2;
+ return 1;
+ }
+ cur = substr.offset + substr.length;
+ } while (substr.length);
+
+ *offset = cur + 1;
+ return 1;
}
#if 0
@@ -378,142 +365,133 @@ mdns_string_equal(const void* buffer_lhs, size_t size_lhs, size_t* ofs_lhs,
}
#endif
-static mdns_string_t
-mdns_string_extract(const void* buffer, size_t size, size_t* offset,
- char* str, size_t capacity) {
- size_t cur = *offset;
- size_t end = MDNS_INVALID_POS;
- mdns_string_pair_t substr;
- mdns_string_t result = {str, 0};
- char* dst = str;
- size_t remain = capacity;
- do {
- substr = mdns_get_next_substring(buffer, size, cur);
- if (substr.offset == MDNS_INVALID_POS)
- return result;
- if (substr.ref && (end == MDNS_INVALID_POS))
- end = cur + 2;
- if (substr.length) {
- size_t to_copy = (substr.length < remain) ? substr.length : remain;
- memcpy(dst, (const char*)buffer + substr.offset, to_copy);
- dst += to_copy;
- remain -= to_copy;
- if (remain) {
- *dst++ = '.';
- --remain;
- }
- }
- cur = substr.offset + substr.length;
- }
- while (substr.length);
-
- if (end == MDNS_INVALID_POS)
- end = cur + 1;
- *offset = end;
-
- result.length = capacity - remain;
- return result;
+static mdns_string_t mdns_string_extract(const void* buffer, size_t size,
+ size_t* offset, char* str,
+ size_t capacity) {
+ size_t cur = *offset;
+ size_t end = MDNS_INVALID_POS;
+ mdns_string_pair_t substr;
+ mdns_string_t result = {str, 0};
+ char* dst = str;
+ size_t remain = capacity;
+ do {
+ substr = mdns_get_next_substring(buffer, size, cur);
+ if (substr.offset == MDNS_INVALID_POS) return result;
+ if (substr.ref && (end == MDNS_INVALID_POS)) end = cur + 2;
+ if (substr.length) {
+ size_t to_copy = (substr.length < remain) ? substr.length : remain;
+ memcpy(dst, (const char*)buffer + substr.offset, to_copy);
+ dst += to_copy;
+ remain -= to_copy;
+ if (remain) {
+ *dst++ = '.';
+ --remain;
+ }
+ }
+ cur = substr.offset + substr.length;
+ } while (substr.length);
+
+ if (end == MDNS_INVALID_POS) end = cur + 1;
+ *offset = end;
+
+ result.length = capacity - remain;
+ return result;
}
-static size_t
-mdns_string_find(const char* str, size_t length, char c, size_t offset) {
- const void* found;
- if (offset >= length)
- return MDNS_INVALID_POS;
- found = memchr(str + offset, c, length - offset);
- if (found)
- return (size_t)((const char*)found - str);
- return MDNS_INVALID_POS;
+static size_t mdns_string_find(const char* str, size_t length, char c,
+ size_t offset) {
+ const void* found;
+ if (offset >= length) return MDNS_INVALID_POS;
+ found = memchr(str + offset, c, length - offset);
+ if (found) return (size_t)((const char*)found - str);
+ return MDNS_INVALID_POS;
}
-static void*
-mdns_string_make(void* data, size_t capacity, const char* name, size_t length) {
- size_t pos = 0;
- size_t last_pos = 0;
- size_t remain = capacity;
- unsigned char* dest = data;
- while ((last_pos < length) && ((pos = mdns_string_find(name, length, '.', last_pos)) != MDNS_INVALID_POS)) {
- size_t sublength = pos - last_pos;
- if (sublength < remain) {
- *dest = (unsigned char)sublength;
- memcpy(dest + 1, name + last_pos, sublength);
- dest += sublength + 1;
- remain -= sublength + 1;
- }
- else {
- return 0;
- }
- last_pos = pos + 1;
- }
- if (last_pos < length) {
- size_t sublength = length - last_pos;
- if (sublength < capacity) {
- *dest = (unsigned char)sublength;
- memcpy(dest + 1, name + last_pos, sublength);
- dest += sublength + 1;
- remain -= sublength + 1;
- }
- else {
- return 0;
- }
- }
- if (!remain)
- return 0;
- *dest++ = 0;
- return dest;
+static void* mdns_string_make(void* data, size_t capacity, const char* name,
+ size_t length) {
+ size_t pos = 0;
+ size_t last_pos = 0;
+ size_t remain = capacity;
+ unsigned char* dest = data;
+ while ((last_pos < length) &&
+ ((pos = mdns_string_find(name, length, '.', last_pos)) !=
+ MDNS_INVALID_POS)) {
+ size_t sublength = pos - last_pos;
+ if (sublength < remain) {
+ *dest = (unsigned char)sublength;
+ memcpy(dest + 1, name + last_pos, sublength);
+ dest += sublength + 1;
+ remain -= sublength + 1;
+ } else {
+ return 0;
+ }
+ last_pos = pos + 1;
+ }
+ if (last_pos < length) {
+ size_t sublength = length - last_pos;
+ if (sublength < capacity) {
+ *dest = (unsigned char)sublength;
+ memcpy(dest + 1, name + last_pos, sublength);
+ dest += sublength + 1;
+ remain -= sublength + 1;
+ } else {
+ return 0;
+ }
+ }
+ if (!remain) return 0;
+ *dest++ = 0;
+ return dest;
}
-static size_t
-mdns_records_parse(const struct sockaddr* from, const void* buffer, size_t size, size_t* offset,
- mdns_entry_type_t type, size_t records, mdns_record_callback_fn callback,
- void* user_data) {
- size_t parsed = 0;
- int do_callback = 1;
- for (size_t i = 0; i < records; ++i) {
- mdns_string_skip(buffer, size, offset);
- const uint16_t* data = (const uint16_t*)((const char*)buffer + (*offset));
-
- uint16_t rtype = ntohs(*data++);
- uint16_t rclass = ntohs(*data++);
- uint32_t ttl = ntohs(*(const uint32_t*)(const void*)data); data += 2;
- uint16_t length = ntohs(*data++);
-
- *offset += 10;
-
- if (do_callback) {
- ++parsed;
- if (callback(from, type, rtype, rclass, ttl, buffer, size, *offset, length,
- user_data))
- do_callback = 0;
- }
-
- *offset += length;
- }
- return parsed;
+static size_t mdns_records_parse(const struct sockaddr* from,
+ const void* buffer, size_t size,
+ size_t* offset, mdns_entry_type_t type,
+ size_t records,
+ mdns_record_callback_fn callback,
+ void* user_data) {
+ size_t parsed = 0;
+ int do_callback = 1;
+ for (size_t i = 0; i < records; ++i) {
+ mdns_string_skip(buffer, size, offset);
+ const uint16_t* data = (const uint16_t*)((const char*)buffer + (*offset));
+
+ uint16_t rtype = ntohs(*data++);
+ uint16_t rclass = ntohs(*data++);
+ uint32_t ttl = ntohs(*(const uint32_t*)(const void*)data);
+ data += 2;
+ uint16_t length = ntohs(*data++);
+
+ *offset += 10;
+
+ if (do_callback) {
+ ++parsed;
+ if (callback(from, type, rtype, rclass, ttl, buffer, size, *offset,
+ length, user_data))
+ do_callback = 0;
+ }
+
+ *offset += length;
+ }
+ return parsed;
}
static const uint8_t mdns_services_query[] = {
- // Transaction ID
- 0x00, 0x00,
- // Flags
- 0x00, 0x00,
- // 1 question
- 0x00, 0x01,
- // No answer, authority or additional RRs
- 0x00, 0x00,
- 0x00, 0x00,
- 0x00, 0x00,
- // _services._dns-sd._udp.local.
- 0x09, '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's',
- 0x07, '_', 'd', 'n', 's', '-', 's', 'd',
- 0x04, '_', 'u', 'd', 'p',
- 0x05, 'l', 'o', 'c', 'a', 'l',
- 0x00,
- // PTR record
- 0x00, MDNS_RECORDTYPE_PTR,
- // QU (unicast response) and class IN
- 0x80, MDNS_CLASS_IN
-};
+ // Transaction ID
+ 0x00, 0x00,
+ // Flags
+ 0x00, 0x00,
+ // 1 question
+ 0x00, 0x01,
+ // No answer, authority or additional RRs
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // _services._dns-sd._udp.local.
+ 0x09, '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', 0x07, '_', 'd', 'n', 's',
+ '-', 's', 'd', 0x04, '_', 'u', 'd', 'p', 0x05, 'l', 'o', 'c', 'a', 'l',
+ 0x00,
+ // PTR record
+ 0x00, MDNS_RECORDTYPE_PTR,
+ // QU (unicast response) and class IN
+ 0x80, MDNS_CLASS_IN};
#if 0
static int
@@ -645,233 +623,223 @@ mdns_discovery_recv(int sock, void* buffer, size_t capacity,
static uint16_t mdns_transaction_id = 0;
-static int
-mdns_query_send(int sock, mdns_record_type_t type, const char* name, size_t length,
- void* buffer, size_t capacity) {
- if (capacity < (17 + length))
- return -1;
-
- uint16_t* data = buffer;
- //Transaction ID
- *data++ = htons(++mdns_transaction_id);
- //Flags
- *data++ = 0;
- //Questions
- *data++ = htons(1);
- //No answer, authority or additional RRs
- *data++ = 0;
- *data++ = 0;
- *data++ = 0;
- //Name string
- data = mdns_string_make(data, capacity - 17, name, length);
- if (!data)
- return -1;
- //Record type
- *data++ = htons(type);
- //! Unicast response, class IN
- *data++ = htons(0x8000U | MDNS_CLASS_IN);
-
- struct sockaddr_storage addr_storage;
- struct sockaddr_in addr;
- struct sockaddr_in6 addr6;
- struct sockaddr* saddr = (struct sockaddr*)&addr_storage;
- socklen_t saddrlen = sizeof(struct sockaddr_storage);
- if (getsockname(sock, saddr, &saddrlen))
- return -1;
- if (saddr->sa_family == AF_INET6) {
- memset(&addr6, 0, sizeof(struct sockaddr_in6));
- addr6.sin6_family = AF_INET6;
+static int mdns_query_send(int sock, mdns_record_type_t type, const char* name,
+ size_t length, void* buffer, size_t capacity) {
+ if (capacity < (17 + length)) return -1;
+
+ uint16_t* data = buffer;
+ // Transaction ID
+ *data++ = htons(++mdns_transaction_id);
+ // Flags
+ *data++ = 0;
+ // Questions
+ *data++ = htons(1);
+ // No answer, authority or additional RRs
+ *data++ = 0;
+ *data++ = 0;
+ *data++ = 0;
+ // Name string
+ data = mdns_string_make(data, capacity - 17, name, length);
+ if (!data) return -1;
+ // Record type
+ *data++ = htons(type);
+ //! Unicast response, class IN
+ *data++ = htons(0x8000U | MDNS_CLASS_IN);
+
+ struct sockaddr_storage addr_storage;
+ struct sockaddr_in addr;
+ struct sockaddr_in6 addr6;
+ struct sockaddr* saddr = (struct sockaddr*)&addr_storage;
+ socklen_t saddrlen = sizeof(struct sockaddr_storage);
+ if (getsockname(sock, saddr, &saddrlen)) return -1;
+ if (saddr->sa_family == AF_INET6) {
+ memset(&addr6, 0, sizeof(struct sockaddr_in6));
+ addr6.sin6_family = AF_INET6;
#ifdef __APPLE__
- addr6.sin6_len = sizeof(struct sockaddr_in6);
+ addr6.sin6_len = sizeof(struct sockaddr_in6);
#endif
- addr6.sin6_addr.s6_addr[0] = 0xFF;
- addr6.sin6_addr.s6_addr[1] = 0x02;
- addr6.sin6_addr.s6_addr[15] = 0xFB;
- addr6.sin6_port = htons((unsigned short)5353);
- saddr = (struct sockaddr*)&addr6;
- saddrlen = sizeof(struct sockaddr_in6);
- }
- else {
- memset(&addr, 0, sizeof(struct sockaddr_in));
- addr.sin_family = AF_INET;
+ addr6.sin6_addr.s6_addr[0] = 0xFF;
+ addr6.sin6_addr.s6_addr[1] = 0x02;
+ addr6.sin6_addr.s6_addr[15] = 0xFB;
+ addr6.sin6_port = htons((unsigned short)5353);
+ saddr = (struct sockaddr*)&addr6;
+ saddrlen = sizeof(struct sockaddr_in6);
+ } else {
+ memset(&addr, 0, sizeof(struct sockaddr_in));
+ addr.sin_family = AF_INET;
#ifdef __APPLE__
- addr.sin_len = sizeof(struct sockaddr_in);
+ addr.sin_len = sizeof(struct sockaddr_in);
#endif
- addr.sin_addr.s_addr = htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U));
- addr.sin_port = htons((unsigned short)5353);
- saddr = (struct sockaddr*)&addr;
- saddrlen = sizeof(struct sockaddr_in);
- }
-
- if (sendto(sock, buffer, (char*)data - (char*)buffer, 0,
- saddr, saddrlen) < 0)
- return -1;
- return 0;
+ addr.sin_addr.s_addr = htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U));
+ addr.sin_port = htons((unsigned short)5353);
+ saddr = (struct sockaddr*)&addr;
+ saddrlen = sizeof(struct sockaddr_in);
+ }
+
+ if (sendto(sock, buffer, (char*)data - (char*)buffer, 0, saddr, saddrlen) < 0)
+ return -1;
+ return 0;
}
-static size_t
-mdns_query_recv(int sock, void* buffer, size_t capacity,
- mdns_record_callback_fn callback, void* user_data,
- uint8_t one_shot) {
- struct sockaddr_in6 addr;
- struct sockaddr* saddr = (struct sockaddr*)&addr;
- memset(&addr, 0, sizeof(addr));
- saddr->sa_family = AF_INET;
+static size_t mdns_query_recv(int sock, void* buffer, size_t capacity,
+ mdns_record_callback_fn callback, void* user_data,
+ uint8_t one_shot) {
+ struct sockaddr_in6 addr;
+ struct sockaddr* saddr = (struct sockaddr*)&addr;
+ memset(&addr, 0, sizeof(addr));
+ saddr->sa_family = AF_INET;
#ifdef __APPLE__
- saddr->sa_len = sizeof(addr);
+ saddr->sa_len = sizeof(addr);
#endif
- socklen_t addrlen = sizeof(addr);
- int ret = recvfrom(sock, buffer, capacity, 0,
- saddr, &addrlen);
- if (ret <= 0)
- return 0;
-
- size_t data_size = (size_t)ret;
- uint16_t* data = (uint16_t*)buffer;
-
- uint16_t transaction_id = ntohs(*data++);
- ++data;// uint16_t flags = ntohs(*data++);
- uint16_t questions = ntohs(*data++);
- uint16_t answer_rrs = ntohs(*data++);
- uint16_t authority_rrs = ntohs(*data++);
- uint16_t additional_rrs = ntohs(*data++);
-
- if (one_shot && transaction_id != mdns_transaction_id)// || (flags != 0x8400))
- return 0; //Not a reply to our last question
-
- if (questions > 1)
- return 0;
-
- //Skip questions part
- int i;
- for (i = 0; i < questions; ++i) {
- size_t ofs = (size_t)((char*)data - (char*)buffer);
- if (!mdns_string_skip(buffer, data_size, &ofs))
- return 0;
- data = (void*)((char*)buffer + ofs);
- ++data;
- ++data;
- }
-
- size_t records = 0;
- size_t offset = (size_t)((char*)data - (char*)buffer);
- records += mdns_records_parse(saddr, buffer, data_size, &offset,
- MDNS_ENTRYTYPE_ANSWER, answer_rrs,
- callback, user_data);
- records += mdns_records_parse(saddr, buffer, data_size, &offset,
- MDNS_ENTRYTYPE_AUTHORITY, authority_rrs,
- callback, user_data);
- records += mdns_records_parse(saddr, buffer, data_size, &offset,
- MDNS_ENTRYTYPE_ADDITIONAL, additional_rrs,
- callback, user_data);
- return records;
+ socklen_t addrlen = sizeof(addr);
+ int ret = recvfrom(sock, buffer, capacity, 0, saddr, &addrlen);
+ if (ret <= 0) return 0;
+
+ size_t data_size = (size_t)ret;
+ uint16_t* data = (uint16_t*)buffer;
+
+ uint16_t transaction_id = ntohs(*data++);
+ ++data; // uint16_t flags = ntohs(*data++);
+ uint16_t questions = ntohs(*data++);
+ uint16_t answer_rrs = ntohs(*data++);
+ uint16_t authority_rrs = ntohs(*data++);
+ uint16_t additional_rrs = ntohs(*data++);
+
+ if (one_shot &&
+ transaction_id != mdns_transaction_id) // || (flags != 0x8400))
+ return 0; // Not a reply to our last question
+
+ if (questions > 1) return 0;
+
+ // Skip questions part
+ int i;
+ for (i = 0; i < questions; ++i) {
+ size_t ofs = (size_t)((char*)data - (char*)buffer);
+ if (!mdns_string_skip(buffer, data_size, &ofs)) return 0;
+ data = (void*)((char*)buffer + ofs);
+ ++data;
+ ++data;
+ }
+
+ size_t records = 0;
+ size_t offset = (size_t)((char*)data - (char*)buffer);
+ records += mdns_records_parse(saddr, buffer, data_size, &offset,
+ MDNS_ENTRYTYPE_ANSWER, answer_rrs, callback,
+ user_data);
+ records += mdns_records_parse(saddr, buffer, data_size, &offset,
+ MDNS_ENTRYTYPE_AUTHORITY, authority_rrs,
+ callback, user_data);
+ records += mdns_records_parse(saddr, buffer, data_size, &offset,
+ MDNS_ENTRYTYPE_ADDITIONAL, additional_rrs,
+ callback, user_data);
+ return records;
}
-static mdns_string_t
-mdns_record_parse_ptr(const void* buffer, size_t size, size_t offset, size_t length,
- char* strbuffer, size_t capacity) {
- //PTR record is just a string
- if ((size >= offset + length) && (length >= 2))
- return mdns_string_extract(buffer, size, &offset, strbuffer, capacity);
- mdns_string_t empty = {0, 0};
- return empty;
+static mdns_string_t mdns_record_parse_ptr(const void* buffer, size_t size,
+ size_t offset, size_t length,
+ char* strbuffer, size_t capacity) {
+ // PTR record is just a string
+ if ((size >= offset + length) && (length >= 2))
+ return mdns_string_extract(buffer, size, &offset, strbuffer, capacity);
+ mdns_string_t empty = {0, 0};
+ return empty;
}
-static mdns_record_srv_t
-mdns_record_parse_srv(const void* buffer, size_t size, size_t offset, size_t length,
- char* strbuffer, size_t capacity) {
- mdns_record_srv_t srv;
- memset(&srv, 0, sizeof(mdns_record_srv_t));
- // Read the priority, weight, port number and the discovery name
- // SRV record format (http://www.ietf.org/rfc/rfc2782.txt):
- // 2 bytes network-order unsigned priority
- // 2 bytes network-order unsigned weight
- // 2 bytes network-order unsigned port
- // string: discovery (domain) name, minimum 2 bytes when compressed
- if ((size >= offset + length) && (length >= 8)) {
- const uint16_t* recorddata = (const uint16_t*)((const char*)buffer + offset);
- srv.priority = ntohs(*recorddata++);
- srv.weight = ntohs(*recorddata++);
- srv.port = ntohs(*recorddata++);
- offset += 6;
- srv.name = mdns_string_extract(buffer, size, &offset, strbuffer, capacity);
- }
- return srv;
+static mdns_record_srv_t mdns_record_parse_srv(const void* buffer, size_t size,
+ size_t offset, size_t length,
+ char* strbuffer,
+ size_t capacity) {
+ mdns_record_srv_t srv;
+ memset(&srv, 0, sizeof(mdns_record_srv_t));
+ // Read the priority, weight, port number and the discovery name
+ // SRV record format (http://www.ietf.org/rfc/rfc2782.txt):
+ // 2 bytes network-order unsigned priority
+ // 2 bytes network-order unsigned weight
+ // 2 bytes network-order unsigned port
+ // string: discovery (domain) name, minimum 2 bytes when compressed
+ if ((size >= offset + length) && (length >= 8)) {
+ const uint16_t* recorddata =
+ (const uint16_t*)((const char*)buffer + offset);
+ srv.priority = ntohs(*recorddata++);
+ srv.weight = ntohs(*recorddata++);
+ srv.port = ntohs(*recorddata++);
+ offset += 6;
+ srv.name = mdns_string_extract(buffer, size, &offset, strbuffer, capacity);
+ }
+ return srv;
}
-static struct sockaddr_in*
-mdns_record_parse_a(const void* buffer, size_t size, size_t offset, size_t length,
- struct sockaddr_in* addr) {
- memset(addr, 0, sizeof(struct sockaddr_in));
- addr->sin_family = AF_INET;
+static struct sockaddr_in* mdns_record_parse_a(const void* buffer, size_t size,
+ size_t offset, size_t length,
+ struct sockaddr_in* addr) {
+ memset(addr, 0, sizeof(struct sockaddr_in));
+ addr->sin_family = AF_INET;
#ifdef __APPLE__
- addr->sin_len = sizeof(struct sockaddr_in);
+ addr->sin_len = sizeof(struct sockaddr_in);
#endif
- if ((size >= offset + length) && (length == 4))
- addr->sin_addr.s_addr = *(const uint32_t*)((const char*)buffer + offset);
- return addr;
+ if ((size >= offset + length) && (length == 4))
+ addr->sin_addr.s_addr = *(const uint32_t*)((const char*)buffer + offset);
+ return addr;
}
-static struct sockaddr_in6*
-mdns_record_parse_aaaa(const void* buffer, size_t size, size_t offset, size_t length,
- struct sockaddr_in6* addr) {
- memset(addr, 0, sizeof(struct sockaddr_in6));
- addr->sin6_family = AF_INET6;
+static struct sockaddr_in6* mdns_record_parse_aaaa(const void* buffer,
+ size_t size, size_t offset,
+ size_t length,
+ struct sockaddr_in6* addr) {
+ memset(addr, 0, sizeof(struct sockaddr_in6));
+ addr->sin6_family = AF_INET6;
#ifdef __APPLE__
- addr->sin6_len = sizeof(struct sockaddr_in6);
+ addr->sin6_len = sizeof(struct sockaddr_in6);
#endif
- if ((size >= offset + length) && (length == 16))
- addr->sin6_addr = *(const struct in6_addr*)((const char*)buffer + offset);
- return addr;
+ if ((size >= offset + length) && (length == 16))
+ addr->sin6_addr = *(const struct in6_addr*)((const char*)buffer + offset);
+ return addr;
}
-static size_t
-mdns_record_parse_txt(const void* buffer, size_t size, size_t offset, size_t length,
- mdns_record_txt_t* records, size_t capacity) {
- size_t parsed = 0;
- const char* strdata;
- size_t separator, sublength;
- size_t end = offset + length;
-
- if (size < end)
- end = size;
-
- while ((offset < end) && (parsed < capacity)) {
- strdata = (const char*)buffer + offset;
- sublength = *(const unsigned char*)strdata;
-
- ++strdata;
- offset += sublength + 1;
-
- separator = 0;
- for (size_t c = 0; c < sublength; ++c) {
- //DNS-SD TXT record keys MUST be printable US-ASCII, [0x20, 0x7E]
- if ((strdata[c] < 0x20) || (strdata[c] > 0x7E))
- break;
- if (strdata[c] == '=') {
- separator = c;
- break;
- }
- }
-
- if (!separator)
- continue;
-
- if (separator < sublength) {
- records[parsed].key.str = strdata;
- records[parsed].key.length = separator;
- records[parsed].value.str = strdata + separator + 1;
- records[parsed].value.length = sublength - (separator + 1);
- }
- else {
- records[parsed].key.str = strdata;
- records[parsed].key.length = sublength;
- }
-
- ++parsed;
- }
-
- return parsed;
+static size_t mdns_record_parse_txt(const void* buffer, size_t size,
+ size_t offset, size_t length,
+ mdns_record_txt_t* records,
+ size_t capacity) {
+ size_t parsed = 0;
+ const char* strdata;
+ size_t separator, sublength;
+ size_t end = offset + length;
+
+ if (size < end) end = size;
+
+ while ((offset < end) && (parsed < capacity)) {
+ strdata = (const char*)buffer + offset;
+ sublength = *(const unsigned char*)strdata;
+
+ ++strdata;
+ offset += sublength + 1;
+
+ separator = 0;
+ for (size_t c = 0; c < sublength; ++c) {
+ // DNS-SD TXT record keys MUST be printable US-ASCII, [0x20, 0x7E]
+ if ((strdata[c] < 0x20) || (strdata[c] > 0x7E)) break;
+ if (strdata[c] == '=') {
+ separator = c;
+ break;
+ }
+ }
+
+ if (!separator) continue;
+
+ if (separator < sublength) {
+ records[parsed].key.str = strdata;
+ records[parsed].key.length = separator;
+ records[parsed].value.str = strdata + separator + 1;
+ records[parsed].value.length = sublength - (separator + 1);
+ } else {
+ records[parsed].key.str = strdata;
+ records[parsed].key.length = sublength;
+ }
+
+ ++parsed;
+ }
+
+ return parsed;
}
#ifdef _WIN32