mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-04-13 20:41:58 +02:00
It's good to be back. Add jdns and make libtomahawk link to it, so that we can do proper SRV resolving. Also create thirdparty/ which portfwd and others should really be moved in to
This commit is contained in:
parent
1867daae4d
commit
c9aec3d55e
@ -23,6 +23,7 @@ ELSE()
|
||||
ADD_SUBDIRECTORY( rtaudio )
|
||||
ENDIF( UNIX AND NOT APPLE )
|
||||
|
||||
ADD_SUBDIRECTORY( thirdparty )
|
||||
ADD_SUBDIRECTORY( libportfwd )
|
||||
ADD_SUBDIRECTORY( qxt )
|
||||
ADD_SUBDIRECTORY( src/libtomahawk )
|
||||
|
@ -236,6 +236,7 @@ SET( OS_SPECIFIC_LINK_LIBRARIES
|
||||
"dnsapi.dll"
|
||||
"dsound.dll"
|
||||
"winmm.dll"
|
||||
"advapi32.dll"
|
||||
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../rtaudio/librtaudio.dll"
|
||||
)
|
||||
@ -282,6 +283,7 @@ target_link_libraries( tomahawklib
|
||||
vorbisfile
|
||||
ogg
|
||||
FLAC++
|
||||
jdns
|
||||
)
|
||||
|
||||
install( TARGETS tomahawklib DESTINATION lib )
|
||||
|
1
thirdparty/CMakeLists.txt
vendored
Normal file
1
thirdparty/CMakeLists.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
add_subdirectory( jdns )
|
44
thirdparty/jdns/CMakeLists.txt
vendored
Normal file
44
thirdparty/jdns/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
PROJECT(jdns)
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6 FATAL_ERROR)
|
||||
SET(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
|
||||
SET( QT_USE_QTNETWORK TRUE )
|
||||
INCLUDE( ${QT_USE_FILE} )
|
||||
|
||||
if(WIN32)
|
||||
SET(PLATFORM_SPECIFIC_LIBS "ws2_32.dll" "advapi32.dll" )
|
||||
endif(WIN32)
|
||||
|
||||
set(JDNS_SOURCES
|
||||
jdns_util.c
|
||||
jdns_packet.c
|
||||
jdns_mdnsd.c
|
||||
jdns_sys.c
|
||||
jdns.c
|
||||
qjdns_sock.cpp
|
||||
qjdns.cpp
|
||||
)
|
||||
|
||||
set(JDNS_HEADERS
|
||||
qjdns.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${QT_INCLUDE_DIR}
|
||||
${QT_INCLUDES}
|
||||
)
|
||||
|
||||
qt4_wrap_cpp( JDNS_MOC ${JDNS_HEADERS} )
|
||||
|
||||
if(WIN32)
|
||||
ADD_LIBRARY(jdns SHARED ${JDNS_SOURCES} ${JDNS_MOC})
|
||||
else()
|
||||
ADD_LIBRARY(jdns STATIC ${JDNS_SOURCES} ${JDNS_MOC})
|
||||
endif()
|
||||
|
||||
target_link_libraries(jdns
|
||||
${QT_LIBRARIES}
|
||||
)
|
||||
|
||||
INSTALL(TARGETS jdns ARCHIVE DESTINATION lib)
|
85
thirdparty/jdns/README
vendored
Normal file
85
thirdparty/jdns/README
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
JDNS
|
||||
----
|
||||
Date: October 1st, 2005
|
||||
Author: Justin Karneges <justin@affinix.com>
|
||||
|
||||
JDNS is a simple DNS implementation that can perform normal DNS queries
|
||||
of any record type (notably SRV), as well as Multicast DNS queries and
|
||||
advertising. Multicast support is based on Jeremie Miller's "mdnsd"
|
||||
implementation.
|
||||
|
||||
For maximum flexibility, JDNS is written in C with no direct dependencies,
|
||||
and is licensed under the MIT license. Your application must supply
|
||||
functionality to JDNS, such as UDP sending/receiving, via callbacks.
|
||||
|
||||
For Qt users there is a wrapper available called QJDns. jdns.pri can
|
||||
be used to include everything into a qmake project. jdns.pro will build
|
||||
the sample Qt-based commandline tool 'jdns'.
|
||||
|
||||
Features:
|
||||
- DNS client "stub" resolver
|
||||
- Can fetch any record type, but provides handy decoding for many
|
||||
known types: A, AAAA, SRV, MX, TXT, etc.
|
||||
- Performs retries, caching/expiration, and CNAME following
|
||||
- Algorithm logic adapted from Q3Dns
|
||||
- Multicast queries
|
||||
- Multicast advertising
|
||||
|
||||
Why?
|
||||
- Trolltech is phasing out the Qt DNS implementation, which in Qt 4 has
|
||||
been relegated to the Qt3Support module. A replacement was desired.
|
||||
|
||||
- While there are many DNS libraries available, at the time of this
|
||||
writing it was (and still may be) hard to find one that satisfies
|
||||
three essential conditions: cross-platform friendliness (and this
|
||||
includes Windows 9x!), the ability to integrate into existing
|
||||
eventloops, sensible licensing (ie, not GPL).
|
||||
|
||||
How to use:
|
||||
- Prepare callbacks and call jdns_session_new()
|
||||
- Call jdns_init_unicast() or jdns_init_multicast(), depending on
|
||||
if you want regular or multicast DNS. If you want both kinds, you
|
||||
can always make two sessions.
|
||||
- Make queries and have fun
|
||||
- Call jdns_step() at the right times to advance JDNS processing
|
||||
|
||||
What is left to you:
|
||||
- The callback functions, obviously.
|
||||
- Querying for several "qualified" names. Here is what Q3Dns does:
|
||||
Query for name as provided
|
||||
Query for name + '.domain' (for every domain the computer is in)
|
||||
- Detecting for '.local' in a name to be queried, and using that
|
||||
to decide whether to query via Multicast or normal DNS.
|
||||
- Recognition of IP addresses. If you want an IP address to resolve
|
||||
to itself, then do that yourself. Passing an IP address as a DNS
|
||||
name to JDNS won't work (especially since it wouldn't make any
|
||||
sense in some contexts, like SRV).
|
||||
- Recognition of known hosts. If you want this, compare inputs against
|
||||
jdns_system_dnsparams().
|
||||
- For zeroconf/Bonjour, keep in mind that JDNS only provides Multicast
|
||||
DNS capability. DNS-SD and any higher layers would be your job.
|
||||
|
||||
Using a custom DNS implementation has the drawback that it is difficult
|
||||
to take advantage of platform-specific features (for example, an OS-wide
|
||||
DNS cache or LDAP integration).
|
||||
|
||||
An application strategy for normal DNS should probably be:
|
||||
- If an A or AAAA record is desired, use a native lookup.
|
||||
- Else, if the platform has advanced DNS features already (ie,
|
||||
res_query), use those.
|
||||
- Else, use JDNS.
|
||||
|
||||
However, it may not be a bad idea at first to use JDNS for all occasions,
|
||||
so that it can be debugged.
|
||||
|
||||
For Multicast DNS, awareness of the platform is doubly important. There
|
||||
should only be one Multicast DNS "Responder" per computer, and using JDNS
|
||||
at the same time could result in a conflict.
|
||||
|
||||
An application strategy for Multicast DNS should be:
|
||||
- If the platform has a Multicast DNS daemon installed already, use
|
||||
it somehow.
|
||||
- Else, use JDNS.
|
||||
|
||||
Have fun!
|
||||
|
20
thirdparty/jdns/TODO
vendored
Normal file
20
thirdparty/jdns/TODO
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
(nothing)
|
||||
|
||||
but, this stuff couldn't hurt:
|
||||
fields that need to be an explicit size should use int16_t, etc
|
||||
support for other DNS record types (SOA, NSPTR)
|
||||
detect CNAME loops, rather than looping max times in order to fail
|
||||
don't follow CNAME for SRV (or so I'm told?)
|
||||
if it is not possible to implement DNSSEC outside of jdns, then add the
|
||||
minimal number of hooks to jdns so that it becomes possible
|
||||
use hash tables to speed up the list lookups
|
||||
unit tests
|
||||
qjdns debug lines reworking:
|
||||
init should emit debugLinesReady, and debug should be available
|
||||
immediately after call (the emit will break SS/DS, put a note about
|
||||
this in a comment about init())
|
||||
anywhere else, debugLines should conform to SS, but be emitted at the
|
||||
proper time, not deferred. currently, the debug arrives out of
|
||||
sequence with the other signals, resulting in strange output in the
|
||||
commandline tool.
|
||||
consideration for these changes in jdnsshared
|
3437
thirdparty/jdns/jdns.c
vendored
Normal file
3437
thirdparty/jdns/jdns.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
507
thirdparty/jdns/jdns.h
vendored
Normal file
507
thirdparty/jdns/jdns.h
vendored
Normal file
@ -0,0 +1,507 @@
|
||||
/*
|
||||
* 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
|
||||
// note: update only works on successfully published records, and no event
|
||||
// is generated for a successful update.
|
||||
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();
|
||||
|
||||
// jdns_set_hold_ids_enabled
|
||||
// s: session
|
||||
// enabled: whether to enable id holding. default is 0 (disabled)
|
||||
// return: nothing
|
||||
// normally, when a unicast query completes or any kind of query or publish
|
||||
// operation results in an error, the operation is automatically "canceled".
|
||||
// when id holding is enabled, the operation still stops internally, but the
|
||||
// id value used by that operation is "held" until the application
|
||||
// explicitly calls jdns_cancel_query() or jdns_cancel_publish() to release
|
||||
// it. this allows the application to ensure there is no ambiguity when
|
||||
// determining which operation a particular event belongs to. it is disabled
|
||||
// be default so as to not introduce memory leaks in existing applications,
|
||||
// however new applications really should use it.
|
||||
void jdns_set_hold_ids_enabled(jdns_session_t *s, int enabled);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
27
thirdparty/jdns/jdns.pri
vendored
Normal file
27
thirdparty/jdns/jdns.pri
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
# qmake project include file
|
||||
|
||||
QT *= network
|
||||
|
||||
windows:{
|
||||
LIBS += -lWs2_32 -lAdvapi32
|
||||
}
|
||||
unix:{
|
||||
#QMAKE_CFLAGS += -pedantic
|
||||
}
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/jdns_packet.h \
|
||||
$$PWD/jdns_mdnsd.h \
|
||||
$$PWD/jdns_p.h \
|
||||
$$PWD/jdns.h \
|
||||
$$PWD/qjdns_sock.h \
|
||||
$$PWD/qjdns.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/jdns_util.c \
|
||||
$$PWD/jdns_packet.c \
|
||||
$$PWD/jdns_mdnsd.c \
|
||||
$$PWD/jdns_sys.c \
|
||||
$$PWD/jdns.c \
|
||||
$$PWD/qjdns_sock.cpp \
|
||||
$$PWD/qjdns.cpp
|
9
thirdparty/jdns/jdns.pro
vendored
Normal file
9
thirdparty/jdns/jdns.pro
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
CONFIG += console
|
||||
CONFIG -= app_bundle
|
||||
QT -= gui
|
||||
QT += network
|
||||
|
||||
include(jdns.pri)
|
||||
|
||||
SOURCES += \
|
||||
main.cpp
|
1125
thirdparty/jdns/jdns_mdnsd.c
vendored
Normal file
1125
thirdparty/jdns/jdns_mdnsd.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
120
thirdparty/jdns/jdns_mdnsd.h
vendored
Normal file
120
thirdparty/jdns/jdns_mdnsd.h
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Jeremie Miller
|
||||
* 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_MDNSD_H
|
||||
#define JDNS_MDNSD_H
|
||||
|
||||
#include "jdns_p.h"
|
||||
|
||||
struct mytimeval
|
||||
{
|
||||
unsigned long int tv_sec; /* seconds */
|
||||
unsigned long int tv_usec; /* microseconds */
|
||||
};
|
||||
|
||||
typedef struct mdnsd_struct *mdnsd; // main daemon data
|
||||
typedef struct mdnsdr_struct *mdnsdr; // record entry
|
||||
// answer data
|
||||
typedef struct mdnsda_struct
|
||||
{
|
||||
unsigned char *name;
|
||||
unsigned short int type;
|
||||
unsigned long int ttl;
|
||||
unsigned long int real_ttl;
|
||||
unsigned short int rdlen;
|
||||
unsigned char *rdata;
|
||||
unsigned long int ip; // A
|
||||
unsigned char *rdname; // NS/CNAME/PTR/SRV
|
||||
struct { unsigned short int priority, weight, port; } srv; // SRV
|
||||
} *mdnsda;
|
||||
|
||||
///////////
|
||||
// Global functions
|
||||
//
|
||||
// create a new mdns daemon for the given class of names (usually 1) and maximum frame size
|
||||
mdnsd mdnsd_new(int class, int frame, int port, int (*time_now)(mdnsd d, void *arg), int (*rand_int)(mdnsd d, void *arg), void *arg);
|
||||
//
|
||||
// gracefully shutdown the daemon, use mdnsd_out() to get the last packets
|
||||
void mdnsd_shutdown(mdnsd d);
|
||||
//
|
||||
// flush all cached records (network/interface changed)
|
||||
void mdnsd_flush(mdnsd d);
|
||||
//
|
||||
// free given mdnsd (should have used mdnsd_shutdown() first!)
|
||||
void mdnsd_free(mdnsd d);
|
||||
//
|
||||
///////////
|
||||
|
||||
///////////
|
||||
// I/O functions
|
||||
//
|
||||
// incoming message from host (to be cached/processed)
|
||||
void mdnsd_in(mdnsd d, const jdns_packet_t *m, const jdns_response_t *resp, const jdns_address_t *addr, unsigned short int port);
|
||||
//
|
||||
// outgoing messge to be delivered to host, returns >0 if one was returned and m/ip/port set
|
||||
int mdnsd_out(mdnsd d, jdns_packet_t **m, jdns_address_t **addr, unsigned short int *port);
|
||||
//
|
||||
// returns the max wait-time until mdnsd_out() needs to be called again
|
||||
struct mytimeval *mdnsd_sleep(mdnsd d);
|
||||
//
|
||||
////////////
|
||||
|
||||
///////////
|
||||
// Q/A functions
|
||||
//
|
||||
// register a new query
|
||||
// answer(record, arg) is called whenever one is found/changes/expires (immediate or anytime after, mdnsda valid until ->ttl==0)
|
||||
// either answer returns -1, or another mdnsd_query with a NULL answer will remove/unregister this query
|
||||
void mdnsd_query(mdnsd d, char *host, int type, int (*answer)(mdnsda a, void *arg), void *arg);
|
||||
//
|
||||
// returns the first (if last == NULL) or next answer after last from the cache
|
||||
// mdnsda only valid until an I/O function is called
|
||||
mdnsda mdnsd_list(mdnsd d, char *host, int type, mdnsda last);
|
||||
//
|
||||
///////////
|
||||
|
||||
///////////
|
||||
// Publishing functions
|
||||
//
|
||||
// create a new unique record (try mdnsda_list first to make sure it's not used)
|
||||
// conflict(arg) called at any point when one is detected and unable to recover
|
||||
// after the first data is set_*(), any future changes effectively expire the old one and attempt to create a new unique record
|
||||
mdnsdr mdnsd_unique(mdnsd d, char *host, int type, long int ttl, void (*pubresult)(int result, char *host, int type, void *arg), void *arg);
|
||||
//
|
||||
// create a new shared record
|
||||
mdnsdr mdnsd_shared(mdnsd d, char *host, int type, long int ttl);
|
||||
//
|
||||
// de-list the given record
|
||||
void mdnsd_done(mdnsd d, mdnsdr r);
|
||||
//
|
||||
// these all set/update the data for the given record, nothing is published until they are called
|
||||
void mdnsd_set_raw(mdnsd d, mdnsdr r, char *data, int len);
|
||||
void mdnsd_set_host(mdnsd d, mdnsdr r, char *name);
|
||||
void mdnsd_set_ip(mdnsd d, mdnsdr r, unsigned long int ip);
|
||||
void mdnsd_set_srv(mdnsd d, mdnsdr r, int priority, int weight, int port, char *name);
|
||||
//
|
||||
///////////
|
||||
|
||||
|
||||
#endif
|
95
thirdparty/jdns/jdns_p.h
vendored
Normal file
95
thirdparty/jdns/jdns_p.h
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 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_P_H
|
||||
#define JDNS_P_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
|
||||
# define JDNS_OS_WIN
|
||||
#else
|
||||
# define JDNS_OS_UNIX
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
# define JDNS_OS_FREEBSD
|
||||
#elif defined(__NetBSD__)
|
||||
# define JDNS_OS_NETBSD
|
||||
#elif defined(sun) || defined(__sun)
|
||||
# define JDNS_OS_SOLARIS
|
||||
#elif defined(__APPLE__) && (defined(__GNUC__) || defined(__xlC__) || defined(__xlc__))
|
||||
# define JDNS_OS_MAC
|
||||
#endif
|
||||
|
||||
#ifdef JDNS_OS_WIN
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef JDNS_OS_UNIX
|
||||
# include <unistd.h>
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include "jdns.h"
|
||||
#include "jdns_packet.h"
|
||||
|
||||
// jdns_util.c
|
||||
void *jdns_alloc(int size);
|
||||
void *jdns_realloc(void *p, int size);
|
||||
void jdns_free(void *p);
|
||||
char *jdns_strdup(const char *s);
|
||||
unsigned char *jdns_copy_array(const unsigned char *src, int size);
|
||||
int jdns_domain_cmp(const unsigned char *a, const unsigned char *b);
|
||||
|
||||
int jdns_sprintf_s(char *str, int n, const char *format, ...);
|
||||
int jdns_vsprintf_s(char *str, int n, const char *format, va_list ap);
|
||||
FILE *jdns_fopen(const char *path, const char *mode);
|
||||
jdns_string_t *jdns_getenv(const char *name);
|
||||
char *jdns_strcpy(char *dst, const char *src);
|
||||
|
||||
int jdns_string_indexOf(const jdns_string_t *s, unsigned char c, int pos);
|
||||
jdns_stringlist_t *jdns_string_split(const jdns_string_t *s, unsigned char sep);
|
||||
|
||||
jdns_dnshost_t *jdns_dnshost_new();
|
||||
jdns_dnshost_t *jdns_dnshost_copy(const jdns_dnshost_t *a);
|
||||
void jdns_dnshost_delete(jdns_dnshost_t *a);
|
||||
jdns_dnshostlist_t *jdns_dnshostlist_new();
|
||||
jdns_dnshostlist_t *jdns_dnshostlist_copy(const jdns_dnshostlist_t *a);
|
||||
void jdns_dnshostlist_delete(jdns_dnshostlist_t *a);
|
||||
void jdns_dnshostlist_append(jdns_dnshostlist_t *a, const jdns_dnshost_t *host);
|
||||
|
||||
jdns_rr_t *jdns_rr_from_resource(const jdns_packet_resource_t *pr, const jdns_packet_t *ref);
|
||||
void jdns_response_remove_extra(jdns_response_t *r);
|
||||
void jdns_response_remove_answer(jdns_response_t *r, int pos);
|
||||
|
||||
#define alloc_type(type) (type *)jdns_alloc(sizeof(type))
|
||||
#define _ustrdup(str) (unsigned char *)jdns_strdup((const char *)str)
|
||||
#define _ustrlen(str) strlen((const char *)str)
|
||||
#define _ustrcmp(a, b) strcmp((const char *)a, (const char *)b)
|
||||
|
||||
#endif
|
1008
thirdparty/jdns/jdns_packet.c
vendored
Normal file
1008
thirdparty/jdns/jdns_packet.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
116
thirdparty/jdns/jdns_packet.h
vendored
Normal file
116
thirdparty/jdns/jdns_packet.h
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 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_PACKET_H
|
||||
#define JDNS_PACKET_H
|
||||
|
||||
#include "jdns.h"
|
||||
|
||||
// -- howto --
|
||||
//
|
||||
// writing packets:
|
||||
// 1) call jdns_packet_new()
|
||||
// 2) populate the jdns_packet_t structure, using the functions
|
||||
// as necessary
|
||||
// 3) call jdns_packet_export() to populate the raw data of the packet
|
||||
//
|
||||
// reading packets:
|
||||
// 1) call jdns_packet_new()
|
||||
// 2) call jdns_packet_import() with the raw data
|
||||
// 3) the jdns_packet_t structure is now populated
|
||||
//
|
||||
// IMPORTANT: all names must be valid. that is, ending in a dot character
|
||||
|
||||
int jdns_packet_name_isvalid(const unsigned char *name, int size); // 0 if not valid
|
||||
|
||||
typedef struct jdns_packet_question
|
||||
{
|
||||
JDNS_OBJECT
|
||||
jdns_string_t *qname;
|
||||
unsigned short int qtype, qclass;
|
||||
} jdns_packet_question_t;
|
||||
|
||||
jdns_packet_question_t *jdns_packet_question_new();
|
||||
jdns_packet_question_t *jdns_packet_question_copy(const jdns_packet_question_t *a);
|
||||
void jdns_packet_question_delete(jdns_packet_question_t *a);
|
||||
|
||||
typedef struct jdns_packet_write jdns_packet_write_t;
|
||||
typedef struct jdns_packet jdns_packet_t;
|
||||
|
||||
typedef struct jdns_packet_resource
|
||||
{
|
||||
JDNS_OBJECT
|
||||
jdns_string_t *qname;
|
||||
unsigned short int qtype, qclass;
|
||||
unsigned long int ttl; // 31-bit number, top bit always 0
|
||||
unsigned short int rdlength;
|
||||
unsigned char *rdata;
|
||||
|
||||
// private
|
||||
jdns_list_t *writelog; // jdns_packet_write_t
|
||||
} jdns_packet_resource_t;
|
||||
|
||||
jdns_packet_resource_t *jdns_packet_resource_new();
|
||||
jdns_packet_resource_t *jdns_packet_resource_copy(const jdns_packet_resource_t *a);
|
||||
void jdns_packet_resource_delete(jdns_packet_resource_t *a);
|
||||
void jdns_packet_resource_add_bytes(jdns_packet_resource_t *a, const unsigned char *data, int size);
|
||||
void jdns_packet_resource_add_name(jdns_packet_resource_t *a, const jdns_string_t *name);
|
||||
int jdns_packet_resource_read_name(const jdns_packet_resource_t *a, const jdns_packet_t *p, int *at, jdns_string_t **name);
|
||||
|
||||
struct jdns_packet
|
||||
{
|
||||
JDNS_OBJECT
|
||||
unsigned short int id;
|
||||
struct
|
||||
{
|
||||
unsigned short qr, opcode, aa, tc, rd, ra, z, rcode;
|
||||
} opts;
|
||||
|
||||
// item counts as specified by the packet. do not use these
|
||||
// for iteration over the item lists, since they can be wrong
|
||||
// if the packet is truncated.
|
||||
int qdcount, ancount, nscount, arcount;
|
||||
|
||||
// value lists
|
||||
jdns_list_t *questions; // jdns_packet_question_t
|
||||
jdns_list_t *answerRecords; // jdns_packet_resource_t
|
||||
jdns_list_t *authorityRecords; // jdns_packet_resource_t
|
||||
jdns_list_t *additionalRecords; // jdns_packet_resource_t
|
||||
|
||||
// since dns packets are allowed to be truncated, it is possible
|
||||
// for a packet to not get fully parsed yet still be considered
|
||||
// successfully parsed. this flag means the packet was fully
|
||||
// parsed also.
|
||||
int fully_parsed;
|
||||
|
||||
int raw_size;
|
||||
unsigned char *raw_data;
|
||||
};
|
||||
|
||||
jdns_packet_t *jdns_packet_new();
|
||||
jdns_packet_t *jdns_packet_copy(const jdns_packet_t *a);
|
||||
void jdns_packet_delete(jdns_packet_t *a);
|
||||
int jdns_packet_import(jdns_packet_t **a, const unsigned char *data, int size); // 0 on fail
|
||||
int jdns_packet_export(jdns_packet_t *a, int maxsize); // 0 on fail
|
||||
|
||||
#endif
|
850
thirdparty/jdns/jdns_sys.c
vendored
Normal file
850
thirdparty/jdns/jdns_sys.c
vendored
Normal file
@ -0,0 +1,850 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
this code probes the system for dns settings. blah.
|
||||
|
||||
q3dns strategies
|
||||
----------------
|
||||
|
||||
windows:
|
||||
|
||||
domain name, name server, "search list" found in windows registry here:
|
||||
|
||||
HKEY_LOCAL_MACHINE
|
||||
System\CurrentControlSet\Services\Tcpip\Parameters <-- win nt+
|
||||
System\CurrentControlSet\Services\VxD\MSTCP <-- win 98
|
||||
|
||||
for domain, try DhcpDomain else Domain
|
||||
for name servers, try DhcpNameServer, else NameServer
|
||||
for search list, try SearchList
|
||||
|
||||
iphlpapi.dll : GetNetworkParams(PFIXED_INFO, PULONG);
|
||||
|
||||
info->DomainName
|
||||
info->DnsServerList (if not null, use it, and loop through ->Next until
|
||||
null)
|
||||
no search list
|
||||
|
||||
first try getnetworkparams. if that fails, try the nt regkey then the 98
|
||||
regkey. it seems that search list can only come from the registry, so
|
||||
maybe we need to grab that entry even if getnetworkparams works.
|
||||
|
||||
in the case of the registry, the nameserver and searchlist entries are
|
||||
delimited by spaces on win nt and commas on win 98. probably a good
|
||||
idea to simplify white space first (chop away space at start and end,
|
||||
reduce all sections of spaces to one char). also, lowercase the search
|
||||
list.
|
||||
|
||||
qt doesn't read the hosts file on windows. this might be a good idea, but
|
||||
probably not worth it.
|
||||
|
||||
unix:
|
||||
|
||||
read /etc/resolv.conf manually:
|
||||
for each line, split at spaces
|
||||
if the first item is "nameserver", then there should be an IP address
|
||||
following it. note: may contain mixed ipv4 and ipv6 addresses
|
||||
if the first item is "search", all other items are added to the domain
|
||||
list
|
||||
if the first item is "domain", then the next item should be added to the
|
||||
domain list.
|
||||
do case-insensitive matching for the item types
|
||||
for search/domain, the items are in the 8-bit system locale
|
||||
|
||||
info can also be fetched using system calls. we use the res_* stuff here.
|
||||
first we should detect for a "modern res api". this is available from
|
||||
glibc 2.3 and onward. use the following scheme to check for it:
|
||||
|
||||
#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2)
|
||||
&& (__GLIBC_MINOR__ >= 3)))
|
||||
// modern res api
|
||||
#endif
|
||||
|
||||
on mac we should look up res_init in the system library. see:
|
||||
qt_mac_resolve_sys(RTLD_NEXT, "res_init"); for a hint.
|
||||
otherwise we can just use res_init() straight.
|
||||
|
||||
under a modern res api, we do:
|
||||
struct __res_state res;
|
||||
res_ninit(&res);
|
||||
otherwise, we simply call res_init(). for the modern api, we use the "res"
|
||||
struct that we made. otherwise, we use the global "_res" struct.
|
||||
|
||||
read the res struct to obtain the name servers, search list, and domain.
|
||||
lowercase the search list and domain.
|
||||
|
||||
qt tries the file, and if that fails it tries the syscalls. we may want to
|
||||
do the syscalls first, or even just do both all the time.
|
||||
|
||||
read /etc/hosts manually:
|
||||
for each line
|
||||
if there is a '#' character in the line, remove it and everything to
|
||||
the right
|
||||
simplify white space
|
||||
convert to lowercase
|
||||
split the line at spaces
|
||||
first item is the ip address
|
||||
all remaining items are hostnames
|
||||
|
||||
note: these hosts could also be used for reverse-dns too
|
||||
note2: Windows has a hosts file as well (like C:\WINDOWS\hosts)
|
||||
*/
|
||||
|
||||
#include "jdns_p.h"
|
||||
|
||||
#ifdef JDNS_OS_WIN
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef JDNS_OS_UNIX
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/nameser.h>
|
||||
# include <resolv.h>
|
||||
# include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#define string_indexOf jdns_string_indexOf
|
||||
#define string_split jdns_string_split
|
||||
|
||||
static int char_isspace(unsigned char c)
|
||||
{
|
||||
if(c == ' ' || c == '\t' || c == '\n' || c == '\r')
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned char *string_getnextword(unsigned char *in, int size, int pos, int *newpos)
|
||||
{
|
||||
int n;
|
||||
int at;
|
||||
int len;
|
||||
unsigned char *out;
|
||||
|
||||
at = pos;
|
||||
|
||||
// skip any space at the start
|
||||
while(at < size && char_isspace(in[at]))
|
||||
++at;
|
||||
|
||||
// all space? no word then
|
||||
if(at >= size)
|
||||
return 0;
|
||||
|
||||
// skip until a space or end
|
||||
n = at;
|
||||
while(n < size && !char_isspace(in[n]))
|
||||
++n;
|
||||
len = n - at;
|
||||
|
||||
// allocate length + zero byte
|
||||
out = (unsigned char *)jdns_alloc(len + 1);
|
||||
if(!out)
|
||||
return 0;
|
||||
memcpy(out, in + at, len);
|
||||
out[len] = 0;
|
||||
*newpos = at + len;
|
||||
return out;
|
||||
}
|
||||
|
||||
static jdns_string_t *string_simplify(const jdns_string_t *in)
|
||||
{
|
||||
int n;
|
||||
int pos;
|
||||
int total;
|
||||
unsigned char *out;
|
||||
int outlen;
|
||||
jdns_string_t *outstr;
|
||||
jdns_stringlist_t *wordlist;
|
||||
|
||||
// gather words and total of lengths
|
||||
pos = 0;
|
||||
total = 0;
|
||||
wordlist = jdns_stringlist_new();
|
||||
while(1)
|
||||
{
|
||||
jdns_string_t *word;
|
||||
unsigned char *str = string_getnextword(in->data, in->size, pos, &pos);
|
||||
if(!str)
|
||||
break;
|
||||
word = jdns_string_new();
|
||||
jdns_string_set_cstr(word, (char *)str);
|
||||
jdns_free(str);
|
||||
jdns_stringlist_append(wordlist, word);
|
||||
total += word->size;
|
||||
jdns_string_delete(word);
|
||||
}
|
||||
|
||||
if(total == 0)
|
||||
{
|
||||
jdns_stringlist_delete(wordlist);
|
||||
|
||||
outstr = jdns_string_new();
|
||||
jdns_string_set_cstr(outstr, "");
|
||||
return outstr;
|
||||
}
|
||||
|
||||
// we need to allocate space for total lengths and wordcount-1 spaces
|
||||
outlen = total + (wordlist->count - 1);
|
||||
out = (unsigned char *)jdns_alloc(outlen);
|
||||
|
||||
// lay out the words
|
||||
pos = 0;
|
||||
for(n = 0; n < wordlist->count; ++n)
|
||||
{
|
||||
unsigned char *data = wordlist->item[n]->data;
|
||||
int size = wordlist->item[n]->size;
|
||||
memcpy(out + pos, data, size);
|
||||
pos += size;
|
||||
|
||||
// if this is not the last word, append a space
|
||||
if(n + 1 < wordlist->count)
|
||||
out[pos++] = ' ';
|
||||
}
|
||||
jdns_stringlist_delete(wordlist);
|
||||
|
||||
outstr = jdns_string_new();
|
||||
jdns_string_set(outstr, out, outlen);
|
||||
jdns_free(out);
|
||||
return outstr;
|
||||
}
|
||||
|
||||
static jdns_string_t *string_tolower(const jdns_string_t *in)
|
||||
{
|
||||
int n;
|
||||
jdns_string_t *out = jdns_string_copy(in);
|
||||
for(n = 0; n < out->size; ++n)
|
||||
out->data[n] = tolower(out->data[n]);
|
||||
return out;
|
||||
}
|
||||
|
||||
static jdns_string_t *file_nextline(FILE *f)
|
||||
{
|
||||
int at, size;
|
||||
unsigned char *buf;
|
||||
jdns_string_t *str;
|
||||
|
||||
size = 1023;
|
||||
buf = (unsigned char *)jdns_alloc(size);
|
||||
at = 0;
|
||||
while(1)
|
||||
{
|
||||
unsigned char c = fgetc(f);
|
||||
if(feof(f))
|
||||
{
|
||||
if(at > 0)
|
||||
{
|
||||
// if we read at least one char, take it as a
|
||||
// line
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
jdns_free(buf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(c == '\n')
|
||||
break;
|
||||
if(c == '\r')
|
||||
continue;
|
||||
if(at < 1023)
|
||||
buf[at++] = c;
|
||||
}
|
||||
|
||||
str = jdns_string_new();
|
||||
jdns_string_set(str, buf, at);
|
||||
jdns_free(buf);
|
||||
return str;
|
||||
}
|
||||
|
||||
static jdns_dnshostlist_t *read_hosts_file(const char *path)
|
||||
{
|
||||
jdns_dnshostlist_t *out;
|
||||
FILE *f;
|
||||
jdns_string_t *line, *simp;
|
||||
jdns_stringlist_t *parts;
|
||||
jdns_address_t *addr;
|
||||
int n;
|
||||
|
||||
out = jdns_dnshostlist_new();
|
||||
|
||||
f = jdns_fopen(path, "r");
|
||||
if(!f)
|
||||
return out;
|
||||
while(1)
|
||||
{
|
||||
line = file_nextline(f);
|
||||
if(!line)
|
||||
break;
|
||||
|
||||
// truncate at comment
|
||||
n = string_indexOf(line, '#', 0);
|
||||
if(n != -1)
|
||||
{
|
||||
line->size = n;
|
||||
line->data[n] = 0;
|
||||
}
|
||||
|
||||
simp = string_simplify(line);
|
||||
jdns_string_delete(line);
|
||||
|
||||
parts = string_split(simp, ' ');
|
||||
jdns_string_delete(simp);
|
||||
|
||||
if(parts->count < 2)
|
||||
{
|
||||
jdns_stringlist_delete(parts);
|
||||
continue;
|
||||
}
|
||||
|
||||
addr = jdns_address_new();
|
||||
if(!jdns_address_set_cstr(addr, (const char *)parts->item[0]->data))
|
||||
{
|
||||
jdns_address_delete(addr);
|
||||
jdns_stringlist_delete(parts);
|
||||
continue;
|
||||
}
|
||||
|
||||
for(n = 1; n < parts->count; ++n)
|
||||
{
|
||||
jdns_dnshost_t *h = jdns_dnshost_new();
|
||||
h->name = jdns_string_copy(parts->item[n]);
|
||||
h->address = jdns_address_copy(addr);
|
||||
jdns_dnshostlist_append(out, h);
|
||||
jdns_dnshost_delete(h);
|
||||
}
|
||||
|
||||
jdns_address_delete(addr);
|
||||
jdns_stringlist_delete(parts);
|
||||
}
|
||||
fclose(f);
|
||||
return out;
|
||||
}
|
||||
|
||||
static void apply_hosts_file(jdns_dnsparams_t *a, const char *path)
|
||||
{
|
||||
int n;
|
||||
jdns_dnshostlist_t *list;
|
||||
|
||||
list = read_hosts_file(path);
|
||||
for(n = 0; n < list->count; ++n)
|
||||
jdns_dnshostlist_append(a->hosts, list->item[n]);
|
||||
jdns_dnshostlist_delete(list);
|
||||
}
|
||||
|
||||
static int dnsparams_have_domain(const jdns_dnsparams_t *a, const jdns_string_t *domain)
|
||||
{
|
||||
int n;
|
||||
for(n = 0; n < a->domains->count; ++n)
|
||||
{
|
||||
jdns_string_t *str = a->domains->item[n];
|
||||
if(strcmp((const char *)str->data, (const char *)domain->data) == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef JDNS_OS_WIN
|
||||
|
||||
// from Microsoft IPTypes.h
|
||||
#ifndef IP_TYPES_INCLUDED
|
||||
#define MAX_HOSTNAME_LEN 128
|
||||
#define MAX_DOMAIN_NAME_LEN 128
|
||||
#define MAX_SCOPE_ID_LEN 256
|
||||
typedef struct {
|
||||
char String[4 * 4];
|
||||
} IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
|
||||
typedef struct _IP_ADDR_STRING {
|
||||
struct _IP_ADDR_STRING* Next;
|
||||
IP_ADDRESS_STRING IpAddress;
|
||||
IP_MASK_STRING IpMask;
|
||||
DWORD Context;
|
||||
} IP_ADDR_STRING, *PIP_ADDR_STRING;
|
||||
typedef struct {
|
||||
char HostName[MAX_HOSTNAME_LEN + 4] ;
|
||||
char DomainName[MAX_DOMAIN_NAME_LEN + 4];
|
||||
PIP_ADDR_STRING CurrentDnsServer;
|
||||
IP_ADDR_STRING DnsServerList;
|
||||
UINT NodeType;
|
||||
char ScopeId[MAX_SCOPE_ID_LEN + 4];
|
||||
UINT EnableRouting;
|
||||
UINT EnableProxy;
|
||||
UINT EnableDns;
|
||||
} FIXED_INFO, *PFIXED_INFO;
|
||||
#endif
|
||||
|
||||
typedef DWORD (WINAPI *GetNetworkParamsFunc)(PFIXED_INFO, PULONG);
|
||||
|
||||
static jdns_string_t *reg_readString(HKEY hk, const char *subkey)
|
||||
{
|
||||
char *buf;
|
||||
DWORD bufsize;
|
||||
int ret;
|
||||
jdns_string_t *str = 0;
|
||||
|
||||
bufsize = 1024;
|
||||
buf = (char *)jdns_alloc((int)bufsize);
|
||||
if(!buf)
|
||||
return 0;
|
||||
ret = RegQueryValueExA(hk, subkey, 0, 0, (LPBYTE)buf, &bufsize);
|
||||
if(ret == ERROR_MORE_DATA)
|
||||
{
|
||||
buf = (char *)jdns_realloc(buf, bufsize);
|
||||
if(!buf)
|
||||
{
|
||||
jdns_free(buf);
|
||||
return 0;
|
||||
}
|
||||
ret = RegQueryValueExA(hk, subkey, 0, 0, (LPBYTE)buf, &bufsize);
|
||||
}
|
||||
if(ret == ERROR_SUCCESS)
|
||||
{
|
||||
str = jdns_string_new();
|
||||
jdns_string_set_cstr(str, (char *)buf);
|
||||
}
|
||||
jdns_free(buf);
|
||||
return str;
|
||||
}
|
||||
|
||||
static jdns_dnsparams_t *dnsparams_get_winreg()
|
||||
{
|
||||
int n;
|
||||
jdns_dnsparams_t *params;
|
||||
HKEY key;
|
||||
int ret;
|
||||
char sep;
|
||||
jdns_string_t *str_domain, *str_nameserver, *str_searchlist;
|
||||
jdns_stringlist_t *list_nameserver, *list_searchlist;
|
||||
|
||||
sep = ' ';
|
||||
ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
|
||||
"System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
|
||||
0, KEY_READ, &key);
|
||||
if(ret != ERROR_SUCCESS)
|
||||
{
|
||||
sep = ',';
|
||||
ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
|
||||
"System\\CurrentControlSet\\Services\\VxD\\MSTCP",
|
||||
0, KEY_READ, &key);
|
||||
if(ret != ERROR_SUCCESS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
str_domain = reg_readString(key, "DhcpDomain");
|
||||
if(!str_domain)
|
||||
str_domain = reg_readString(key, "Domain");
|
||||
str_nameserver = reg_readString(key, "DhcpNameServer");
|
||||
if(!str_nameserver)
|
||||
str_nameserver = reg_readString(key, "NameServer");
|
||||
str_searchlist = reg_readString(key, "SearchList");
|
||||
|
||||
RegCloseKey(key);
|
||||
|
||||
list_nameserver = 0;
|
||||
if(str_nameserver)
|
||||
{
|
||||
list_nameserver = string_split(str_nameserver, sep);
|
||||
jdns_string_delete(str_nameserver);
|
||||
}
|
||||
list_searchlist = 0;
|
||||
if(str_searchlist)
|
||||
{
|
||||
// lowercase the string
|
||||
jdns_string_t *p = string_tolower(str_searchlist);
|
||||
jdns_string_delete(str_searchlist);
|
||||
str_searchlist = p;
|
||||
|
||||
list_searchlist = string_split(str_searchlist, sep);
|
||||
jdns_string_delete(str_searchlist);
|
||||
}
|
||||
|
||||
params = jdns_dnsparams_new();
|
||||
if(list_nameserver)
|
||||
{
|
||||
// qt seems to do a strange thing here by running each name
|
||||
// server address through the q3dns setLabel function, and
|
||||
// then pulls the result as a list of addresses. i have
|
||||
// no idea why they do this, or how one IP address would
|
||||
// turn into anything else, let alone several addresses.
|
||||
// so, uh, we're not going to do that.
|
||||
for(n = 0; n < list_nameserver->count; ++n)
|
||||
{
|
||||
jdns_address_t *addr = jdns_address_new();
|
||||
if(jdns_address_set_cstr(addr, (char *)list_nameserver->item[n]->data))
|
||||
jdns_dnsparams_append_nameserver(params, addr, JDNS_UNICAST_PORT);
|
||||
jdns_address_delete(addr);
|
||||
}
|
||||
jdns_stringlist_delete(list_nameserver);
|
||||
}
|
||||
if(str_domain)
|
||||
{
|
||||
if(str_domain->size > 0)
|
||||
jdns_dnsparams_append_domain(params, str_domain);
|
||||
jdns_string_delete(str_domain);
|
||||
}
|
||||
if(list_searchlist)
|
||||
{
|
||||
for(n = 0; n < list_searchlist->count; ++n)
|
||||
{
|
||||
if(list_searchlist->item[n]->size > 0)
|
||||
jdns_dnsparams_append_domain(params, list_searchlist->item[n]);
|
||||
}
|
||||
jdns_stringlist_delete(list_searchlist);
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
static jdns_dnsparams_t *dnsparams_get_winsys()
|
||||
{
|
||||
jdns_dnsparams_t *params;
|
||||
GetNetworkParamsFunc myGetNetworkParams;
|
||||
DWORD ret;
|
||||
HINSTANCE lib;
|
||||
jdns_address_t *addr;
|
||||
jdns_string_t *str;
|
||||
IP_ADDR_STRING *ipstr;
|
||||
|
||||
lib = LoadLibraryA("iphlpapi");
|
||||
if(!lib)
|
||||
return 0;
|
||||
|
||||
params = 0;
|
||||
myGetNetworkParams = (GetNetworkParamsFunc)GetProcAddress(lib, "GetNetworkParams");
|
||||
if(myGetNetworkParams)
|
||||
{
|
||||
ULONG bufsize = 0;
|
||||
ret = myGetNetworkParams(0, &bufsize);
|
||||
if(ret == ERROR_BUFFER_OVERFLOW)
|
||||
{
|
||||
FIXED_INFO *info = (FIXED_INFO *)jdns_alloc((int)bufsize);
|
||||
ret = myGetNetworkParams(info, &bufsize);
|
||||
if(ret == ERROR_SUCCESS)
|
||||
{
|
||||
params = jdns_dnsparams_new();
|
||||
ipstr = &info->DnsServerList;
|
||||
while(ipstr)
|
||||
{
|
||||
addr = jdns_address_new();
|
||||
if(jdns_address_set_cstr(addr, (char *)ipstr->IpAddress.String))
|
||||
jdns_dnsparams_append_nameserver(params, addr, JDNS_UNICAST_PORT);
|
||||
jdns_address_delete(addr);
|
||||
ipstr = ipstr->Next;
|
||||
}
|
||||
str = jdns_string_new();
|
||||
jdns_string_set_cstr(str, info->DomainName);
|
||||
if(str->size > 0)
|
||||
jdns_dnsparams_append_domain(params, str);
|
||||
jdns_string_delete(str);
|
||||
}
|
||||
jdns_free(info);
|
||||
}
|
||||
}
|
||||
FreeLibrary(lib);
|
||||
return params;
|
||||
}
|
||||
|
||||
static void apply_hosts_var_filepath(jdns_dnsparams_t *a, const char *envvar, const char *path)
|
||||
{
|
||||
jdns_string_t *e;
|
||||
char *str;
|
||||
int elen, plen;
|
||||
|
||||
e = jdns_getenv(envvar);
|
||||
if(!e)
|
||||
return;
|
||||
elen = strlen((char *)e->data);
|
||||
plen = strlen(path);
|
||||
str = (char *)jdns_alloc(elen + plen + 1);
|
||||
memcpy(str, e->data, elen);
|
||||
jdns_string_delete(e);
|
||||
|
||||
jdns_strcpy(str + elen, path);
|
||||
apply_hosts_file(a, str);
|
||||
jdns_free(str);
|
||||
}
|
||||
|
||||
static void apply_win_hosts_file(jdns_dnsparams_t *a)
|
||||
{
|
||||
// windows 64-bit
|
||||
apply_hosts_var_filepath(a, "SystemRoot", "\\SysWOW64\\drivers\\etc\\hosts");
|
||||
|
||||
// winnt+
|
||||
apply_hosts_var_filepath(a, "SystemRoot", "\\system32\\drivers\\etc\\hosts");
|
||||
|
||||
// win9x
|
||||
apply_hosts_var_filepath(a, "WINDIR", "\\hosts");
|
||||
}
|
||||
|
||||
static jdns_dnsparams_t *dnsparams_get_win()
|
||||
{
|
||||
int n;
|
||||
jdns_dnsparams_t *sys_params, *reg_params;
|
||||
|
||||
reg_params = dnsparams_get_winreg();
|
||||
sys_params = dnsparams_get_winsys();
|
||||
|
||||
// no sys params? take the reg params then
|
||||
if(!sys_params)
|
||||
{
|
||||
apply_win_hosts_file(reg_params);
|
||||
return reg_params;
|
||||
}
|
||||
|
||||
// sys params don't have a search list, so merge the domains from
|
||||
// the registry if possible
|
||||
if(reg_params)
|
||||
{
|
||||
for(n = 0; n < reg_params->domains->count; ++n)
|
||||
{
|
||||
jdns_string_t *reg_str = reg_params->domains->item[n];
|
||||
|
||||
// don't add dups
|
||||
if(!dnsparams_have_domain(sys_params, reg_str))
|
||||
jdns_dnsparams_append_domain(sys_params, reg_str);
|
||||
}
|
||||
jdns_dnsparams_delete(reg_params);
|
||||
}
|
||||
apply_win_hosts_file(sys_params);
|
||||
return sys_params;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef JDNS_OS_UNIX
|
||||
|
||||
static jdns_dnsparams_t *dnsparams_get_unixfiles()
|
||||
{
|
||||
FILE *f;
|
||||
int n;
|
||||
jdns_dnsparams_t *params;
|
||||
jdns_string_t *line, *simp;
|
||||
jdns_stringlist_t *parts;
|
||||
|
||||
params = jdns_dnsparams_new();
|
||||
|
||||
f = jdns_fopen("/etc/resolv.conf", "r");
|
||||
if(!f)
|
||||
return params;
|
||||
while(1)
|
||||
{
|
||||
line = file_nextline(f);
|
||||
if(!line)
|
||||
break;
|
||||
|
||||
// truncate at comment
|
||||
n = string_indexOf(line, '#', 0);
|
||||
if(n != -1)
|
||||
{
|
||||
line->size = n;
|
||||
line->data[n] = 0;
|
||||
}
|
||||
|
||||
simp = string_simplify(line);
|
||||
jdns_string_delete(line);
|
||||
|
||||
parts = string_split(simp, ' ');
|
||||
jdns_string_delete(simp);
|
||||
|
||||
if(parts->count < 2)
|
||||
{
|
||||
jdns_stringlist_delete(parts);
|
||||
continue;
|
||||
}
|
||||
|
||||
simp = string_tolower(parts->item[0]);
|
||||
if(strcmp((char *)simp->data, "nameserver") == 0)
|
||||
{
|
||||
jdns_address_t *addr = jdns_address_new();
|
||||
jdns_address_set_cstr(addr, (const char *)parts->item[1]->data);
|
||||
jdns_dnsparams_append_nameserver(params, addr, JDNS_UNICAST_PORT);
|
||||
jdns_address_delete(addr);
|
||||
}
|
||||
else if(strcmp((char *)simp->data, "search") == 0)
|
||||
{
|
||||
for(n = 1; n < parts->count; ++n)
|
||||
{
|
||||
jdns_dnsparams_append_domain(params, parts->item[n]);
|
||||
}
|
||||
}
|
||||
else if(strcmp((char *)simp->data, "domain") == 0)
|
||||
{
|
||||
jdns_dnsparams_append_domain(params, parts->item[1]);
|
||||
}
|
||||
jdns_string_delete(simp);
|
||||
|
||||
jdns_stringlist_delete(parts);
|
||||
}
|
||||
fclose(f);
|
||||
return params;
|
||||
}
|
||||
|
||||
#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 3)))
|
||||
# define JDNS_MODERN_RES_API
|
||||
#endif
|
||||
|
||||
#ifndef JDNS_MODERN_RES_API
|
||||
typedef int (*res_init_func)();
|
||||
static int my_res_init()
|
||||
{
|
||||
#ifdef JDNS_OS_MAC
|
||||
res_init_func mac_res_init;
|
||||
|
||||
// look up res_init in the system library (qt does this, not sure why)
|
||||
mac_res_init = (res_init_func)dlsym(RTLD_NEXT, "res_init");
|
||||
if(!mac_res_init)
|
||||
return -1;
|
||||
return mac_res_init();
|
||||
#else
|
||||
return res_init();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// on some platforms, __res_state_ext exists as a struct but it is not
|
||||
// a define, so the #ifdef doesn't work. as a workaround, we'll explicitly
|
||||
// specify the platforms that have __res_state_ext
|
||||
//#ifdef __res_state_ext
|
||||
#if defined(JDNS_OS_MAC) || defined(JDNS_OS_FREEBSD) || \
|
||||
defined(JDNS_OS_NETBSD) || defined (JDNS_OS_SOLARIS)
|
||||
# define USE_EXTEXT
|
||||
#endif
|
||||
|
||||
static jdns_dnsparams_t *dnsparams_get_unixsys()
|
||||
{
|
||||
int n;
|
||||
jdns_dnsparams_t *params;
|
||||
|
||||
#ifdef JDNS_MODERN_RES_API
|
||||
struct __res_state res;
|
||||
memset(&res, 0, sizeof(struct __res_state));
|
||||
n = res_ninit(&res);
|
||||
#define RESVAR res
|
||||
#else
|
||||
n = my_res_init();
|
||||
#define RESVAR _res
|
||||
#endif
|
||||
|
||||
params = jdns_dnsparams_new();
|
||||
|
||||
// error initializing?
|
||||
if(n == -1)
|
||||
return params;
|
||||
|
||||
// nameservers - ipv6
|
||||
for(n = 0; n < MAXNS && n < RESVAR._u._ext.nscount; ++n)
|
||||
{
|
||||
jdns_address_t *addr;
|
||||
struct sockaddr_in6 *sa6;
|
||||
|
||||
#ifdef USE_EXTEXT
|
||||
sa6 = ((struct sockaddr_in6 *)RESVAR._u._ext.ext) + n;
|
||||
#else
|
||||
sa6 = RESVAR._u._ext.nsaddrs[n];
|
||||
#endif
|
||||
|
||||
if(sa6 == NULL)
|
||||
continue;
|
||||
addr = jdns_address_new();
|
||||
jdns_address_set_ipv6(addr, sa6->sin6_addr.s6_addr);
|
||||
jdns_dnsparams_append_nameserver(params, addr, JDNS_UNICAST_PORT);
|
||||
jdns_address_delete(addr);
|
||||
}
|
||||
|
||||
// nameservers - ipv4
|
||||
for(n = 0; n < MAXNS && n < RESVAR.nscount; ++n)
|
||||
{
|
||||
jdns_address_t *addr = jdns_address_new();
|
||||
jdns_address_set_ipv4(addr, ntohl(RESVAR.nsaddr_list[n].sin_addr.s_addr));
|
||||
jdns_dnsparams_append_nameserver(params, addr, JDNS_UNICAST_PORT);
|
||||
jdns_address_delete(addr);
|
||||
}
|
||||
|
||||
// domain name
|
||||
if(strlen(RESVAR.defdname) > 0)
|
||||
{
|
||||
jdns_string_t *str;
|
||||
jdns_string_t *p;
|
||||
str = jdns_string_new();
|
||||
jdns_string_set_cstr(str, RESVAR.defdname);
|
||||
p = string_tolower(str);
|
||||
jdns_string_delete(str);
|
||||
str = p;
|
||||
jdns_dnsparams_append_domain(params, str);
|
||||
jdns_string_delete(str);
|
||||
}
|
||||
|
||||
// search list
|
||||
#ifdef MAXDFLSRCH
|
||||
for(n = 0; n < MAXDFLSRCH && RESVAR.dnsrch[n]; ++n)
|
||||
{
|
||||
if(strlen(RESVAR.dnsrch[n]) > 0)
|
||||
{
|
||||
jdns_string_t *str;
|
||||
jdns_string_t *p;
|
||||
str = jdns_string_new();
|
||||
jdns_string_set_cstr(str, RESVAR.dnsrch[n]);
|
||||
p = string_tolower(str);
|
||||
jdns_string_delete(str);
|
||||
str = p;
|
||||
|
||||
// don't add dups
|
||||
if(!dnsparams_have_domain(params, str))
|
||||
jdns_dnsparams_append_domain(params, str);
|
||||
|
||||
jdns_string_delete(str);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
static jdns_dnsparams_t *dnsparams_get_unix()
|
||||
{
|
||||
jdns_dnsparams_t *params;
|
||||
|
||||
// prefer system calls over files
|
||||
params = dnsparams_get_unixsys();
|
||||
if(params->nameservers->count == 0)
|
||||
{
|
||||
jdns_dnsparams_delete(params);
|
||||
params = dnsparams_get_unixfiles();
|
||||
}
|
||||
|
||||
apply_hosts_file(params, "/etc/hosts");
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
jdns_dnsparams_t *jdns_system_dnsparams()
|
||||
{
|
||||
#ifdef JDNS_OS_WIN
|
||||
return dnsparams_get_win();
|
||||
#else
|
||||
return dnsparams_get_unix();
|
||||
#endif
|
||||
}
|
1553
thirdparty/jdns/jdns_util.c
vendored
Normal file
1553
thirdparty/jdns/jdns_util.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
596
thirdparty/jdns/main.cpp
vendored
Normal file
596
thirdparty/jdns/main.cpp
vendored
Normal file
@ -0,0 +1,596 @@
|
||||
/*
|
||||
* Copyright (C) 2005 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.
|
||||
*/
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtNetwork>
|
||||
#include "qjdns.h"
|
||||
|
||||
QString dataToString(const QByteArray &buf)
|
||||
{
|
||||
QString out;
|
||||
for(int n = 0; n < buf.size(); ++n)
|
||||
{
|
||||
unsigned char c = (unsigned char)buf[n];
|
||||
if(c == '\\')
|
||||
out += "\\\\";
|
||||
else if(c >= 0x20 && c < 0x7f)
|
||||
out += c;
|
||||
else
|
||||
out += QString().sprintf("\\x%02x", (unsigned int)c);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void print_record(const QJDns::Record &r)
|
||||
{
|
||||
switch(r.type)
|
||||
{
|
||||
case QJDns::A:
|
||||
printf(" A: [%s] (ttl=%d)\n", qPrintable(r.address.toString()), r.ttl);
|
||||
break;
|
||||
case QJDns::Aaaa:
|
||||
printf(" AAAA: [%s] (ttl=%d)\n", qPrintable(r.address.toString()), r.ttl);
|
||||
break;
|
||||
case QJDns::Mx:
|
||||
printf(" MX: [%s] priority=%d (ttl=%d)\n", r.name.data(), r.priority, r.ttl);
|
||||
break;
|
||||
case QJDns::Srv:
|
||||
printf(" SRV: [%s] port=%d priority=%d weight=%d (ttl=%d)\n", r.name.data(), r.port, r.priority, r.weight, r.ttl);
|
||||
break;
|
||||
case QJDns::Cname:
|
||||
printf(" CNAME: [%s] (ttl=%d)\n", r.name.data(), r.ttl);
|
||||
break;
|
||||
case QJDns::Ptr:
|
||||
printf(" PTR: [%s] (ttl=%d)\n", r.name.data(), r.ttl);
|
||||
break;
|
||||
case QJDns::Txt:
|
||||
{
|
||||
printf(" TXT: count=%d (ttl=%d)\n", r.texts.count(), r.ttl);
|
||||
for(int n = 0; n < r.texts.count(); ++n)
|
||||
printf(" len=%d [%s]\n", r.texts[n].size(), qPrintable(dataToString(r.texts[n])));
|
||||
break;
|
||||
}
|
||||
case QJDns::Hinfo:
|
||||
printf(" HINFO: [%s] [%s] (ttl=%d)\n", r.cpu.data(), r.os.data(), r.ttl);
|
||||
break;
|
||||
case QJDns::Ns:
|
||||
printf(" NS: [%s] (ttl=%d)\n", r.name.data(), r.ttl);
|
||||
break;
|
||||
default:
|
||||
printf(" (Unknown): type=%d, size=%d (ttl=%d)\n", r.type, r.rdata.size(), r.ttl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
class App : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
bool opt_debug, opt_ipv6, opt_quit;
|
||||
int quit_time;
|
||||
QString mode, type, name, ipaddr;
|
||||
QStringList nslist;
|
||||
QList<QJDns::Record> pubitems;
|
||||
QJDns jdns;
|
||||
int req_id;
|
||||
|
||||
App()
|
||||
{
|
||||
connect(&jdns, SIGNAL(resultsReady(int, const QJDns::Response &)), SLOT(jdns_resultsReady(int, const QJDns::Response &)));
|
||||
connect(&jdns, SIGNAL(published(int)), SLOT(jdns_published(int)));
|
||||
connect(&jdns, SIGNAL(error(int, QJDns::Error)), SLOT(jdns_error(int, QJDns::Error)));
|
||||
connect(&jdns, SIGNAL(shutdownFinished()), SLOT(jdns_shutdownFinished()));
|
||||
connect(&jdns, SIGNAL(debugLinesReady()), SLOT(jdns_debugLinesReady()));
|
||||
}
|
||||
|
||||
~App()
|
||||
{
|
||||
}
|
||||
|
||||
public slots:
|
||||
void start()
|
||||
{
|
||||
if(mode == "uni")
|
||||
{
|
||||
if(!jdns.init(QJDns::Unicast, opt_ipv6 ? QHostAddress::AnyIPv6 : QHostAddress::Any))
|
||||
{
|
||||
jdns_debugLinesReady();
|
||||
printf("unable to bind\n");
|
||||
emit quit();
|
||||
return;
|
||||
}
|
||||
|
||||
QList<QJDns::NameServer> addrs;
|
||||
for(int n = 0; n < nslist.count(); ++n)
|
||||
{
|
||||
QJDns::NameServer host;
|
||||
QString str = nslist[n];
|
||||
if(str == "mul")
|
||||
{
|
||||
if(opt_ipv6)
|
||||
host.address = QHostAddress("FF02::FB");
|
||||
else
|
||||
host.address = QHostAddress("224.0.0.251");
|
||||
host.port = 5353;
|
||||
}
|
||||
else
|
||||
{
|
||||
int at = str.indexOf(';');
|
||||
if(at != -1)
|
||||
{
|
||||
host.address = QHostAddress(str.mid(0, at));
|
||||
host.port = str.mid(at + 1).toInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
host.address = QHostAddress(str);
|
||||
}
|
||||
}
|
||||
|
||||
if(host.address.isNull() || host.port <= 0)
|
||||
{
|
||||
printf("bad nameserver: [%s]\n", qPrintable(nslist[n]));
|
||||
emit quit();
|
||||
return;
|
||||
}
|
||||
addrs += host;
|
||||
}
|
||||
|
||||
if(addrs.isEmpty())
|
||||
addrs = QJDns::systemInfo().nameServers;
|
||||
|
||||
if(addrs.isEmpty())
|
||||
{
|
||||
printf("no nameservers were detected or specified\n");
|
||||
emit quit();
|
||||
return;
|
||||
}
|
||||
|
||||
jdns.setNameServers(addrs);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!jdns.init(QJDns::Multicast, opt_ipv6 ? QHostAddress::AnyIPv6 : QHostAddress::Any))
|
||||
{
|
||||
jdns_debugLinesReady();
|
||||
printf("unable to bind\n");
|
||||
emit quit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(mode == "uni" || mode == "mul")
|
||||
{
|
||||
int x = QJDns::A;
|
||||
if(type == "ptr")
|
||||
x = QJDns::Ptr;
|
||||
else if(type == "srv")
|
||||
x = QJDns::Srv;
|
||||
else if(type == "a")
|
||||
x = QJDns::A;
|
||||
else if(type == "aaaa")
|
||||
x = QJDns::Aaaa;
|
||||
else if(type == "mx")
|
||||
x = QJDns::Mx;
|
||||
else if(type == "txt")
|
||||
x = QJDns::Txt;
|
||||
else if(type == "hinfo")
|
||||
x = QJDns::Hinfo;
|
||||
else if(type == "cname")
|
||||
x = QJDns::Cname;
|
||||
else if(type == "any")
|
||||
x = QJDns::Any;
|
||||
else
|
||||
{
|
||||
bool ok;
|
||||
int y = type.toInt(&ok);
|
||||
if(ok)
|
||||
x = y;
|
||||
}
|
||||
|
||||
req_id = jdns.queryStart(name.toLatin1(), x);
|
||||
printf("[%d] Querying for [%s] type=%d ...\n", req_id, qPrintable(name), x);
|
||||
}
|
||||
else // publish
|
||||
{
|
||||
for(int n = 0; n < pubitems.count(); ++n)
|
||||
{
|
||||
const QJDns::Record &rr = pubitems[n];
|
||||
QJDns::PublishMode m = QJDns::Unique;
|
||||
if(rr.type == QJDns::Ptr)
|
||||
m = QJDns::Shared;
|
||||
int id = jdns.publishStart(m, rr);
|
||||
printf("[%d] Publishing [%s] type=%d ...\n", id, rr.owner.data(), rr.type);
|
||||
}
|
||||
}
|
||||
|
||||
if(opt_quit)
|
||||
QTimer::singleShot(quit_time * 1000, this, SLOT(doShutdown()));
|
||||
}
|
||||
|
||||
signals:
|
||||
void quit();
|
||||
|
||||
private slots:
|
||||
void jdns_resultsReady(int id, const QJDns::Response &results)
|
||||
{
|
||||
printf("[%d] Results\n", id);
|
||||
for(int n = 0; n < results.answerRecords.count(); ++n)
|
||||
print_record(results.answerRecords[n]);
|
||||
|
||||
if(mode == "uni")
|
||||
jdns.shutdown();
|
||||
}
|
||||
|
||||
void jdns_published(int id)
|
||||
{
|
||||
printf("[%d] Published\n", id);
|
||||
}
|
||||
|
||||
void jdns_error(int id, QJDns::Error e)
|
||||
{
|
||||
QString str;
|
||||
if(e == QJDns::ErrorGeneric)
|
||||
str = "Generic";
|
||||
else if(e == QJDns::ErrorNXDomain)
|
||||
str = "NXDomain";
|
||||
else if(e == QJDns::ErrorTimeout)
|
||||
str = "Timeout";
|
||||
else if(e == QJDns::ErrorConflict)
|
||||
str = "Conflict";
|
||||
printf("[%d] Error: %s\n", id, qPrintable(str));
|
||||
jdns.shutdown();
|
||||
}
|
||||
|
||||
void jdns_shutdownFinished()
|
||||
{
|
||||
emit quit();
|
||||
}
|
||||
|
||||
void jdns_debugLinesReady()
|
||||
{
|
||||
QStringList lines = jdns.debugLines();
|
||||
if(opt_debug)
|
||||
{
|
||||
for(int n = 0; n < lines.count(); ++n)
|
||||
printf("jdns: %s\n", qPrintable(lines[n]));
|
||||
}
|
||||
}
|
||||
|
||||
void doShutdown()
|
||||
{
|
||||
jdns.shutdown();
|
||||
}
|
||||
};
|
||||
|
||||
#include "main.moc"
|
||||
|
||||
void usage()
|
||||
{
|
||||
printf("usage: jdns (options) uni [type] [name] (nameserver(;port)|mul ...)\n");
|
||||
printf(" jdns (options) mul [type] [name]\n");
|
||||
printf(" jdns (options) pub [items ...]\n");
|
||||
printf(" jdns sys\n");
|
||||
printf("\n");
|
||||
printf("options:\n");
|
||||
printf(" -d show debug output\n");
|
||||
printf(" -6 use ipv6\n");
|
||||
printf(" -q x quit x seconds after starting\n");
|
||||
printf("\n");
|
||||
printf("uni/mul types: a aaaa ptr srv mx txt hinfo cname any\n");
|
||||
printf("pub items: ptr:name,answer srv:name,answer,port a:name,ipaddr\n");
|
||||
printf(" txt:name,str0,...,strn aaaa:name,ipaddr\n");
|
||||
printf("\n");
|
||||
printf("examples:\n");
|
||||
printf(" jdns uni a jabber.org 192.168.0.1\n");
|
||||
printf(" jdns uni srv _xmpp-client._tcp.jabber.org 192.168.0.1;53\n");
|
||||
printf(" jdns uni 10 user@host._presence._tcp.local mul\n");
|
||||
printf(" jdns mul a foobar.local\n");
|
||||
printf(" jdns mul ptr _services._dns-sd._udp.local\n");
|
||||
printf(" jdns pub a:mybox.local.,192.168.0.55\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
if(argc < 2)
|
||||
{
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get args
|
||||
QStringList args;
|
||||
for(int n = 1; n < argc; ++n)
|
||||
args += QString(argv[n]);
|
||||
|
||||
bool opt_debug = false;
|
||||
bool opt_ipv6 = false;
|
||||
bool opt_quit = false;
|
||||
int quit_time = 0;
|
||||
QString mode, type, name, ipaddr;
|
||||
QStringList nslist;
|
||||
QList<QJDns::Record> pubitems;
|
||||
|
||||
// options
|
||||
for(int n = 0; n < args.count(); ++n)
|
||||
{
|
||||
if(args[n].left(1) == "-")
|
||||
{
|
||||
if(args[n] == "-d")
|
||||
opt_debug = true;
|
||||
else if(args[n] == "-6")
|
||||
opt_ipv6 = true;
|
||||
else if(args[n] == "-q")
|
||||
{
|
||||
if(n + 1 >= args.count())
|
||||
{
|
||||
printf("need to specify number of seconds\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x = args[n + 1].toInt();
|
||||
if(x < 1)
|
||||
x = 30;
|
||||
|
||||
opt_quit = true;
|
||||
quit_time = x;
|
||||
|
||||
args.removeAt(n + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("bad option\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
args.removeAt(n);
|
||||
--n; // adjust position
|
||||
}
|
||||
}
|
||||
|
||||
mode = args[0];
|
||||
if(mode == "uni" || mode == "mul")
|
||||
{
|
||||
if(args.count() < 3)
|
||||
{
|
||||
printf("not enough args\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
type = args[1];
|
||||
name = args[2];
|
||||
if(mode == "uni")
|
||||
{
|
||||
for(int n = 3; n < args.count(); ++n)
|
||||
nslist += QString(args[n]);
|
||||
}
|
||||
}
|
||||
else if(mode == "pub")
|
||||
{
|
||||
if(args.count() < 2)
|
||||
{
|
||||
printf("not enough args\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
for(int n = 1; n < args.count(); ++n)
|
||||
{
|
||||
QString arg = args[n];
|
||||
int at = arg.indexOf(':');
|
||||
if(at == -1)
|
||||
{
|
||||
printf("missing colon\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
QString type = arg.mid(0, at).toLower();
|
||||
QString val = arg.mid(at + 1);
|
||||
if(type == "a")
|
||||
{
|
||||
QStringList list = val.split(',');
|
||||
if(list.count() != 2)
|
||||
{
|
||||
printf("bad format for A type\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
QHostAddress host(list[1]);
|
||||
if(host.isNull() || host.protocol() != QAbstractSocket::IPv4Protocol)
|
||||
{
|
||||
printf("bad format for A type IP address\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
QJDns::Record rec;
|
||||
rec.owner = list[0].toLatin1();
|
||||
rec.type = QJDns::A;
|
||||
rec.ttl = 120;
|
||||
rec.haveKnown = true;
|
||||
rec.address = host;
|
||||
pubitems += rec;
|
||||
}
|
||||
else if(type == "aaaa")
|
||||
{
|
||||
QStringList list = val.split(',');
|
||||
if(list.count() != 2)
|
||||
{
|
||||
printf("bad format for AAAA type\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
QHostAddress host(list[1]);
|
||||
if(host.isNull() || host.protocol() != QAbstractSocket::IPv6Protocol)
|
||||
{
|
||||
printf("bad format for AAAA type IP address\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
QJDns::Record rec;
|
||||
rec.owner = list[0].toLatin1();
|
||||
rec.type = QJDns::Aaaa;
|
||||
rec.ttl = 120;
|
||||
rec.haveKnown = true;
|
||||
rec.address = host;
|
||||
pubitems += rec;
|
||||
}
|
||||
else if(type == "srv")
|
||||
{
|
||||
QStringList list = val.split(',');
|
||||
if(list.count() != 3)
|
||||
{
|
||||
printf("bad format for SRV type\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
QJDns::Record rec;
|
||||
rec.owner = list[0].toLatin1();
|
||||
rec.type = QJDns::Srv;
|
||||
rec.ttl = 120;
|
||||
rec.haveKnown = true;
|
||||
rec.name = list[1].toLatin1();
|
||||
rec.priority = 0;
|
||||
rec.weight = 0;
|
||||
rec.port = list[2].toInt();
|
||||
pubitems += rec;
|
||||
}
|
||||
else if(type == "ptr")
|
||||
{
|
||||
QStringList list = val.split(',');
|
||||
if(list.count() != 2)
|
||||
{
|
||||
printf("bad format for PTR type\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
QJDns::Record rec;
|
||||
rec.owner = list[0].toLatin1();
|
||||
rec.type = QJDns::Ptr;
|
||||
rec.ttl = 120;
|
||||
rec.haveKnown = true;
|
||||
rec.name = list[1].toLatin1();
|
||||
pubitems += rec;
|
||||
}
|
||||
else if(type == "txt")
|
||||
{
|
||||
QStringList list = val.split(',');
|
||||
QList<QByteArray> texts;
|
||||
for(int n = 1; n < list.count(); ++n)
|
||||
texts += list[n].toLatin1();
|
||||
|
||||
QJDns::Record rec;
|
||||
rec.owner = list[0].toLatin1();
|
||||
rec.type = QJDns::Txt;
|
||||
rec.ttl = 120;
|
||||
rec.haveKnown = true;
|
||||
rec.texts = texts;
|
||||
pubitems += rec;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("bad record type [%s]\n", qPrintable(type));
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(mode == "sys")
|
||||
{
|
||||
QJDns::SystemInfo info = QJDns::systemInfo();
|
||||
|
||||
printf("DNS System Information\n");
|
||||
printf(" Name Servers:\n");
|
||||
if(!info.nameServers.isEmpty())
|
||||
{
|
||||
for(int n = 0; n < info.nameServers.count(); ++n)
|
||||
printf(" %s\n", qPrintable(info.nameServers[n].address.toString()));
|
||||
}
|
||||
else
|
||||
printf(" (None)\n");
|
||||
|
||||
printf(" Domains:\n");
|
||||
if(!info.domains.isEmpty())
|
||||
{
|
||||
for(int n = 0; n < info.domains.count(); ++n)
|
||||
printf(" [%s]\n", info.domains[n].data());
|
||||
}
|
||||
else
|
||||
printf(" (None)\n");
|
||||
|
||||
printf(" Hosts:\n");
|
||||
if(!info.hosts.isEmpty())
|
||||
{
|
||||
for(int n = 0; n < info.hosts.count(); ++n)
|
||||
{
|
||||
const QJDns::DnsHost &h = info.hosts[n];
|
||||
printf(" [%s] -> %s\n", h.name.data(), qPrintable(h.address.toString()));
|
||||
}
|
||||
}
|
||||
else
|
||||
printf(" (None)\n");
|
||||
|
||||
QHostAddress addr;
|
||||
printf("Primary IPv4 Multicast Address: ");
|
||||
addr = QJDns::detectPrimaryMulticast(QHostAddress::Any);
|
||||
if(!addr.isNull())
|
||||
printf("%s\n", qPrintable(addr.toString()));
|
||||
else
|
||||
printf("(None)\n");
|
||||
printf("Primary IPv6 Multicast Address: ");
|
||||
addr = QJDns::detectPrimaryMulticast(QHostAddress::AnyIPv6);
|
||||
if(!addr.isNull())
|
||||
printf("%s\n", qPrintable(addr.toString()));
|
||||
else
|
||||
printf("(None)\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
App a;
|
||||
a.opt_debug = opt_debug;
|
||||
a.opt_ipv6 = opt_ipv6;
|
||||
a.opt_quit = opt_quit;
|
||||
a.quit_time = quit_time;
|
||||
a.mode = mode;
|
||||
a.type = type.toLower();
|
||||
a.name = name;
|
||||
a.ipaddr = ipaddr;
|
||||
a.nslist = nslist;
|
||||
a.pubitems = pubitems;
|
||||
QObject::connect(&a, SIGNAL(quit()), &app, SLOT(quit()));
|
||||
QTimer::singleShot(0, &a, SLOT(start()));
|
||||
app.exec();
|
||||
return 0;
|
||||
}
|
1047
thirdparty/jdns/qjdns.cpp
vendored
Normal file
1047
thirdparty/jdns/qjdns.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
158
thirdparty/jdns/qjdns.h
vendored
Normal file
158
thirdparty/jdns/qjdns.h
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// this is the Qt wrapper to jdns. it requires Qt 4.1+
|
||||
|
||||
#ifndef QJDNS_H
|
||||
#define QJDNS_H
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtNetwork>
|
||||
|
||||
class QJDns : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Mode
|
||||
{
|
||||
Unicast,
|
||||
Multicast
|
||||
};
|
||||
|
||||
enum PublishMode
|
||||
{
|
||||
Unique,
|
||||
Shared
|
||||
};
|
||||
|
||||
enum Type
|
||||
{
|
||||
A = 1,
|
||||
Aaaa = 28,
|
||||
Mx = 15,
|
||||
Srv = 33,
|
||||
Cname = 5,
|
||||
Ptr = 12,
|
||||
Txt = 16,
|
||||
Hinfo = 13,
|
||||
Ns = 2,
|
||||
Any = 255
|
||||
};
|
||||
|
||||
enum Error
|
||||
{
|
||||
ErrorGeneric,
|
||||
ErrorNXDomain, // query only
|
||||
ErrorTimeout, // query only
|
||||
ErrorConflict // publish only
|
||||
};
|
||||
|
||||
class NameServer
|
||||
{
|
||||
public:
|
||||
QHostAddress address;
|
||||
int port;
|
||||
|
||||
NameServer();
|
||||
};
|
||||
|
||||
class DnsHost
|
||||
{
|
||||
public:
|
||||
QByteArray name;
|
||||
QHostAddress address;
|
||||
};
|
||||
|
||||
class SystemInfo
|
||||
{
|
||||
public:
|
||||
QList<NameServer> nameServers;
|
||||
QList<QByteArray> domains;
|
||||
QList<DnsHost> hosts;
|
||||
};
|
||||
|
||||
class Record
|
||||
{
|
||||
public:
|
||||
QByteArray owner;
|
||||
int ttl;
|
||||
int type;
|
||||
QByteArray rdata;
|
||||
bool haveKnown;
|
||||
|
||||
// known
|
||||
QHostAddress address; // for A, Aaaa
|
||||
QByteArray name; // for Mx, Srv, Cname, Ptr, Ns
|
||||
int priority; // for Mx, Srv
|
||||
int weight; // for Srv
|
||||
int port; // for Srv
|
||||
QList<QByteArray> texts; // for Txt
|
||||
QByteArray cpu; // for Hinfo
|
||||
QByteArray os; // for Hinfo
|
||||
|
||||
Record();
|
||||
bool verify() const;
|
||||
};
|
||||
|
||||
class Response
|
||||
{
|
||||
public:
|
||||
QList<Record> answerRecords;
|
||||
QList<Record> authorityRecords;
|
||||
QList<Record> additionalRecords;
|
||||
};
|
||||
|
||||
QJDns(QObject *parent = 0);
|
||||
~QJDns();
|
||||
|
||||
bool init(Mode mode, const QHostAddress &address);
|
||||
void shutdown();
|
||||
QStringList debugLines();
|
||||
|
||||
static SystemInfo systemInfo();
|
||||
static QHostAddress detectPrimaryMulticast(const QHostAddress &address);
|
||||
|
||||
void setNameServers(const QList<NameServer> &list);
|
||||
|
||||
int queryStart(const QByteArray &name, int type);
|
||||
void queryCancel(int id);
|
||||
|
||||
// for multicast mode only
|
||||
int publishStart(PublishMode m, const Record &record);
|
||||
void publishUpdate(int id, const Record &record);
|
||||
void publishCancel(int id);
|
||||
|
||||
signals:
|
||||
void resultsReady(int id, const QJDns::Response &results);
|
||||
void published(int id);
|
||||
void error(int id, QJDns::Error e);
|
||||
void shutdownFinished();
|
||||
void debugLinesReady();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
friend class Private;
|
||||
Private *d;
|
||||
};
|
||||
|
||||
#endif
|
184
thirdparty/jdns/qjdns_sock.cpp
vendored
Normal file
184
thirdparty/jdns/qjdns_sock.cpp
vendored
Normal file
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "qjdns_sock.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
# include <sys/time.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# include <fcntl.h>
|
||||
# include <errno.h>
|
||||
# include <signal.h>
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifndef QT_NO_IPV6
|
||||
# define HAVE_IPV6
|
||||
# ifndef s6_addr
|
||||
# define IPPROTO_IPV6 41
|
||||
struct in6_addr
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned char _S6_u8[16];
|
||||
unsigned short _S6_u16[8];
|
||||
unsigned long _S6_u32[4];
|
||||
} _S6_un;
|
||||
};
|
||||
# define s6_addr _S6_un._S6_u8
|
||||
# endif
|
||||
# ifndef IPV6_JOIN_GROUP
|
||||
# define IPV6_JOIN_GROUP 12
|
||||
# define IPV6_MULTICAST_HOPS 10
|
||||
struct ipv6_mreq
|
||||
{
|
||||
struct in6_addr ipv6mr_multiaddr;
|
||||
unsigned int ipv6mr_interface;
|
||||
};
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static int get_last_error()
|
||||
{
|
||||
int x;
|
||||
#ifdef Q_OS_WIN
|
||||
x = WSAGetLastError();
|
||||
#else
|
||||
x = errno;
|
||||
#endif
|
||||
return x;
|
||||
}
|
||||
|
||||
bool qjdns_sock_setMulticast4(int s, unsigned long int addr, int *errorCode)
|
||||
{
|
||||
int ret;
|
||||
struct ip_mreq mc;
|
||||
|
||||
memset(&mc, 0, sizeof(mc));
|
||||
mc.imr_multiaddr.s_addr = htonl(addr);
|
||||
mc.imr_interface.s_addr = INADDR_ANY;
|
||||
|
||||
ret = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&mc, sizeof(mc));
|
||||
if(ret != 0)
|
||||
{
|
||||
if(errorCode)
|
||||
*errorCode = get_last_error();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool qjdns_sock_setMulticast6(int s, unsigned char *addr, int *errorCode)
|
||||
{
|
||||
#ifdef HAVE_IPV6
|
||||
int ret;
|
||||
struct ipv6_mreq mc;
|
||||
|
||||
memset(&mc, 0, sizeof(mc));
|
||||
memcpy(mc.ipv6mr_multiaddr.s6_addr, addr, 16);
|
||||
mc.ipv6mr_interface = 0;
|
||||
|
||||
ret = setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, (const char *)&mc, sizeof(mc));
|
||||
if(ret != 0)
|
||||
{
|
||||
if(errorCode)
|
||||
*errorCode = get_last_error();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
Q_UNUSED(s);
|
||||
Q_UNUSED(addr);
|
||||
Q_UNUSED(errorCode);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool qjdns_sock_setTTL4(int s, int ttl)
|
||||
{
|
||||
unsigned char cttl;
|
||||
int ret, ittl;
|
||||
|
||||
cttl = ttl;
|
||||
ittl = ttl;
|
||||
|
||||
// IP_MULTICAST_TTL might take 1 byte or 4, try both
|
||||
ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&cttl, sizeof(cttl));
|
||||
if(ret != 0)
|
||||
{
|
||||
ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&ittl, sizeof(ittl));
|
||||
if(ret != 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool qjdns_sock_setTTL6(int s, int ttl)
|
||||
{
|
||||
#ifdef HAVE_IPV6
|
||||
unsigned char cttl;
|
||||
int ret, ittl;
|
||||
|
||||
cttl = ttl;
|
||||
ittl = ttl;
|
||||
|
||||
// IPV6_MULTICAST_HOPS might take 1 byte or 4, try both
|
||||
ret = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char *)&cttl, sizeof(cttl));
|
||||
if(ret != 0)
|
||||
{
|
||||
ret = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char *)&ittl, sizeof(ittl));
|
||||
if(ret != 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
Q_UNUSED(s);
|
||||
Q_UNUSED(ttl);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool qjdns_sock_setIPv6Only(int s)
|
||||
{
|
||||
#if defined(HAVE_IPV6) && defined(IPV6_V6ONLY)
|
||||
int x = 1;
|
||||
if(setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&x, sizeof(x)) != 0)
|
||||
return false;
|
||||
return true;
|
||||
#else
|
||||
Q_UNUSED(s);
|
||||
return false;
|
||||
#endif
|
||||
}
|
33
thirdparty/jdns/qjdns_sock.h
vendored
Normal file
33
thirdparty/jdns/qjdns_sock.h
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 QJDNS_SOCK_H
|
||||
#define QJDNS_SOCK_H
|
||||
|
||||
bool qjdns_sock_setMulticast4(int s, unsigned long int addr, int *errorCode);
|
||||
bool qjdns_sock_setMulticast6(int s, unsigned char *addr, int *errorCode);
|
||||
bool qjdns_sock_setTTL4(int s, int ttl);
|
||||
bool qjdns_sock_setTTL6(int s, int ttl);
|
||||
bool qjdns_sock_setIPv6Only(int s);
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user