initial commit

This commit is contained in:
mikhail "synzr" 2025-12-25 01:37:49 +05:00
commit 9d20827c46
2469 changed files with 470994 additions and 0 deletions

View file

@ -0,0 +1,490 @@
/*
* Copyright (C) 2005,2006 Justin Karneges
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef JDNS_H
#define JDNS_H
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*jdns_object_dtor_func)(void *);
typedef void *(*jdns_object_cctor_func)(const void *);
#define JDNS_OBJECT \
jdns_object_dtor_func dtor; \
jdns_object_cctor_func cctor;
#define JDNS_OBJECT_NEW(name) \
(name##_t *)jdns_object_new(sizeof(name##_t), \
(jdns_object_dtor_func)name##_delete, \
(jdns_object_cctor_func)name##_copy);
typedef struct jdns_object
{
JDNS_OBJECT
} jdns_object_t;
void *jdns_object_new(int size, void (*dtor)(void *),
void *(*cctor)(const void *));
void *jdns_object_copy(const void *a);
void jdns_object_delete(void *a);
void jdns_object_free(void *a);
#define JDNS_LIST_DECLARE(name) \
JDNS_OBJECT \
int count; \
name##_t **item;
typedef struct jdns_list
{
JDNS_OBJECT
int count;
void **item;
int valueList;
int autoDelete;
} jdns_list_t;
jdns_list_t *jdns_list_new();
jdns_list_t *jdns_list_copy(const jdns_list_t *a);
void jdns_list_delete(jdns_list_t *a);
void jdns_list_clear(jdns_list_t *a);
void jdns_list_insert(jdns_list_t *a, void *item, int pos);
void jdns_list_insert_value(jdns_list_t *a, const void *item, int pos);
void jdns_list_remove(jdns_list_t *a, void *item);
void jdns_list_remove_at(jdns_list_t *a, int pos);
typedef struct jdns_string
{
JDNS_OBJECT
unsigned char *data;
int size;
} jdns_string_t;
jdns_string_t *jdns_string_new();
jdns_string_t *jdns_string_copy(const jdns_string_t *s);
void jdns_string_delete(jdns_string_t *s);
void jdns_string_set(jdns_string_t *s, const unsigned char *str,
int str_len);
void jdns_string_set_cstr(jdns_string_t *s, const char *str);
// overlays jdns_list
typedef struct jdns_stringlist
{
JDNS_OBJECT
int count;
jdns_string_t **item;
} jdns_stringlist_t;
jdns_stringlist_t *jdns_stringlist_new();
jdns_stringlist_t *jdns_stringlist_copy(const jdns_stringlist_t *a);
void jdns_stringlist_delete(jdns_stringlist_t *a);
void jdns_stringlist_append(jdns_stringlist_t *a, const jdns_string_t *str);
typedef struct jdns_address
{
int isIpv6;
union
{
unsigned long int v4;
unsigned char *v6; // 16 bytes
} addr;
char *c_str;
} jdns_address_t;
jdns_address_t *jdns_address_new();
jdns_address_t *jdns_address_copy(const jdns_address_t *a);
void jdns_address_delete(jdns_address_t *a);
void jdns_address_set_ipv4(jdns_address_t *a, unsigned long int ipv4);
void jdns_address_set_ipv6(jdns_address_t *a, const unsigned char *ipv6);
// return 1 if string was ok, else 0. Note: IPv4 addresses only!
int jdns_address_set_cstr(jdns_address_t *a, const char *str);
// return 1 if the same, else 0
int jdns_address_cmp(const jdns_address_t *a, const jdns_address_t *b);
// convenient predefined addresses/ports
#define JDNS_UNICAST_PORT 53
#define JDNS_MULTICAST_PORT 5353
jdns_address_t *jdns_address_multicast4_new(); // 224.0.0.251
jdns_address_t *jdns_address_multicast6_new(); // FF02::FB
typedef struct jdns_server
{
unsigned char *name;
int port; // SRV only
int priority;
int weight; // SRV only
} jdns_server_t;
jdns_server_t *jdns_server_new();
jdns_server_t *jdns_server_copy(const jdns_server_t *s);
void jdns_server_delete(jdns_server_t *s);
void jdns_server_set_name(jdns_server_t *s, const unsigned char *name);
typedef struct jdns_nameserver
{
jdns_address_t *address;
int port;
} jdns_nameserver_t;
jdns_nameserver_t *jdns_nameserver_new();
jdns_nameserver_t *jdns_nameserver_copy(const jdns_nameserver_t *a);
void jdns_nameserver_delete(jdns_nameserver_t *a);
void jdns_nameserver_set(jdns_nameserver_t *a, const jdns_address_t *addr,
int port);
typedef struct jdns_nameserverlist
{
int count;
jdns_nameserver_t **item;
} jdns_nameserverlist_t;
jdns_nameserverlist_t *jdns_nameserverlist_new();
jdns_nameserverlist_t *jdns_nameserverlist_copy(
const jdns_nameserverlist_t *a);
void jdns_nameserverlist_delete(jdns_nameserverlist_t *a);
void jdns_nameserverlist_append(jdns_nameserverlist_t *a,
const jdns_address_t *addr, int port);
typedef struct jdns_dnshost
{
jdns_string_t *name;
jdns_address_t *address;
} jdns_dnshost_t;
typedef struct jdns_dnshostlist
{
int count;
jdns_dnshost_t **item;
} jdns_dnshostlist_t;
typedef struct jdns_dnsparams
{
jdns_nameserverlist_t *nameservers;
jdns_stringlist_t *domains;
jdns_dnshostlist_t *hosts;
} jdns_dnsparams_t;
jdns_dnsparams_t *jdns_dnsparams_new();
jdns_dnsparams_t *jdns_dnsparams_copy(jdns_dnsparams_t *a);
void jdns_dnsparams_delete(jdns_dnsparams_t *a);
void jdns_dnsparams_append_nameserver(jdns_dnsparams_t *a,
const jdns_address_t *addr, int port);
void jdns_dnsparams_append_domain(jdns_dnsparams_t *a,
const jdns_string_t *domain);
void jdns_dnsparams_append_host(jdns_dnsparams_t *a,
const jdns_string_t *name, const jdns_address_t *address);
#define JDNS_RTYPE_A 1
#define JDNS_RTYPE_AAAA 28
#define JDNS_RTYPE_MX 15
#define JDNS_RTYPE_SRV 33
#define JDNS_RTYPE_CNAME 5
#define JDNS_RTYPE_PTR 12
#define JDNS_RTYPE_TXT 16
#define JDNS_RTYPE_HINFO 13
#define JDNS_RTYPE_NS 2
#define JDNS_RTYPE_ANY 255
typedef struct jdns_rr
{
unsigned char *owner;
int ttl;
int type;
int qclass;
int rdlength;
unsigned char *rdata;
int haveKnown;
union
{
jdns_address_t *address; // for A, AAAA
jdns_server_t *server; // for MX, SRV
unsigned char *name; // for CNAME, PTR, NS
jdns_stringlist_t *texts; // for TXT
struct
{
jdns_string_t *cpu;
jdns_string_t *os;
} hinfo; // for HINFO
} data;
} jdns_rr_t;
jdns_rr_t *jdns_rr_new();
jdns_rr_t *jdns_rr_copy(const jdns_rr_t *r);
void jdns_rr_delete(jdns_rr_t *r);
void jdns_rr_set_owner(jdns_rr_t *r, const unsigned char *name);
void jdns_rr_set_record(jdns_rr_t *r, int type, const unsigned char *rdata,
int rdlength);
void jdns_rr_set_A(jdns_rr_t *r, const jdns_address_t *address);
void jdns_rr_set_AAAA(jdns_rr_t *r, const jdns_address_t *address);
void jdns_rr_set_MX(jdns_rr_t *r, const unsigned char *name, int priority);
void jdns_rr_set_SRV(jdns_rr_t *r, const unsigned char *name, int port,
int priority, int weight);
void jdns_rr_set_CNAME(jdns_rr_t *r, const unsigned char *name);
void jdns_rr_set_PTR(jdns_rr_t *r, const unsigned char *name);
void jdns_rr_set_TXT(jdns_rr_t *r, const jdns_stringlist_t *texts);
void jdns_rr_set_HINFO(jdns_rr_t *r, const jdns_string_t *cpu,
const jdns_string_t *os);
void jdns_rr_set_NS(jdns_rr_t *r, const unsigned char *name);
// note: only works on known types
int jdns_rr_verify(const jdns_rr_t *r);
typedef struct jdns_response
{
int answerCount;
jdns_rr_t **answerRecords;
int authorityCount;
jdns_rr_t **authorityRecords;
int additionalCount;
jdns_rr_t **additionalRecords;
} jdns_response_t;
jdns_response_t *jdns_response_new();
jdns_response_t *jdns_response_copy(const jdns_response_t *r);
void jdns_response_delete(jdns_response_t *r);
void jdns_response_append_answer(jdns_response_t *r, const jdns_rr_t *rr);
void jdns_response_append_authority(jdns_response_t *r, const jdns_rr_t *rr);
void jdns_response_append_additional(jdns_response_t *r,
const jdns_rr_t *rr);
#define JDNS_PUBLISH_SHARED 0x0001
#define JDNS_PUBLISH_UNIQUE 0x0002
#define JDNS_STEP_TIMER 0x0001
#define JDNS_STEP_HANDLE 0x0002
#define JDNS_EVENT_RESPONSE 0x0001
#define JDNS_EVENT_PUBLISH 0x0002
#define JDNS_EVENT_SHUTDOWN 0x0003
#define JDNS_STATUS_SUCCESS 0x0001
#define JDNS_STATUS_NXDOMAIN 0x0002
#define JDNS_STATUS_ERROR 0x0003
#define JDNS_STATUS_TIMEOUT 0x0004
#define JDNS_STATUS_CONFLICT 0x0005
typedef struct jdns_session jdns_session_t;
typedef struct jdns_callbacks
{
void *app; // user-supplied context
// time_now:
// s: session
// app: user-supplied context
// return: milliseconds since session started
int (*time_now)(jdns_session_t *s, void *app);
// rand_int:
// s: session
// app: user-supplied context
// return: random integer between 0-65535
int (*rand_int)(jdns_session_t *s, void *app);
// debug_line:
// s: session
// app: user-supplied context
// str: a line of debug text
// return: nothing
void (*debug_line)(jdns_session_t *s, void *app, const char *str);
// udp_bind:
// s: session
// app: user-supplied context
// addr: ip address of interface to bind to. 0 for all
// port: port of interface to bind to. 0 for any
// maddr: multicast address. 0 if not using multicast
// return: handle (>0) of bound socket, or 0 on error
// note: for multicast, the following must be done:
// use SO_REUSEPORT to share with other mdns programs
// use IP_ADD_MEMBERSHIP to associate addr and maddr
// set IP_MULTICAST_TTL to 255
int (*udp_bind)(jdns_session_t *s, void *app,
const jdns_address_t *addr, int port,
const jdns_address_t *maddr);
// udp_unbind:
// s: session
// app: user-supplied context
// handle: handle of socket obtained with udp_bind
// return: nothing
void (*udp_unbind)(jdns_session_t *s, void *app, int handle);
// udp_read:
// s: session
// app: user-supplied context
// handle: handle of socket obtained with udp_bind
// addr: store ip address of sender
// port: store port of sender
// buf: store packet content
// bufsize: value contains max size, to be changed to real size
// return: 1 if packet read, 0 if none available
int (*udp_read)(jdns_session_t *s, void *app, int handle,
jdns_address_t *addr, int *port, unsigned char *buf,
int *bufsize);
// udp_write:
// s: session
// app: user-supplied context
// handle: handle of socket obtained with udp_bind
// addr: ip address of recipient
// port: port of recipient
// buf: packet content
// bufsize: size of packet
// return: 1 if packet taken for writing, 0 if this is a bad time
int (*udp_write)(jdns_session_t *s, void *app, int handle,
const jdns_address_t *addr, int port, unsigned char *buf,
int bufsize);
} jdns_callbacks_t;
typedef struct jdns_event
{
int type; // JDNS_EVENT
int id; // query id or publish id
// for query, this can be SUCCESS, NXDOMAIN, ERROR, or TIMEOUT
// for publish, this can be SUCCESS, ERROR, or CONFLICT
int status;
// for query
jdns_response_t *response;
} jdns_event_t;
void jdns_event_delete(jdns_event_t *e);
// jdns_session_new:
// callbacks: the struct of callbacks
// return: newly allocated session
jdns_session_t *jdns_session_new(jdns_callbacks_t *callbacks);
// jdns_session_delete:
// s: session to free
// return: nothing
void jdns_session_delete(jdns_session_t *s);
// jdns_init_unicast:
// s: session
// addr: ip address of interface to bind to. NULL for all
// port: port of interface to bind to. 0 for any
// return: 1 on success, 0 on failure
int jdns_init_unicast(jdns_session_t *s, const jdns_address_t *addr,
int port);
// jdns_init_multicast:
// s: session
// addr: ip address of interface to bind to. NULL for all
// port: port of interface to bind to. 0 for any
// addr: multicast address to associate with. cannot be NULL
// return: 1 on success, 0 on failure
int jdns_init_multicast(jdns_session_t *s, const jdns_address_t *addr,
int port, const jdns_address_t *maddr);
// jdns_shutdown:
// s: session
// return: nothing
void jdns_shutdown(jdns_session_t *s);
// jdns_set_nameservers:
// s: session
// nslist: list of nameservers
// return nothing
void jdns_set_nameservers(jdns_session_t *s,
const jdns_nameserverlist_t *nslist);
// jdns_probe:
// s: session
// return: nothing
void jdns_probe(jdns_session_t *s);
// jdns_query:
// s: session
// name: the name to look up
// rtype: the record type
// return: id of this operation
int jdns_query(jdns_session_t *s, const unsigned char *name, int rtype);
// jdns_cancel_query:
// s: session
// id: the operation id to cancel
// return: nothing
void jdns_cancel_query(jdns_session_t *s, int id);
// jdns_publish:
// s: session
// mode: JDNS_PUBLISH shared or unique
// rec: the record data
// return: id of this operation
// note: supported record types: A, AAAA, SRV, CNAME, PTR, TXT, and HINFO.
// if the published type is not one of these, raw rdata must be set.
int jdns_publish(jdns_session_t *s, int mode, const jdns_rr_t *rec);
// jdns_update_publish:
// s: session
// id: the operation id to update
// rec: the record data
// return: nothing
void jdns_update_publish(jdns_session_t *s, int id, const jdns_rr_t *rec);
// jdns_cancel_publish:
// s: session
// id: the operation id to cancel
// return: nothing
void jdns_cancel_publish(jdns_session_t *s, int id);
// jdns_step:
// s: session
// return: JDNS_STEP flags OR'd together
int jdns_step(jdns_session_t *s);
// jdns_next_timer:
// s: session
// return: milliseconds until timeout
int jdns_next_timer(jdns_session_t *s);
// jdns_set_handle_readable:
// s: session
// handle: handle that is now readable
// return: nothing
void jdns_set_handle_readable(jdns_session_t *s, int handle);
// jdns_set_handle_writable:
// s: session
// handle: handle that is now writable
// return: nothing
void jdns_set_handle_writable(jdns_session_t *s, int handle);
// jdns_next_event:
// s: session
// return: newly allocated event, or zero if none are ready
jdns_event_t *jdns_next_event(jdns_session_t *s);
// jdns_system_dnsparams:
// return: newly allocated dnsparams from the system
jdns_dnsparams_t *jdns_system_dnsparams();
#ifdef __cplusplus
}
#endif
#endif