3661 Sync mDNS with upstream
Reviewed by: Richard Lowe <richlowe@richlowe.net> Approved by: Robert Mustacchi <rm@joyent.com>
This commit is contained in:
parent
8551f527ef
commit
5ffb0c9b03
|
@ -30,6 +30,11 @@ exception_lists/closed-bins
|
||||||
exception_lists/copyright
|
exception_lists/copyright
|
||||||
exception_lists/cstyle
|
exception_lists/cstyle
|
||||||
exception_lists/hdrchk
|
exception_lists/hdrchk
|
||||||
|
usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.c
|
||||||
|
usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.h
|
||||||
|
usr/src/cmd/cmd-inet/usr.bin/dns-sd/dns-sd.c
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/THIRDPARTYLICENSE
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/*.[ch]
|
||||||
usr/src/cmd/dtrace/test/tst/common/*/*.out
|
usr/src/cmd/dtrace/test/tst/common/*/*.out
|
||||||
usr/src/cmd/krb5/kadmin/cli/kadmin_ct.c
|
usr/src/cmd/krb5/kadmin/cli/kadmin_ct.c
|
||||||
usr/src/cmd/krb5/kadmin/cli/kadmin.h
|
usr/src/cmd/krb5/kadmin/cli/kadmin.h
|
||||||
|
@ -340,6 +345,11 @@ usr/src/lib/krb5/ss/mit-sipb-copyright.h
|
||||||
usr/src/lib/krb5/ss/options.c
|
usr/src/lib/krb5/ss/options.c
|
||||||
usr/src/lib/krb5/ss/std_rqs.c
|
usr/src/lib/krb5/ss/std_rqs.c
|
||||||
usr/src/lib/krb5/ss/utils.c
|
usr/src/lib/krb5/ss/utils.c
|
||||||
|
usr/src/lib/libdns_sd/THIRDPARTYLICENSE
|
||||||
|
usr/src/lib/libdns_sd/common/*.[ch]
|
||||||
|
usr/src/lib/libdns_sd/java/common/JNISupport.c
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/*.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/*
|
||||||
usr/src/lib/librstp/common/*.[ch]
|
usr/src/lib/librstp/common/*.[ch]
|
||||||
usr/src/lib/librstp/common/[CRT]*
|
usr/src/lib/librstp/common/[CRT]*
|
||||||
# these have copyrights that the nit checker doesn't grok
|
# these have copyrights that the nit checker doesn't grok
|
||||||
|
|
|
@ -1,3 +1,21 @@
|
||||||
|
usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.[ch]
|
||||||
|
usr/src/cmd/cmd-inet/usr.bin/dns-sd/dns-sd.c
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.[ch]
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.[ch]
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSDigest.[ch]
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/PosixDaemon.c
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/PlatformCommon.[ch]
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/GenLinkedList.[ch]
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNS.[ch]
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.[ch]
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSEmbeddedAPI.h
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSPosix.[ch]
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSUNP.[ch]
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/nsec.h
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.[ch]
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/dnssec.h
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/uDNS.[ch]
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.[ch]
|
||||||
usr/src/cmd/krb5/kadmin/cli/kadmin_ct.c
|
usr/src/cmd/krb5/kadmin/cli/kadmin_ct.c
|
||||||
usr/src/cmd/krb5/kadmin/cli/kadmin.c
|
usr/src/cmd/krb5/kadmin/cli/kadmin.c
|
||||||
usr/src/cmd/krb5/kadmin/cli/kadmin.h
|
usr/src/cmd/krb5/kadmin/cli/kadmin.h
|
||||||
|
@ -570,6 +588,12 @@ usr/src/lib/krb5/ss/ss_internal.h
|
||||||
usr/src/lib/krb5/ss/ss.h
|
usr/src/lib/krb5/ss/ss.h
|
||||||
usr/src/lib/krb5/ss/std_rqs.c
|
usr/src/lib/krb5/ss/std_rqs.c
|
||||||
usr/src/lib/krb5/ss/utils.c
|
usr/src/lib/krb5/ss/utils.c
|
||||||
|
usr/src/lib/libdns_sd/common/dnssd_clientlib.c
|
||||||
|
usr/src/lib/libdns_sd/common/dnssd_clientstub.c
|
||||||
|
usr/src/lib/libdns_sd/common/dnssd_ipc.c
|
||||||
|
usr/src/lib/libdns_sd/common/dnssd_ipc.h
|
||||||
|
usr/src/lib/libdns_sd/common/dns_sd.h
|
||||||
|
usr/src/lib/libdns_sd/java/common/JNISupport.c
|
||||||
usr/src/lib/libgss/g_glue.c
|
usr/src/lib/libgss/g_glue.c
|
||||||
usr/src/lib/libresolv2/common
|
usr/src/lib/libresolv2/common
|
||||||
usr/src/lib/librstp/common/base.h
|
usr/src/lib/librstp/common/base.h
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.h
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.h
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.h
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/GenLinkedList.h
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/PlatformCommon.h
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.h
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/dnssec.h
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.h
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSEmbeddedAPI.h
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSPosix.h
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSUNP.h
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/uDNS.h
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/nsec.h
|
||||||
|
usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.h
|
||||||
usr/src/cmd/krb5/kadmin/cli/kadmin.h
|
usr/src/cmd/krb5/kadmin/cli/kadmin.h
|
||||||
usr/src/cmd/krb5/kadmin/dbutil/import_err.h
|
usr/src/cmd/krb5/kadmin/dbutil/import_err.h
|
||||||
usr/src/cmd/krb5/kadmin/dbutil/kdb5_util.h
|
usr/src/cmd/krb5/kadmin/dbutil/kdb5_util.h
|
||||||
|
@ -135,6 +149,8 @@ usr/src/lib/krb5/ss/mit-sipb-copyright.h
|
||||||
usr/src/lib/krb5/ss/ss_internal.h
|
usr/src/lib/krb5/ss/ss_internal.h
|
||||||
usr/src/lib/krb5/ss/ss.h
|
usr/src/lib/krb5/ss/ss.h
|
||||||
usr/src/lib/libc/port/locale/utils.h
|
usr/src/lib/libc/port/locale/utils.h
|
||||||
|
usr/src/lib/libdns_sd/common/dns_sd.h
|
||||||
|
usr/src/lib/libdns_sd/common/dnssd_ipc.h
|
||||||
usr/src/lib/librstp/common/base.h
|
usr/src/lib/librstp/common/base.h
|
||||||
usr/src/lib/librstp/common/choose.h
|
usr/src/lib/librstp/common/choose.h
|
||||||
usr/src/lib/librstp/common/edge.h
|
usr/src/lib/librstp/common/edge.h
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
#
|
||||||
|
# This file and its contents are supplied under the terms of the
|
||||||
|
# Common Development and Distribution License ("CDDL"), version 1.0.
|
||||||
|
# You may only use this file in accordance with the terms of version
|
||||||
|
# 1.0 of the CDDL.
|
||||||
|
#
|
||||||
|
# A full copy of the text of the CDDL should have accompanied this
|
||||||
|
# source. A copy of the CDDL is also available via the Internet at
|
||||||
|
# http://www.illumos.org/license/CDDL.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2016 Toomas Soome <tsoome@me.com>
|
||||||
|
#
|
||||||
|
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/BaseListener.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/BrowseListener.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSRecord.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSD.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDException.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDRecordRegistrar.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDRegistration.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDService.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/DomainListener.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/QueryListener.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/RegisterListener.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/RegisterRecordListener.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/ResolveListener.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/TXTRecord.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/BrowserApp.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SimpleChat.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingBrowseListener.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingDomainListener.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingQueryListener.java
|
||||||
|
usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingResolveListener.java
|
|
@ -21,9 +21,11 @@
|
||||||
# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||||
# Copyright (c) 2013 by Delphix. All rights reserved.
|
# Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
|
# Copyright 2016 Toomas Soome <tsoome@me.com>
|
||||||
#
|
#
|
||||||
|
|
||||||
syntax: glob
|
syntax: glob
|
||||||
|
usr/src/cmd/cmd-inet/usr.bin/dns-sd/dns-sd.c
|
||||||
usr/src/cmd/localedef/data/zh_CN.UTF-8.src
|
usr/src/cmd/localedef/data/zh_CN.UTF-8.src
|
||||||
usr/src/cmd/localedef/data/zh_HK.UTF-8.src
|
usr/src/cmd/localedef/data/zh_HK.UTF-8.src
|
||||||
usr/src/cmd/localedef/data/zh_MO.UTF-8.src
|
usr/src/cmd/localedef/data/zh_MO.UTF-8.src
|
||||||
|
|
|
@ -23,15 +23,16 @@
|
||||||
# Use is subject to license terms.
|
# Use is subject to license terms.
|
||||||
#
|
#
|
||||||
# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||||
|
# Copyright 2016 Toomas Soome <tsoome@me.com>
|
||||||
#
|
#
|
||||||
|
|
||||||
PROG= dns-sd finger rdate ruptime rwho whois
|
PROG= finger rdate ruptime rwho whois
|
||||||
SUIDPROG= rcp rlogin rsh
|
SUIDPROG= rcp rlogin rsh
|
||||||
ALL= $(PROG) $(SUIDPROG)
|
ALL= $(PROG) $(SUIDPROG)
|
||||||
SRCS= $(ALL:%=%.c)
|
SRCS= $(ALL:%=%.c)
|
||||||
KCMDPROGS= rcp rlogin rsh
|
KCMDPROGS= rcp rlogin rsh
|
||||||
|
|
||||||
SUBDIRS= chat ftp nc nca netstat \
|
SUBDIRS= chat dns-sd ftp nc nca netstat \
|
||||||
pppd pppdump pppstats rdist talk telnet tftp
|
pppd pppdump pppstats rdist talk telnet tftp
|
||||||
SUBDIR1= talk
|
SUBDIR1= talk
|
||||||
MSGSUBDIRS= nca talk
|
MSGSUBDIRS= nca talk
|
||||||
|
@ -78,12 +79,10 @@ CERRWARN += -_gcc=-Wno-unused-function
|
||||||
# PROGS are lint clean.
|
# PROGS are lint clean.
|
||||||
$(LINTCLEAN) := CFLAGS += $(CCVERBOSE)
|
$(LINTCLEAN) := CFLAGS += $(CCVERBOSE)
|
||||||
|
|
||||||
dns-sd := CFLAGS += $(C99_ENABLE)
|
|
||||||
finger := CFLAGS += $(CCVERBOSE)
|
finger := CFLAGS += $(CCVERBOSE)
|
||||||
# Enable large file support for reading the lastlog file.
|
# Enable large file support for reading the lastlog file.
|
||||||
finger := CPPFLAGS += -D_FILE_OFFSET_BITS=64
|
finger := CPPFLAGS += -D_FILE_OFFSET_BITS=64
|
||||||
|
|
||||||
dns-sd := LDLIBS += -lsocket -ldns_sd
|
|
||||||
finger := LDLIBS += -lnsl -lcurses -lsocket
|
finger := LDLIBS += -lnsl -lcurses -lsocket
|
||||||
rcp lint-rcp := LDLIBS += -lsocket -lsec -lsendfile
|
rcp lint-rcp := LDLIBS += -lsocket -lsec -lsendfile
|
||||||
rdate lint-rdate:= LDLIBS += -lsocket
|
rdate lint-rdate:= LDLIBS += -lsocket
|
||||||
|
|
|
@ -1,805 +0,0 @@
|
||||||
/* -*- Mode: C; tab-width: 4 -*-
|
|
||||||
*
|
|
||||||
* Copyright (c) 2002-2006 Apple Computer, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
|
||||||
* ("Apple") in consideration of your agreement to the following terms, and your
|
|
||||||
* use, installation, modification or redistribution of this Apple software
|
|
||||||
* constitutes acceptance of these terms. If you do not agree with these terms,
|
|
||||||
* please do not use, install, modify or redistribute this Apple software.
|
|
||||||
*
|
|
||||||
* In consideration of your agreement to abide by the following terms, and subject
|
|
||||||
* to these terms, Apple grants you a personal, non-exclusive license, under Apple's
|
|
||||||
* copyrights in this original Apple software (the "Apple Software"), to use,
|
|
||||||
* reproduce, modify and redistribute the Apple Software, with or without
|
|
||||||
* modifications, in source and/or binary forms; provided that if you redistribute
|
|
||||||
* the Apple Software in its entirety and without modifications, you must retain
|
|
||||||
* this notice and the following text and disclaimers in all such redistributions of
|
|
||||||
* the Apple Software. Neither the name, trademarks, service marks or logos of
|
|
||||||
* Apple Computer, Inc. may be used to endorse or promote products derived from the
|
|
||||||
* Apple Software without specific prior written permission from Apple. Except as
|
|
||||||
* expressly stated in this notice, no other rights or licenses, express or implied,
|
|
||||||
* are granted by Apple herein, including but not limited to any patent rights that
|
|
||||||
* may be infringed by your derivative works or by other works in which the Apple
|
|
||||||
* Software may be incorporated.
|
|
||||||
*
|
|
||||||
* The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
|
||||||
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
|
||||||
* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
|
||||||
* COMBINATION WITH YOUR PRODUCTS.
|
|
||||||
*
|
|
||||||
* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
|
||||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
|
||||||
* OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
|
||||||
* (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* Formatting notes:
|
|
||||||
* This code follows the "Whitesmiths style" C indentation rules. Plenty of discussion
|
|
||||||
* on C indentation can be found on the web, such as <http://www.kafejo.com/komp/1tbs.htm>,
|
|
||||||
* but for the sake of brevity here I will say just this: Curly braces are not syntactially
|
|
||||||
* part of an "if" statement; they are the beginning and ending markers of a compound statement;
|
|
||||||
* therefore common sense dictates that if they are part of a compound statement then they
|
|
||||||
* should be indented to the same level as everything else in that compound statement.
|
|
||||||
* Indenting curly braces at the same level as the "if" implies that curly braces are
|
|
||||||
* part of the "if", which is false. (This is as misleading as people who write "char* x,y;"
|
|
||||||
* thinking that variables x and y are both of type "char*" -- and anyone who doesn't
|
|
||||||
* understand why variable y is not of type "char*" just proves the point that poor code
|
|
||||||
* layout leads people to unfortunate misunderstandings about how the C language really works.)
|
|
||||||
|
|
||||||
To build this tool, copy and paste the following into a command line:
|
|
||||||
|
|
||||||
OS X:
|
|
||||||
gcc dns-sd.c -o dns-sd
|
|
||||||
|
|
||||||
POSIX systems:
|
|
||||||
gcc dns-sd.c -o dns-sd -I../mDNSShared -ldns_sd
|
|
||||||
|
|
||||||
Windows:
|
|
||||||
cl dns-sd.c -I../mDNSShared -DNOT_HAVE_GETOPT ws2_32.lib ..\mDNSWindows\DLL\Release\dnssd.lib
|
|
||||||
(may require that you run a Visual Studio script such as vsvars32.bat first)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
// For testing changes to dnssd_clientstub.c, uncomment this line and the #include below
|
|
||||||
// #define __APPLE_API_PRIVATE 1
|
|
||||||
|
|
||||||
#include "dns_sd.h"
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdio.h> // For stdout, stderr
|
|
||||||
#include <stdlib.h> // For exit()
|
|
||||||
#include <string.h> // For strlen(), strcpy(), bzero()
|
|
||||||
#include <errno.h> // For errno, EINTR
|
|
||||||
#include <time.h>
|
|
||||||
#include <sys/types.h> // For u_char
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
#include <process.h>
|
|
||||||
typedef int pid_t;
|
|
||||||
#define getpid _getpid
|
|
||||||
#define strcasecmp _stricmp
|
|
||||||
#define snprintf _snprintf
|
|
||||||
static const char kFilePathSep = '\\';
|
|
||||||
#else
|
|
||||||
#include <unistd.h> // For getopt() and optind
|
|
||||||
#include <netdb.h> // For getaddrinfo()
|
|
||||||
#include <sys/time.h> // For struct timeval
|
|
||||||
#include <sys/socket.h> // For AF_INET
|
|
||||||
#include <netinet/in.h> // For struct sockaddr_in()
|
|
||||||
#include <arpa/inet.h> // For inet_addr()
|
|
||||||
static const char kFilePathSep = '/';
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//#include "../mDNSShared/dnssd_clientstub.c"
|
|
||||||
|
|
||||||
//*************************************************************************************************************
|
|
||||||
// Globals
|
|
||||||
|
|
||||||
typedef union { unsigned char b[2]; unsigned short NotAnInteger; } Opaque16;
|
|
||||||
|
|
||||||
static int operation;
|
|
||||||
static uint32_t opinterface = kDNSServiceInterfaceIndexAny;
|
|
||||||
static DNSServiceRef client = NULL;
|
|
||||||
static DNSServiceRef client2 = NULL;
|
|
||||||
static int num_printed;
|
|
||||||
static char addtest = 0;
|
|
||||||
static DNSRecordRef record = NULL;
|
|
||||||
static char myhinfoW[14] = "\002PC\012Windows XP";
|
|
||||||
static char myhinfoX[ 9] = "\003Mac\004OS X";
|
|
||||||
static char updatetest[3] = "\002AA";
|
|
||||||
static char bigNULL[8200];
|
|
||||||
|
|
||||||
// Note: the select() implementation on Windows (Winsock2) fails with any timeout much larger than this
|
|
||||||
#define LONG_TIME 100000000
|
|
||||||
|
|
||||||
static volatile int stopNow = 0;
|
|
||||||
static volatile int timeOut = LONG_TIME;
|
|
||||||
|
|
||||||
//*************************************************************************************************************
|
|
||||||
// Supporting Utility Function
|
|
||||||
|
|
||||||
static uint16_t GetRRType(const char *s)
|
|
||||||
{
|
|
||||||
if (!strcasecmp(s, "A" )) return(kDNSServiceType_A);
|
|
||||||
else if (!strcasecmp(s, "NS" )) return(kDNSServiceType_NS);
|
|
||||||
else if (!strcasecmp(s, "MD" )) return(kDNSServiceType_MD);
|
|
||||||
else if (!strcasecmp(s, "MF" )) return(kDNSServiceType_MF);
|
|
||||||
else if (!strcasecmp(s, "CNAME" )) return(kDNSServiceType_CNAME);
|
|
||||||
else if (!strcasecmp(s, "SOA" )) return(kDNSServiceType_SOA);
|
|
||||||
else if (!strcasecmp(s, "MB" )) return(kDNSServiceType_MB);
|
|
||||||
else if (!strcasecmp(s, "MG" )) return(kDNSServiceType_MG);
|
|
||||||
else if (!strcasecmp(s, "MR" )) return(kDNSServiceType_MR);
|
|
||||||
else if (!strcasecmp(s, "NULL" )) return(kDNSServiceType_NULL);
|
|
||||||
else if (!strcasecmp(s, "WKS" )) return(kDNSServiceType_WKS);
|
|
||||||
else if (!strcasecmp(s, "PTR" )) return(kDNSServiceType_PTR);
|
|
||||||
else if (!strcasecmp(s, "HINFO" )) return(kDNSServiceType_HINFO);
|
|
||||||
else if (!strcasecmp(s, "MINFO" )) return(kDNSServiceType_MINFO);
|
|
||||||
else if (!strcasecmp(s, "MX" )) return(kDNSServiceType_MX);
|
|
||||||
else if (!strcasecmp(s, "TXT" )) return(kDNSServiceType_TXT);
|
|
||||||
else if (!strcasecmp(s, "RP" )) return(kDNSServiceType_RP);
|
|
||||||
else if (!strcasecmp(s, "AFSDB" )) return(kDNSServiceType_AFSDB);
|
|
||||||
else if (!strcasecmp(s, "X25" )) return(kDNSServiceType_X25);
|
|
||||||
else if (!strcasecmp(s, "ISDN" )) return(kDNSServiceType_ISDN);
|
|
||||||
else if (!strcasecmp(s, "RT" )) return(kDNSServiceType_RT);
|
|
||||||
else if (!strcasecmp(s, "NSAP" )) return(kDNSServiceType_NSAP);
|
|
||||||
else if (!strcasecmp(s, "NSAP_PTR")) return(kDNSServiceType_NSAP_PTR);
|
|
||||||
else if (!strcasecmp(s, "SIG" )) return(kDNSServiceType_SIG);
|
|
||||||
else if (!strcasecmp(s, "KEY" )) return(kDNSServiceType_KEY);
|
|
||||||
else if (!strcasecmp(s, "PX" )) return(kDNSServiceType_PX);
|
|
||||||
else if (!strcasecmp(s, "GPOS" )) return(kDNSServiceType_GPOS);
|
|
||||||
else if (!strcasecmp(s, "AAAA" )) return(kDNSServiceType_AAAA);
|
|
||||||
else if (!strcasecmp(s, "LOC" )) return(kDNSServiceType_LOC);
|
|
||||||
else if (!strcasecmp(s, "NXT" )) return(kDNSServiceType_NXT);
|
|
||||||
else if (!strcasecmp(s, "EID" )) return(kDNSServiceType_EID);
|
|
||||||
else if (!strcasecmp(s, "NIMLOC" )) return(kDNSServiceType_NIMLOC);
|
|
||||||
else if (!strcasecmp(s, "SRV" )) return(kDNSServiceType_SRV);
|
|
||||||
else if (!strcasecmp(s, "ATMA" )) return(kDNSServiceType_ATMA);
|
|
||||||
else if (!strcasecmp(s, "NAPTR" )) return(kDNSServiceType_NAPTR);
|
|
||||||
else if (!strcasecmp(s, "KX" )) return(kDNSServiceType_KX);
|
|
||||||
else if (!strcasecmp(s, "CERT" )) return(kDNSServiceType_CERT);
|
|
||||||
else if (!strcasecmp(s, "A6" )) return(kDNSServiceType_A6);
|
|
||||||
else if (!strcasecmp(s, "DNAME" )) return(kDNSServiceType_DNAME);
|
|
||||||
else if (!strcasecmp(s, "SINK" )) return(kDNSServiceType_SINK);
|
|
||||||
else if (!strcasecmp(s, "OPT" )) return(kDNSServiceType_OPT);
|
|
||||||
else if (!strcasecmp(s, "TKEY" )) return(kDNSServiceType_TKEY);
|
|
||||||
else if (!strcasecmp(s, "TSIG" )) return(kDNSServiceType_TSIG);
|
|
||||||
else if (!strcasecmp(s, "IXFR" )) return(kDNSServiceType_IXFR);
|
|
||||||
else if (!strcasecmp(s, "AXFR" )) return(kDNSServiceType_AXFR);
|
|
||||||
else if (!strcasecmp(s, "MAILB" )) return(kDNSServiceType_MAILB);
|
|
||||||
else if (!strcasecmp(s, "MAILA" )) return(kDNSServiceType_MAILA);
|
|
||||||
else if (!strcasecmp(s, "ANY" )) return(kDNSServiceType_ANY);
|
|
||||||
else return(atoi(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
//*************************************************************************************************************
|
|
||||||
// Sample callback functions for each of the operation types
|
|
||||||
|
|
||||||
static void printtimestamp(void)
|
|
||||||
{
|
|
||||||
struct tm tm;
|
|
||||||
int ms;
|
|
||||||
#ifdef _WIN32
|
|
||||||
SYSTEMTIME sysTime;
|
|
||||||
time_t uct = time(NULL);
|
|
||||||
tm = *localtime(&uct);
|
|
||||||
GetLocalTime(&sysTime);
|
|
||||||
ms = sysTime.wMilliseconds;
|
|
||||||
#else
|
|
||||||
struct timeval tv;
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
localtime_r((time_t*)&tv.tv_sec, &tm);
|
|
||||||
ms = tv.tv_usec/1000;
|
|
||||||
#endif
|
|
||||||
printf("%2d:%02d:%02d.%03d ", tm.tm_hour, tm.tm_min, tm.tm_sec, ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DomainMsg(X) (((X) & kDNSServiceFlagsDefault) ? "(Default)" : \
|
|
||||||
((X) & kDNSServiceFlagsAdd) ? "Added" : "Removed")
|
|
||||||
|
|
||||||
static const char *GetNextLabel(const char *cstr, char label[64])
|
|
||||||
{
|
|
||||||
char *ptr = label;
|
|
||||||
while (*cstr && *cstr != '.') // While we have characters in the label...
|
|
||||||
{
|
|
||||||
char c = *cstr++;
|
|
||||||
if (c == '\\')
|
|
||||||
{
|
|
||||||
c = *cstr++;
|
|
||||||
if (isdigit(cstr[-1]) && isdigit(cstr[0]) && isdigit(cstr[1]))
|
|
||||||
{
|
|
||||||
int v0 = cstr[-1] - '0'; // then interpret as three-digit decimal
|
|
||||||
int v1 = cstr[ 0] - '0';
|
|
||||||
int v2 = cstr[ 1] - '0';
|
|
||||||
int val = v0 * 100 + v1 * 10 + v2;
|
|
||||||
if (val <= 255) { c = (char)val; cstr += 2; } // If valid three-digit decimal value, use it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*ptr++ = c;
|
|
||||||
if (ptr >= label+64) return(NULL);
|
|
||||||
}
|
|
||||||
if (*cstr) cstr++; // Skip over the trailing dot (if present)
|
|
||||||
*ptr++ = 0;
|
|
||||||
return(cstr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DNSSD_API enum_reply(DNSServiceRef client, const DNSServiceFlags flags, uint32_t ifIndex,
|
|
||||||
DNSServiceErrorType errorCode, const char *replyDomain, void *context)
|
|
||||||
{
|
|
||||||
DNSServiceFlags partialflags = flags & ~(kDNSServiceFlagsMoreComing | kDNSServiceFlagsAdd | kDNSServiceFlagsDefault);
|
|
||||||
int labels = 0, depth = 0, i, initial = 0;
|
|
||||||
char text[64];
|
|
||||||
const char *label[128];
|
|
||||||
|
|
||||||
(void)client; // Unused
|
|
||||||
(void)ifIndex; // Unused
|
|
||||||
(void)context; // Unused
|
|
||||||
|
|
||||||
// 1. Print the header
|
|
||||||
if (num_printed++ == 0) printf("Timestamp Recommended %s domain\n", operation == 'E' ? "Registration" : "Browsing");
|
|
||||||
printtimestamp();
|
|
||||||
if (errorCode)
|
|
||||||
printf("Error code %d\n", errorCode);
|
|
||||||
else if (!*replyDomain)
|
|
||||||
printf("Error: No reply domain\n");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("%-10s", DomainMsg(flags));
|
|
||||||
printf("%-8s", (flags & kDNSServiceFlagsMoreComing) ? "(More)" : "");
|
|
||||||
if (partialflags) printf("Flags: %4X ", partialflags);
|
|
||||||
else printf(" ");
|
|
||||||
|
|
||||||
// 2. Count the labels
|
|
||||||
while (*replyDomain)
|
|
||||||
{
|
|
||||||
label[labels++] = replyDomain;
|
|
||||||
replyDomain = GetNextLabel(replyDomain, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Decide if we're going to clump the last two or three labels (e.g. "apple.com", or "nicta.com.au")
|
|
||||||
if (labels >= 3 && replyDomain - label[labels-1] <= 3 && label[labels-1] - label[labels-2] <= 4) initial = 3;
|
|
||||||
else if (labels >= 2 && replyDomain - label[labels-1] <= 4) initial = 2;
|
|
||||||
else initial = 1;
|
|
||||||
labels -= initial;
|
|
||||||
|
|
||||||
// 4. Print the initial one-, two- or three-label clump
|
|
||||||
for (i=0; i<initial; i++)
|
|
||||||
{
|
|
||||||
GetNextLabel(label[labels+i], text);
|
|
||||||
if (i>0) printf(".");
|
|
||||||
printf("%s", text);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
// 5. Print the remainder of the hierarchy
|
|
||||||
for (depth=0; depth<labels; depth++)
|
|
||||||
{
|
|
||||||
printf(" ");
|
|
||||||
for (i=0; i<=depth; i++) printf("- ");
|
|
||||||
GetNextLabel(label[labels-1-depth], text);
|
|
||||||
printf("> %s\n", text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DNSSD_API browse_reply(DNSServiceRef client, const DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode,
|
|
||||||
const char *replyName, const char *replyType, const char *replyDomain, void *context)
|
|
||||||
{
|
|
||||||
char *op = (flags & kDNSServiceFlagsAdd) ? "Add" : "Rmv";
|
|
||||||
(void)client; // Unused
|
|
||||||
(void)context; // Unused
|
|
||||||
if (num_printed++ == 0) printf("Timestamp A/R Flags if %-25s %-25s %s\n", "Domain", "Service Type", "Instance Name");
|
|
||||||
printtimestamp();
|
|
||||||
if (errorCode) printf("Error code %d\n", errorCode);
|
|
||||||
else printf("%s%6X%3d %-25s %-25s %s\n", op, flags, ifIndex, replyDomain, replyType, replyName);
|
|
||||||
if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ShowTXTRecord(uint16_t txtLen, const unsigned char *txtRecord)
|
|
||||||
{
|
|
||||||
const unsigned char *ptr = txtRecord;
|
|
||||||
const unsigned char *max = txtRecord + txtLen;
|
|
||||||
while (ptr < max)
|
|
||||||
{
|
|
||||||
const unsigned char *const end = ptr + 1 + ptr[0];
|
|
||||||
if (end > max) { printf("<< invalid data >>"); break; }
|
|
||||||
if (++ptr < end) printf(" "); // As long as string is non-empty, begin with a space
|
|
||||||
while (ptr<end)
|
|
||||||
{
|
|
||||||
// We'd like the output to be shell-friendly, so that it can be copied and pasted unchanged into a "dns-sd -R" command.
|
|
||||||
// However, this is trickier than it seems. Enclosing a string in double quotes doesn't necessarily make it
|
|
||||||
// shell-safe, because shells still expand variables like $foo even when they appear inside quoted strings.
|
|
||||||
// Enclosing a string in single quotes is better, but when using single quotes even backslash escapes are ignored,
|
|
||||||
// meaning there's simply no way to represent a single quote (or apostrophe) inside a single-quoted string.
|
|
||||||
// The only remaining solution is not to surround the string with quotes at all, but instead to use backslash
|
|
||||||
// escapes to encode spaces and all other known shell metacharacters.
|
|
||||||
// (If we've missed any known shell metacharacters, please let us know.)
|
|
||||||
// In addition, non-printing ascii codes (0-31) are displayed as \xHH, using a two-digit hex value.
|
|
||||||
// Because '\' is itself a shell metacharacter (the shell escape character), it has to be escaped as "\\" to survive
|
|
||||||
// the round-trip to the shell and back. This means that a single '\' is represented here as EIGHT backslashes:
|
|
||||||
// The C compiler eats half of them, resulting in four appearing in the output.
|
|
||||||
// The shell parses those four as a pair of "\\" sequences, passing two backslashes to the "dns-sd -R" command.
|
|
||||||
// The "dns-sd -R" command interprets this single "\\" pair as an escaped literal backslash. Sigh.
|
|
||||||
if (strchr(" &;`'\"|*?~<>^()[]{}$", *ptr)) printf("\\");
|
|
||||||
if (*ptr == '\\') printf("\\\\\\\\");
|
|
||||||
else if (*ptr >= ' ' ) printf("%c", *ptr);
|
|
||||||
else printf("\\\\x%02X", *ptr);
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DNSSD_API resolve_reply(DNSServiceRef client, const DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode,
|
|
||||||
const char *fullname, const char *hosttarget, uint16_t opaqueport, uint16_t txtLen, const unsigned char *txtRecord, void *context)
|
|
||||||
{
|
|
||||||
union { uint16_t s; u_char b[2]; } port = { opaqueport };
|
|
||||||
uint16_t PortAsNumber = ((uint16_t)port.b[0]) << 8 | port.b[1];
|
|
||||||
|
|
||||||
(void)client; // Unused
|
|
||||||
(void)ifIndex; // Unused
|
|
||||||
(void)context; // Unused
|
|
||||||
|
|
||||||
printtimestamp();
|
|
||||||
if (errorCode) printf("Error code %d\n", errorCode);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("%s can be reached at %s:%u", fullname, hosttarget, PortAsNumber);
|
|
||||||
if (flags) printf(" Flags: %X", flags);
|
|
||||||
// Don't show degenerate TXT records containing nothing but a single empty string
|
|
||||||
if (txtLen > 1) { printf("\n"); ShowTXTRecord(txtLen, txtRecord); }
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void myTimerCallBack(void)
|
|
||||||
{
|
|
||||||
DNSServiceErrorType err = kDNSServiceErr_Unknown;
|
|
||||||
|
|
||||||
switch (operation)
|
|
||||||
{
|
|
||||||
case 'A':
|
|
||||||
{
|
|
||||||
switch (addtest)
|
|
||||||
{
|
|
||||||
case 0: printf("Adding Test HINFO record\n");
|
|
||||||
err = DNSServiceAddRecord(client, &record, 0, kDNSServiceType_HINFO, sizeof(myhinfoW), &myhinfoW[0], 0);
|
|
||||||
addtest = 1;
|
|
||||||
break;
|
|
||||||
case 1: printf("Updating Test HINFO record\n");
|
|
||||||
err = DNSServiceUpdateRecord(client, record, 0, sizeof(myhinfoX), &myhinfoX[0], 0);
|
|
||||||
addtest = 2;
|
|
||||||
break;
|
|
||||||
case 2: printf("Removing Test HINFO record\n");
|
|
||||||
err = DNSServiceRemoveRecord(client, record, 0);
|
|
||||||
addtest = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'U':
|
|
||||||
{
|
|
||||||
if (updatetest[1] != 'Z') updatetest[1]++;
|
|
||||||
else updatetest[1] = 'A';
|
|
||||||
updatetest[0] = 3 - updatetest[0];
|
|
||||||
updatetest[2] = updatetest[1];
|
|
||||||
printf("Updating Test TXT record to %c\n", updatetest[1]);
|
|
||||||
err = DNSServiceUpdateRecord(client, NULL, 0, 1+updatetest[0], &updatetest[0], 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'N':
|
|
||||||
{
|
|
||||||
printf("Adding big NULL record\n");
|
|
||||||
err = DNSServiceAddRecord(client, &record, 0, kDNSServiceType_NULL, sizeof(bigNULL), &bigNULL[0], 0);
|
|
||||||
timeOut = LONG_TIME;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err != kDNSServiceErr_NoError)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "DNSService call failed %ld\n", (long int)err);
|
|
||||||
stopNow = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DNSSD_API reg_reply(DNSServiceRef client, const DNSServiceFlags flags, DNSServiceErrorType errorCode,
|
|
||||||
const char *name, const char *regtype, const char *domain, void *context)
|
|
||||||
{
|
|
||||||
(void)client; // Unused
|
|
||||||
(void)flags; // Unused
|
|
||||||
(void)context; // Unused
|
|
||||||
|
|
||||||
printf("Got a reply for %s.%s%s: ", name, regtype, domain);
|
|
||||||
|
|
||||||
if (errorCode == kDNSServiceErr_NoError)
|
|
||||||
{
|
|
||||||
printf("Name now registered and active\n");
|
|
||||||
if (operation == 'A' || operation == 'U' || operation == 'N') timeOut = 5;
|
|
||||||
}
|
|
||||||
else if (errorCode == kDNSServiceErr_NameConflict)
|
|
||||||
{
|
|
||||||
printf("Name in use, please choose another\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf("Error %d\n", errorCode);
|
|
||||||
|
|
||||||
if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DNSSD_API qr_reply(DNSServiceRef sdRef, const DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode,
|
|
||||||
const char *fullname, uint16_t rrtype, uint16_t rrclass, uint16_t rdlen, const void *rdata, uint32_t ttl, void *context)
|
|
||||||
{
|
|
||||||
char *op = (flags & kDNSServiceFlagsAdd) ? "Add" : "Rmv";
|
|
||||||
const unsigned char *rd = rdata;
|
|
||||||
const unsigned char *end = (const unsigned char *) rdata + rdlen;
|
|
||||||
char rdb[1000];
|
|
||||||
int unknowntype = 0;
|
|
||||||
|
|
||||||
(void)sdRef; // Unused
|
|
||||||
(void)flags; // Unused
|
|
||||||
(void)ifIndex; // Unused
|
|
||||||
(void)ttl; // Unused
|
|
||||||
(void)context; // Unused
|
|
||||||
|
|
||||||
if (num_printed++ == 0) printf("Timestamp A/R Flags if %-30s%4s%4s Rdata\n", "Name", "T", "C");
|
|
||||||
printtimestamp();
|
|
||||||
if (errorCode)
|
|
||||||
printf("Error code %d\n", errorCode);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (rrtype)
|
|
||||||
{
|
|
||||||
case kDNSServiceType_A: sprintf(rdb, "%d.%d.%d.%d", rd[0], rd[1], rd[2], rd[3]); break;
|
|
||||||
case kDNSServiceType_AAAA: sprintf(rdb, "%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X",
|
|
||||||
rd[0x0], rd[0x1], rd[0x2], rd[0x3], rd[0x4], rd[0x5], rd[0x6], rd[0x7],
|
|
||||||
rd[0x8], rd[0x9], rd[0xA], rd[0xB], rd[0xC], rd[0xD], rd[0xE], rd[0xF]); break;
|
|
||||||
break;
|
|
||||||
default : sprintf(rdb, "%d bytes%s", rdlen, rdlen ? ":" : ""); unknowntype = 1; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s%6X%3d %-30s%4d%4d %s", op, flags, ifIndex, fullname, rrtype, rrclass, rdb);
|
|
||||||
if (unknowntype) while (rd < end) printf(" %02X", *rd++);
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
if (operation == 'C')
|
|
||||||
if (flags & kDNSServiceFlagsAdd)
|
|
||||||
DNSServiceReconfirmRecord(flags, ifIndex, fullname, rrtype, rrclass, rdlen, rdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
//*************************************************************************************************************
|
|
||||||
// The main test function
|
|
||||||
|
|
||||||
static void HandleEvents(void)
|
|
||||||
{
|
|
||||||
int dns_sd_fd = client ? DNSServiceRefSockFD(client ) : -1;
|
|
||||||
int dns_sd_fd2 = client2 ? DNSServiceRefSockFD(client2) : -1;
|
|
||||||
int nfds = dns_sd_fd + 1;
|
|
||||||
fd_set readfds;
|
|
||||||
struct timeval tv;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (dns_sd_fd2 > dns_sd_fd) nfds = dns_sd_fd2 + 1;
|
|
||||||
|
|
||||||
while (!stopNow)
|
|
||||||
{
|
|
||||||
// 1. Set up the fd_set as usual here.
|
|
||||||
// This example client has no file descriptors of its own,
|
|
||||||
// but a real application would call FD_SET to add them to the set here
|
|
||||||
FD_ZERO(&readfds);
|
|
||||||
|
|
||||||
// 2. Add the fd for our client(s) to the fd_set
|
|
||||||
if (client ) FD_SET(dns_sd_fd , &readfds);
|
|
||||||
if (client2) FD_SET(dns_sd_fd2, &readfds);
|
|
||||||
|
|
||||||
// 3. Set up the timeout.
|
|
||||||
tv.tv_sec = timeOut;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
|
|
||||||
result = select(nfds, &readfds, (fd_set*)NULL, (fd_set*)NULL, &tv);
|
|
||||||
if (result > 0)
|
|
||||||
{
|
|
||||||
DNSServiceErrorType err = kDNSServiceErr_NoError;
|
|
||||||
if (client && FD_ISSET(dns_sd_fd , &readfds)) err = DNSServiceProcessResult(client );
|
|
||||||
else if (client2 && FD_ISSET(dns_sd_fd2, &readfds)) err = DNSServiceProcessResult(client2);
|
|
||||||
if (err) { fprintf(stderr, "DNSServiceProcessResult returned %d\n", err); stopNow = 1; }
|
|
||||||
}
|
|
||||||
else if (result == 0)
|
|
||||||
myTimerCallBack();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("select() returned %d errno %d %s\n", result, errno, strerror(errno));
|
|
||||||
if (errno != EINTR) stopNow = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getfirstoption( int argc, char **argv, const char *optstr, int *pOptInd)
|
|
||||||
// Return the recognized option in optstr and the option index of the next arg.
|
|
||||||
#if NOT_HAVE_GETOPT
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for ( i=1; i < argc; i++)
|
|
||||||
{
|
|
||||||
if ( argv[i][0] == '-' && &argv[i][1] &&
|
|
||||||
NULL != strchr( optstr, argv[i][1]))
|
|
||||||
{
|
|
||||||
*pOptInd = i + 1;
|
|
||||||
return argv[i][1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
int operation = getopt(argc, (char * const *)argv, optstr);
|
|
||||||
*pOptInd = optind;
|
|
||||||
return operation;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void DNSSD_API MyRegisterRecordCallback(DNSServiceRef service, DNSRecordRef record, const DNSServiceFlags flags,
|
|
||||||
DNSServiceErrorType errorCode, void * context)
|
|
||||||
{
|
|
||||||
char *name = (char *)context;
|
|
||||||
|
|
||||||
(void)service; // Unused
|
|
||||||
(void)record; // Unused
|
|
||||||
(void)flags; // Unused
|
|
||||||
|
|
||||||
printf("Got a reply for %s: ", name);
|
|
||||||
switch (errorCode)
|
|
||||||
{
|
|
||||||
case kDNSServiceErr_NoError: printf("Name now registered and active\n"); break;
|
|
||||||
case kDNSServiceErr_NameConflict: printf("Name in use, please choose another\n"); exit(-1);
|
|
||||||
default: printf("Error %d\n", errorCode); break;
|
|
||||||
}
|
|
||||||
if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned long getip(const char *const name)
|
|
||||||
{
|
|
||||||
unsigned long ip = 0;
|
|
||||||
struct addrinfo hints;
|
|
||||||
struct addrinfo * addrs = NULL;
|
|
||||||
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
|
||||||
hints.ai_family = AF_INET;
|
|
||||||
|
|
||||||
if (getaddrinfo(name, NULL, &hints, &addrs) == 0)
|
|
||||||
{
|
|
||||||
ip = ((struct sockaddr_in*) addrs->ai_addr)->sin_addr.s_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addrs)
|
|
||||||
{
|
|
||||||
freeaddrinfo(addrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
static DNSServiceErrorType RegisterProxyAddressRecord(DNSServiceRef *sdRef, const char *host, const char *ip)
|
|
||||||
{
|
|
||||||
// Call getip() after the call DNSServiceCreateConnection().
|
|
||||||
// On the Win32 platform, WinSock must be initialized for getip() to succeed.
|
|
||||||
// Any DNSService* call will initialize WinSock for us, so we make sure
|
|
||||||
// DNSServiceCreateConnection() is called before getip() is.
|
|
||||||
unsigned long addr = 0;
|
|
||||||
DNSServiceErrorType err = DNSServiceCreateConnection(sdRef);
|
|
||||||
if (err) { fprintf(stderr, "DNSServiceCreateConnection returned %d\n", err); return(err); }
|
|
||||||
addr = getip(ip);
|
|
||||||
return(DNSServiceRegisterRecord(*sdRef, &record, kDNSServiceFlagsUnique, kDNSServiceInterfaceIndexAny, host,
|
|
||||||
kDNSServiceType_A, kDNSServiceClass_IN, sizeof(addr), &addr, 240, MyRegisterRecordCallback, (void*)host));
|
|
||||||
// Note, should probably add support for creating proxy AAAA records too, one day
|
|
||||||
}
|
|
||||||
|
|
||||||
#define HexVal(X) ( ((X) >= '0' && (X) <= '9') ? ((X) - '0' ) : \
|
|
||||||
((X) >= 'A' && (X) <= 'F') ? ((X) - 'A' + 10) : \
|
|
||||||
((X) >= 'a' && (X) <= 'f') ? ((X) - 'a' + 10) : 0)
|
|
||||||
|
|
||||||
#define HexPair(P) ((HexVal((P)[0]) << 4) | HexVal((P)[1]))
|
|
||||||
|
|
||||||
static DNSServiceErrorType RegisterService(DNSServiceRef *sdRef,
|
|
||||||
const char *nam, const char *typ, const char *dom, const char *host, const char *port, int argc, char **argv)
|
|
||||||
{
|
|
||||||
uint16_t PortAsNumber = atoi(port);
|
|
||||||
Opaque16 registerPort = { { PortAsNumber >> 8, PortAsNumber & 0xFF } };
|
|
||||||
unsigned char txt[2048] = "";
|
|
||||||
unsigned char *ptr = txt;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (nam[0] == '.' && nam[1] == 0) nam = ""; // We allow '.' on the command line as a synonym for empty string
|
|
||||||
if (dom[0] == '.' && dom[1] == 0) dom = ""; // We allow '.' on the command line as a synonym for empty string
|
|
||||||
|
|
||||||
printf("Registering Service %s.%s%s%s", nam[0] ? nam : "<<Default>>", typ, dom[0] ? "." : "", dom);
|
|
||||||
if (host && *host) printf(" host %s", host);
|
|
||||||
printf(" port %s\n", port);
|
|
||||||
|
|
||||||
if (argc)
|
|
||||||
{
|
|
||||||
for (i = 0; i < argc; i++)
|
|
||||||
{
|
|
||||||
const char *p = argv[i];
|
|
||||||
*ptr = 0;
|
|
||||||
while (*p && *ptr < 255 && ptr + 1 + *ptr < txt+sizeof(txt))
|
|
||||||
{
|
|
||||||
if (p[0] != '\\' || p[1] == 0) { ptr[++*ptr] = *p; p+=1; }
|
|
||||||
else if (p[1] == 'x' && isxdigit(p[2]) && isxdigit(p[3])) { ptr[++*ptr] = HexPair(p+2); p+=4; }
|
|
||||||
else { ptr[++*ptr] = p[1]; p+=2; }
|
|
||||||
}
|
|
||||||
ptr += 1 + *ptr;
|
|
||||||
}
|
|
||||||
ShowTXTRecord(ptr-txt, txt);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return(DNSServiceRegister(sdRef, /* kDNSServiceFlagsAllowRemoteQuery */ 0, opinterface, nam, typ, dom, host, registerPort.NotAnInteger, (uint16_t) (ptr-txt), txt, reg_reply, NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
DNSServiceErrorType err;
|
|
||||||
char *dom;
|
|
||||||
int optind;
|
|
||||||
|
|
||||||
// Extract the program name from argv[0], which by convention contains the path to this executable.
|
|
||||||
// Note that this is just a voluntary convention, not enforced by the kernel --
|
|
||||||
// the process calling exec() can pass bogus data in argv[0] if it chooses to.
|
|
||||||
const char *a0 = strrchr(argv[0], kFilePathSep) + 1;
|
|
||||||
if (a0 == (const char *)1) a0 = argv[0];
|
|
||||||
|
|
||||||
if (argc > 1 && !strcmp(argv[1], "-lo"))
|
|
||||||
{
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
opinterface = kDNSServiceInterfaceIndexLocalOnly;
|
|
||||||
printf("Using LocalOnly\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc > 2 && !strcmp(argv[1], "-i") && atoi(argv[2]))
|
|
||||||
{
|
|
||||||
opinterface = atoi(argv[2]);
|
|
||||||
argc -= 2;
|
|
||||||
argv += 2;
|
|
||||||
printf("Using interface %d\n", opinterface);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc < 2) goto Fail; // Minimum command line is the command name and one argument
|
|
||||||
operation = getfirstoption( argc, argv, "EFBLRPQCAUNTMI", &optind);
|
|
||||||
if (operation == -1) goto Fail;
|
|
||||||
|
|
||||||
switch (operation)
|
|
||||||
{
|
|
||||||
case 'E': printf("Looking for recommended registration domains:\n");
|
|
||||||
err = DNSServiceEnumerateDomains(&client, kDNSServiceFlagsRegistrationDomains, opinterface, enum_reply, NULL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'F': printf("Looking for recommended browsing domains:\n");
|
|
||||||
err = DNSServiceEnumerateDomains(&client, kDNSServiceFlagsBrowseDomains, opinterface, enum_reply, NULL);
|
|
||||||
//enum_reply(client, kDNSServiceFlagsAdd, 0, 0, "nicta.com.au.", NULL);
|
|
||||||
//enum_reply(client, kDNSServiceFlagsAdd, 0, 0, "bonjour.nicta.com.au.", NULL);
|
|
||||||
//enum_reply(client, kDNSServiceFlagsAdd, 0, 0, "ibm.com.", NULL);
|
|
||||||
//enum_reply(client, kDNSServiceFlagsAdd, 0, 0, "dns-sd.ibm.com.", NULL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'B': if (argc < optind+1) goto Fail;
|
|
||||||
dom = (argc < optind+2) ? "" : argv[optind+1];
|
|
||||||
if (dom[0] == '.' && dom[1] == 0) dom[0] = 0; // We allow '.' on the command line as a synonym for empty string
|
|
||||||
printf("Browsing for %s%s%s\n", argv[optind+0], dom[0] ? "." : "", dom);
|
|
||||||
err = DNSServiceBrowse(&client, 0, opinterface, argv[optind+0], dom, browse_reply, NULL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'L': if (argc < optind+2) goto Fail;
|
|
||||||
dom = (argc < optind+3) ? "local" : argv[optind+2];
|
|
||||||
if (dom[0] == '.' && dom[1] == 0) dom = "local"; // We allow '.' on the command line as a synonym for "local"
|
|
||||||
printf("Lookup %s.%s.%s\n", argv[optind+0], argv[optind+1], dom);
|
|
||||||
err = DNSServiceResolve(&client, 0, opinterface, argv[optind+0], argv[optind+1], dom, (DNSServiceResolveReply)resolve_reply, NULL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'R': if (argc < optind+4) goto Fail;
|
|
||||||
err = RegisterService(&client, argv[optind+0], argv[optind+1], argv[optind+2], NULL, argv[optind+3], argc-(optind+4), argv+(optind+4));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'P': if (argc < optind+6) goto Fail;
|
|
||||||
err = RegisterProxyAddressRecord(&client2, argv[optind+4], argv[optind+5]);
|
|
||||||
if (err) break;
|
|
||||||
err = RegisterService(&client, argv[optind+0], argv[optind+1], argv[optind+2], argv[optind+4], argv[optind+3], argc-(optind+6), argv+(optind+6));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'Q':
|
|
||||||
case 'C': {
|
|
||||||
uint16_t rrtype, rrclass;
|
|
||||||
DNSServiceFlags flags = kDNSServiceFlagsReturnCNAME;
|
|
||||||
if (argc < optind+1) goto Fail;
|
|
||||||
rrtype = (argc <= optind+1) ? kDNSServiceType_A : GetRRType(argv[optind+1]);
|
|
||||||
rrclass = (argc <= optind+2) ? kDNSServiceClass_IN : atoi(argv[optind+2]);
|
|
||||||
if (rrtype == kDNSServiceType_TXT || rrtype == kDNSServiceType_PTR) flags |= kDNSServiceFlagsLongLivedQuery;
|
|
||||||
err = DNSServiceQueryRecord(&client, flags, opinterface, argv[optind+0], rrtype, rrclass, qr_reply, NULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'A':
|
|
||||||
case 'U':
|
|
||||||
case 'N': {
|
|
||||||
Opaque16 registerPort = { { 0x12, 0x34 } };
|
|
||||||
static const char TXT[] = "\xC" "First String" "\xD" "Second String" "\xC" "Third String";
|
|
||||||
printf("Registering Service Test._testupdate._tcp.local.\n");
|
|
||||||
err = DNSServiceRegister(&client, 0, opinterface, "Test", "_testupdate._tcp.", "", NULL, registerPort.NotAnInteger, sizeof(TXT)-1, TXT, reg_reply, NULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'T': {
|
|
||||||
Opaque16 registerPort = { { 0x23, 0x45 } };
|
|
||||||
char TXT[1024];
|
|
||||||
unsigned int i;
|
|
||||||
for (i=0; i<sizeof(TXT); i++)
|
|
||||||
if ((i & 0x1F) == 0) TXT[i] = 0x1F; else TXT[i] = 'A' + (i >> 5);
|
|
||||||
printf("Registering Service Test._testlargetxt._tcp.local.\n");
|
|
||||||
err = DNSServiceRegister(&client, 0, opinterface, "Test", "_testlargetxt._tcp.", "", NULL, registerPort.NotAnInteger, sizeof(TXT), TXT, reg_reply, NULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'M': {
|
|
||||||
pid_t pid = getpid();
|
|
||||||
Opaque16 registerPort = { { pid >> 8, pid & 0xFF } };
|
|
||||||
static const char TXT1[] = "\xC" "First String" "\xD" "Second String" "\xC" "Third String";
|
|
||||||
static const char TXT2[] = "\xD" "Fourth String" "\xC" "Fifth String" "\xC" "Sixth String";
|
|
||||||
printf("Registering Service Test._testdualtxt._tcp.local.\n");
|
|
||||||
err = DNSServiceRegister(&client, 0, opinterface, "Test", "_testdualtxt._tcp.", "", NULL, registerPort.NotAnInteger, sizeof(TXT1)-1, TXT1, reg_reply, NULL);
|
|
||||||
if (!err) err = DNSServiceAddRecord(client, &record, 0, kDNSServiceType_TXT, sizeof(TXT2)-1, TXT2, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'I': {
|
|
||||||
pid_t pid = getpid();
|
|
||||||
Opaque16 registerPort = { { pid >> 8, pid & 0xFF } };
|
|
||||||
static const char TXT[] = "\x09" "Test Data";
|
|
||||||
printf("Registering Service Test._testtxt._tcp.local.\n");
|
|
||||||
err = DNSServiceRegister(&client, 0, opinterface, "Test", "_testtxt._tcp.", "", NULL, registerPort.NotAnInteger, 0, NULL, reg_reply, NULL);
|
|
||||||
if (!err) err = DNSServiceUpdateRecord(client, NULL, 0, sizeof(TXT)-1, TXT, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: goto Fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!client || err != kDNSServiceErr_NoError) { fprintf(stderr, "DNSService call failed %ld\n", (long int)err); return (-1); }
|
|
||||||
HandleEvents();
|
|
||||||
|
|
||||||
// Be sure to deallocate the DNSServiceRef when you're finished
|
|
||||||
if (client ) DNSServiceRefDeallocate(client );
|
|
||||||
if (client2) DNSServiceRefDeallocate(client2);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
Fail:
|
|
||||||
fprintf(stderr, "%s -E (Enumerate recommended registration domains)\n", a0);
|
|
||||||
fprintf(stderr, "%s -F (Enumerate recommended browsing domains)\n", a0);
|
|
||||||
fprintf(stderr, "%s -B <Type> <Domain> (Browse for services instances)\n", a0);
|
|
||||||
fprintf(stderr, "%s -L <Name> <Type> <Domain> (Look up a service instance)\n", a0);
|
|
||||||
fprintf(stderr, "%s -R <Name> <Type> <Domain> <Port> [<TXT>...] (Register a service)\n", a0);
|
|
||||||
fprintf(stderr, "%s -P <Name> <Type> <Domain> <Port> <Host> <IP> [<TXT>...] (Proxy)\n", a0);
|
|
||||||
fprintf(stderr, "%s -Q <FQDN> <rrtype> <rrclass> (Generic query for any record type)\n", a0);
|
|
||||||
fprintf(stderr, "%s -C <FQDN> <rrtype> <rrclass> (Query; reconfirming each result)\n", a0);
|
|
||||||
fprintf(stderr, "%s -A (Test Adding/Updating/Deleting a record)\n", a0);
|
|
||||||
fprintf(stderr, "%s -U (Test updating a TXT record)\n", a0);
|
|
||||||
fprintf(stderr, "%s -N (Test adding a large NULL record)\n", a0);
|
|
||||||
fprintf(stderr, "%s -T (Test creating a large TXT record)\n", a0);
|
|
||||||
fprintf(stderr, "%s -M (Test creating a registration with multiple TXT records)\n", a0);
|
|
||||||
fprintf(stderr, "%s -I (Test registering and then immediately updating TXT record)\n", a0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008 Apple Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||||
|
* ("Apple") in consideration of your agreement to the following terms, and your
|
||||||
|
* use, installation, modification or redistribution of this Apple software
|
||||||
|
* constitutes acceptance of these terms. If you do not agree with these terms,
|
||||||
|
* please do not use, install, modify or redistribute this Apple software.
|
||||||
|
*
|
||||||
|
* In consideration of your agreement to abide by the following terms, and subject
|
||||||
|
* to these terms, Apple grants you a personal, non-exclusive license, under Apple's
|
||||||
|
* copyrights in this original Apple software (the "Apple Software"), to use,
|
||||||
|
* reproduce, modify and redistribute the Apple Software, with or without
|
||||||
|
* modifications, in source and/or binary forms; provided that if you redistribute
|
||||||
|
* the Apple Software in its entirety and without modifications, you must retain
|
||||||
|
* this notice and the following text and disclaimers in all such redistributions of
|
||||||
|
* the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||||
|
* Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||||
|
* Apple Software without specific prior written permission from Apple. Except as
|
||||||
|
* expressly stated in this notice, no other rights or licenses, express or implied,
|
||||||
|
* are granted by Apple herein, including but not limited to any patent rights that
|
||||||
|
* may be infringed by your derivative works or by other works in which the Apple
|
||||||
|
* Software may be incorporated.
|
||||||
|
*
|
||||||
|
* The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||||
|
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||||
|
* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||||
|
* COMBINATION WITH YOUR PRODUCTS.
|
||||||
|
*
|
||||||
|
* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||||
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||||
|
* OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||||
|
* (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h> // For stdout, stderr
|
||||||
|
|
||||||
|
#include "ClientCommon.h"
|
||||||
|
|
||||||
|
const char *GetNextLabel(const char *cstr, char label[64])
|
||||||
|
{
|
||||||
|
char *ptr = label;
|
||||||
|
while (*cstr && *cstr != '.') // While we have characters in the label...
|
||||||
|
{
|
||||||
|
char c = *cstr++;
|
||||||
|
if (c == '\\' && *cstr) // If we have a backslash, and it's not the last character of the string
|
||||||
|
{
|
||||||
|
c = *cstr++;
|
||||||
|
if (isdigit(cstr[-1]) && isdigit(cstr[0]) && isdigit(cstr[1]))
|
||||||
|
{
|
||||||
|
int v0 = cstr[-1] - '0'; // then interpret as three-digit decimal
|
||||||
|
int v1 = cstr[ 0] - '0';
|
||||||
|
int v2 = cstr[ 1] - '0';
|
||||||
|
int val = v0 * 100 + v1 * 10 + v2;
|
||||||
|
// If valid three-digit decimal value, use it
|
||||||
|
// Note that although ascii nuls are possible in DNS labels
|
||||||
|
// we're building a C string here so we have no way to represent that
|
||||||
|
if (val == 0) val = '-';
|
||||||
|
if (val <= 255) { c = (char)val; cstr += 2; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*ptr++ = c;
|
||||||
|
if (ptr >= label+64) { label[63] = 0; return(NULL); } // Illegal label more than 63 bytes
|
||||||
|
}
|
||||||
|
*ptr = 0; // Null-terminate label text
|
||||||
|
if (ptr == label) return(NULL); // Illegal empty label
|
||||||
|
if (*cstr) cstr++; // Skip over the trailing dot (if present)
|
||||||
|
return(cstr);
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008 Apple Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||||
|
* ("Apple") in consideration of your agreement to the following terms, and your
|
||||||
|
* use, installation, modification or redistribution of this Apple software
|
||||||
|
* constitutes acceptance of these terms. If you do not agree with these terms,
|
||||||
|
* please do not use, install, modify or redistribute this Apple software.
|
||||||
|
*
|
||||||
|
* In consideration of your agreement to abide by the following terms, and subject
|
||||||
|
* to these terms, Apple grants you a personal, non-exclusive license, under Apple's
|
||||||
|
* copyrights in this original Apple software (the "Apple Software"), to use,
|
||||||
|
* reproduce, modify and redistribute the Apple Software, with or without
|
||||||
|
* modifications, in source and/or binary forms; provided that if you redistribute
|
||||||
|
* the Apple Software in its entirety and without modifications, you must retain
|
||||||
|
* this notice and the following text and disclaimers in all such redistributions of
|
||||||
|
* the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||||
|
* Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||||
|
* Apple Software without specific prior written permission from Apple. Except as
|
||||||
|
* expressly stated in this notice, no other rights or licenses, express or implied,
|
||||||
|
* are granted by Apple herein, including but not limited to any patent rights that
|
||||||
|
* may be infringed by your derivative works or by other works in which the Apple
|
||||||
|
* Software may be incorporated.
|
||||||
|
*
|
||||||
|
* The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||||
|
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||||
|
* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||||
|
* COMBINATION WITH YOUR PRODUCTS.
|
||||||
|
*
|
||||||
|
* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||||
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||||
|
* OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||||
|
* (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern const char *GetNextLabel(const char *cstr, char label[64]);
|
|
@ -0,0 +1,47 @@
|
||||||
|
#
|
||||||
|
# This file and its contents are supplied under the terms of the
|
||||||
|
# Common Development and Distribution License ("CDDL"), version 1.0.
|
||||||
|
# You may only use this file in accordance with the terms of version
|
||||||
|
# 1.0 of the CDDL.
|
||||||
|
#
|
||||||
|
# A full copy of the text of the CDDL should have accompanied this
|
||||||
|
# source. A copy of the CDDL is also available via the Internet at
|
||||||
|
# http://www.illumos.org/license/CDDL.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2016 Toomas Soome <tsoome@me.com>
|
||||||
|
#
|
||||||
|
|
||||||
|
# cmd/cmd-inet/usr.bin/dns-sd/Makefile
|
||||||
|
|
||||||
|
PROG= dns-sd
|
||||||
|
|
||||||
|
include ../../../Makefile.cmd
|
||||||
|
include ../../Makefile.cmd-inet
|
||||||
|
|
||||||
|
OBJS= ClientCommon.o dns-sd.o
|
||||||
|
SRCS= ClientCommon.c dns-sd.c
|
||||||
|
|
||||||
|
CFLAGS += $(C99_ENABLE)
|
||||||
|
LDLIBS += -lsocket -ldns_sd
|
||||||
|
|
||||||
|
.KEEP_STATE:
|
||||||
|
|
||||||
|
all: $(PROG)
|
||||||
|
|
||||||
|
ROOTPROG= $(PROG:%=$(ROOTBIN)/%)
|
||||||
|
|
||||||
|
$(PROG): $(OBJS)
|
||||||
|
$(LINK.c) $(OBJS) -o $@ $(LDLIBS)
|
||||||
|
$(POST_PROCESS)
|
||||||
|
|
||||||
|
install: all $(ROOTPROG)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(OBJS)
|
||||||
|
|
||||||
|
lint: lint_SRCS
|
||||||
|
|
||||||
|
include ../../../Makefile.targ
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,280 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
// CryptoAlg.c:
|
||||||
|
// Interface to DNSSEC cryptographic algorithms. The crypto support itself is
|
||||||
|
// provided by the platform and the functions in this file just provide an
|
||||||
|
// interface to access them in a more generic way.
|
||||||
|
// ***************************************************************************
|
||||||
|
|
||||||
|
#include "mDNSEmbeddedAPI.h"
|
||||||
|
#include "CryptoAlg.h"
|
||||||
|
|
||||||
|
AlgFuncs *DigestAlgFuncs[DIGEST_TYPE_MAX];
|
||||||
|
AlgFuncs *CryptoAlgFuncs[CRYPTO_ALG_MAX];
|
||||||
|
AlgFuncs *EncAlgFuncs[ENC_ALG_MAX];
|
||||||
|
|
||||||
|
mDNSexport mStatus DigestAlgInit(mDNSu8 digestType, AlgFuncs *func)
|
||||||
|
{
|
||||||
|
if (digestType >= DIGEST_TYPE_MAX)
|
||||||
|
{
|
||||||
|
LogMsg("DigestAlgInit: digestType %d exceeds bounds", digestType);
|
||||||
|
return mStatus_BadParamErr;
|
||||||
|
}
|
||||||
|
// As digestTypes may not be consecutive, check for specific digest types
|
||||||
|
// that we support
|
||||||
|
if (digestType != SHA1_DIGEST_TYPE &&
|
||||||
|
digestType != SHA256_DIGEST_TYPE)
|
||||||
|
{
|
||||||
|
LogMsg("DigestAlgInit: digestType %d not supported", digestType);
|
||||||
|
return mStatus_BadParamErr;
|
||||||
|
}
|
||||||
|
DigestAlgFuncs[digestType] = func;
|
||||||
|
return mStatus_NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport mStatus CryptoAlgInit(mDNSu8 alg, AlgFuncs *func)
|
||||||
|
{
|
||||||
|
if (alg >= CRYPTO_ALG_MAX)
|
||||||
|
{
|
||||||
|
LogMsg("CryptoAlgInit: alg %d exceeds bounds", alg);
|
||||||
|
return mStatus_BadParamErr;
|
||||||
|
}
|
||||||
|
// As algs may not be consecutive, check for specific algorithms
|
||||||
|
// that we support
|
||||||
|
if (alg != CRYPTO_RSA_SHA1 && alg != CRYPTO_RSA_SHA256 && alg != CRYPTO_RSA_SHA512 &&
|
||||||
|
alg != CRYPTO_DSA_NSEC3_SHA1 && alg != CRYPTO_RSA_NSEC3_SHA1)
|
||||||
|
{
|
||||||
|
LogMsg("CryptoAlgInit: alg %d not supported", alg);
|
||||||
|
return mStatus_BadParamErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
CryptoAlgFuncs[alg] = func;
|
||||||
|
return mStatus_NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport mStatus EncAlgInit(mDNSu8 alg, AlgFuncs *func)
|
||||||
|
{
|
||||||
|
if (alg >= ENC_ALG_MAX)
|
||||||
|
{
|
||||||
|
LogMsg("EncAlgInit: alg %d exceeds bounds", alg);
|
||||||
|
return mStatus_BadParamErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// As algs may not be consecutive, check for specific algorithms
|
||||||
|
// that we support
|
||||||
|
if (alg != ENC_BASE32 && alg != ENC_BASE64)
|
||||||
|
{
|
||||||
|
LogMsg("EncAlgInit: alg %d not supported", alg);
|
||||||
|
return mStatus_BadParamErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
EncAlgFuncs[alg] = func;
|
||||||
|
return mStatus_NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport AlgContext *AlgCreate(AlgType type, mDNSu8 alg)
|
||||||
|
{
|
||||||
|
AlgFuncs *func = mDNSNULL;
|
||||||
|
AlgContext *ctx;
|
||||||
|
|
||||||
|
if (type == CRYPTO_ALG)
|
||||||
|
{
|
||||||
|
if (alg >= CRYPTO_ALG_MAX) return mDNSNULL;
|
||||||
|
func = CryptoAlgFuncs[alg];
|
||||||
|
}
|
||||||
|
else if (type == DIGEST_ALG)
|
||||||
|
{
|
||||||
|
if (alg >= DIGEST_TYPE_MAX) return mDNSNULL;
|
||||||
|
func = DigestAlgFuncs[alg];
|
||||||
|
}
|
||||||
|
else if (type == ENC_ALG)
|
||||||
|
{
|
||||||
|
if (alg >= ENC_ALG_MAX) return mDNSNULL;
|
||||||
|
func = EncAlgFuncs[alg];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!func)
|
||||||
|
{
|
||||||
|
// If there is no support from the platform, this case can happen.
|
||||||
|
LogInfo("AlgCreate: func is NULL");
|
||||||
|
return mDNSNULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (func->Create)
|
||||||
|
{
|
||||||
|
mStatus err;
|
||||||
|
ctx = mDNSPlatformMemAllocate(sizeof(AlgContext));
|
||||||
|
if (!ctx) return mDNSNULL;
|
||||||
|
// Create expects ctx->alg to be initialized
|
||||||
|
ctx->alg = alg;
|
||||||
|
err = func->Create(ctx);
|
||||||
|
if (err == mStatus_NoError)
|
||||||
|
{
|
||||||
|
ctx->type = type;
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
mDNSPlatformMemFree(ctx);
|
||||||
|
}
|
||||||
|
return mDNSNULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport mStatus AlgDestroy(AlgContext *ctx)
|
||||||
|
{
|
||||||
|
AlgFuncs *func = mDNSNULL;
|
||||||
|
|
||||||
|
if (ctx->type == CRYPTO_ALG)
|
||||||
|
func = CryptoAlgFuncs[ctx->alg];
|
||||||
|
else if (ctx->type == DIGEST_ALG)
|
||||||
|
func = DigestAlgFuncs[ctx->alg];
|
||||||
|
else if (ctx->type == ENC_ALG)
|
||||||
|
func = EncAlgFuncs[ctx->alg];
|
||||||
|
|
||||||
|
if (!func)
|
||||||
|
{
|
||||||
|
LogMsg("AlgDestroy: ERROR!! func is NULL");
|
||||||
|
mDNSPlatformMemFree(ctx);
|
||||||
|
return mStatus_BadParamErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (func->Destroy)
|
||||||
|
func->Destroy(ctx);
|
||||||
|
|
||||||
|
mDNSPlatformMemFree(ctx);
|
||||||
|
return mStatus_NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport mDNSu32 AlgLength(AlgContext *ctx)
|
||||||
|
{
|
||||||
|
AlgFuncs *func = mDNSNULL;
|
||||||
|
|
||||||
|
if (ctx->type == CRYPTO_ALG)
|
||||||
|
func = CryptoAlgFuncs[ctx->alg];
|
||||||
|
else if (ctx->type == DIGEST_ALG)
|
||||||
|
func = DigestAlgFuncs[ctx->alg];
|
||||||
|
else if (ctx->type == ENC_ALG)
|
||||||
|
func = EncAlgFuncs[ctx->alg];
|
||||||
|
|
||||||
|
// This should never happen as AlgCreate would have failed
|
||||||
|
if (!func)
|
||||||
|
{
|
||||||
|
LogMsg("AlgLength: ERROR!! func is NULL");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (func->Length)
|
||||||
|
return (func->Length(ctx));
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport mStatus AlgAdd(AlgContext *ctx, const void *data, mDNSu32 len)
|
||||||
|
{
|
||||||
|
AlgFuncs *func = mDNSNULL;
|
||||||
|
|
||||||
|
if (ctx->type == CRYPTO_ALG)
|
||||||
|
func = CryptoAlgFuncs[ctx->alg];
|
||||||
|
else if (ctx->type == DIGEST_ALG)
|
||||||
|
func = DigestAlgFuncs[ctx->alg];
|
||||||
|
else if (ctx->type == ENC_ALG)
|
||||||
|
func = EncAlgFuncs[ctx->alg];
|
||||||
|
|
||||||
|
// This should never happen as AlgCreate would have failed
|
||||||
|
if (!func)
|
||||||
|
{
|
||||||
|
LogMsg("AlgAdd: ERROR!! func is NULL");
|
||||||
|
return mStatus_BadParamErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (func->Add)
|
||||||
|
return (func->Add(ctx, data, len));
|
||||||
|
else
|
||||||
|
return mStatus_BadParamErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport mStatus AlgVerify(AlgContext *ctx, mDNSu8 *key, mDNSu32 keylen, mDNSu8 *signature, mDNSu32 siglen)
|
||||||
|
{
|
||||||
|
AlgFuncs *func = mDNSNULL;
|
||||||
|
|
||||||
|
if (ctx->type == CRYPTO_ALG)
|
||||||
|
func = CryptoAlgFuncs[ctx->alg];
|
||||||
|
else if (ctx->type == DIGEST_ALG)
|
||||||
|
func = DigestAlgFuncs[ctx->alg];
|
||||||
|
else if (ctx->type == ENC_ALG)
|
||||||
|
func = EncAlgFuncs[ctx->alg];
|
||||||
|
|
||||||
|
// This should never happen as AlgCreate would have failed
|
||||||
|
if (!func)
|
||||||
|
{
|
||||||
|
LogMsg("AlgVerify: ERROR!! func is NULL");
|
||||||
|
return mStatus_BadParamErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (func->Verify)
|
||||||
|
return (func->Verify(ctx, key, keylen, signature, siglen));
|
||||||
|
else
|
||||||
|
return mStatus_BadParamErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport mDNSu8* AlgEncode(AlgContext *ctx)
|
||||||
|
{
|
||||||
|
AlgFuncs *func = mDNSNULL;
|
||||||
|
|
||||||
|
if (ctx->type == CRYPTO_ALG)
|
||||||
|
func = CryptoAlgFuncs[ctx->alg];
|
||||||
|
else if (ctx->type == DIGEST_ALG)
|
||||||
|
func = DigestAlgFuncs[ctx->alg];
|
||||||
|
else if (ctx->type == ENC_ALG)
|
||||||
|
func = EncAlgFuncs[ctx->alg];
|
||||||
|
|
||||||
|
// This should never happen as AlgCreate would have failed
|
||||||
|
if (!func)
|
||||||
|
{
|
||||||
|
LogMsg("AlgEncode: ERROR!! func is NULL");
|
||||||
|
return mDNSNULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (func->Encode)
|
||||||
|
return (func->Encode(ctx));
|
||||||
|
else
|
||||||
|
return mDNSNULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport mStatus AlgFinal(AlgContext *ctx, void *data, mDNSu32 len)
|
||||||
|
{
|
||||||
|
AlgFuncs *func = mDNSNULL;
|
||||||
|
|
||||||
|
if (ctx->type == CRYPTO_ALG)
|
||||||
|
func = CryptoAlgFuncs[ctx->alg];
|
||||||
|
else if (ctx->type == DIGEST_ALG)
|
||||||
|
func = DigestAlgFuncs[ctx->alg];
|
||||||
|
else if (ctx->type == ENC_ALG)
|
||||||
|
func = EncAlgFuncs[ctx->alg];
|
||||||
|
|
||||||
|
// This should never happen as AlgCreate would have failed
|
||||||
|
if (!func)
|
||||||
|
{
|
||||||
|
LogMsg("AlgEncode: ERROR!! func is NULL");
|
||||||
|
return mDNSNULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (func->Final)
|
||||||
|
return (func->Final(ctx, data, len));
|
||||||
|
else
|
||||||
|
return mStatus_BadParamErr;
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef __CRYPTO_ALG_H
|
||||||
|
#define __CRYPTO_ALG_H
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
CRYPTO_ALG,
|
||||||
|
DIGEST_ALG,
|
||||||
|
ENC_ALG,
|
||||||
|
} AlgType;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *context;
|
||||||
|
AlgType type;
|
||||||
|
mDNSu8 alg;
|
||||||
|
} AlgContext;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
mStatus (*Create)(AlgContext *ctx);
|
||||||
|
mStatus (*Destroy)(AlgContext *ctx);
|
||||||
|
mDNSu32 (*Length)(AlgContext *ctx);
|
||||||
|
mStatus (*Add)(AlgContext *ctx, const void *data, mDNSu32 len);
|
||||||
|
// Verify the ctx using the key and compare it against signature/siglen
|
||||||
|
mStatus (*Verify)(AlgContext *ctx, mDNSu8 *key, mDNSu32 keylen, mDNSu8 *signature, mDNSu32 siglen);
|
||||||
|
// Encode the data and return the encoded data
|
||||||
|
mDNSu8* (*Encode)(AlgContext *ctx);
|
||||||
|
// Return the finalized data in data whose length is len (used by hash algorithms)
|
||||||
|
mStatus (*Final)(AlgContext *ctx, void *data, mDNSu32 len);
|
||||||
|
} AlgFuncs;
|
||||||
|
|
||||||
|
mDNSexport mStatus DigestAlgInit(mDNSu8 digestType, AlgFuncs *func);
|
||||||
|
mDNSexport mStatus CryptoAlgInit(mDNSu8 algType, AlgFuncs *func);
|
||||||
|
mDNSexport mStatus EncAlgInit(mDNSu8 algType, AlgFuncs *func);
|
||||||
|
|
||||||
|
|
||||||
|
extern AlgContext *AlgCreate(AlgType type, mDNSu8 alg);
|
||||||
|
extern mStatus AlgDestroy(AlgContext *ctx);
|
||||||
|
extern mDNSu32 AlgLength(AlgContext *ctx);
|
||||||
|
extern mStatus AlgAdd(AlgContext *ctx, const void *data, mDNSu32 len);
|
||||||
|
extern mStatus AlgVerify(AlgContext *ctx, mDNSu8 *key, mDNSu32 keylen, mDNSu8 *signature, mDNSu32 siglen);
|
||||||
|
extern mDNSu8* AlgEncode(AlgContext *ctx);
|
||||||
|
extern mStatus AlgFinal(AlgContext *ctx, void *data, mDNSu32 len);
|
||||||
|
|
||||||
|
#endif // __CRYPTO_ALG_H
|
File diff suppressed because it is too large
Load Diff
|
@ -5,148 +5,33 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: DNSCommon.h,v $
|
|
||||||
Revision 1.34.2.1 2006/08/29 06:24:22 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.34 2006/03/18 21:47:56 cheshire
|
|
||||||
<rdar://problem/4073825> Improve logic for delaying packets after repeated interface transitions
|
|
||||||
|
|
||||||
Revision 1.33 2006/03/10 21:51:41 cheshire
|
|
||||||
<rdar://problem/4111464> After record update, old record sometimes remains in cache
|
|
||||||
Split out SameRDataBody() into a separate routine so it can be called from other code
|
|
||||||
|
|
||||||
Revision 1.32 2005/03/21 00:33:51 shersche
|
|
||||||
<rdar://problem/4021486> Fix build warnings on Win32 platform
|
|
||||||
|
|
||||||
Revision 1.31 2005/02/18 00:43:11 cheshire
|
|
||||||
<rdar://problem/4010245> mDNSResponder should auto-truncate service names that are too long
|
|
||||||
|
|
||||||
Revision 1.30 2005/01/19 03:12:44 cheshire
|
|
||||||
Move LocalRecordReady() macro from mDNS.c to DNSCommon.h
|
|
||||||
|
|
||||||
Revision 1.29 2004/12/15 02:11:22 ksekar
|
|
||||||
<rdar://problem/3917317> Don't check for Dynamic DNS hostname uniqueness
|
|
||||||
|
|
||||||
Revision 1.28 2004/12/06 21:15:22 ksekar
|
|
||||||
<rdar://problem/3884386> mDNSResponder crashed in CheckServiceRegistrations
|
|
||||||
|
|
||||||
Revision 1.27 2004/12/03 07:20:50 ksekar
|
|
||||||
<rdar://problem/3674208> Wide-Area: Registration of large TXT record fails
|
|
||||||
|
|
||||||
Revision 1.26 2004/12/03 05:18:33 ksekar
|
|
||||||
<rdar://problem/3810596> mDNSResponder needs to return more specific TSIG errors
|
|
||||||
|
|
||||||
Revision 1.25 2004/10/26 03:52:02 cheshire
|
|
||||||
Update checkin comments
|
|
||||||
|
|
||||||
Revision 1.24 2004/10/23 01:16:00 cheshire
|
|
||||||
<rdar://problem/3851677> uDNS operations not always reliable on multi-homed hosts
|
|
||||||
|
|
||||||
Revision 1.23 2004/10/03 23:18:58 cheshire
|
|
||||||
Move address comparison macros from DNSCommon.h to mDNSEmbeddedAPI.h
|
|
||||||
|
|
||||||
Revision 1.22 2004/09/30 00:24:56 ksekar
|
|
||||||
<rdar://problem/3695802> Dynamically update default registration domains on config change
|
|
||||||
|
|
||||||
Revision 1.21 2004/09/17 01:08:48 cheshire
|
|
||||||
Renamed mDNSClientAPI.h to mDNSEmbeddedAPI.h
|
|
||||||
The name "mDNSClientAPI.h" is misleading to new developers looking at this code. The interfaces
|
|
||||||
declared in that file are ONLY appropriate to single-address-space embedded applications.
|
|
||||||
For clients on general-purpose computers, the interfaces defined in dns_sd.h should be used.
|
|
||||||
|
|
||||||
Revision 1.20 2004/09/17 00:49:51 cheshire
|
|
||||||
Get rid of now-unused GetResourceRecord -- the correct (safe) routine to use
|
|
||||||
is GetLargeResourceRecord
|
|
||||||
|
|
||||||
Revision 1.19 2004/09/16 21:59:15 cheshire
|
|
||||||
For consistency with zerov6Addr, rename zeroIPAddr to zerov4Addr
|
|
||||||
|
|
||||||
Revision 1.18 2004/09/16 02:29:39 cheshire
|
|
||||||
Moved mDNS_Lock/mDNS_Unlock to DNSCommon.c; Added necessary locking around
|
|
||||||
uDNS_ReceiveMsg, uDNS_StartQuery, uDNS_UpdateRecord, uDNS_RegisterService
|
|
||||||
|
|
||||||
Revision 1.17 2004/09/14 23:27:46 cheshire
|
|
||||||
Fix compile errors
|
|
||||||
|
|
||||||
Revision 1.16 2004/08/13 23:46:58 cheshire
|
|
||||||
"asyncronous" -> "asynchronous"
|
|
||||||
|
|
||||||
Revision 1.15 2004/08/10 23:19:14 ksekar
|
|
||||||
<rdar://problem/3722542>: DNS Extension daemon for Wide Area Service Discovery
|
|
||||||
Moved routines/constants to allow extern access for garbage collection daemon
|
|
||||||
|
|
||||||
Revision 1.14 2004/05/28 23:42:36 ksekar
|
|
||||||
<rdar://problem/3258021>: Feature: DNS server->client notification on record changes (#7805)
|
|
||||||
|
|
||||||
Revision 1.13 2004/05/18 23:51:25 cheshire
|
|
||||||
Tidy up all checkin comments to use consistent "<rdar://problem/xxxxxxx>" format for bug numbers
|
|
||||||
|
|
||||||
Revision 1.12 2004/04/22 04:03:59 cheshire
|
|
||||||
Headers should use "extern" declarations, not "mDNSexport"
|
|
||||||
|
|
||||||
Revision 1.11 2004/04/14 23:09:28 ksekar
|
|
||||||
Support for TSIG signed dynamic updates.
|
|
||||||
|
|
||||||
Revision 1.10 2004/03/13 01:57:33 ksekar
|
|
||||||
<rdar://problem/3192546>: DynDNS: Dynamic update of service records
|
|
||||||
|
|
||||||
Revision 1.9 2004/02/21 08:56:58 bradley
|
|
||||||
Wrap prototypes with extern "C" for C++ builds.
|
|
||||||
|
|
||||||
Revision 1.8 2004/02/06 23:04:18 ksekar
|
|
||||||
Basic Dynamic Update support via mDNS_Register (dissabled via
|
|
||||||
UNICAST_REGISTRATION #define)
|
|
||||||
|
|
||||||
Revision 1.7 2004/02/03 19:47:36 ksekar
|
|
||||||
Added an asynchronous state machine mechanism to uDNS.c, including
|
|
||||||
calls to find the parent zone for a domain name. Changes include code
|
|
||||||
in repository previously dissabled via "#if 0 incomplete". Codepath
|
|
||||||
is currently unused, and will be called to create update records, etc.
|
|
||||||
|
|
||||||
Revision 1.6 2004/01/27 20:15:22 cheshire
|
|
||||||
<rdar://problem/3541288>: Time to prune obsolete code for listening on port 53
|
|
||||||
|
|
||||||
Revision 1.5 2004/01/24 03:40:56 cheshire
|
|
||||||
Move mDNSAddrIsDNSMulticast() from DNSCommon.h to mDNSEmbeddedAPI.h so embedded clients can use it
|
|
||||||
|
|
||||||
Revision 1.4 2004/01/24 03:38:27 cheshire
|
|
||||||
Fix minor syntactic error: Headers should use "extern" declarations, not "mDNSexport"
|
|
||||||
|
|
||||||
Revision 1.3 2004/01/23 23:23:14 ksekar
|
|
||||||
Added TCP support for truncated unicast messages.
|
|
||||||
|
|
||||||
Revision 1.2 2004/01/21 21:12:23 cheshire
|
|
||||||
Add missing newline at end of file to make Unix tools happier
|
|
||||||
|
|
||||||
Revision 1.1 2003/12/13 03:05:27 ksekar
|
|
||||||
<rdar://problem/3192548>: DynDNS: Unicast query of service records
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
#ifndef __DNSCOMMON_H_
|
#ifndef __DNSCOMMON_H_
|
||||||
#define __DNSCOMMON_H_
|
#define __DNSCOMMON_H_
|
||||||
|
|
||||||
#include "mDNSEmbeddedAPI.h"
|
#include "mDNSEmbeddedAPI.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//*************************************************************************************************************
|
||||||
|
// Macros
|
||||||
|
|
||||||
|
// Note: The C preprocessor stringify operator ('#') makes a string from its argument, without macro expansion
|
||||||
|
// e.g. If "version" is #define'd to be "4", then STRINGIFY_AWE(version) will return the string "version", not "4"
|
||||||
|
// To expand "version" to its value before making the string, use STRINGIFY(version) instead
|
||||||
|
#define STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) # s
|
||||||
|
#define STRINGIFY(s) STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s)
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
#if COMPILER_LIKES_PRAGMA_MARK
|
#if COMPILER_LIKES_PRAGMA_MARK
|
||||||
|
@ -154,51 +39,50 @@ Revision 1.1 2003/12/13 03:05:27 ksekar
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
kDNSFlag0_QR_Mask = 0x80, // Query or response?
|
kDNSFlag0_QR_Mask = 0x80, // Query or response?
|
||||||
kDNSFlag0_QR_Query = 0x00,
|
kDNSFlag0_QR_Query = 0x00,
|
||||||
kDNSFlag0_QR_Response = 0x80,
|
kDNSFlag0_QR_Response = 0x80,
|
||||||
|
|
||||||
kDNSFlag0_OP_Mask = 0x78, // Operation type
|
|
||||||
kDNSFlag0_OP_StdQuery = 0x00,
|
|
||||||
kDNSFlag0_OP_Iquery = 0x08,
|
|
||||||
kDNSFlag0_OP_Status = 0x10,
|
|
||||||
kDNSFlag0_OP_Unused3 = 0x18,
|
|
||||||
kDNSFlag0_OP_Notify = 0x20,
|
|
||||||
kDNSFlag0_OP_Update = 0x28,
|
|
||||||
|
|
||||||
kDNSFlag0_QROP_Mask = kDNSFlag0_QR_Mask | kDNSFlag0_OP_Mask,
|
|
||||||
|
|
||||||
kDNSFlag0_AA = 0x04, // Authoritative Answer?
|
|
||||||
kDNSFlag0_TC = 0x02, // Truncated?
|
|
||||||
kDNSFlag0_RD = 0x01, // Recursion Desired?
|
|
||||||
kDNSFlag1_RA = 0x80, // Recursion Available?
|
|
||||||
|
|
||||||
kDNSFlag1_Zero = 0x40, // Reserved; must be zero
|
|
||||||
kDNSFlag1_AD = 0x20, // Authentic Data [RFC 2535]
|
|
||||||
kDNSFlag1_CD = 0x10, // Checking Disabled [RFC 2535]
|
|
||||||
|
|
||||||
kDNSFlag1_RC = 0x0F, // Response code
|
kDNSFlag0_OP_Mask = 0x78, // Operation type
|
||||||
kDNSFlag1_RC_NoErr = 0x00,
|
kDNSFlag0_OP_StdQuery = 0x00,
|
||||||
kDNSFlag1_RC_FmtErr = 0x01,
|
kDNSFlag0_OP_Iquery = 0x08,
|
||||||
kDNSFlag1_RC_SrvErr = 0x02,
|
kDNSFlag0_OP_Status = 0x10,
|
||||||
kDNSFlag1_RC_NXDomain = 0x03,
|
kDNSFlag0_OP_Unused3 = 0x18,
|
||||||
kDNSFlag1_RC_NotImpl = 0x04,
|
kDNSFlag0_OP_Notify = 0x20,
|
||||||
kDNSFlag1_RC_Refused = 0x05,
|
kDNSFlag0_OP_Update = 0x28,
|
||||||
kDNSFlag1_RC_YXDomain = 0x06,
|
|
||||||
kDNSFlag1_RC_YXRRSet = 0x07,
|
kDNSFlag0_QROP_Mask = kDNSFlag0_QR_Mask | kDNSFlag0_OP_Mask,
|
||||||
kDNSFlag1_RC_NXRRSet = 0x08,
|
|
||||||
kDNSFlag1_RC_NotAuth = 0x09,
|
kDNSFlag0_AA = 0x04, // Authoritative Answer?
|
||||||
kDNSFlag1_RC_NotZone = 0x0A
|
kDNSFlag0_TC = 0x02, // Truncated?
|
||||||
} DNS_Flags;
|
kDNSFlag0_RD = 0x01, // Recursion Desired?
|
||||||
|
kDNSFlag1_RA = 0x80, // Recursion Available?
|
||||||
|
|
||||||
|
kDNSFlag1_Zero = 0x40, // Reserved; must be zero
|
||||||
|
kDNSFlag1_AD = 0x20, // Authentic Data [RFC 2535]
|
||||||
|
kDNSFlag1_CD = 0x10, // Checking Disabled [RFC 2535]
|
||||||
|
|
||||||
|
kDNSFlag1_RC_Mask = 0x0F, // Response code
|
||||||
|
kDNSFlag1_RC_NoErr = 0x00,
|
||||||
|
kDNSFlag1_RC_FormErr = 0x01,
|
||||||
|
kDNSFlag1_RC_ServFail = 0x02,
|
||||||
|
kDNSFlag1_RC_NXDomain = 0x03,
|
||||||
|
kDNSFlag1_RC_NotImpl = 0x04,
|
||||||
|
kDNSFlag1_RC_Refused = 0x05,
|
||||||
|
kDNSFlag1_RC_YXDomain = 0x06,
|
||||||
|
kDNSFlag1_RC_YXRRSet = 0x07,
|
||||||
|
kDNSFlag1_RC_NXRRSet = 0x08,
|
||||||
|
kDNSFlag1_RC_NotAuth = 0x09,
|
||||||
|
kDNSFlag1_RC_NotZone = 0x0A
|
||||||
|
} DNS_Flags;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TSIG_ErrBadSig = 16,
|
TSIG_ErrBadSig = 16,
|
||||||
TSIG_ErrBadKey = 17,
|
TSIG_ErrBadKey = 17,
|
||||||
TSIG_ErrBadTime = 18
|
TSIG_ErrBadTime = 18
|
||||||
} TSIG_ErrorCode;
|
} TSIG_ErrorCode;
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
#if COMPILER_LIKES_PRAGMA_MARK
|
#if COMPILER_LIKES_PRAGMA_MARK
|
||||||
|
@ -206,107 +90,146 @@ typedef enum
|
||||||
#pragma mark - General Utility Functions
|
#pragma mark - General Utility Functions
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern const NetworkInterfaceInfo *GetFirstActiveInterface(const NetworkInterfaceInfo *intf);
|
extern NetworkInterfaceInfo *GetFirstActiveInterface(NetworkInterfaceInfo *intf);
|
||||||
extern mDNSInterfaceID GetNextActiveInterfaceID(const NetworkInterfaceInfo *intf);
|
extern mDNSInterfaceID GetNextActiveInterfaceID(const NetworkInterfaceInfo *intf);
|
||||||
|
|
||||||
extern mDNSu32 mDNSRandom(mDNSu32 max);
|
extern mDNSu32 mDNSRandom(mDNSu32 max); // Returns pseudo-random result from zero to max inclusive
|
||||||
extern mDNSu32 mDNSRandomFromFixedSeed(mDNSu32 seed, mDNSu32 max);
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
#if COMPILER_LIKES_PRAGMA_MARK
|
#if COMPILER_LIKES_PRAGMA_MARK
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark - Domain Name Utility Functions
|
#pragma mark - Domain Name Utility Functions
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define mdnsIsDigit(X) ((X) >= '0' && (X) <= '9')
|
#define mDNSSubTypeLabel "\x04_sub"
|
||||||
|
|
||||||
|
#define mDNSIsDigit(X) ((X) >= '0' && (X) <= '9')
|
||||||
#define mDNSIsUpperCase(X) ((X) >= 'A' && (X) <= 'Z')
|
#define mDNSIsUpperCase(X) ((X) >= 'A' && (X) <= 'Z')
|
||||||
#define mDNSIsLowerCase(X) ((X) >= 'a' && (X) <= 'z')
|
#define mDNSIsLowerCase(X) ((X) >= 'a' && (X) <= 'z')
|
||||||
#define mdnsIsLetter(X) (mDNSIsUpperCase(X) || mDNSIsLowerCase(X))
|
#define mDNSIsLetter(X) (mDNSIsUpperCase(X) || mDNSIsLowerCase(X))
|
||||||
|
|
||||||
#define mdnsValidHostChar(X, notfirst, notlast) (mdnsIsLetter(X) || mdnsIsDigit(X) || ((notfirst) && (notlast) && (X) == '-') )
|
#define mDNSValidHostChar(X, notfirst, notlast) (mDNSIsLetter(X) || mDNSIsDigit(X) || ((notfirst) && (notlast) && (X) == '-') )
|
||||||
|
|
||||||
extern mDNSu16 CompressedDomainNameLength(const domainname *const name, const domainname *parent);
|
extern mDNSu16 CompressedDomainNameLength(const domainname *const name, const domainname *parent);
|
||||||
|
extern int CountLabels(const domainname *d);
|
||||||
|
extern const domainname *SkipLeadingLabels(const domainname *d, int skip);
|
||||||
|
|
||||||
extern mDNSu32 TruncateUTF8ToLength(mDNSu8 *string, mDNSu32 length, mDNSu32 max);
|
extern mDNSu32 TruncateUTF8ToLength(mDNSu8 *string, mDNSu32 length, mDNSu32 max);
|
||||||
extern mDNSBool LabelContainsSuffix(const domainlabel *const name, const mDNSBool RichText);
|
extern mDNSBool LabelContainsSuffix(const domainlabel *const name, const mDNSBool RichText);
|
||||||
extern mDNSu32 RemoveLabelSuffix(domainlabel *name, mDNSBool RichText);
|
extern mDNSu32 RemoveLabelSuffix(domainlabel *name, mDNSBool RichText);
|
||||||
extern void AppendLabelSuffix(domainlabel *name, mDNSu32 val, mDNSBool RichText);
|
extern void AppendLabelSuffix(domainlabel *const name, mDNSu32 val, const mDNSBool RichText);
|
||||||
extern void mDNS_HostNameCallback(mDNS *const m, AuthRecord *const rr, mStatus result);
|
|
||||||
#define ValidateDomainName(N) (DomainNameLength(N) <= MAX_DOMAIN_NAME)
|
#define ValidateDomainName(N) (DomainNameLength(N) <= MAX_DOMAIN_NAME)
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
#if COMPILER_LIKES_PRAGMA_MARK
|
#if COMPILER_LIKES_PRAGMA_MARK
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark - Resource Record Utility Functions
|
#pragma mark - Resource Record Utility Functions
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern mDNSu32 RDataHashValue(mDNSu16 const rdlength, const RDataBody *const rdb);
|
// IdenticalResourceRecord returns true if two resources records have
|
||||||
|
// the same name, type, class, and identical rdata (InterfaceID and TTL may differ)
|
||||||
|
|
||||||
extern mDNSBool SameRDataBody(const ResourceRecord *const r1, const RDataBody *const r2);
|
// IdenticalSameNameRecord is the same, except it skips the expensive SameDomainName() check,
|
||||||
extern mDNSBool SameRData(const ResourceRecord *const r1, const ResourceRecord *const r2);
|
// which is at its most expensive and least useful in cases where we know in advance that the names match
|
||||||
|
|
||||||
|
// Note: The dominant use of IdenticalResourceRecord is from ProcessQuery(), handling known-answer lists. In this case
|
||||||
|
// it's common to have a whole bunch or records with exactly the same name (e.g. "_http._tcp.local") but different RDATA.
|
||||||
|
// The SameDomainName() check is expensive when the names match, and in this case *all* the names match, so we
|
||||||
|
// used to waste a lot of CPU time verifying that the names match, only then to find that the RDATA is different.
|
||||||
|
// We observed mDNSResponder spending 30% of its total CPU time on this single task alone.
|
||||||
|
// By swapping the checks so that we check the RDATA first, we can quickly detect when it's different
|
||||||
|
// (99% of the time) and then bail out before we waste time on the expensive SameDomainName() check.
|
||||||
|
|
||||||
|
#define IdenticalResourceRecord(r1,r2) ( \
|
||||||
|
(r1)->rrtype == (r2)->rrtype && \
|
||||||
|
(r1)->rrclass == (r2)->rrclass && \
|
||||||
|
(r1)->namehash == (r2)->namehash && \
|
||||||
|
(r1)->rdlength == (r2)->rdlength && \
|
||||||
|
(r1)->rdatahash == (r2)->rdatahash && \
|
||||||
|
SameRDataBody((r1), &(r2)->rdata->u, SameDomainName) && \
|
||||||
|
SameDomainName((r1)->name, (r2)->name))
|
||||||
|
|
||||||
|
#define IdenticalSameNameRecord(r1,r2) ( \
|
||||||
|
(r1)->rrtype == (r2)->rrtype && \
|
||||||
|
(r1)->rrclass == (r2)->rrclass && \
|
||||||
|
(r1)->rdlength == (r2)->rdlength && \
|
||||||
|
(r1)->rdatahash == (r2)->rdatahash && \
|
||||||
|
SameRDataBody((r1), &(r2)->rdata->u, SameDomainName))
|
||||||
|
|
||||||
|
// A given RRType answers a QuestionType if RRType is CNAME, or types match, or QuestionType is ANY,
|
||||||
|
// or the RRType is NSEC and positively asserts the nonexistence of the type being requested
|
||||||
|
#define RRTypeAnswersQuestionType(R,Q) ((R)->rrtype == kDNSType_CNAME || (R)->rrtype == (Q) || (Q) == kDNSQType_ANY || RRAssertsNonexistence((R),(Q)))
|
||||||
|
// Unicast NSEC records have the NSEC bit set whereas the multicast NSEC ones don't
|
||||||
|
#define UNICAST_NSEC(rr) ((rr)->rrtype == kDNSType_NSEC && RRAssertsExistence((rr), kDNSType_NSEC))
|
||||||
|
|
||||||
|
extern mDNSu32 RDataHashValue(const ResourceRecord *const rr);
|
||||||
|
extern mDNSBool SameRDataBody(const ResourceRecord *const r1, const RDataBody *const r2, DomainNameComparisonFn *samename);
|
||||||
|
extern mDNSBool SameNameRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
|
||||||
extern mDNSBool ResourceRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
|
extern mDNSBool ResourceRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
|
||||||
|
extern mDNSBool AnyTypeRecordAnswersQuestion (const ResourceRecord *const rr, const DNSQuestion *const q);
|
||||||
extern mDNSBool SameResourceRecord(ResourceRecord *r1, ResourceRecord *r2);
|
extern mDNSBool ResourceRecordAnswersUnicastResponse(const ResourceRecord *const rr, const DNSQuestion *const q);
|
||||||
|
extern mDNSBool LocalOnlyRecordAnswersQuestion(AuthRecord *const rr, const DNSQuestion *const q);
|
||||||
extern mDNSu16 GetRDLength(const ResourceRecord *const rr, mDNSBool estimate);
|
extern mDNSu16 GetRDLength(const ResourceRecord *const rr, mDNSBool estimate);
|
||||||
|
extern mDNSBool ValidateRData(const mDNSu16 rrtype, const mDNSu16 rdlength, const RData *const rd);
|
||||||
|
extern mStatus DNSNameToLowerCase(domainname *d, domainname *result);
|
||||||
|
|
||||||
#define GetRRDomainNameTarget(RR) ( \
|
#define GetRRDomainNameTarget(RR) ( \
|
||||||
((RR)->rrtype == kDNSType_CNAME || (RR)->rrtype == kDNSType_PTR || (RR)->rrtype == kDNSType_NS) \
|
((RR)->rrtype == kDNSType_NS || (RR)->rrtype == kDNSType_CNAME || (RR)->rrtype == kDNSType_PTR || (RR)->rrtype == kDNSType_DNAME) ? &(RR)->rdata->u.name : \
|
||||||
? &(RR)->rdata->u.name : \
|
((RR)->rrtype == kDNSType_MX || (RR)->rrtype == kDNSType_AFSDB || (RR)->rrtype == kDNSType_RT || (RR)->rrtype == kDNSType_KX ) ? &(RR)->rdata->u.mx.exchange : \
|
||||||
((RR)->rrtype == kDNSType_SRV ) ? &(RR)->rdata->u.srv.target : mDNSNULL )
|
((RR)->rrtype == kDNSType_SRV ) ? &(RR)->rdata->u.srv.target : mDNSNULL )
|
||||||
|
|
||||||
extern mDNSBool ValidateRData(const mDNSu16 rrtype, const mDNSu16 rdlength, const RData *const rd);
|
|
||||||
#define LocalRecordReady(X) ((X)->resrec.RecordType != kDNSRecordTypeUnique && (X)->resrec.RecordType != kDNSRecordTypeDeregistering)
|
|
||||||
|
|
||||||
|
#define LocalRecordReady(X) ((X)->resrec.RecordType != kDNSRecordTypeUnique)
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
#if COMPILER_LIKES_PRAGMA_MARK
|
#if COMPILER_LIKES_PRAGMA_MARK
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark -
|
|
||||||
#pragma mark - DNS Message Creation Functions
|
#pragma mark - DNS Message Creation Functions
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void InitializeDNSMessage(DNSMessageHeader *h, mDNSOpaque16 id, mDNSOpaque16 flags);
|
extern void InitializeDNSMessage(DNSMessageHeader *h, mDNSOpaque16 id, mDNSOpaque16 flags);
|
||||||
extern const mDNSu8 *FindCompressionPointer(const mDNSu8 *const base, const mDNSu8 *const end, const mDNSu8 *const domname);
|
extern const mDNSu8 *FindCompressionPointer(const mDNSu8 *const base, const mDNSu8 *const end, const mDNSu8 *const domname);
|
||||||
|
|
||||||
extern mDNSu8 *putDomainNameAsLabels(const DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, const domainname *const name);
|
extern mDNSu8 *putDomainNameAsLabels(const DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, const domainname *const name);
|
||||||
|
extern mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, const ResourceRecord *const rr);
|
||||||
extern mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, ResourceRecord *rr);
|
|
||||||
|
|
||||||
// If we have a single large record to put in the packet, then we allow the packet to be up to 9K bytes,
|
// If we have a single large record to put in the packet, then we allow the packet to be up to 9K bytes,
|
||||||
// but in the normal case we try to keep the packets below 1500 to avoid IP fragmentation on standard Ethernet
|
// but in the normal case we try to keep the packets below 1500 to avoid IP fragmentation on standard Ethernet
|
||||||
|
|
||||||
|
#define AllowedRRSpace(msg) (((msg)->h.numAnswers || (msg)->h.numAuthorities || (msg)->h.numAdditionals) ? NormalMaxDNSMessageData : AbsoluteMaxDNSMessageData)
|
||||||
|
|
||||||
extern mDNSu8 *PutResourceRecordTTLWithLimit(DNSMessage *const msg, mDNSu8 *ptr, mDNSu16 *count, ResourceRecord *rr, mDNSu32 ttl, const mDNSu8 *limit);
|
extern mDNSu8 *PutResourceRecordTTLWithLimit(DNSMessage *const msg, mDNSu8 *ptr, mDNSu16 *count, ResourceRecord *rr, mDNSu32 ttl, const mDNSu8 *limit);
|
||||||
|
|
||||||
#define PutResourceRecordTTL(msg, ptr, count, rr, ttl) PutResourceRecordTTLWithLimit((msg), (ptr), (count), (rr), (ttl), \
|
#define PutResourceRecordTTL(msg, ptr, count, rr, ttl) \
|
||||||
((msg)->h.numAnswers || (msg)->h.numAuthorities || (msg)->h.numAdditionals) ? (msg)->data + NormalMaxDNSMessageData : (msg)->data + AbsoluteMaxDNSMessageData)
|
PutResourceRecordTTLWithLimit((msg), (ptr), (count), (rr), (ttl), (msg)->data + AllowedRRSpace(msg))
|
||||||
|
|
||||||
#define PutResourceRecordTTLJumbo(msg, ptr, count, rr, ttl) PutResourceRecordTTLWithLimit((msg), (ptr), (count), (rr), (ttl), \
|
#define PutResourceRecordTTLJumbo(msg, ptr, count, rr, ttl) \
|
||||||
(msg)->data + AbsoluteMaxDNSMessageData)
|
PutResourceRecordTTLWithLimit((msg), (ptr), (count), (rr), (ttl), (msg)->data + AbsoluteMaxDNSMessageData)
|
||||||
|
|
||||||
extern mDNSu8 *PutResourceRecordCappedTTL(DNSMessage *const msg, mDNSu8 *ptr, mDNSu16 *count, ResourceRecord *rr, mDNSu32 maxttl);
|
|
||||||
|
|
||||||
extern mDNSu8 *putEmptyResourceRecord(DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, mDNSu16 *count, const AuthRecord *rr);
|
|
||||||
|
|
||||||
extern mDNSu8 *putQuestion(DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, const domainname *const name, mDNSu16 rrtype, mDNSu16 rrclass);
|
|
||||||
|
|
||||||
extern mDNSu8 *putZone(DNSMessage *const msg, mDNSu8 *ptr, mDNSu8 *limit, const domainname *zone, mDNSOpaque16 zoneClass);
|
|
||||||
|
|
||||||
extern mDNSu8 *putPrereqNameNotInUse(domainname *name, DNSMessage *msg, mDNSu8 *ptr, mDNSu8 *end);
|
|
||||||
|
|
||||||
extern mDNSu8 *putDeletionRecord(DNSMessage *msg, mDNSu8 *ptr, ResourceRecord *rr);
|
|
||||||
|
|
||||||
extern mDNSu8 *putDeleteRRSet(DNSMessage *msg, mDNSu8 *ptr, const domainname *name, mDNSu16 rrtype);
|
|
||||||
|
|
||||||
extern mDNSu8 *putDeleteAllRRSets(DNSMessage *msg, mDNSu8 *ptr, const domainname *name);
|
|
||||||
|
|
||||||
extern mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease);
|
|
||||||
|
|
||||||
#define PutResourceRecord(MSG, P, C, RR) PutResourceRecordTTL((MSG), (P), (C), (RR), (RR)->rroriginalttl)
|
#define PutResourceRecord(MSG, P, C, RR) PutResourceRecordTTL((MSG), (P), (C), (RR), (RR)->rroriginalttl)
|
||||||
|
|
||||||
|
// The PutRR_OS variants assume a local variable 'm', put build the packet at m->omsg,
|
||||||
|
// and assume local variables 'OwnerRecordSpace' & 'TraceRecordSpace' indicating how many bytes (if any) to reserve to add an OWNER/TRACER option at the end
|
||||||
|
#define PutRR_OS_TTL(ptr, count, rr, ttl) \
|
||||||
|
PutResourceRecordTTLWithLimit(&m->omsg, (ptr), (count), (rr), (ttl), m->omsg.data + AllowedRRSpace(&m->omsg) - OwnerRecordSpace - TraceRecordSpace)
|
||||||
|
|
||||||
|
#define PutRR_OS(P, C, RR) PutRR_OS_TTL((P), (C), (RR), (RR)->rroriginalttl)
|
||||||
|
|
||||||
|
extern mDNSu8 *putQuestion(DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, const domainname *const name, mDNSu16 rrtype, mDNSu16 rrclass);
|
||||||
|
extern mDNSu8 *putZone(DNSMessage *const msg, mDNSu8 *ptr, mDNSu8 *limit, const domainname *zone, mDNSOpaque16 zoneClass);
|
||||||
|
extern mDNSu8 *putPrereqNameNotInUse(const domainname *const name, DNSMessage *const msg, mDNSu8 *const ptr, mDNSu8 *const end);
|
||||||
|
extern mDNSu8 *putDeletionRecord(DNSMessage *msg, mDNSu8 *ptr, ResourceRecord *rr);
|
||||||
|
extern mDNSu8 *putDeletionRecordWithLimit(DNSMessage *msg, mDNSu8 *ptr, ResourceRecord *rr, mDNSu8 *limit);
|
||||||
|
extern mDNSu8 *putDeleteRRSetWithLimit(DNSMessage *msg, mDNSu8 *ptr, const domainname *name, mDNSu16 rrtype, mDNSu8 *limit);
|
||||||
|
extern mDNSu8 *putDeleteAllRRSets(DNSMessage *msg, mDNSu8 *ptr, const domainname *name);
|
||||||
|
extern mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease);
|
||||||
|
extern mDNSu8 *putUpdateLeaseWithLimit(DNSMessage *msg, mDNSu8 *ptr, mDNSu32 lease, mDNSu8 *limit);
|
||||||
|
|
||||||
|
extern mDNSu8 *putHINFO(const mDNS *const m, DNSMessage *const msg, mDNSu8 *ptr, DomainAuthInfo *authInfo, mDNSu8 *limit);
|
||||||
|
extern mDNSu8 *putDNSSECOption(DNSMessage *msg, mDNSu8 *end, mDNSu8 *limit);
|
||||||
|
extern int baseEncode(char *buffer, int blen, const mDNSu8 *data, int len, int encAlg);
|
||||||
|
extern void NSEC3Parse(const ResourceRecord *const rr, mDNSu8 **salt, int *hashLength, mDNSu8 **nxtName, int *bitmaplen, mDNSu8 **bitmap);
|
||||||
|
|
||||||
|
extern const mDNSu8 *NSEC3HashName(const domainname *name, rdataNSEC3 *nsec3, const mDNSu8 *AnonData, int AnonDataLen,
|
||||||
|
const mDNSu8 hash[NSEC3_MAX_HASH_LEN], int *dlen);
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
#if COMPILER_LIKES_PRAGMA_MARK
|
#if COMPILER_LIKES_PRAGMA_MARK
|
||||||
|
@ -314,43 +237,47 @@ extern mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease);
|
||||||
#pragma mark - DNS Message Parsing Functions
|
#pragma mark - DNS Message Parsing Functions
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define AuthHashSlot(X) (DomainNameHashValue(X) % AUTH_HASH_SLOTS)
|
||||||
|
#define HashSlot(X) (DomainNameHashValue(X) % CACHE_HASH_SLOTS)
|
||||||
extern mDNSu32 DomainNameHashValue(const domainname *const name);
|
extern mDNSu32 DomainNameHashValue(const domainname *const name);
|
||||||
|
|
||||||
extern void SetNewRData(ResourceRecord *const rr, RData *NewRData, mDNSu16 rdlength);
|
extern void SetNewRData(ResourceRecord *const rr, RData *NewRData, mDNSu16 rdlength);
|
||||||
|
|
||||||
|
|
||||||
extern const mDNSu8 *skipDomainName(const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end);
|
extern const mDNSu8 *skipDomainName(const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end);
|
||||||
|
|
||||||
extern const mDNSu8 *getDomainName(const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end,
|
extern const mDNSu8 *getDomainName(const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end,
|
||||||
domainname *const name);
|
domainname *const name);
|
||||||
|
|
||||||
extern const mDNSu8 *skipResourceRecord(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end);
|
extern const mDNSu8 *skipResourceRecord(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end);
|
||||||
|
extern const mDNSu8 *GetLargeResourceRecord(mDNS *const m, const DNSMessage * const msg, const mDNSu8 *ptr,
|
||||||
extern const mDNSu8 *GetLargeResourceRecord(mDNS *const m, const DNSMessage * const msg, const mDNSu8 *ptr,
|
const mDNSu8 * end, const mDNSInterfaceID InterfaceID, mDNSu8 RecordType, LargeCacheRecord *const largecr);
|
||||||
const mDNSu8 * end, const mDNSInterfaceID InterfaceID, mDNSu8 RecordType, LargeCacheRecord *largecr);
|
extern mDNSBool SetRData(const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *end,
|
||||||
|
LargeCacheRecord *const largecr, mDNSu16 rdlength);
|
||||||
extern const mDNSu8 *skipQuestion(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end);
|
extern const mDNSu8 *skipQuestion(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end);
|
||||||
|
|
||||||
extern const mDNSu8 *getQuestion(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end, const mDNSInterfaceID InterfaceID,
|
extern const mDNSu8 *getQuestion(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end, const mDNSInterfaceID InterfaceID,
|
||||||
DNSQuestion *question);
|
DNSQuestion *question);
|
||||||
|
|
||||||
extern const mDNSu8 *LocateAnswers(const DNSMessage *const msg, const mDNSu8 *const end);
|
extern const mDNSu8 *LocateAnswers(const DNSMessage *const msg, const mDNSu8 *const end);
|
||||||
|
|
||||||
extern const mDNSu8 *LocateAuthorities(const DNSMessage *const msg, const mDNSu8 *const end);
|
extern const mDNSu8 *LocateAuthorities(const DNSMessage *const msg, const mDNSu8 *const end);
|
||||||
|
|
||||||
extern const mDNSu8 *LocateAdditionals(const DNSMessage *const msg, const mDNSu8 *const end);
|
extern const mDNSu8 *LocateAdditionals(const DNSMessage *const msg, const mDNSu8 *const end);
|
||||||
|
extern const mDNSu8 *LocateOptRR(const DNSMessage *const msg, const mDNSu8 *const end, int minsize);
|
||||||
|
extern const rdataOPT *GetLLQOptData(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end);
|
||||||
|
extern mDNSu32 GetPktLease(mDNS *m, DNSMessage *msg, const mDNSu8 *end);
|
||||||
|
extern void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *transport,
|
||||||
|
const mDNSAddr *srcaddr, mDNSIPPort srcport,
|
||||||
|
const mDNSAddr *dstaddr, mDNSIPPort dstport, const DNSMessage *const msg, const mDNSu8 *const end);
|
||||||
|
extern mDNSBool RRAssertsNonexistence(const ResourceRecord *const rr, mDNSu16 type);
|
||||||
|
extern mDNSBool RRAssertsExistence(const ResourceRecord *const rr, mDNSu16 type);
|
||||||
|
extern mDNSBool BitmapTypeCheck(mDNSu8 *bmap, int bitmaplen, mDNSu16 type);
|
||||||
|
|
||||||
|
extern mDNSu16 swap16(mDNSu16 x);
|
||||||
|
extern mDNSu32 swap32(mDNSu32 x);
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
#if COMPILER_LIKES_PRAGMA_MARK
|
#if COMPILER_LIKES_PRAGMA_MARK
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark -
|
|
||||||
#pragma mark - Packet Sending Functions
|
#pragma mark - Packet Sending Functions
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern mStatus mDNSSendDNSMessage(const mDNS *const m, DNSMessage *const msg, mDNSu8 *end,
|
extern mStatus mDNSSendDNSMessage(mDNS *const m, DNSMessage *const msg, mDNSu8 *end,
|
||||||
mDNSInterfaceID InterfaceID, const mDNSAddr *dst, mDNSIPPort dstport, int sd, uDNS_AuthInfo *authInfo);
|
mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst,
|
||||||
|
mDNSIPPort dstport, TCPSocket *sock, DomainAuthInfo *authInfo,
|
||||||
|
mDNSBool useBackgroundTrafficClass);
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
#if COMPILER_LIKES_PRAGMA_MARK
|
#if COMPILER_LIKES_PRAGMA_MARK
|
||||||
|
@ -358,11 +285,31 @@ extern mStatus mDNSSendDNSMessage(const mDNS *const m, DNSMessage *const msg, mD
|
||||||
#pragma mark - RR List Management & Task Management
|
#pragma mark - RR List Management & Task Management
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void mDNS_Lock(mDNS *const m);
|
extern void ShowTaskSchedulingError(mDNS *const m);
|
||||||
extern void mDNS_Unlock(mDNS *const m);
|
extern void mDNS_Lock_(mDNS *const m, const char * const functionname);
|
||||||
|
extern void mDNS_Unlock_(mDNS *const m, const char * const functionname);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#if defined(_WIN32)
|
||||||
}
|
#define __func__ __FUNCTION__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define mDNS_Lock(X) mDNS_Lock_((X), __func__)
|
||||||
|
|
||||||
|
#define mDNS_Unlock(X) mDNS_Unlock_((X), __func__)
|
||||||
|
|
||||||
|
#define mDNS_CheckLock(X) { if ((X)->mDNS_busy != (X)->mDNS_reentrancy+1) \
|
||||||
|
LogMsg("%s: Lock not held! mDNS_busy (%ld) mDNS_reentrancy (%ld)", __func__, (X)->mDNS_busy, (X)->mDNS_reentrancy); }
|
||||||
|
|
||||||
|
#define mDNS_DropLockBeforeCallback() do { m->mDNS_reentrancy++; \
|
||||||
|
if (m->mDNS_busy != m->mDNS_reentrancy) LogMsg("%s: Locking Failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", __func__, m->mDNS_busy, m->mDNS_reentrancy); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define mDNS_ReclaimLockAfterCallback() do { \
|
||||||
|
if (m->mDNS_busy != m->mDNS_reentrancy) LogMsg("%s: Unlocking Failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", __func__, m->mDNS_busy, m->mDNS_reentrancy); \
|
||||||
|
m->mDNS_reentrancy--; } while (0)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // __DNSCOMMON_H_
|
#endif // __DNSCOMMON_H_
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,330 +5,315 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
File: GenLinkedList.c
|
File: GenLinkedList.c
|
||||||
|
|
||||||
Contains: implementation of generic linked lists.
|
Contains: implementation of generic linked lists.
|
||||||
|
|
||||||
Version: 1.0
|
Version: 1.0
|
||||||
Tabs: 4 spaces
|
Tabs: 4 spaces
|
||||||
|
*/
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: GenLinkedList.c,v $
|
|
||||||
Revision 1.4 2006/08/14 23:24:56 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.3 2004/04/22 21:14:42 cheshire
|
|
||||||
Fix comment spelling mistake
|
|
||||||
|
|
||||||
Revision 1.2 2004/02/05 07:41:08 cheshire
|
|
||||||
Add Log header
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
#include "GenLinkedList.h"
|
#include "GenLinkedList.h"
|
||||||
|
|
||||||
|
|
||||||
// Return the link pointer contained within element e at offset o.
|
// Return the link pointer contained within element e at offset o.
|
||||||
#define GETLINK( e, o) ( *(void**)((char*) (e) + (o)) )
|
#define GETLINK( e, o) ( *(void**)((char*) (e) + (o)) )
|
||||||
|
|
||||||
// Assign the link pointer l to element e at offset o.
|
// Assign the link pointer l to element e at offset o.
|
||||||
#define ASSIGNLINK( e, l, o) ( *((void**)((char*) (e) + (o))) = (l))
|
#define ASSIGNLINK( e, l, o) ( *((void**)((char*) (e) + (o))) = (l))
|
||||||
|
|
||||||
|
|
||||||
// GenLinkedList /////////////////////////////////////////////////////////////
|
// GenLinkedList /////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void InitLinkedList( GenLinkedList *pList, size_t linkOffset)
|
void InitLinkedList( GenLinkedList *pList, size_t linkOffset)
|
||||||
/* Initialize the block of memory pointed to by pList as a linked list. */
|
/* Initialize the block of memory pointed to by pList as a linked list. */
|
||||||
{
|
{
|
||||||
pList->Head = NULL;
|
pList->Head = NULL;
|
||||||
pList->Tail = NULL;
|
pList->Tail = NULL;
|
||||||
pList->LinkOffset = linkOffset;
|
pList->LinkOffset = linkOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AddToTail( GenLinkedList *pList, void *elem)
|
void AddToTail( GenLinkedList *pList, void *elem)
|
||||||
/* Add a linked list element to the tail of the list. */
|
/* Add a linked list element to the tail of the list. */
|
||||||
{
|
{
|
||||||
if ( pList->Tail) {
|
if ( pList->Tail) {
|
||||||
ASSIGNLINK( pList->Tail, elem, pList->LinkOffset);
|
ASSIGNLINK( pList->Tail, elem, pList->LinkOffset);
|
||||||
} else
|
} else
|
||||||
pList->Head = elem;
|
pList->Head = elem;
|
||||||
ASSIGNLINK( elem, NULL, pList->LinkOffset);
|
ASSIGNLINK( elem, NULL, pList->LinkOffset);
|
||||||
|
|
||||||
pList->Tail = elem;
|
pList->Tail = elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AddToHead( GenLinkedList *pList, void *elem)
|
void AddToHead( GenLinkedList *pList, void *elem)
|
||||||
/* Add a linked list element to the head of the list. */
|
/* Add a linked list element to the head of the list. */
|
||||||
{
|
{
|
||||||
ASSIGNLINK( elem, pList->Head, pList->LinkOffset);
|
ASSIGNLINK( elem, pList->Head, pList->LinkOffset);
|
||||||
if ( pList->Tail == NULL)
|
if ( pList->Tail == NULL)
|
||||||
pList->Tail = elem;
|
pList->Tail = elem;
|
||||||
|
|
||||||
pList->Head = elem;
|
pList->Head = elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int RemoveFromList( GenLinkedList *pList, void *elem)
|
int RemoveFromList( GenLinkedList *pList, void *elem)
|
||||||
/* Remove a linked list element from the list. Return 0 if it was not found. */
|
/* Remove a linked list element from the list. Return 0 if it was not found. */
|
||||||
/* If the element is removed, its link will be set to NULL. */
|
/* If the element is removed, its link will be set to NULL. */
|
||||||
{
|
{
|
||||||
void *iElem, *lastElem;
|
void *iElem, *lastElem;
|
||||||
|
|
||||||
for ( iElem = pList->Head, lastElem = NULL; iElem; iElem = GETLINK( iElem, pList->LinkOffset)) {
|
for ( iElem = pList->Head, lastElem = NULL; iElem; iElem = GETLINK( iElem, pList->LinkOffset)) {
|
||||||
if ( iElem == elem) {
|
if ( iElem == elem) {
|
||||||
if ( lastElem) { // somewhere past the head
|
if ( lastElem) { // somewhere past the head
|
||||||
ASSIGNLINK( lastElem, GETLINK( elem, pList->LinkOffset), pList->LinkOffset);
|
ASSIGNLINK( lastElem, GETLINK( elem, pList->LinkOffset), pList->LinkOffset);
|
||||||
} else { // at the head
|
} else { // at the head
|
||||||
pList->Head = GETLINK( elem, pList->LinkOffset);
|
pList->Head = GETLINK( elem, pList->LinkOffset);
|
||||||
}
|
}
|
||||||
if ( pList->Tail == elem)
|
if ( pList->Tail == elem)
|
||||||
pList->Tail = lastElem ? lastElem : NULL;
|
pList->Tail = lastElem ? lastElem : NULL;
|
||||||
ASSIGNLINK( elem, NULL, pList->LinkOffset); // maybe catch a stale reference bug.
|
ASSIGNLINK( elem, NULL, pList->LinkOffset); // maybe catch a stale reference bug.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
lastElem = iElem;
|
lastElem = iElem;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ReplaceElem( GenLinkedList *pList, void *elemInList, void *newElem)
|
int ReplaceElem( GenLinkedList *pList, void *elemInList, void *newElem)
|
||||||
/* Replace an element in the list with a new element, in the same position. */
|
/* Replace an element in the list with a new element, in the same position. */
|
||||||
{
|
{
|
||||||
void *iElem, *lastElem;
|
void *iElem, *lastElem;
|
||||||
|
|
||||||
if ( elemInList == NULL || newElem == NULL)
|
if ( elemInList == NULL || newElem == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for ( iElem = pList->Head, lastElem = NULL; iElem; iElem = GETLINK( iElem, pList->LinkOffset))
|
for ( iElem = pList->Head, lastElem = NULL; iElem; iElem = GETLINK( iElem, pList->LinkOffset))
|
||||||
{
|
{
|
||||||
if ( iElem == elemInList)
|
if ( iElem == elemInList)
|
||||||
{
|
{
|
||||||
ASSIGNLINK( newElem, GETLINK( elemInList, pList->LinkOffset), pList->LinkOffset);
|
ASSIGNLINK( newElem, GETLINK( elemInList, pList->LinkOffset), pList->LinkOffset);
|
||||||
if ( lastElem) // somewhere past the head
|
if ( lastElem) // somewhere past the head
|
||||||
{
|
{
|
||||||
ASSIGNLINK( lastElem, newElem, pList->LinkOffset);
|
ASSIGNLINK( lastElem, newElem, pList->LinkOffset);
|
||||||
}
|
}
|
||||||
else // at the head
|
else // at the head
|
||||||
{
|
{
|
||||||
pList->Head = newElem;
|
pList->Head = newElem;
|
||||||
}
|
}
|
||||||
if ( pList->Tail == elemInList)
|
if ( pList->Tail == elemInList)
|
||||||
pList->Tail = newElem;
|
pList->Tail = newElem;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
lastElem = iElem;
|
lastElem = iElem;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// GenDoubleLinkedList /////////////////////////////////////////////////////////
|
// GenDoubleLinkedList /////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void InitDoubleLinkedList( GenDoubleLinkedList *pList, size_t fwdLinkOffset,
|
void InitDoubleLinkedList( GenDoubleLinkedList *pList, size_t fwdLinkOffset,
|
||||||
size_t backLinkOffset)
|
size_t backLinkOffset)
|
||||||
/* Initialize the block of memory pointed to by pList as a double linked list. */
|
/* Initialize the block of memory pointed to by pList as a double linked list. */
|
||||||
{
|
{
|
||||||
pList->Head = NULL;
|
pList->Head = NULL;
|
||||||
pList->Tail = NULL;
|
pList->Tail = NULL;
|
||||||
pList->FwdLinkOffset = fwdLinkOffset;
|
pList->FwdLinkOffset = fwdLinkOffset;
|
||||||
pList->BackLinkOffset = backLinkOffset;
|
pList->BackLinkOffset = backLinkOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DLLAddToHead( GenDoubleLinkedList *pList, void *elem)
|
void DLLAddToHead( GenDoubleLinkedList *pList, void *elem)
|
||||||
/* Add a linked list element to the head of the list. */
|
/* Add a linked list element to the head of the list. */
|
||||||
{
|
{
|
||||||
void *pNext;
|
void *pNext;
|
||||||
|
|
||||||
pNext = pList->Head;
|
pNext = pList->Head;
|
||||||
|
|
||||||
// fix up the forward links
|
// fix up the forward links
|
||||||
ASSIGNLINK( elem, pList->Head, pList->FwdLinkOffset);
|
ASSIGNLINK( elem, pList->Head, pList->FwdLinkOffset);
|
||||||
pList->Head = elem;
|
pList->Head = elem;
|
||||||
|
|
||||||
// fix up the backward links
|
// fix up the backward links
|
||||||
if ( pNext) {
|
if ( pNext) {
|
||||||
ASSIGNLINK( pNext, elem, pList->BackLinkOffset);
|
ASSIGNLINK( pNext, elem, pList->BackLinkOffset);
|
||||||
} else
|
} else
|
||||||
pList->Tail = elem;
|
pList->Tail = elem;
|
||||||
ASSIGNLINK( elem, NULL, pList->BackLinkOffset);
|
ASSIGNLINK( elem, NULL, pList->BackLinkOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DLLRemoveFromList( GenDoubleLinkedList *pList, void *elem)
|
void DLLRemoveFromList( GenDoubleLinkedList *pList, void *elem)
|
||||||
/* Remove a linked list element from the list. */
|
/* Remove a linked list element from the list. */
|
||||||
/* When the element is removed, its link will be set to NULL. */
|
/* When the element is removed, its link will be set to NULL. */
|
||||||
{
|
{
|
||||||
void *pNext, *pPrev;
|
void *pNext, *pPrev;
|
||||||
|
|
||||||
pNext = GETLINK( elem, pList->FwdLinkOffset);
|
pNext = GETLINK( elem, pList->FwdLinkOffset);
|
||||||
pPrev = GETLINK( elem, pList->BackLinkOffset);
|
pPrev = GETLINK( elem, pList->BackLinkOffset);
|
||||||
|
|
||||||
// fix up the forward links
|
// fix up the forward links
|
||||||
if ( pPrev)
|
if ( pPrev)
|
||||||
ASSIGNLINK( pPrev, pNext, pList->FwdLinkOffset);
|
ASSIGNLINK( pPrev, pNext, pList->FwdLinkOffset);
|
||||||
else
|
else
|
||||||
pList->Head = pNext;
|
pList->Head = pNext;
|
||||||
|
|
||||||
// fix up the backward links
|
|
||||||
if ( pNext)
|
|
||||||
ASSIGNLINK( pNext, pPrev, pList->BackLinkOffset);
|
|
||||||
else
|
|
||||||
pList->Tail = pPrev;
|
|
||||||
|
|
||||||
ASSIGNLINK( elem, NULL, pList->FwdLinkOffset);
|
// fix up the backward links
|
||||||
ASSIGNLINK( elem, NULL, pList->BackLinkOffset);
|
if ( pNext)
|
||||||
|
ASSIGNLINK( pNext, pPrev, pList->BackLinkOffset);
|
||||||
|
else
|
||||||
|
pList->Tail = pPrev;
|
||||||
|
|
||||||
|
ASSIGNLINK( elem, NULL, pList->FwdLinkOffset);
|
||||||
|
ASSIGNLINK( elem, NULL, pList->BackLinkOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// GenLinkedOffsetList /////////////////////////////////////////////////////
|
// GenLinkedOffsetList /////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Extract the Next offset from element
|
// Extract the Next offset from element
|
||||||
#define GETOFFSET( e, o) ( *(size_t*)((char*) (e) + (o)) )
|
#define GETOFFSET( e, o) ( *(size_t*)((char*) (e) + (o)) )
|
||||||
|
|
||||||
static void AssignOffsetLink( void *elem, void *link, size_t linkOffset);
|
static void AssignOffsetLink( void *elem, void *link, size_t linkOffset);
|
||||||
|
|
||||||
|
|
||||||
static void AssignOffsetLink( void *elem, void *link, size_t linkOffset)
|
static void AssignOffsetLink( void *elem, void *link, size_t linkOffset)
|
||||||
// Assign link to elem as an offset from elem. Assign 0 to elem if link is NULL.
|
// Assign link to elem as an offset from elem. Assign 0 to elem if link is NULL.
|
||||||
{
|
{
|
||||||
GETOFFSET( elem, linkOffset) = link ? (size_t) link - (size_t) elem : 0;
|
GETOFFSET( elem, linkOffset) = link ? (size_t) link - (size_t) elem : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *GetHeadPtr( GenLinkedOffsetList *pList)
|
void *GetHeadPtr( GenLinkedOffsetList *pList)
|
||||||
/* Return a pointer to the head element of a list, or NULL if none. */
|
/* Return a pointer to the head element of a list, or NULL if none. */
|
||||||
{
|
{
|
||||||
return pList->Head ? ( (char*) (pList) + pList->Head) : NULL;
|
return pList->Head ? ( (char*) (pList) + pList->Head) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *GetTailPtr( GenLinkedOffsetList *pList)
|
void *GetTailPtr( GenLinkedOffsetList *pList)
|
||||||
/* Return a pointer to the tail element of a list, or NULL if none. */
|
/* Return a pointer to the tail element of a list, or NULL if none. */
|
||||||
{
|
{
|
||||||
return pList->Tail ? ( (char*) (pList) + pList->Tail) : NULL;
|
return pList->Tail ? ( (char*) (pList) + pList->Tail) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *GetOffsetLink( GenLinkedOffsetList *pList, void *elem)
|
void *GetOffsetLink( GenLinkedOffsetList *pList, void *elem)
|
||||||
/* Return the link pointer contained within element e for pList, or NULL if it is 0. */
|
/* Return the link pointer contained within element e for pList, or NULL if it is 0. */
|
||||||
{
|
{
|
||||||
size_t nextOffset;
|
size_t nextOffset;
|
||||||
|
|
||||||
nextOffset = GETOFFSET( elem, pList->LinkOffset);
|
nextOffset = GETOFFSET( elem, pList->LinkOffset);
|
||||||
|
|
||||||
return nextOffset ? (char*) elem + nextOffset : NULL;
|
return nextOffset ? (char*) elem + nextOffset : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InitLinkedOffsetList( GenLinkedOffsetList *pList, size_t linkOffset)
|
void InitLinkedOffsetList( GenLinkedOffsetList *pList, size_t linkOffset)
|
||||||
/* Initialize the block of memory pointed to by pList as a linked list. */
|
/* Initialize the block of memory pointed to by pList as a linked list. */
|
||||||
{
|
{
|
||||||
pList->Head = 0;
|
pList->Head = 0;
|
||||||
pList->Tail = 0;
|
pList->Tail = 0;
|
||||||
pList->LinkOffset = linkOffset;
|
pList->LinkOffset = linkOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OffsetAddToTail( GenLinkedOffsetList *pList, void *elem)
|
void OffsetAddToTail( GenLinkedOffsetList *pList, void *elem)
|
||||||
/* Add a linked list element to the tail of the list. */
|
/* Add a linked list element to the tail of the list. */
|
||||||
{
|
{
|
||||||
if ( pList->Tail) {
|
if ( pList->Tail) {
|
||||||
AssignOffsetLink( GetTailPtr( pList), elem, pList->LinkOffset);
|
AssignOffsetLink( GetTailPtr( pList), elem, pList->LinkOffset);
|
||||||
} else
|
} else
|
||||||
pList->Head = (size_t) elem - (size_t) pList;
|
pList->Head = (size_t) elem - (size_t) pList;
|
||||||
AssignOffsetLink( elem, NULL, pList->LinkOffset);
|
AssignOffsetLink( elem, NULL, pList->LinkOffset);
|
||||||
|
|
||||||
pList->Tail = (size_t) elem - (size_t) pList;
|
pList->Tail = (size_t) elem - (size_t) pList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OffsetAddToHead( GenLinkedOffsetList *pList, void *elem)
|
void OffsetAddToHead( GenLinkedOffsetList *pList, void *elem)
|
||||||
/* Add a linked list element to the head of the list. */
|
/* Add a linked list element to the head of the list. */
|
||||||
{
|
{
|
||||||
AssignOffsetLink( elem, GetHeadPtr( pList), pList->LinkOffset);
|
AssignOffsetLink( elem, GetHeadPtr( pList), pList->LinkOffset);
|
||||||
if ( pList->Tail == 0)
|
if ( pList->Tail == 0)
|
||||||
pList->Tail = (size_t) elem - (size_t) pList;
|
pList->Tail = (size_t) elem - (size_t) pList;
|
||||||
|
|
||||||
pList->Head = (size_t) elem - (size_t) pList;
|
pList->Head = (size_t) elem - (size_t) pList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int OffsetRemoveFromList( GenLinkedOffsetList *pList, void *elem)
|
int OffsetRemoveFromList( GenLinkedOffsetList *pList, void *elem)
|
||||||
/* Remove a linked list element from the list. Return 0 if it was not found. */
|
/* Remove a linked list element from the list. Return 0 if it was not found. */
|
||||||
/* If the element is removed, its link will be set to NULL. */
|
/* If the element is removed, its link will be set to NULL. */
|
||||||
{
|
{
|
||||||
void *iElem, *lastElem;
|
void *iElem, *lastElem;
|
||||||
|
|
||||||
for ( iElem = GetHeadPtr( pList), lastElem = NULL; iElem;
|
for ( iElem = GetHeadPtr( pList), lastElem = NULL; iElem;
|
||||||
iElem = GetOffsetLink( pList, iElem))
|
iElem = GetOffsetLink( pList, iElem))
|
||||||
{
|
{
|
||||||
if ( iElem == elem) {
|
if ( iElem == elem) {
|
||||||
if ( lastElem) { // somewhere past the head
|
if ( lastElem) { // somewhere past the head
|
||||||
AssignOffsetLink( lastElem, GetOffsetLink( pList, elem), pList->LinkOffset);
|
AssignOffsetLink( lastElem, GetOffsetLink( pList, elem), pList->LinkOffset);
|
||||||
} else { // at the head
|
} else { // at the head
|
||||||
iElem = GetOffsetLink( pList, elem);
|
iElem = GetOffsetLink( pList, elem);
|
||||||
pList->Head = iElem ? (size_t) iElem - (size_t) pList : 0;
|
pList->Head = iElem ? (size_t) iElem - (size_t) pList : 0;
|
||||||
}
|
}
|
||||||
if ( GetTailPtr( pList) == elem)
|
if ( GetTailPtr( pList) == elem)
|
||||||
pList->Tail = lastElem ? (size_t) lastElem - (size_t) pList : 0;
|
pList->Tail = lastElem ? (size_t) lastElem - (size_t) pList : 0;
|
||||||
AssignOffsetLink( elem, NULL, pList->LinkOffset); // maybe catch a stale reference bug.
|
AssignOffsetLink( elem, NULL, pList->LinkOffset); // maybe catch a stale reference bug.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
lastElem = iElem;
|
lastElem = iElem;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int OffsetReplaceElem( GenLinkedOffsetList *pList, void *elemInList, void *newElem)
|
int OffsetReplaceElem( GenLinkedOffsetList *pList, void *elemInList, void *newElem)
|
||||||
/* Replace an element in the list with a new element, in the same position. */
|
/* Replace an element in the list with a new element, in the same position. */
|
||||||
{
|
{
|
||||||
void *iElem, *lastElem;
|
void *iElem, *lastElem;
|
||||||
|
|
||||||
if ( elemInList == NULL || newElem == NULL)
|
if ( elemInList == NULL || newElem == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for ( iElem = GetHeadPtr( pList), lastElem = NULL; iElem;
|
for ( iElem = GetHeadPtr( pList), lastElem = NULL; iElem;
|
||||||
iElem = GetOffsetLink( pList, iElem))
|
iElem = GetOffsetLink( pList, iElem))
|
||||||
{
|
{
|
||||||
if ( iElem == elemInList)
|
if ( iElem == elemInList)
|
||||||
{
|
{
|
||||||
AssignOffsetLink( newElem, GetOffsetLink( pList, elemInList), pList->LinkOffset);
|
AssignOffsetLink( newElem, GetOffsetLink( pList, elemInList), pList->LinkOffset);
|
||||||
if ( lastElem) // somewhere past the head
|
if ( lastElem) // somewhere past the head
|
||||||
{
|
{
|
||||||
AssignOffsetLink( lastElem, newElem, pList->LinkOffset);
|
AssignOffsetLink( lastElem, newElem, pList->LinkOffset);
|
||||||
}
|
}
|
||||||
else // at the head
|
else // at the head
|
||||||
{
|
{
|
||||||
pList->Head = (size_t) newElem - (size_t) pList;
|
pList->Head = (size_t) newElem - (size_t) pList;
|
||||||
}
|
}
|
||||||
if ( GetTailPtr( pList) == elemInList)
|
if ( GetTailPtr( pList) == elemInList)
|
||||||
pList->Tail = (size_t) newElem - (size_t) pList;
|
pList->Tail = (size_t) newElem - (size_t) pList;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
lastElem = iElem;
|
lastElem = iElem;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,34 +5,15 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
*/
|
||||||
File: GenLinkedList.c
|
|
||||||
|
|
||||||
Contains: interface to generic linked lists.
|
|
||||||
|
|
||||||
Version: 1.0
|
|
||||||
Tabs: 4 spaces
|
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: GenLinkedList.h,v $
|
|
||||||
Revision 1.3 2006/08/14 23:24:56 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.2 2004/02/05 07:41:08 cheshire
|
|
||||||
Add Log header
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
#ifndef __GenLinkedList__
|
#ifndef __GenLinkedList__
|
||||||
#define __GenLinkedList__
|
#define __GenLinkedList__
|
||||||
|
@ -41,69 +22,69 @@ Add Log header
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|
||||||
struct GenLinkedList
|
struct GenLinkedList
|
||||||
{
|
{
|
||||||
void *Head,
|
void *Head,
|
||||||
*Tail;
|
*Tail;
|
||||||
size_t LinkOffset;
|
size_t LinkOffset;
|
||||||
};
|
};
|
||||||
typedef struct GenLinkedList GenLinkedList;
|
typedef struct GenLinkedList GenLinkedList;
|
||||||
|
|
||||||
|
|
||||||
void InitLinkedList( GenLinkedList *pList, size_t linkOffset);
|
void InitLinkedList( GenLinkedList *pList, size_t linkOffset);
|
||||||
|
|
||||||
void AddToHead( GenLinkedList *pList, void *elem);
|
void AddToHead( GenLinkedList *pList, void *elem);
|
||||||
void AddToTail( GenLinkedList *pList, void *elem);
|
void AddToTail( GenLinkedList *pList, void *elem);
|
||||||
|
|
||||||
int RemoveFromList( GenLinkedList *pList, void *elem);
|
int RemoveFromList( GenLinkedList *pList, void *elem);
|
||||||
|
|
||||||
int ReplaceElem( GenLinkedList *pList, void *elemInList, void *newElem);
|
int ReplaceElem( GenLinkedList *pList, void *elemInList, void *newElem);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct GenDoubleLinkedList
|
struct GenDoubleLinkedList
|
||||||
{
|
{
|
||||||
void *Head,
|
void *Head,
|
||||||
*Tail;
|
*Tail;
|
||||||
size_t FwdLinkOffset,
|
size_t FwdLinkOffset,
|
||||||
BackLinkOffset;
|
BackLinkOffset;
|
||||||
};
|
};
|
||||||
typedef struct GenDoubleLinkedList GenDoubleLinkedList;
|
typedef struct GenDoubleLinkedList GenDoubleLinkedList;
|
||||||
|
|
||||||
|
|
||||||
void InitDoubleLinkedList( GenDoubleLinkedList *pList, size_t fwdLinkOffset,
|
void InitDoubleLinkedList( GenDoubleLinkedList *pList, size_t fwdLinkOffset,
|
||||||
size_t backLinkOffset);
|
size_t backLinkOffset);
|
||||||
|
|
||||||
void DLLAddToHead( GenDoubleLinkedList *pList, void *elem);
|
void DLLAddToHead( GenDoubleLinkedList *pList, void *elem);
|
||||||
|
|
||||||
void DLLRemoveFromList( GenDoubleLinkedList *pList, void *elem);
|
void DLLRemoveFromList( GenDoubleLinkedList *pList, void *elem);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* A GenLinkedOffsetList is like a GenLinkedList that stores the *Next field as a signed */
|
/* A GenLinkedOffsetList is like a GenLinkedList that stores the *Next field as a signed */
|
||||||
/* offset from the address of the beginning of the element, rather than as a pointer. */
|
/* offset from the address of the beginning of the element, rather than as a pointer. */
|
||||||
|
|
||||||
struct GenLinkedOffsetList
|
struct GenLinkedOffsetList
|
||||||
{
|
{
|
||||||
size_t Head,
|
size_t Head,
|
||||||
Tail;
|
Tail;
|
||||||
size_t LinkOffset;
|
size_t LinkOffset;
|
||||||
};
|
};
|
||||||
typedef struct GenLinkedOffsetList GenLinkedOffsetList;
|
typedef struct GenLinkedOffsetList GenLinkedOffsetList;
|
||||||
|
|
||||||
|
|
||||||
void InitLinkedOffsetList( GenLinkedOffsetList *pList, size_t linkOffset);
|
void InitLinkedOffsetList( GenLinkedOffsetList *pList, size_t linkOffset);
|
||||||
|
|
||||||
void *GetHeadPtr( GenLinkedOffsetList *pList);
|
void *GetHeadPtr( GenLinkedOffsetList *pList);
|
||||||
void *GetTailPtr( GenLinkedOffsetList *pList);
|
void *GetTailPtr( GenLinkedOffsetList *pList);
|
||||||
void *GetOffsetLink( GenLinkedOffsetList *pList, void *elem);
|
void *GetOffsetLink( GenLinkedOffsetList *pList, void *elem);
|
||||||
|
|
||||||
void OffsetAddToHead( GenLinkedOffsetList *pList, void *elem);
|
void OffsetAddToHead( GenLinkedOffsetList *pList, void *elem);
|
||||||
void OffsetAddToTail( GenLinkedOffsetList *pList, void *elem);
|
void OffsetAddToTail( GenLinkedOffsetList *pList, void *elem);
|
||||||
|
|
||||||
int OffsetRemoveFromList( GenLinkedOffsetList *pList, void *elem);
|
int OffsetRemoveFromList( GenLinkedOffsetList *pList, void *elem);
|
||||||
|
|
||||||
int OffsetReplaceElem( GenLinkedOffsetList *pList, void *elemInList, void *newElem);
|
int OffsetReplaceElem( GenLinkedOffsetList *pList, void *elemInList, void *newElem);
|
||||||
|
|
||||||
|
|
||||||
#endif // __GenLinkedList__
|
#endif // __GenLinkedList__
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#
|
#
|
||||||
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||||
# Use is subject to license terms.
|
# Use is subject to license terms.
|
||||||
|
# Copyright 2016 Toomas Soome <tsoome@me.com>
|
||||||
#
|
#
|
||||||
|
|
||||||
PROG= mdnsd
|
PROG= mdnsd
|
||||||
|
@ -32,15 +33,15 @@ CMN_SRCS= $(CMN_OBJS:%.o=$(CMN_DIR)/%.c)
|
||||||
LOCAL_OBJS= DNSCommon.o DNSDigest.o GenLinkedList.o \
|
LOCAL_OBJS= DNSCommon.o DNSDigest.o GenLinkedList.o \
|
||||||
PlatformCommon.o PosixDaemon.o \
|
PlatformCommon.o PosixDaemon.o \
|
||||||
mDNS.o mDNSDebug.o mDNSPosix.o mDNSUNP.o \
|
mDNS.o mDNSDebug.o mDNSPosix.o mDNSUNP.o \
|
||||||
uDNS.o uds_daemon.o
|
uDNS.o uds_daemon.o CryptoAlg.o anonymous.o
|
||||||
LOCAL_SRCS= $(LOCAL_OBJS:%.o=%.c)
|
LOCAL_SRCS= $(LOCAL_OBJS:%.o=%.c)
|
||||||
|
|
||||||
SRCS= $(LOCAL_SRCS) $(CMN_SRCS)
|
SRCS= $(LOCAL_SRCS) $(CMN_SRCS)
|
||||||
OBJS= $(LOCAL_OBJS) $(CMN_OBJS)
|
OBJS= $(LOCAL_OBJS) $(CMN_OBJS)
|
||||||
|
|
||||||
|
|
||||||
MDNSFLAGS= -DNOT_HAVE_DAEMON -DNOT_HAVE_SA_LEN \
|
MDNSFLAGS= -DNOT_HAVE_SA_LEN \
|
||||||
-DLOG_PERROR=0 -DHAVE_SOLARIS \
|
-DLOG_PERROR=0 -DHAVE_SOLARIS -DTARGET_OS_SOLARIS \
|
||||||
-D_XPG4_2 -D__EXTENSIONS__ -DHAVE_BROKEN_RECVIF_NAME \
|
-D_XPG4_2 -D__EXTENSIONS__ -DHAVE_BROKEN_RECVIF_NAME \
|
||||||
-DHAVE_IPV6=1 -Dasm=__asm -DMDNSD_NOROOT \
|
-DHAVE_IPV6=1 -Dasm=__asm -DMDNSD_NOROOT \
|
||||||
-DPID_FILE=\"\" -DMDNSD_USER=\"noaccess\" \
|
-DPID_FILE=\"\" -DMDNSD_USER=\"noaccess\" \
|
||||||
|
|
|
@ -5,134 +5,195 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: PlatformCommon.c,v $
|
|
||||||
Revision 1.7 2006/08/14 23:24:56 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.6 2005/04/08 21:30:16 ksekar
|
|
||||||
<rdar://problem/4007457> Compiling problems with mDNSResponder-98 on Solaris/Sparc v9
|
|
||||||
Patch submitted by Bernd Kuhls
|
|
||||||
|
|
||||||
Revision 1.5 2005/02/01 19:33:30 ksekar
|
|
||||||
<rdar://problem/3985239> Keychain format too restrictive
|
|
||||||
|
|
||||||
Revision 1.4 2005/01/19 19:19:21 ksekar
|
|
||||||
<rdar://problem/3960191> Need a way to turn off domain discovery
|
|
||||||
|
|
||||||
Revision 1.3 2004/12/13 17:46:52 cheshire
|
|
||||||
Use sizeof(buf) instead of fixed constant 1024
|
|
||||||
|
|
||||||
Revision 1.2 2004/12/01 03:30:29 cheshire
|
|
||||||
<rdar://problem/3889346> Add Unicast DNS support to mDNSPosix
|
|
||||||
|
|
||||||
Revision 1.1 2004/12/01 01:51:35 cheshire
|
|
||||||
Move ReadDDNSSettingsFromConfFile() from mDNSMacOSX.c to PlatformCommon.c
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
#include <stdio.h> // Needed for fopen() etc.
|
||||||
|
#include <unistd.h> // Needed for close()
|
||||||
|
#include <string.h> // Needed for strlen() etc.
|
||||||
|
#include <errno.h> // Needed for errno etc.
|
||||||
|
#include <sys/socket.h> // Needed for socket() etc.
|
||||||
|
#include <netinet/in.h> // Needed for sockaddr_in
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
#include <stdio.h> // Needed for fopen() etc.
|
#include "mDNSEmbeddedAPI.h" // Defines the interface provided to the client layer above
|
||||||
#include <unistd.h> // Needed for close()
|
#include "DNSCommon.h"
|
||||||
#include <string.h> // Needed for strlen() etc.
|
|
||||||
#include <errno.h> // Needed for errno etc.
|
|
||||||
#include <sys/socket.h> // Needed for socket() etc.
|
|
||||||
#include <netinet/in.h> // Needed for sockaddr_in
|
|
||||||
|
|
||||||
#include "mDNSEmbeddedAPI.h" // Defines the interface provided to the client layer above
|
|
||||||
#include "PlatformCommon.h"
|
#include "PlatformCommon.h"
|
||||||
|
|
||||||
#ifdef NOT_HAVE_SOCKLEN_T
|
#ifdef NOT_HAVE_SOCKLEN_T
|
||||||
typedef unsigned int socklen_t;
|
typedef unsigned int socklen_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Bind a UDP socket to a global destination to find the default route's interface address
|
// Bind a UDP socket to find the source address to a destination
|
||||||
mDNSexport void FindDefaultRouteIP(mDNSAddr *a)
|
mDNSexport void mDNSPlatformSourceAddrForDest(mDNSAddr *const src, const mDNSAddr *const dst)
|
||||||
{
|
{
|
||||||
struct sockaddr_in addr;
|
union { struct sockaddr s; struct sockaddr_in a4; struct sockaddr_in6 a6; } addr;
|
||||||
socklen_t len = sizeof(addr);
|
socklen_t len = sizeof(addr);
|
||||||
int sock = socket(AF_INET,SOCK_DGRAM,0);
|
socklen_t inner_len = 0;
|
||||||
a->type = mDNSAddrType_None;
|
int sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (sock == -1) return;
|
src->type = mDNSAddrType_None;
|
||||||
addr.sin_family = AF_INET;
|
if (sock == -1) return;
|
||||||
addr.sin_port = 1; // Not important, any port and public address will do
|
if (dst->type == mDNSAddrType_IPv4)
|
||||||
addr.sin_addr.s_addr = 0x11111111;
|
{
|
||||||
if ((connect(sock,(const struct sockaddr*)&addr,sizeof(addr))) == -1) { close(sock); return; }
|
inner_len = sizeof(addr.a4);
|
||||||
if ((getsockname(sock,(struct sockaddr*)&addr, &len)) == -1) { close(sock); return; }
|
#ifndef NOT_HAVE_SA_LEN
|
||||||
close(sock);
|
addr.a4.sin_len = inner_len;
|
||||||
a->type = mDNSAddrType_IPv4;
|
#endif
|
||||||
a->ip.v4.NotAnInteger = addr.sin_addr.s_addr;
|
addr.a4.sin_family = AF_INET;
|
||||||
}
|
addr.a4.sin_port = 1; // Not important, any port will do
|
||||||
|
addr.a4.sin_addr.s_addr = dst->ip.v4.NotAnInteger;
|
||||||
|
}
|
||||||
|
else if (dst->type == mDNSAddrType_IPv6)
|
||||||
|
{
|
||||||
|
inner_len = sizeof(addr.a6);
|
||||||
|
#ifndef NOT_HAVE_SA_LEN
|
||||||
|
addr.a6.sin6_len = inner_len;
|
||||||
|
#endif
|
||||||
|
addr.a6.sin6_family = AF_INET6;
|
||||||
|
addr.a6.sin6_flowinfo = 0;
|
||||||
|
addr.a6.sin6_port = 1; // Not important, any port will do
|
||||||
|
addr.a6.sin6_addr = *(struct in6_addr*)&dst->ip.v6;
|
||||||
|
addr.a6.sin6_scope_id = 0;
|
||||||
|
}
|
||||||
|
else return;
|
||||||
|
|
||||||
|
if ((connect(sock, &addr.s, inner_len)) < 0)
|
||||||
|
{ if (errno != ENETUNREACH) LogMsg("mDNSPlatformSourceAddrForDest: connect %#a failed errno %d (%s)", dst, errno, strerror(errno)); goto exit; }
|
||||||
|
|
||||||
|
if ((getsockname(sock, &addr.s, &len)) < 0)
|
||||||
|
{ LogMsg("mDNSPlatformSourceAddrForDest: getsockname failed errno %d (%s)", errno, strerror(errno)); goto exit; }
|
||||||
|
|
||||||
|
src->type = dst->type;
|
||||||
|
if (dst->type == mDNSAddrType_IPv4) src->ip.v4.NotAnInteger = addr.a4.sin_addr.s_addr;
|
||||||
|
else src->ip.v6 = *(mDNSv6Addr*)&addr.a6.sin6_addr;
|
||||||
|
exit:
|
||||||
|
close(sock);
|
||||||
|
}
|
||||||
|
|
||||||
// dst must be at least MAX_ESCAPED_DOMAIN_NAME bytes, and option must be less than 32 bytes in length
|
// dst must be at least MAX_ESCAPED_DOMAIN_NAME bytes, and option must be less than 32 bytes in length
|
||||||
mDNSlocal mDNSBool GetConfigOption(char *dst, const char *option, FILE *f)
|
mDNSlocal mDNSBool GetConfigOption(char *dst, const char *option, FILE *f)
|
||||||
{
|
{
|
||||||
char buf[32+1+MAX_ESCAPED_DOMAIN_NAME]; // Option name, one space, option value
|
char buf[32+1+MAX_ESCAPED_DOMAIN_NAME]; // Option name, one space, option value
|
||||||
unsigned int len = strlen(option);
|
unsigned int len = strlen(option);
|
||||||
if (len + 1 + MAX_ESCAPED_DOMAIN_NAME > sizeof(buf)-1) { LogMsg("GetConfigOption: option %s too long", option); return mDNSfalse; }
|
if (len + 1 + MAX_ESCAPED_DOMAIN_NAME > sizeof(buf)-1) { LogMsg("GetConfigOption: option %s too long", option); return mDNSfalse; }
|
||||||
fseek(f, 0, SEEK_SET); // set position to beginning of stream
|
fseek(f, 0, SEEK_SET); // set position to beginning of stream
|
||||||
while (fgets(buf, sizeof(buf), f)) // Read at most sizeof(buf)-1 bytes from file, and append '\0' C-string terminator
|
while (fgets(buf, sizeof(buf), f)) // Read at most sizeof(buf)-1 bytes from file, and append '\0' C-string terminator
|
||||||
{
|
{
|
||||||
if (!strncmp(buf, option, len))
|
if (!strncmp(buf, option, len))
|
||||||
{
|
{
|
||||||
strncpy(dst, buf + len + 1, MAX_ESCAPED_DOMAIN_NAME-1);
|
strncpy(dst, buf + len + 1, MAX_ESCAPED_DOMAIN_NAME-1);
|
||||||
if (dst[MAX_ESCAPED_DOMAIN_NAME-1]) dst[MAX_ESCAPED_DOMAIN_NAME-1] = '\0';
|
if (dst[MAX_ESCAPED_DOMAIN_NAME-1]) dst[MAX_ESCAPED_DOMAIN_NAME-1] = '\0';
|
||||||
len = strlen(dst);
|
len = strlen(dst);
|
||||||
if (len && dst[len-1] == '\n') dst[len-1] = '\0'; // chop newline
|
if (len && dst[len-1] == '\n') dst[len-1] = '\0'; // chop newline
|
||||||
return mDNStrue;
|
return mDNStrue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debugf("Option %s not set", option);
|
debugf("Option %s not set", option);
|
||||||
return mDNSfalse;
|
return mDNSfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
mDNSexport void ReadDDNSSettingsFromConfFile(mDNS *const m, const char *const filename, domainname *const hostname, domainname *const domain, mDNSBool *DomainDiscoveryDisabled)
|
mDNSexport void ReadDDNSSettingsFromConfFile(mDNS *const m, const char *const filename, domainname *const hostname, domainname *const domain, mDNSBool *DomainDiscoveryDisabled)
|
||||||
{
|
{
|
||||||
char buf [MAX_ESCAPED_DOMAIN_NAME];
|
char buf[MAX_ESCAPED_DOMAIN_NAME] = "";
|
||||||
char secret[MAX_ESCAPED_DOMAIN_NAME] = "";
|
mStatus err;
|
||||||
mStatus err;
|
FILE *f = fopen(filename, "r");
|
||||||
FILE *f = fopen(filename, "r");
|
|
||||||
|
|
||||||
if (hostname) hostname->c[0] = 0;
|
if (hostname) hostname->c[0] = 0;
|
||||||
if (domain) domain->c[0] = 0;
|
if (domain) domain->c[0] = 0;
|
||||||
if (DomainDiscoveryDisabled) *DomainDiscoveryDisabled = mDNSfalse;
|
if (DomainDiscoveryDisabled) *DomainDiscoveryDisabled = mDNSfalse;
|
||||||
|
|
||||||
if (f)
|
if (f)
|
||||||
{
|
{
|
||||||
if (DomainDiscoveryDisabled && GetConfigOption(buf, "DomainDiscoveryDisabled", f) && !strcasecmp(buf, "true")) *DomainDiscoveryDisabled = mDNStrue;
|
if (DomainDiscoveryDisabled && GetConfigOption(buf, "DomainDiscoveryDisabled", f) && !strcasecmp(buf, "true")) *DomainDiscoveryDisabled = mDNStrue;
|
||||||
if (hostname && GetConfigOption(buf, "hostname", f) && !MakeDomainNameFromDNSNameString(hostname, buf)) goto badf;
|
if (hostname && GetConfigOption(buf, "hostname", f) && !MakeDomainNameFromDNSNameString(hostname, buf)) goto badf;
|
||||||
if (domain && GetConfigOption(buf, "zone", f) && !MakeDomainNameFromDNSNameString(domain, buf)) goto badf;
|
if (domain && GetConfigOption(buf, "zone", f) && !MakeDomainNameFromDNSNameString(domain, buf)) goto badf;
|
||||||
GetConfigOption(secret, "secret-64", f); // failure means no authentication
|
buf[0] = 0;
|
||||||
fclose(f);
|
GetConfigOption(buf, "secret-64", f); // failure means no authentication
|
||||||
f = NULL;
|
fclose(f);
|
||||||
}
|
f = NULL;
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
if (errno != ENOENT) LogMsg("ERROR: Config file exists, but cannot be opened.");
|
{
|
||||||
return;
|
if (errno != ENOENT) LogMsg("ERROR: Config file exists, but cannot be opened.");
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (domain && domain->c[0] && secret[0])
|
if (domain && domain->c[0] && buf[0])
|
||||||
{
|
{
|
||||||
// for now we assume keyname = service reg domain and we use same key for service and hostname registration
|
DomainAuthInfo *info = (DomainAuthInfo*)mDNSPlatformMemAllocate(sizeof(*info));
|
||||||
err = mDNS_SetSecretForZone(m, domain, domain, secret);
|
// for now we assume keyname = service reg domain and we use same key for service and hostname registration
|
||||||
if (err) LogMsg("ERROR: mDNS_SetSecretForZone returned %d for domain %##s", err, domain->c);
|
err = mDNS_SetSecretForDomain(m, info, domain, domain, buf, NULL, 0, mDNSfalse);
|
||||||
}
|
if (err) LogMsg("ERROR: mDNS_SetSecretForDomain returned %d for domain %##s", err, domain->c);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
badf:
|
badf:
|
||||||
LogMsg("ERROR: malformatted config file");
|
LogMsg("ERROR: malformatted config file");
|
||||||
if (f) fclose(f);
|
if (f) fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MDNS_DEBUGMSGS
|
||||||
|
mDNSexport void mDNSPlatformWriteDebugMsg(const char *msg)
|
||||||
|
{
|
||||||
|
fprintf(stderr,"%s\n", msg);
|
||||||
|
fflush(stderr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mDNSexport void mDNSPlatformWriteLogMsg(const char *ident, const char *buffer, mDNSLogLevel_t loglevel)
|
||||||
|
{
|
||||||
|
#if APPLE_OSX_mDNSResponder && LogTimeStamps
|
||||||
|
extern mDNS mDNSStorage;
|
||||||
|
extern mDNSu32 mDNSPlatformClockDivisor;
|
||||||
|
mDNSs32 t = mDNSStorage.timenow ? mDNSStorage.timenow : mDNSPlatformClockDivisor ? mDNS_TimeNow_NoLock(&mDNSStorage) : 0;
|
||||||
|
int ms = ((t < 0) ? -t : t) % 1000;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (mDNS_DebugMode) // In debug mode we write to stderr
|
||||||
|
{
|
||||||
|
#if APPLE_OSX_mDNSResponder && LogTimeStamps
|
||||||
|
if (ident && ident[0] && mDNSPlatformClockDivisor)
|
||||||
|
fprintf(stderr,"%8d.%03d: %s\n", (int)(t/1000), ms, buffer);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
fprintf(stderr,"%s\n", buffer);
|
||||||
|
fflush(stderr);
|
||||||
|
}
|
||||||
|
else // else, in production mode, we write to syslog
|
||||||
|
{
|
||||||
|
static int log_inited = 0;
|
||||||
|
|
||||||
|
int syslog_level = LOG_ERR;
|
||||||
|
switch (loglevel)
|
||||||
|
{
|
||||||
|
case MDNS_LOG_MSG: syslog_level = LOG_ERR; break;
|
||||||
|
case MDNS_LOG_OPERATION: syslog_level = LOG_WARNING; break;
|
||||||
|
case MDNS_LOG_SPS: syslog_level = LOG_NOTICE; break;
|
||||||
|
case MDNS_LOG_INFO: syslog_level = LOG_INFO; break;
|
||||||
|
case MDNS_LOG_DEBUG: syslog_level = LOG_DEBUG; break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Unknown loglevel %d, assuming LOG_ERR\n", loglevel);
|
||||||
|
fflush(stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!log_inited) { openlog(ident, LOG_CONS, LOG_DAEMON); log_inited++; }
|
||||||
|
|
||||||
|
#if APPLE_OSX_mDNSResponder && LogTimeStamps
|
||||||
|
if (ident && ident[0] && mDNSPlatformClockDivisor)
|
||||||
|
syslog(syslog_level, "%8d.%03d: %s", (int)(t/1000), ms, buffer);
|
||||||
|
else
|
||||||
|
#elif APPLE_OSX_mDNSResponder
|
||||||
|
mDNSPlatformLogToFile(syslog_level, buffer);
|
||||||
|
#else
|
||||||
|
syslog(syslog_level, "%s", buffer);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,33 +5,14 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: PlatformCommon.h,v $
|
|
||||||
Revision 1.4 2006/08/14 23:24:56 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.3 2005/01/19 19:19:21 ksekar
|
|
||||||
<rdar://problem/3960191> Need a way to turn off domain discovery
|
|
||||||
|
|
||||||
Revision 1.2 2004/12/01 03:30:29 cheshire
|
|
||||||
<rdar://problem/3889346> Add Unicast DNS support to mDNSPosix
|
|
||||||
|
|
||||||
Revision 1.1 2004/12/01 01:51:35 cheshire
|
|
||||||
Move ReadDDNSSettingsFromConfFile() from mDNSMacOSX.c to PlatformCommon.c
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
extern void FindDefaultRouteIP(mDNSAddr *a);
|
|
||||||
extern void ReadDDNSSettingsFromConfFile(mDNS *const m, const char *const filename, domainname *const hostname, domainname *const domain, mDNSBool *DomainDiscoveryDisabled);
|
extern void ReadDDNSSettingsFromConfFile(mDNS *const m, const char *const filename, domainname *const hostname, domainname *const domain, mDNSBool *DomainDiscoveryDisabled);
|
||||||
|
|
|
@ -5,119 +5,28 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
File: daemon.c
|
File: daemon.c
|
||||||
|
|
||||||
Contains: main & associated Application layer for mDNSResponder on Linux.
|
Contains: main & associated Application layer for mDNSResponder on Linux.
|
||||||
|
|
||||||
Change History (most recent first):
|
*/
|
||||||
|
|
||||||
$Log: PosixDaemon.c,v $
|
#if __APPLE__
|
||||||
Revision 1.29.2.1 2006/08/29 06:24:34 cheshire
|
// In Mac OS X 10.5 and later trying to use the daemon function gives a “‘daemon’ is deprecated”
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
// error, which prevents compilation because we build with "-Werror".
|
||||||
|
// Since this is supposed to be portable cross-platform code, we don't care that daemon is
|
||||||
Revision 1.29 2005/08/04 03:37:45 mkrochma
|
// deprecated on Mac OS X 10.5, so we use this preprocessor trick to eliminate the error message.
|
||||||
Temporary workaround to fix posix after mDNS_SetPrimaryInterfaceInfo changed
|
#define daemon yes_we_know_that_daemon_is_deprecated_in_os_x_10_5_thankyou
|
||||||
|
#endif
|
||||||
Revision 1.28 2005/07/19 11:21:09 cheshire
|
|
||||||
<rdar://problem/4170449> Unix Domain Socket leak in mdnsd
|
|
||||||
|
|
||||||
Revision 1.27 2005/02/04 00:39:59 cheshire
|
|
||||||
Move ParseDNSServers() from PosixDaemon.c to mDNSPosix.c so all Posix client layers can use it
|
|
||||||
|
|
||||||
Revision 1.26 2005/02/02 02:21:30 cheshire
|
|
||||||
Update references to "mDNSResponder" to say "mdnsd" instead
|
|
||||||
|
|
||||||
Revision 1.25 2005/01/27 20:01:50 cheshire
|
|
||||||
udsSupportRemoveFDFromEventLoop() needs to close the file descriptor as well
|
|
||||||
|
|
||||||
Revision 1.24 2005/01/19 19:20:49 ksekar
|
|
||||||
<rdar://problem/3960191> Need a way to turn off domain discovery
|
|
||||||
|
|
||||||
Revision 1.23 2004/12/16 20:17:11 cheshire
|
|
||||||
<rdar://problem/3324626> Cache memory management improvements
|
|
||||||
|
|
||||||
Revision 1.22 2004/12/10 13:12:08 cheshire
|
|
||||||
Create no-op function RecordUpdatedNiceLabel(), required by uds_daemon.c
|
|
||||||
|
|
||||||
Revision 1.21 2004/12/01 20:57:20 ksekar
|
|
||||||
<rdar://problem/3873921> Wide Area Service Discovery must be split-DNS aware
|
|
||||||
|
|
||||||
Revision 1.20 2004/12/01 04:28:43 cheshire
|
|
||||||
<rdar://problem/3872803> Darwin patches for Solaris and Suse
|
|
||||||
Use version of daemon() provided in mDNSUNP.c instead of local copy
|
|
||||||
|
|
||||||
Revision 1.19 2004/12/01 03:30:29 cheshire
|
|
||||||
<rdar://problem/3889346> Add Unicast DNS support to mDNSPosix
|
|
||||||
|
|
||||||
Revision 1.18 2004/11/30 22:45:59 cheshire
|
|
||||||
Minor code tidying
|
|
||||||
|
|
||||||
Revision 1.17 2004/11/30 22:18:59 cheshire
|
|
||||||
<rdar://problem/3889351> Posix needs to read the list of unicast DNS servers and set server list
|
|
||||||
|
|
||||||
Revision 1.16 2004/09/21 21:05:12 cheshire
|
|
||||||
Move duplicate code out of mDNSMacOSX/daemon.c and mDNSPosix/PosixDaemon.c,
|
|
||||||
into mDNSShared/uds_daemon.c
|
|
||||||
|
|
||||||
Revision 1.15 2004/09/17 01:08:53 cheshire
|
|
||||||
Renamed mDNSClientAPI.h to mDNSEmbeddedAPI.h
|
|
||||||
The name "mDNSClientAPI.h" is misleading to new developers looking at this code. The interfaces
|
|
||||||
declared in that file are ONLY appropriate to single-address-space embedded applications.
|
|
||||||
For clients on general-purpose computers, the interfaces defined in dns_sd.h should be used.
|
|
||||||
|
|
||||||
Revision 1.14 2004/09/16 00:24:49 cheshire
|
|
||||||
<rdar://problem/3803162> Fix unsafe use of mDNSPlatformTimeNow()
|
|
||||||
|
|
||||||
Revision 1.13 2004/08/11 01:59:41 cheshire
|
|
||||||
Remove "mDNS *globalInstance" parameter from udsserver_init()
|
|
||||||
|
|
||||||
Revision 1.12 2004/06/28 23:19:19 cheshire
|
|
||||||
Fix "Daemon_Init declared but never defined" warning on Linux
|
|
||||||
|
|
||||||
Revision 1.11 2004/06/25 00:26:27 rpantos
|
|
||||||
Changes to fix the Posix build on Solaris.
|
|
||||||
|
|
||||||
Revision 1.10 2004/06/08 04:59:40 cheshire
|
|
||||||
Tidy up wording -- log messages are already prefixed with "mDNSResponder", so don't need to repeat it
|
|
||||||
|
|
||||||
Revision 1.9 2004/05/29 00:14:20 rpantos
|
|
||||||
<rdar://problem/3508093> Runtime check to disable prod mdnsd on OS X.
|
|
||||||
|
|
||||||
Revision 1.8 2004/04/07 01:19:04 cheshire
|
|
||||||
Hash slot value should be unsigned
|
|
||||||
|
|
||||||
Revision 1.7 2004/02/14 06:34:57 cheshire
|
|
||||||
Use LogMsg instead of fprintf( stderr
|
|
||||||
|
|
||||||
Revision 1.6 2004/02/14 01:10:42 rpantos
|
|
||||||
Allow daemon to run if 'nobody' is not defined, with a warning. (For Roku HD1000.)
|
|
||||||
|
|
||||||
Revision 1.5 2004/02/05 07:45:43 cheshire
|
|
||||||
Add Log header
|
|
||||||
|
|
||||||
Revision 1.4 2004/01/28 21:14:23 cheshire
|
|
||||||
Reconcile debug_mode and gDebugLogging into a single flag (mDNS_DebugMode)
|
|
||||||
|
|
||||||
Revision 1.3 2004/01/19 19:51:46 cheshire
|
|
||||||
Fix compiler error (mixed declarations and code) on some versions of Linux
|
|
||||||
|
|
||||||
Revision 1.2 2003/12/11 03:03:51 rpantos
|
|
||||||
Clean up mDNSPosix so that it builds on OS X again.
|
|
||||||
|
|
||||||
Revision 1.1 2003/12/08 20:47:02 rpantos
|
|
||||||
Add support for mDNSResponder on Linux.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -129,12 +38,16 @@ Add support for mDNSResponder on Linux.
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#if __APPLE__
|
||||||
|
#undef daemon
|
||||||
|
extern int daemon(int, int);
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "mDNSEmbeddedAPI.h"
|
#include "mDNSEmbeddedAPI.h"
|
||||||
#include "mDNSDebug.h"
|
|
||||||
#include "mDNSPosix.h"
|
#include "mDNSPosix.h"
|
||||||
|
#include "mDNSUNP.h" // For daemon()
|
||||||
#include "uds_daemon.h"
|
#include "uds_daemon.h"
|
||||||
#include "PlatformCommon.h"
|
#include "PlatformCommon.h"
|
||||||
#include "mDNSUNP.h"
|
|
||||||
|
|
||||||
#ifndef MDNSD_USER
|
#ifndef MDNSD_USER
|
||||||
#define MDNSD_USER "nobody"
|
#define MDNSD_USER "nobody"
|
||||||
|
@ -146,226 +59,225 @@ static domainname DynDNSHostname;
|
||||||
|
|
||||||
#define RR_CACHE_SIZE 500
|
#define RR_CACHE_SIZE 500
|
||||||
static CacheEntity gRRCache[RR_CACHE_SIZE];
|
static CacheEntity gRRCache[RR_CACHE_SIZE];
|
||||||
|
static mDNS_PlatformSupport PlatformStorage;
|
||||||
|
|
||||||
extern const char mDNSResponderVersionString[];
|
mDNSlocal void mDNS_StatusCallback(mDNS *const m, mStatus result)
|
||||||
|
{
|
||||||
|
(void)m; // Unused
|
||||||
|
if (result == mStatus_NoError)
|
||||||
|
{
|
||||||
|
// On successful registration of dot-local mDNS host name, daemon may want to check if
|
||||||
|
// any name conflict and automatic renaming took place, and if so, record the newly negotiated
|
||||||
|
// name in persistent storage for next time. It should also inform the user of the name change.
|
||||||
|
// On Mac OS X we store the current dot-local mDNS host name in the SCPreferences store,
|
||||||
|
// and notify the user with a CFUserNotification.
|
||||||
|
}
|
||||||
|
else if (result == mStatus_ConfigChanged)
|
||||||
|
{
|
||||||
|
udsserver_handle_configchange(m);
|
||||||
|
}
|
||||||
|
else if (result == mStatus_GrowCache)
|
||||||
|
{
|
||||||
|
// Allocate another chunk of cache storage
|
||||||
|
CacheEntity *storage = malloc(sizeof(CacheEntity) * RR_CACHE_SIZE);
|
||||||
|
if (storage) mDNS_GrowCache(m, storage, RR_CACHE_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// %%% Reconfigure() probably belongs in the platform support layer (mDNSPosix.c), not the daemon cde
|
||||||
|
// -- all client layers running on top of mDNSPosix.c need to handle network configuration changes,
|
||||||
|
// not only the Unix Domain Socket Daemon
|
||||||
|
|
||||||
static void Reconfigure(mDNS *m)
|
static void Reconfigure(mDNS *m)
|
||||||
{
|
{
|
||||||
mDNSAddr DynDNSIP;
|
mDNSAddr DynDNSIP;
|
||||||
mDNS_SetPrimaryInterfaceInfo(m, NULL, NULL, NULL);
|
const mDNSAddr dummy = { mDNSAddrType_IPv4, { { { 1, 1, 1, 1 } } } };;
|
||||||
mDNS_DeleteDNSServers(m);
|
mDNS_SetPrimaryInterfaceInfo(m, NULL, NULL, NULL);
|
||||||
if (ParseDNSServers(m, uDNS_SERVERS_FILE) < 0)
|
if (ParseDNSServers(m, uDNS_SERVERS_FILE) < 0)
|
||||||
LogMsgNoIdent("Unable to parse DNS server list. Unicast DNS-SD unavailable");
|
LogMsg("Unable to parse DNS server list. Unicast DNS-SD unavailable");
|
||||||
ReadDDNSSettingsFromConfFile(m, CONFIG_FILE, &DynDNSHostname, &DynDNSZone, NULL);
|
ReadDDNSSettingsFromConfFile(m, CONFIG_FILE, &DynDNSHostname, &DynDNSZone, NULL);
|
||||||
FindDefaultRouteIP(&DynDNSIP);
|
mDNSPlatformSourceAddrForDest(&DynDNSIP, &dummy);
|
||||||
if (DynDNSHostname.c[0]) mDNS_AddDynDNSHostName(m, &DynDNSHostname, NULL, NULL);
|
if (DynDNSHostname.c[0]) mDNS_AddDynDNSHostName(m, &DynDNSHostname, NULL, NULL);
|
||||||
if (DynDNSIP.type) mDNS_SetPrimaryInterfaceInfo(m, &DynDNSIP, NULL, NULL);
|
if (DynDNSIP.type) mDNS_SetPrimaryInterfaceInfo(m, &DynDNSIP, NULL, NULL);
|
||||||
}
|
mDNS_ConfigChanged(m);
|
||||||
|
}
|
||||||
|
|
||||||
// Do appropriate things at startup with command line arguments. Calls exit() if unhappy.
|
// Do appropriate things at startup with command line arguments. Calls exit() if unhappy.
|
||||||
static void ParseCmdLinArgs(int argc, char **argv)
|
mDNSlocal void ParseCmdLinArgs(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
{
|
{
|
||||||
if (0 == strcmp(argv[1], "-debug")) mDNS_DebugMode = mDNStrue;
|
if (0 == strcmp(argv[1], "-debug")) mDNS_DebugMode = mDNStrue;
|
||||||
else printf("Usage: %s [-debug]\n", argv[0]);
|
else printf("Usage: %s [-debug]\n", argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mDNS_DebugMode)
|
if (!mDNS_DebugMode)
|
||||||
{
|
{
|
||||||
int result = daemon(0, 0);
|
int result = daemon(0, 0);
|
||||||
if (result != 0) { LogMsg("Could not run as daemon - exiting"); exit(result); }
|
if (result != 0) { LogMsg("Could not run as daemon - exiting"); exit(result); }
|
||||||
#if __APPLE__
|
#if __APPLE__
|
||||||
LogMsg("The POSIX mdnsd should only be used on OS X for testing - exiting");
|
LogMsg("The POSIX mdnsd should only be used on OS X for testing - exiting");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DumpStateLog(mDNS *const m)
|
mDNSlocal void ToggleLog(void)
|
||||||
|
{
|
||||||
|
mDNS_LoggingEnabled = !mDNS_LoggingEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSlocal void ToggleLogPacket(void)
|
||||||
|
{
|
||||||
|
mDNS_PacketLoggingEnabled = !mDNS_PacketLoggingEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSlocal void DumpStateLog(mDNS *const m)
|
||||||
// Dump a little log of what we've been up to.
|
// Dump a little log of what we've been up to.
|
||||||
{
|
{
|
||||||
LogMsgIdent(mDNSResponderVersionString, "---- BEGIN STATE LOG ----");
|
LogMsg("---- BEGIN STATE LOG ----");
|
||||||
udsserver_info(m);
|
udsserver_info(m);
|
||||||
LogMsgIdent(mDNSResponderVersionString, "---- END STATE LOG ----");
|
LogMsg("---- END STATE LOG ----");
|
||||||
}
|
}
|
||||||
|
|
||||||
static mStatus MainLoop(mDNS *m) // Loop until we quit.
|
mDNSlocal mStatus MainLoop(mDNS *m) // Loop until we quit.
|
||||||
{
|
{
|
||||||
sigset_t signals;
|
sigset_t signals;
|
||||||
mDNSBool gotData = mDNSfalse;
|
mDNSBool gotData = mDNSfalse;
|
||||||
|
|
||||||
mDNSPosixListenForSignalInEventLoop(SIGINT);
|
mDNSPosixListenForSignalInEventLoop(SIGINT);
|
||||||
mDNSPosixListenForSignalInEventLoop(SIGTERM);
|
mDNSPosixListenForSignalInEventLoop(SIGTERM);
|
||||||
mDNSPosixListenForSignalInEventLoop(SIGUSR1);
|
mDNSPosixListenForSignalInEventLoop(SIGUSR1);
|
||||||
mDNSPosixListenForSignalInEventLoop(SIGPIPE);
|
mDNSPosixListenForSignalInEventLoop(SIGUSR2);
|
||||||
mDNSPosixListenForSignalInEventLoop(SIGHUP) ;
|
mDNSPosixListenForSignalInEventLoop(SIGINFO);
|
||||||
|
mDNSPosixListenForSignalInEventLoop(SIGPIPE);
|
||||||
|
mDNSPosixListenForSignalInEventLoop(SIGHUP) ;
|
||||||
|
|
||||||
for (; ;)
|
for (; ;)
|
||||||
{
|
{
|
||||||
// Work out how long we expect to sleep before the next scheduled task
|
// Work out how long we expect to sleep before the next scheduled task
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
mDNSs32 ticks;
|
mDNSs32 ticks;
|
||||||
|
|
||||||
// Only idle if we didn't find any data the last time around
|
// Only idle if we didn't find any data the last time around
|
||||||
if (!gotData)
|
if (!gotData)
|
||||||
{
|
{
|
||||||
mDNSs32 nextTimerEvent = mDNS_Execute(m);
|
mDNSs32 nextTimerEvent = mDNS_Execute(m);
|
||||||
nextTimerEvent = udsserver_idle(nextTimerEvent);
|
nextTimerEvent = udsserver_idle(nextTimerEvent);
|
||||||
ticks = nextTimerEvent - mDNS_TimeNow(m);
|
ticks = nextTimerEvent - mDNS_TimeNow(m);
|
||||||
if (ticks < 1) ticks = 1;
|
if (ticks < 1) ticks = 1;
|
||||||
}
|
}
|
||||||
else // otherwise call EventLoop again with 0 timemout
|
else // otherwise call EventLoop again with 0 timemout
|
||||||
ticks = 0;
|
ticks = 0;
|
||||||
|
|
||||||
timeout.tv_sec = ticks / mDNSPlatformOneSecond;
|
timeout.tv_sec = ticks / mDNSPlatformOneSecond;
|
||||||
timeout.tv_usec = (ticks % mDNSPlatformOneSecond) * 1000000 / mDNSPlatformOneSecond;
|
timeout.tv_usec = (ticks % mDNSPlatformOneSecond) * 1000000 / mDNSPlatformOneSecond;
|
||||||
|
|
||||||
(void) mDNSPosixRunEventLoopOnce(m, &timeout, &signals, &gotData);
|
(void) mDNSPosixRunEventLoopOnce(m, &timeout, &signals, &gotData);
|
||||||
|
|
||||||
if (sigismember(&signals, SIGHUP )) Reconfigure(m);
|
if (sigismember(&signals, SIGHUP )) Reconfigure(m);
|
||||||
if (sigismember(&signals, SIGUSR1)) DumpStateLog(m);
|
if (sigismember(&signals, SIGINFO)) DumpStateLog(m);
|
||||||
// SIGPIPE happens when we try to write to a dead client; death should be detected soon in request_callback() and cleaned up.
|
if (sigismember(&signals, SIGUSR1)) ToggleLog();
|
||||||
if (sigismember(&signals, SIGPIPE)) LogMsg("Received SIGPIPE - ignoring");
|
if (sigismember(&signals, SIGUSR2)) ToggleLogPacket();
|
||||||
if (sigismember(&signals, SIGINT) || sigismember(&signals, SIGTERM)) break;
|
// SIGPIPE happens when we try to write to a dead client; death should be detected soon in request_callback() and cleaned up.
|
||||||
}
|
if (sigismember(&signals, SIGPIPE)) LogMsg("Received SIGPIPE - ignoring");
|
||||||
return EINTR;
|
if (sigismember(&signals, SIGINT) || sigismember(&signals, SIGTERM)) break;
|
||||||
}
|
}
|
||||||
|
return EINTR;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
#define mDNSRecord mDNSStorage
|
mStatus err;
|
||||||
mDNS_PlatformSupport platformStorage;
|
|
||||||
mStatus err;
|
|
||||||
|
|
||||||
bzero(&mDNSRecord, sizeof mDNSRecord);
|
ParseCmdLinArgs(argc, argv);
|
||||||
bzero(&platformStorage, sizeof platformStorage);
|
|
||||||
|
|
||||||
ParseCmdLinArgs(argc, argv);
|
LogInfo("%s starting", mDNSResponderVersionString);
|
||||||
|
|
||||||
LogMsgIdent(mDNSResponderVersionString, "starting");
|
err = mDNS_Init(&mDNSStorage, &PlatformStorage, gRRCache, RR_CACHE_SIZE, mDNS_Init_AdvertiseLocalAddresses,
|
||||||
|
mDNS_StatusCallback, mDNS_Init_NoInitCallbackContext);
|
||||||
|
|
||||||
err = mDNS_Init(&mDNSRecord, &platformStorage, gRRCache, RR_CACHE_SIZE, mDNS_Init_AdvertiseLocalAddresses,
|
if (mStatus_NoError == err)
|
||||||
mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);
|
err = udsserver_init(mDNSNULL, 0);
|
||||||
|
|
||||||
if (mStatus_NoError == err)
|
Reconfigure(&mDNSStorage);
|
||||||
err = udsserver_init();
|
|
||||||
|
|
||||||
Reconfigure(&mDNSRecord);
|
|
||||||
|
|
||||||
// Now that we're finished with anything privileged, switch over to running as "nobody"
|
// Now that we're finished with anything privileged, switch over to running as "nobody"
|
||||||
if (mStatus_NoError == err)
|
if (mStatus_NoError == err)
|
||||||
{
|
{
|
||||||
const struct passwd *pw = getpwnam(MDNSD_USER);
|
const struct passwd *pw = getpwnam(MDNSD_USER);
|
||||||
if (pw != NULL)
|
if (pw != NULL)
|
||||||
setuid(pw->pw_uid);
|
setuid(pw->pw_uid);
|
||||||
else
|
else
|
||||||
#ifdef MDNSD_NOROOT
|
#ifdef MDNSD_NOROOT
|
||||||
{
|
{
|
||||||
LogMsg("WARNING: mdnsd exiting because user \""MDNSD_USER"\" does not exist");
|
LogMsg("WARNING: mdnsd exiting because user \""MDNSD_USER"\" does not exist");
|
||||||
err = mStatus_Invalid;
|
err = mStatus_Invalid;
|
||||||
}
|
|
||||||
#else
|
|
||||||
LogMsg("WARNING: mdnsd continuing as root because user \""MDNSD_USER"\" does not exist");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mStatus_NoError == err)
|
|
||||||
err = MainLoop(&mDNSRecord);
|
|
||||||
|
|
||||||
LogMsgIdent(mDNSResponderVersionString, "stopping");
|
|
||||||
|
|
||||||
mDNS_Close(&mDNSRecord);
|
|
||||||
|
|
||||||
if (udsserver_exit() < 0)
|
|
||||||
LogMsg("ExitCallback: udsserver_exit failed");
|
|
||||||
|
|
||||||
#if MDNS_DEBUGMSGS > 0
|
|
||||||
printf("mDNSResponder exiting normally with %ld\n", err);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
LogMsg("WARNING: mdnsd continuing as root because user \""MDNSD_USER"\" does not exist");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mStatus_NoError == err)
|
||||||
|
err = MainLoop(&mDNSStorage);
|
||||||
|
|
||||||
|
LogInfo("%s stopping", mDNSResponderVersionString);
|
||||||
|
|
||||||
|
mDNS_Close(&mDNSStorage);
|
||||||
|
|
||||||
|
if (udsserver_exit() < 0)
|
||||||
|
LogMsg("ExitCallback: udsserver_exit failed");
|
||||||
|
|
||||||
|
#if MDNS_DEBUGMSGS > 0
|
||||||
|
printf("mDNSResponder exiting normally with %ld\n", err);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
// uds_daemon support ////////////////////////////////////////////////////////////
|
// uds_daemon support ////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#undef LogMalloc
|
mStatus udsSupportAddFDToEventLoop(int fd, udsEventCallback callback, void *context, void **platform_data)
|
||||||
|
|
||||||
#if MDNS_MALLOC_DEBUGGING >= 2
|
|
||||||
#define LogMalloc LogMsg
|
|
||||||
#else
|
|
||||||
#define LogMalloc(ARGS...) ((void)0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mStatus udsSupportAddFDToEventLoop(int fd, udsEventCallback callback, void *context)
|
|
||||||
/* Support routine for uds_daemon.c */
|
/* Support routine for uds_daemon.c */
|
||||||
{
|
{
|
||||||
// Depends on the fact that udsEventCallback == mDNSPosixEventCallback
|
// Depends on the fact that udsEventCallback == mDNSPosixEventCallback
|
||||||
return mDNSPosixAddFDToEventLoop(fd, callback, context);
|
(void) platform_data;
|
||||||
}
|
return mDNSPosixAddFDToEventLoop(fd, callback, context);
|
||||||
|
}
|
||||||
|
|
||||||
mStatus udsSupportRemoveFDFromEventLoop(int fd) // Note: This also CLOSES the file descriptor
|
int udsSupportReadFD(dnssd_sock_t fd, char *buf, int len, int flags, void *platform_data)
|
||||||
{
|
{
|
||||||
mStatus err = mDNSPosixRemoveFDFromEventLoop(fd);
|
(void) platform_data;
|
||||||
close(fd);
|
return recv(fd, buf, len, flags);
|
||||||
return err;
|
}
|
||||||
}
|
|
||||||
|
mStatus udsSupportRemoveFDFromEventLoop(int fd, void *platform_data) // Note: This also CLOSES the file descriptor
|
||||||
|
{
|
||||||
|
mStatus err = mDNSPosixRemoveFDFromEventLoop(fd);
|
||||||
|
(void) platform_data;
|
||||||
|
close(fd);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
mDNSexport void RecordUpdatedNiceLabel(mDNS *const m, mDNSs32 delay)
|
mDNSexport void RecordUpdatedNiceLabel(mDNS *const m, mDNSs32 delay)
|
||||||
{
|
{
|
||||||
(void)m;
|
(void)m;
|
||||||
(void)delay;
|
(void)delay;
|
||||||
// No-op, for now
|
// No-op, for now
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MACOSX_MDNS_MALLOC_DEBUGGING >= 1
|
#if _BUILDING_XCODE_PROJECT_
|
||||||
|
// If the process crashes, then this string will be magically included in the automatically-generated crash log
|
||||||
void *mallocL(char *msg, unsigned int size)
|
const char *__crashreporter_info__ = mDNSResponderVersionString_SCCS + 5;
|
||||||
{
|
asm (".desc ___crashreporter_info__, 0x10");
|
||||||
unsigned long *mem = malloc(size+8);
|
#endif
|
||||||
if (!mem)
|
|
||||||
{
|
|
||||||
LogMsg("malloc( %s : %d ) failed", msg, size);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogMalloc("malloc( %s : %lu ) = %p", msg, size, &mem[2]);
|
|
||||||
mem[0] = 0xDEAD1234;
|
|
||||||
mem[1] = size;
|
|
||||||
//bzero(&mem[2], size);
|
|
||||||
memset(&mem[2], 0xFF, size);
|
|
||||||
// validatelists(&mDNSStorage);
|
|
||||||
return(&mem[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void freeL(char *msg, void *x)
|
|
||||||
{
|
|
||||||
if (!x)
|
|
||||||
LogMsg("free( %s @ NULL )!", msg);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned long *mem = ((unsigned long *)x) - 2;
|
|
||||||
if (mem[0] != 0xDEAD1234)
|
|
||||||
{ LogMsg("free( %s @ %p ) !!!! NOT ALLOCATED !!!!", msg, &mem[2]); return; }
|
|
||||||
if (mem[1] > 8000)
|
|
||||||
{ LogMsg("free( %s : %ld @ %p) too big!", msg, mem[1], &mem[2]); return; }
|
|
||||||
LogMalloc("free( %s : %ld @ %p)", msg, mem[1], &mem[2]);
|
|
||||||
//bzero(mem, mem[1]+8);
|
|
||||||
memset(mem, 0xDD, mem[1]+8);
|
|
||||||
// validatelists(&mDNSStorage);
|
|
||||||
free(mem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // MACOSX_MDNS_MALLOC_DEBUGGING >= 1
|
|
||||||
|
|
||||||
// For convenience when using the "strings" command, this is the last thing in the file
|
// For convenience when using the "strings" command, this is the last thing in the file
|
||||||
#if mDNSResponderVersion > 1
|
#if mDNSResponderVersion > 1
|
||||||
mDNSexport const char mDNSResponderVersionString[] = "mDNSResponder-" STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ") ";
|
mDNSexport const char mDNSResponderVersionString_SCCS[] = "@(#) mDNSResponder-" STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
|
||||||
#elif MDNS_VERSIONSTR_NODTS
|
#elif MDNS_VERSIONSTR_NODTS
|
||||||
mDNSexport const char mDNSResponderVersionString[] = "mDNSResponder (Engineering Build) ";
|
mDNSexport const char mDNSResponderVersionString_SCCS[] = "@(#) mDNSResponder (Engineering Build)";
|
||||||
#else
|
#else
|
||||||
mDNSexport const char mDNSResponderVersionString[] = "mDNSResponder (Engineering Build) (" __DATE__ " " __TIME__ ") ";
|
mDNSexport const char mDNSResponderVersionString_SCCS[] = "@(#) mDNSResponder (Engineering Build) (" __DATE__ " " __TIME__ ")";
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
* Copyright (c) 2002-2006 Apple Computer, Inc. All rights reserved.
|
The majority of the source code in the mDNSResponder project is licensed
|
||||||
*
|
under the terms of the Apache License, Version 2.0, available from:
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
<http://www.apache.org/licenses/LICENSE-2.0>
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
To accommodate license compatibility with the widest possible range
|
||||||
*
|
of client code licenses, the shared library code, which is linked
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
at runtime into the same address space as the client using it, is
|
||||||
*
|
licensed under the terms of the "Three-Clause BSD License".
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
The Linux Name Service Switch code, contributed by National ICT
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
Australia Ltd (NICTA) is licensed under the terms of the NICTA Public
|
||||||
* See the License for the specific language governing permissions and
|
Software Licence (which is substantially similar to the "Three-Clause
|
||||||
* limitations under the License.
|
BSD License", with some additional language pertaining to Australian law).
|
||||||
|
|
|
@ -0,0 +1,597 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 Apple Computer, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mDNSEmbeddedAPI.h"
|
||||||
|
#include "CryptoAlg.h"
|
||||||
|
#include "anonymous.h"
|
||||||
|
#include "DNSCommon.h"
|
||||||
|
|
||||||
|
// Define ANONYMOUS_DISABLED to remove all the anonymous functionality
|
||||||
|
// and use the stub functions implemented later in this file.
|
||||||
|
|
||||||
|
#ifndef ANONYMOUS_DISABLED
|
||||||
|
|
||||||
|
#define ANON_NSEC3_ITERATIONS 1
|
||||||
|
|
||||||
|
mDNSlocal mDNSBool InitializeNSEC3Record(ResourceRecord *rr, const mDNSu8 *AnonData, int len, mDNSu32 salt)
|
||||||
|
{
|
||||||
|
const mDNSu8 *ptr;
|
||||||
|
rdataNSEC3 *nsec3 = (rdataNSEC3 *)rr->rdata->u.data;
|
||||||
|
mDNSu8 *tmp, *nxt;
|
||||||
|
unsigned short iter = ANON_NSEC3_ITERATIONS;
|
||||||
|
int hlen;
|
||||||
|
const mDNSu8 hashName[NSEC3_MAX_HASH_LEN];
|
||||||
|
|
||||||
|
// Construct the RDATA first and construct the owner name based on that.
|
||||||
|
ptr = (const mDNSu8 *)&salt;
|
||||||
|
debugf("InitializeNSEC3Record: %x%x%x%x, name %##s", ptr[0], ptr[1], ptr[2], ptr[3], rr->name->c);
|
||||||
|
|
||||||
|
// Set the RDATA
|
||||||
|
nsec3->alg = SHA1_DIGEST_TYPE;
|
||||||
|
nsec3->flags = 0;
|
||||||
|
nsec3->iterations = swap16(iter);
|
||||||
|
nsec3->saltLength = 4;
|
||||||
|
tmp = (mDNSu8 *)&nsec3->salt;
|
||||||
|
*tmp++ = ptr[0];
|
||||||
|
*tmp++ = ptr[1];
|
||||||
|
*tmp++ = ptr[2];
|
||||||
|
*tmp++ = ptr[3];
|
||||||
|
|
||||||
|
// hashLength, nxt, bitmap
|
||||||
|
*tmp++ = SHA1_HASH_LENGTH; // hash length
|
||||||
|
nxt = tmp;
|
||||||
|
tmp += SHA1_HASH_LENGTH;
|
||||||
|
*tmp++ = 0; // window number
|
||||||
|
*tmp++ = NSEC_MCAST_WINDOW_SIZE; // window length
|
||||||
|
mDNSPlatformMemZero(tmp, NSEC_MCAST_WINDOW_SIZE);
|
||||||
|
tmp[kDNSType_PTR >> 3] |= 128 >> (kDNSType_PTR & 7);
|
||||||
|
|
||||||
|
// Hash the base service name + salt + AnonData
|
||||||
|
if (!NSEC3HashName(rr->name, nsec3, AnonData, len, hashName, &hlen))
|
||||||
|
{
|
||||||
|
LogMsg("InitializeNSEC3Record: NSEC3HashName failed for ##s", rr->name->c);
|
||||||
|
return mDNSfalse;
|
||||||
|
}
|
||||||
|
if (hlen != SHA1_HASH_LENGTH)
|
||||||
|
{
|
||||||
|
LogMsg("InitializeNSEC3Record: hlen wrong %d", hlen);
|
||||||
|
return mDNSfalse;
|
||||||
|
}
|
||||||
|
mDNSPlatformMemCopy(nxt, hashName, hlen);
|
||||||
|
|
||||||
|
return mDNStrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSlocal ResourceRecord *ConstructNSEC3Record(const domainname *service, const mDNSu8 *AnonData, int len, mDNSu32 salt)
|
||||||
|
{
|
||||||
|
ResourceRecord *rr;
|
||||||
|
int dlen;
|
||||||
|
domainname *name;
|
||||||
|
|
||||||
|
// We are just allocating an RData which has StandardAuthRDSize
|
||||||
|
if (StandardAuthRDSize < MCAST_NSEC3_RDLENGTH)
|
||||||
|
{
|
||||||
|
LogMsg("ConstructNSEC3Record: StandardAuthRDSize %d smaller than MCAST_NSEC3_RDLENGTH %d", StandardAuthRDSize, MCAST_NSEC3_RDLENGTH);
|
||||||
|
return mDNSNULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dlen = DomainNameLength(service);
|
||||||
|
|
||||||
|
// Allocate space for the name and RData.
|
||||||
|
rr = mDNSPlatformMemAllocate(sizeof(ResourceRecord) + dlen + sizeof(RData));
|
||||||
|
if (!rr)
|
||||||
|
return mDNSNULL;
|
||||||
|
name = (domainname *)((mDNSu8 *)rr + sizeof(ResourceRecord));
|
||||||
|
rr->RecordType = kDNSRecordTypePacketAuth;
|
||||||
|
rr->InterfaceID = mDNSInterface_Any;
|
||||||
|
rr->name = (const domainname *)name;
|
||||||
|
rr->rrtype = kDNSType_NSEC3;
|
||||||
|
rr->rrclass = kDNSClass_IN;
|
||||||
|
rr->rroriginalttl = kStandardTTL;
|
||||||
|
rr->rDNSServer = mDNSNULL;
|
||||||
|
rr->rdlength = MCAST_NSEC3_RDLENGTH;
|
||||||
|
rr->rdestimate = MCAST_NSEC3_RDLENGTH;
|
||||||
|
rr->rdata = (RData *)((mDNSu8 *)rr->name + dlen);
|
||||||
|
|
||||||
|
AssignDomainName(name, service);
|
||||||
|
if (!InitializeNSEC3Record(rr, AnonData, len, salt))
|
||||||
|
{
|
||||||
|
mDNSPlatformMemFree(rr);
|
||||||
|
return mDNSNULL;
|
||||||
|
}
|
||||||
|
return rr;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSlocal ResourceRecord *CopyNSEC3ResourceRecord(AnonymousInfo *si, const ResourceRecord *rr)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
domainname *name;
|
||||||
|
ResourceRecord *nsec3rr;
|
||||||
|
|
||||||
|
if (rr->rdlength < MCAST_NSEC3_RDLENGTH)
|
||||||
|
{
|
||||||
|
LogMsg("CopyNSEC3ResourceRecord: rdlength %d smaller than MCAST_NSEC3_RDLENGTH %d", rr->rdlength, MCAST_NSEC3_RDLENGTH);
|
||||||
|
return mDNSNULL;
|
||||||
|
}
|
||||||
|
// Allocate space for the name and the rdata along with the ResourceRecord
|
||||||
|
len = DomainNameLength(rr->name);
|
||||||
|
nsec3rr = mDNSPlatformMemAllocate(sizeof(ResourceRecord) + len + sizeof(RData));
|
||||||
|
if (!nsec3rr)
|
||||||
|
return mDNSNULL;
|
||||||
|
|
||||||
|
*nsec3rr = *rr;
|
||||||
|
name = (domainname *)((mDNSu8 *)nsec3rr + sizeof(ResourceRecord));
|
||||||
|
nsec3rr->name = (const domainname *)name;
|
||||||
|
AssignDomainName(name, rr->name);
|
||||||
|
|
||||||
|
nsec3rr->rdata = (RData *)((mDNSu8 *)nsec3rr->name + len);
|
||||||
|
mDNSPlatformMemCopy(nsec3rr->rdata->u.data, rr->rdata->u.data, rr->rdlength);
|
||||||
|
|
||||||
|
si->nsec3RR = nsec3rr;
|
||||||
|
|
||||||
|
return nsec3rr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When a service is started or a browse is started with the Anonymous data, we allocate a new random
|
||||||
|
// number and based on that allocate a new NSEC3 resource record whose hash is a function of random number (salt) and
|
||||||
|
// the anonymous data.
|
||||||
|
//
|
||||||
|
// If we receive a packet with the NSEC3 option, we need to cache that along with the resource record so that we can
|
||||||
|
// check against the question to see whether it answers them or not. In that case, we pass the "rr" that we received.
|
||||||
|
mDNSexport AnonymousInfo *AllocateAnonInfo(const domainname *service, const mDNSu8 *data, int len, const ResourceRecord *rr)
|
||||||
|
{
|
||||||
|
AnonymousInfo *ai;
|
||||||
|
ai = (AnonymousInfo *)mDNSPlatformMemAllocate(sizeof(AnonymousInfo));
|
||||||
|
if (!ai)
|
||||||
|
{
|
||||||
|
return mDNSNULL;
|
||||||
|
}
|
||||||
|
mDNSPlatformMemZero(ai, sizeof(AnonymousInfo));
|
||||||
|
if (rr)
|
||||||
|
{
|
||||||
|
if (!CopyNSEC3ResourceRecord(ai, rr))
|
||||||
|
{
|
||||||
|
mDNSPlatformMemFree(ai);
|
||||||
|
return mDNSNULL;
|
||||||
|
}
|
||||||
|
return ai;
|
||||||
|
}
|
||||||
|
ai->salt = mDNSRandom(0xFFFFFFFF);
|
||||||
|
ai->AnonData = mDNSPlatformMemAllocate(len);
|
||||||
|
if (!ai->AnonData)
|
||||||
|
{
|
||||||
|
mDNSPlatformMemFree(ai);
|
||||||
|
return mDNSNULL;
|
||||||
|
}
|
||||||
|
ai->AnonDataLen = len;
|
||||||
|
mDNSPlatformMemCopy(ai->AnonData, data, len);
|
||||||
|
ai->nsec3RR = ConstructNSEC3Record(service, data, len, ai->salt);
|
||||||
|
if (!ai->nsec3RR)
|
||||||
|
{
|
||||||
|
mDNSPlatformMemFree(ai);
|
||||||
|
return mDNSNULL;
|
||||||
|
}
|
||||||
|
return ai;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport void FreeAnonInfo(AnonymousInfo *ai)
|
||||||
|
{
|
||||||
|
if (ai->nsec3RR)
|
||||||
|
mDNSPlatformMemFree(ai->nsec3RR);
|
||||||
|
if (ai->AnonData)
|
||||||
|
mDNSPlatformMemFree(ai->AnonData);
|
||||||
|
mDNSPlatformMemFree(ai);
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport void ReInitAnonInfo(AnonymousInfo **AnonInfo, const domainname *name)
|
||||||
|
{
|
||||||
|
if (*AnonInfo)
|
||||||
|
{
|
||||||
|
AnonymousInfo *ai = *AnonInfo;
|
||||||
|
*AnonInfo = AllocateAnonInfo(name, ai->AnonData, ai->AnonDataLen, mDNSNULL);
|
||||||
|
if (!(*AnonInfo))
|
||||||
|
*AnonInfo = ai;
|
||||||
|
else
|
||||||
|
FreeAnonInfo(ai);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function should be used only if you know that the question and
|
||||||
|
// the resource record belongs to the same set. The main usage is
|
||||||
|
// in ProcessQuery where we find the question to be part of the same
|
||||||
|
// set as the resource record, but it needs the AnonData to be
|
||||||
|
// initialized so that it can walk the cache records to see if they
|
||||||
|
// answer the question.
|
||||||
|
mDNSexport void SetAnonData(DNSQuestion *q, ResourceRecord *rr, mDNSBool ForQuestion)
|
||||||
|
{
|
||||||
|
if (!q->AnonInfo || !rr->AnonInfo)
|
||||||
|
{
|
||||||
|
LogMsg("SetAnonData: question %##s(%p), rr %##s(%p), NULL", q->qname.c, q->AnonInfo, rr->name->c, rr->AnonInfo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
debugf("SetAnonData: question %##s(%p), rr %##s(%p)", q->qname.c, q->AnonInfo, rr->name->c, rr->AnonInfo);
|
||||||
|
if (ForQuestion)
|
||||||
|
{
|
||||||
|
if (!q->AnonInfo->AnonData)
|
||||||
|
{
|
||||||
|
q->AnonInfo->AnonData = mDNSPlatformMemAllocate(rr->AnonInfo->AnonDataLen);
|
||||||
|
if (!q->AnonInfo->AnonData)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mDNSPlatformMemCopy(q->AnonInfo->AnonData, rr->AnonInfo->AnonData, rr->AnonInfo->AnonDataLen);
|
||||||
|
q->AnonInfo->AnonDataLen = rr->AnonInfo->AnonDataLen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!rr->AnonInfo->AnonData)
|
||||||
|
{
|
||||||
|
rr->AnonInfo->AnonData = mDNSPlatformMemAllocate(q->AnonInfo->AnonDataLen);
|
||||||
|
if (!rr->AnonInfo->AnonData)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mDNSPlatformMemCopy(rr->AnonInfo->AnonData, q->AnonInfo->AnonData, q->AnonInfo->AnonDataLen);
|
||||||
|
rr->AnonInfo->AnonDataLen = q->AnonInfo->AnonDataLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns -1 if the caller should ignore the result
|
||||||
|
// returns 1 if the record answers the question
|
||||||
|
// returns 0 if the record does not answer the question
|
||||||
|
mDNSexport int AnonInfoAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q)
|
||||||
|
{
|
||||||
|
mDNSexport mDNS mDNSStorage;
|
||||||
|
ResourceRecord *nsec3RR;
|
||||||
|
int i;
|
||||||
|
AnonymousInfo *qai, *rai;
|
||||||
|
mDNSu8 *AnonData;
|
||||||
|
int AnonDataLen;
|
||||||
|
rdataNSEC3 *nsec3;
|
||||||
|
int hlen;
|
||||||
|
const mDNSu8 hashName[NSEC3_MAX_HASH_LEN];
|
||||||
|
int nxtLength;
|
||||||
|
mDNSu8 *nxtName;
|
||||||
|
|
||||||
|
debugf("AnonInfoAnswersQuestion: question qname %##s", q->qname.c);
|
||||||
|
|
||||||
|
// Currently only PTR records can have anonymous information
|
||||||
|
if (q->qtype != kDNSType_PTR)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We allow anonymous questions to be answered by both normal services (without the
|
||||||
|
// anonymous information) and anonymous services that are part of the same set. And
|
||||||
|
// normal questions discover normal services and all anonymous services.
|
||||||
|
//
|
||||||
|
// The three cases have been enumerated clearly even though they all behave the
|
||||||
|
// same way.
|
||||||
|
if (!q->AnonInfo)
|
||||||
|
{
|
||||||
|
debugf("AnonInfoAnswersQuestion: not a anonymous type question");
|
||||||
|
if (!rr->AnonInfo)
|
||||||
|
{
|
||||||
|
// case 1
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// case 2
|
||||||
|
debugf("AnonInfoAnswersQuestion: Question %##s not answered using anonymous record %##s", q->qname.c, rr->name->c);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// case 3
|
||||||
|
if (!rr->AnonInfo)
|
||||||
|
{
|
||||||
|
debugf("AnonInfoAnswersQuestion: not a anonymous type record");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// case 4: We have the anonymous information both in the question and the record. We need
|
||||||
|
// two sets of information to validate.
|
||||||
|
//
|
||||||
|
// 1) Anonymous data that identifies the set/group
|
||||||
|
// 2) NSEC3 record that contains the hash and the salt
|
||||||
|
//
|
||||||
|
// If the question is a remote one, it does not have the anonymous information to validate (just
|
||||||
|
// the NSEC3 record) and hence the anonymous data should come from the local resource record. If the
|
||||||
|
// question is local, it can come from either of them and if there is a mismatch between the
|
||||||
|
// question and record, it won't validate.
|
||||||
|
|
||||||
|
qai = q->AnonInfo;
|
||||||
|
rai = rr->AnonInfo;
|
||||||
|
|
||||||
|
if (qai->AnonData && rai->AnonData)
|
||||||
|
{
|
||||||
|
// Before a cache record is created, if there is a matching question i.e., part
|
||||||
|
// of the same set, then when the cache is created we also set the anonymous
|
||||||
|
// information. Otherwise, the cache record contains just the NSEC3 record and we
|
||||||
|
// won't be here for that case.
|
||||||
|
//
|
||||||
|
// It is also possible that a local question is matched against the local AuthRecord
|
||||||
|
// as that is also the case for which the AnonData would be non-NULL for both.
|
||||||
|
// We match questions against AuthRecords (rather than the cache) for LocalOnly case and
|
||||||
|
// to see whether a .local query should be suppressed or not. The latter never happens
|
||||||
|
// because PTR queries are never suppressed.
|
||||||
|
|
||||||
|
// If they don't belong to the same anonymous set, then no point in validating.
|
||||||
|
if ((qai->AnonDataLen != rai->AnonDataLen) ||
|
||||||
|
mDNSPlatformMemCmp(qai->AnonData, rai->AnonData, qai->AnonDataLen) != 0)
|
||||||
|
{
|
||||||
|
debugf("AnonInfoAnswersQuestion: AnonData mis-match for record %s question %##s ",
|
||||||
|
RRDisplayString(&mDNSStorage, rr), q->qname.c);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// AnonData matches i.e they belong to the same group and the same service.
|
||||||
|
LogInfo("AnonInfoAnswersQuestion: Answering qname %##s, rname %##s, without validation", q->qname.c,
|
||||||
|
rr->name->c);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debugf("AnonInfoAnswersQuestion: question %p, record %p", qai->AnonData, rai->AnonData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qai->AnonData)
|
||||||
|
{
|
||||||
|
// If there is AnonData, then this is a local question. The
|
||||||
|
// NSEC3 RR comes from the resource record which could be part
|
||||||
|
// of the cache or local auth record. The cache entry could
|
||||||
|
// be from a remote host or created when we heard our own
|
||||||
|
// announcements. In any case, we use that to see if it matches
|
||||||
|
// the question.
|
||||||
|
AnonData = qai->AnonData;
|
||||||
|
AnonDataLen = qai->AnonDataLen;
|
||||||
|
nsec3RR = rai->nsec3RR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Remote question or hearing our own question back
|
||||||
|
AnonData = rai->AnonData;
|
||||||
|
AnonDataLen = rai->AnonDataLen;
|
||||||
|
nsec3RR = qai->nsec3RR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AnonData || !nsec3RR)
|
||||||
|
{
|
||||||
|
// AnonData can be NULL for the cache entry and if we are hearing our own question back, AnonData is NULL for
|
||||||
|
// that too and we can end up here for that case.
|
||||||
|
debugf("AnonInfoAnswersQuestion: AnonData %p or nsec3RR %p, NULL for question %##s, record %s", AnonData, nsec3RR,
|
||||||
|
q->qname.c, RRDisplayString(&mDNSStorage, rr));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
debugf("AnonInfoAnswersQuestion: Validating question %##s, ResourceRecord %s", q->qname.c, RRDisplayString(&mDNSStorage, nsec3RR));
|
||||||
|
|
||||||
|
|
||||||
|
nsec3 = (rdataNSEC3 *)nsec3RR->rdata->u.data;
|
||||||
|
|
||||||
|
if (!NSEC3HashName(nsec3RR->name, nsec3, AnonData, AnonDataLen, hashName, &hlen))
|
||||||
|
{
|
||||||
|
LogMsg("AnonInfoAnswersQuestion: NSEC3HashName failed for ##s", nsec3RR->name->c);
|
||||||
|
return mDNSfalse;
|
||||||
|
}
|
||||||
|
if (hlen != SHA1_HASH_LENGTH)
|
||||||
|
{
|
||||||
|
LogMsg("AnonInfoAnswersQuestion: hlen wrong %d", hlen);
|
||||||
|
return mDNSfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSEC3Parse(nsec3RR, mDNSNULL, &nxtLength, &nxtName, mDNSNULL, mDNSNULL);
|
||||||
|
|
||||||
|
if (hlen != nxtLength)
|
||||||
|
{
|
||||||
|
LogMsg("AnonInfoAnswersQuestion: ERROR!! hlen %d not same as nxtLength %d", hlen, nxtLength);
|
||||||
|
return mDNSfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < nxtLength; i++)
|
||||||
|
{
|
||||||
|
if (nxtName[i] != hashName[i])
|
||||||
|
{
|
||||||
|
debugf("AnonInfoAnswersQuestion: mismatch output %x, digest %x, i %d", nxtName[i+1], hashName[i], i);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LogInfo("AnonInfoAnswersQuestion: ResourceRecord %s matched question %##s (%s)", RRDisplayString(&mDNSStorage, nsec3RR), q->qname.c, DNSTypeName(q->qtype));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find a matching NSEC3 record for the name. We parse the questions and the records in the packet in order.
|
||||||
|
// Similarly we also parse the NSEC3 records in order and this mapping to the questions and records
|
||||||
|
// respectively.
|
||||||
|
mDNSlocal CacheRecord *FindMatchingNSEC3ForName(mDNS *const m, CacheRecord **nsec3, const domainname *name)
|
||||||
|
{
|
||||||
|
CacheRecord *cr;
|
||||||
|
CacheRecord **prev = nsec3;
|
||||||
|
|
||||||
|
(void) m;
|
||||||
|
|
||||||
|
for (cr = *nsec3; cr; cr = cr->next)
|
||||||
|
{
|
||||||
|
if (SameDomainName(cr->resrec.name, name))
|
||||||
|
{
|
||||||
|
debugf("FindMatchingNSEC3ForName: NSEC3 record %s matched %##s", CRDisplayString(m, cr), name->c);
|
||||||
|
*prev = cr->next;
|
||||||
|
cr->next = mDNSNULL;
|
||||||
|
return cr;
|
||||||
|
}
|
||||||
|
prev = &cr->next;
|
||||||
|
}
|
||||||
|
return mDNSNULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport void InitializeAnonInfoForQuestion(mDNS *const m, CacheRecord **McastNSEC3Records, DNSQuestion *q)
|
||||||
|
{
|
||||||
|
CacheRecord *nsec3CR;
|
||||||
|
|
||||||
|
if (q->qtype != kDNSType_PTR)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nsec3CR = FindMatchingNSEC3ForName(m, McastNSEC3Records, &q->qname);
|
||||||
|
if (nsec3CR)
|
||||||
|
{
|
||||||
|
q->AnonInfo = AllocateAnonInfo(mDNSNULL, mDNSNULL, 0, &nsec3CR->resrec);
|
||||||
|
if (q->AnonInfo)
|
||||||
|
{
|
||||||
|
debugf("InitializeAnonInfoForQuestion: Found a matching NSEC3 record %s, for %##s (%s)",
|
||||||
|
RRDisplayString(m, q->AnonInfo->nsec3RR), q->qname.c, DNSTypeName(q->qtype));
|
||||||
|
}
|
||||||
|
ReleaseCacheRecord(m, nsec3CR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport void InitializeAnonInfoForCR(mDNS *const m, CacheRecord **McastNSEC3Records, CacheRecord *cr)
|
||||||
|
{
|
||||||
|
CacheRecord *nsec3CR;
|
||||||
|
|
||||||
|
if (!(*McastNSEC3Records))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If already initialized or not a PTR type, we don't have to do anything
|
||||||
|
if (cr->resrec.AnonInfo || cr->resrec.rrtype != kDNSType_PTR)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nsec3CR = FindMatchingNSEC3ForName(m, McastNSEC3Records, cr->resrec.name);
|
||||||
|
if (nsec3CR)
|
||||||
|
{
|
||||||
|
cr->resrec.AnonInfo = AllocateAnonInfo(mDNSNULL, mDNSNULL, 0, &nsec3CR->resrec);
|
||||||
|
if (cr->resrec.AnonInfo)
|
||||||
|
{
|
||||||
|
debugf("InitializeAnonInfoForCR: Found a matching NSEC3 record %s, for %##s (%s)",
|
||||||
|
RRDisplayString(m, cr->resrec.AnonInfo->nsec3RR), cr->resrec.name->c,
|
||||||
|
DNSTypeName(cr->resrec.rrtype));
|
||||||
|
}
|
||||||
|
ReleaseCacheRecord(m, nsec3CR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport mDNSBool IdenticalAnonInfo(AnonymousInfo *a1, AnonymousInfo *a2)
|
||||||
|
{
|
||||||
|
// if a1 is NULL and a2 is not NULL AND vice-versa
|
||||||
|
// return false as there is a change.
|
||||||
|
if ((a1 != mDNSNULL) != (a2 != mDNSNULL))
|
||||||
|
return mDNSfalse;
|
||||||
|
|
||||||
|
// Both could be NULL or non-NULL
|
||||||
|
if (a1 && a2)
|
||||||
|
{
|
||||||
|
// The caller already verified that the owner name is the same.
|
||||||
|
// Check whether the RData is same.
|
||||||
|
if (!IdenticalSameNameRecord(a1->nsec3RR, a2->nsec3RR))
|
||||||
|
{
|
||||||
|
debugf("IdenticalAnonInfo: nsec3RR mismatch");
|
||||||
|
return mDNSfalse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mDNStrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport void CopyAnonInfoForCR(mDNS *const m, CacheRecord *crto, CacheRecord *crfrom)
|
||||||
|
{
|
||||||
|
AnonymousInfo *aifrom = crfrom->resrec.AnonInfo;
|
||||||
|
AnonymousInfo *aito = crto->resrec.AnonInfo;
|
||||||
|
|
||||||
|
(void) m;
|
||||||
|
|
||||||
|
if (!aifrom)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (aito)
|
||||||
|
{
|
||||||
|
crto->resrec.AnonInfo = aifrom;
|
||||||
|
FreeAnonInfo(aito);
|
||||||
|
crfrom->resrec.AnonInfo = mDNSNULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FreeAnonInfo(aifrom);
|
||||||
|
crfrom->resrec.AnonInfo = mDNSNULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // !ANONYMOUS_DISABLED
|
||||||
|
|
||||||
|
mDNSexport void ReInitAnonInfo(AnonymousInfo **si, const domainname *name)
|
||||||
|
{
|
||||||
|
(void)si;
|
||||||
|
(void)name;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport AnonymousInfo * AllocateAnonInfo(const domainname *service, const mDNSu8 *AnonData, int len, const ResourceRecord *rr)
|
||||||
|
{
|
||||||
|
(void)service;
|
||||||
|
(void)AnonData;
|
||||||
|
(void)len;
|
||||||
|
(void)rr;
|
||||||
|
|
||||||
|
return mDNSNULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport void FreeAnonInfo(AnonymousInfo *ai)
|
||||||
|
{
|
||||||
|
(void)ai;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport void SetAnonData(DNSQuestion *q, ResourceRecord *rr, mDNSBool ForQuestion)
|
||||||
|
{
|
||||||
|
(void)q;
|
||||||
|
(void)rr;
|
||||||
|
(void)ForQuestion;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport int AnonInfoAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q)
|
||||||
|
{
|
||||||
|
(void)rr;
|
||||||
|
(void)q;
|
||||||
|
|
||||||
|
return mDNSfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport void InitializeAnonInfoForQuestion(mDNS *const m, CacheRecord **McastNSEC3Records, DNSQuestion *q)
|
||||||
|
{
|
||||||
|
(void)m;
|
||||||
|
(void)McastNSEC3Records;
|
||||||
|
(void)q;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport void InitializeAnonInfoForCR(mDNS *const m, CacheRecord **McastNSEC3Records, CacheRecord *cr)
|
||||||
|
{
|
||||||
|
(void)m;
|
||||||
|
(void)McastNSEC3Records;
|
||||||
|
(void)cr;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport void CopyAnonInfoForCR(mDNS *const m, CacheRecord *crto, CacheRecord *crfrom)
|
||||||
|
{
|
||||||
|
(void)m;
|
||||||
|
(void)crto;
|
||||||
|
(void)crfrom;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDNSexport mDNSBool IdenticalAnonInfo(AnonymousInfo *a1, AnonymousInfo *a2)
|
||||||
|
{
|
||||||
|
(void)a1;
|
||||||
|
(void)a2;
|
||||||
|
|
||||||
|
return mDNStrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !ANONYMOUS_DISABLED
|
|
@ -0,0 +1,31 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 Apple Computer, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ANONYMOUS_H_
|
||||||
|
#define __ANONYMOUS_H_
|
||||||
|
|
||||||
|
extern void ReInitAnonInfo(AnonymousInfo **si, const domainname *name);
|
||||||
|
extern AnonymousInfo *AllocateAnonInfo(const domainname *service, const mDNSu8 *AnonData, int len, const ResourceRecord *rr);
|
||||||
|
extern void FreeAnonInfo(AnonymousInfo *ai);
|
||||||
|
extern void SetAnonData(DNSQuestion *q, ResourceRecord *rr, mDNSBool ForQuestion);
|
||||||
|
extern int AnonInfoAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
|
||||||
|
extern void InitializeAnonInfoForCR(mDNS *const m, CacheRecord **McastNSEC3Records, CacheRecord *cr);
|
||||||
|
extern void InitializeAnonInfoForQuestion(mDNS *const m, CacheRecord **McastNSEC3Records, DNSQuestion *q);
|
||||||
|
extern void CopyAnonInfoForCR(mDNS *const m, CacheRecord *crto, CacheRecord *crfrom);
|
||||||
|
extern mDNSBool IdenticalAnonInfo(AnonymousInfo *a1, AnonymousInfo *a2);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,157 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef __DNSSEC_H
|
||||||
|
#define __DNSSEC_H
|
||||||
|
|
||||||
|
#include "CryptoAlg.h"
|
||||||
|
#include "mDNSDebug.h"
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
RRVS_rr, RRVS_rrsig, RRVS_key, RRVS_rrsig_key, RRVS_ds, RRVS_done,
|
||||||
|
} RRVerifierSet;
|
||||||
|
|
||||||
|
typedef struct RRVerifier_struct RRVerifier;
|
||||||
|
typedef struct DNSSECVerifier_struct DNSSECVerifier;
|
||||||
|
typedef struct AuthChain_struct AuthChain;
|
||||||
|
typedef struct InsecureContext_struct InsecureContext;
|
||||||
|
|
||||||
|
struct RRVerifier_struct
|
||||||
|
{
|
||||||
|
RRVerifier *next;
|
||||||
|
mDNSu16 rrtype;
|
||||||
|
mDNSu16 rrclass;
|
||||||
|
mDNSu32 rroriginalttl;
|
||||||
|
mDNSu16 rdlength;
|
||||||
|
mDNSu16 found;
|
||||||
|
mDNSu32 namehash;
|
||||||
|
mDNSu32 rdatahash;
|
||||||
|
domainname name;
|
||||||
|
mDNSu8 *rdata;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Each AuthChain element has one rrset (with multiple resource records of same type), rrsig and key
|
||||||
|
// that validates the rrset.
|
||||||
|
struct AuthChain_struct
|
||||||
|
{
|
||||||
|
AuthChain *next; // Next element in the chain
|
||||||
|
RRVerifier *rrset; // RRSET that is authenticated
|
||||||
|
RRVerifier *rrsig; // Signature for that RRSET
|
||||||
|
RRVerifier *key; // Public key for that RRSET
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ResetAuthChain(dv) { \
|
||||||
|
(dv)->ac = mDNSNULL; \
|
||||||
|
(dv)->actail = &((dv)->ac); \
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void DNSSECVerifierCallback (mDNS *const m, DNSSECVerifier *dv, DNSSECStatus status);
|
||||||
|
//
|
||||||
|
// When we do a validation for a question, there might be additional validations that needs to be done e.g.,
|
||||||
|
// wildcard expanded answer. It is also possible that in the case of nsec we need to prove both that a wildcard
|
||||||
|
// does not apply and the closest encloser proves that name does not exist. We identify these with the following
|
||||||
|
// flags.
|
||||||
|
//
|
||||||
|
// Note: In the following, by "marking the validation", we mean that as part of validation we need to prove
|
||||||
|
// the ones that are marked with.
|
||||||
|
//
|
||||||
|
// A wildcard may be used to answer a question. In that case, we need to verify that the right wildcard was
|
||||||
|
// used in answering the question. This is done by marking the validation with WILDCARD_PROVES_ANSWER_EXPANDED.
|
||||||
|
//
|
||||||
|
// Sometimes we get a NXDOMAIN response. In this case, we may have a wildcard where we need to prove
|
||||||
|
// that the wildcard proves that the name does not exist. This is done by marking the validation with
|
||||||
|
// WILDCARD_PROVES_NONAME_EXISTS.
|
||||||
|
//
|
||||||
|
// In the case of NODATA error, sometimes the name may exist but the query type does not exist. This is done by
|
||||||
|
// marking the validation with NSEC_PROVES_NOTYPE_EXISTS.
|
||||||
|
//
|
||||||
|
// In both NXDOMAIN and NODATA proofs, we may have to prove that the NAME does not exist. This is done by marking
|
||||||
|
// the validation with NSEC_PROVES_NONAME_EXISTS.
|
||||||
|
//
|
||||||
|
#define WILDCARD_PROVES_ANSWER_EXPANDED 0x00000001
|
||||||
|
#define WILDCARD_PROVES_NONAME_EXISTS 0x00000002
|
||||||
|
#define NSEC_PROVES_NOTYPE_EXISTS 0x00000004
|
||||||
|
#define NSEC_PROVES_NONAME_EXISTS 0x00000008
|
||||||
|
#define NSEC3_OPT_OUT 0x00000010 // OptOut was set in NSEC3
|
||||||
|
|
||||||
|
struct DNSSECVerifier_struct
|
||||||
|
{
|
||||||
|
domainname origName; // Original question name that needs verification
|
||||||
|
mDNSu16 origType; // Original question type corresponding to origName
|
||||||
|
mDNSu16 currQtype; // Current question type that is being verified
|
||||||
|
mDNSInterfaceID InterfaceID; // InterfaceID of the question
|
||||||
|
DNSQuestion q;
|
||||||
|
mDNSu8 recursed; // Number of times recursed during validation
|
||||||
|
mDNSu8 ValidationRequired; // Copy of the question's ValidationRequired status
|
||||||
|
mDNSu8 InsecureProofDone;
|
||||||
|
mDNSu8 NumPackets; // Number of packets that we send on the wire for DNSSEC verification.
|
||||||
|
mDNSs32 StartTime; // Time the DNSSEC verification starts
|
||||||
|
mDNSu32 flags;
|
||||||
|
RRVerifierSet next;
|
||||||
|
domainname *wildcardName; // set if the answer is wildcard expanded
|
||||||
|
RRVerifier *pendingNSEC;
|
||||||
|
DNSSECVerifierCallback *DVCallback;
|
||||||
|
DNSSECVerifier *parent;
|
||||||
|
RRVerifier *rrset; // rrset for which we have to verify
|
||||||
|
RRVerifier *rrsig; // RRSIG for rrset
|
||||||
|
RRVerifier *key; // DNSKEY for rrset
|
||||||
|
RRVerifier *rrsigKey; // RRSIG for DNSKEY
|
||||||
|
RRVerifier *ds; // DS for DNSKEY set in parent zone
|
||||||
|
AuthChain *saveac;
|
||||||
|
AuthChain *ac;
|
||||||
|
AuthChain **actail;
|
||||||
|
AlgContext *ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct InsecureContext_struct
|
||||||
|
{
|
||||||
|
DNSSECVerifier *dv; // dv for which we are doing the insecure proof
|
||||||
|
mDNSu8 skip; // labels to skip for forming the name from origName
|
||||||
|
DNSSECStatus status; // status to deliver when done
|
||||||
|
mDNSu8 triggerLabelCount; // Label count of the name that triggered the insecure proof
|
||||||
|
DNSQuestion q;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LogDNSSEC LogOperation
|
||||||
|
|
||||||
|
#define DNS_SERIAL_GT(a, b) ((int)((a) - (b)) > 0)
|
||||||
|
#define DNS_SERIAL_LT(a, b) ((int)((a) - (b)) < 0)
|
||||||
|
|
||||||
|
extern void StartDNSSECVerification(mDNS *const m, void *context);
|
||||||
|
extern RRVerifier* AllocateRRVerifier(const ResourceRecord *const rr, mStatus *status);
|
||||||
|
extern mStatus AddRRSetToVerifier(DNSSECVerifier *dv, const ResourceRecord *const rr, RRVerifier *rv, RRVerifierSet set);
|
||||||
|
extern void VerifySignature(mDNS *const m, DNSSECVerifier *dv, DNSQuestion *q);
|
||||||
|
extern void FreeDNSSECVerifier(mDNS *const m, DNSSECVerifier *dv);
|
||||||
|
extern DNSSECVerifier *AllocateDNSSECVerifier(mDNS *const m, const domainname *name, mDNSu16 rrtype, mDNSInterfaceID InterfaceID,
|
||||||
|
mDNSu8 ValidationRequired, DNSSECVerifierCallback dvcallback, mDNSQuestionCallback qcallback);
|
||||||
|
extern void InitializeQuestion(mDNS *const m, DNSQuestion *question, mDNSInterfaceID InterfaceID, const domainname *qname,
|
||||||
|
mDNSu16 qtype, mDNSQuestionCallback *callback, void *context);
|
||||||
|
extern void ValidateRRSIG(DNSSECVerifier *dv, RRVerifierSet type, const ResourceRecord *const rr);
|
||||||
|
extern void AuthChainLink(DNSSECVerifier *dv, AuthChain *ae);
|
||||||
|
extern mStatus DNSNameToLowerCase(domainname *d, domainname *result);
|
||||||
|
extern int DNSMemCmp(const mDNSu8 *const m1, const mDNSu8 *const m2, int len);
|
||||||
|
extern int DNSSECCanonicalOrder(const domainname *const d1, const domainname *const d2, int *subdomain);
|
||||||
|
extern void ProveInsecure(mDNS *const m, DNSSECVerifier *dv, InsecureContext *ic, domainname *trigger);
|
||||||
|
extern void BumpDNSSECStats(mDNS *const m, DNSSECStatsAction action, DNSSECStatsType type, mDNSu32 value);
|
||||||
|
extern char *DNSSECStatusName(DNSSECStatus status);
|
||||||
|
|
||||||
|
// DNSSECProbe belongs in DNSSECSupport.h but then we don't want to expose yet another plaform specific dnssec file
|
||||||
|
// to other platforms where dnssec is not supported.
|
||||||
|
extern void DNSSECProbe(mDNS *const m);
|
||||||
|
|
||||||
|
#endif // __DNSSEC_H
|
File diff suppressed because it is too large
Load Diff
|
@ -5,70 +5,43 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
File: mDNSDebug.c
|
File: mDNSDebug.c
|
||||||
|
|
||||||
Contains: Implementation of debugging utilities. Requires a POSIX environment.
|
Contains: Implementation of debugging utilities. Requires a POSIX environment.
|
||||||
|
|
||||||
Version: 1.0
|
Version: 1.0
|
||||||
|
|
||||||
Change History (most recent first):
|
*/
|
||||||
|
|
||||||
$Log: mDNSDebug.c,v $
|
|
||||||
Revision 1.7 2006/08/14 23:24:56 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.6 2005/01/27 22:57:56 cheshire
|
|
||||||
Fix compile errors on gcc4
|
|
||||||
|
|
||||||
Revision 1.5 2004/09/17 01:08:55 cheshire
|
|
||||||
Renamed mDNSClientAPI.h to mDNSEmbeddedAPI.h
|
|
||||||
The name "mDNSClientAPI.h" is misleading to new developers looking at this code. The interfaces
|
|
||||||
declared in that file are ONLY appropriate to single-address-space embedded applications.
|
|
||||||
For clients on general-purpose computers, the interfaces defined in dns_sd.h should be used.
|
|
||||||
|
|
||||||
Revision 1.4 2004/06/11 22:36:51 cheshire
|
|
||||||
Fixes for compatibility with Windows
|
|
||||||
|
|
||||||
Revision 1.3 2004/01/28 21:14:23 cheshire
|
|
||||||
Reconcile debug_mode and gDebugLogging into a single flag (mDNS_DebugMode)
|
|
||||||
|
|
||||||
Revision 1.2 2003/12/09 01:30:40 rpantos
|
|
||||||
Fix usage of ARGS... macros to build properly on Windows.
|
|
||||||
|
|
||||||
Revision 1.1 2003/12/08 21:11:42; rpantos
|
|
||||||
Changes necessary to support mDNSResponder on Linux.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
#include "mDNSDebug.h"
|
#include "mDNSDebug.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(WIN32) || defined(EFI32) || defined(EFI64) || defined(EFIX64)
|
||||||
// Need to add Windows syslog support here
|
// Need to add Windows/EFI syslog support here
|
||||||
#define LOG_PID 0x01
|
#define LOG_PID 0x01
|
||||||
#define LOG_CONS 0x02
|
#define LOG_CONS 0x02
|
||||||
#define LOG_PERROR 0x20
|
#define LOG_PERROR 0x20
|
||||||
#define openlog(A,B,C) (void)(A); (void)(B)
|
|
||||||
#define syslog(A,B,C)
|
|
||||||
#define closelog()
|
|
||||||
#else
|
#else
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "mDNSEmbeddedAPI.h"
|
#include "mDNSEmbeddedAPI.h"
|
||||||
|
|
||||||
|
mDNSexport int mDNS_LoggingEnabled = 0;
|
||||||
|
mDNSexport int mDNS_PacketLoggingEnabled = 0;
|
||||||
|
mDNSexport int mDNS_McastLoggingEnabled = 0;
|
||||||
|
mDNSexport int mDNS_McastTracingEnabled = 0;
|
||||||
|
|
||||||
#if MDNS_DEBUGMSGS
|
#if MDNS_DEBUGMSGS
|
||||||
mDNSexport int mDNS_DebugMode = mDNStrue;
|
mDNSexport int mDNS_DebugMode = mDNStrue;
|
||||||
#else
|
#else
|
||||||
|
@ -77,76 +50,46 @@ mDNSexport int mDNS_DebugMode = mDNSfalse;
|
||||||
|
|
||||||
// Note, this uses mDNS_vsnprintf instead of standard "vsnprintf", because mDNS_vsnprintf knows
|
// Note, this uses mDNS_vsnprintf instead of standard "vsnprintf", because mDNS_vsnprintf knows
|
||||||
// how to print special data types like IP addresses and length-prefixed domain names
|
// how to print special data types like IP addresses and length-prefixed domain names
|
||||||
#if MDNS_DEBUGMSGS
|
|
||||||
mDNSexport void debugf_(const char *format, ...)
|
|
||||||
{
|
|
||||||
unsigned char buffer[512];
|
|
||||||
va_list ptr;
|
|
||||||
va_start(ptr,format);
|
|
||||||
buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
|
|
||||||
va_end(ptr);
|
|
||||||
fprintf(stderr,"%s\n", buffer);
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MDNS_DEBUGMSGS > 1
|
#if MDNS_DEBUGMSGS > 1
|
||||||
mDNSexport void verbosedebugf_(const char *format, ...)
|
mDNSexport void verbosedebugf_(const char *format, ...)
|
||||||
{
|
{
|
||||||
unsigned char buffer[512];
|
char buffer[512];
|
||||||
va_list ptr;
|
va_list ptr;
|
||||||
va_start(ptr,format);
|
va_start(ptr,format);
|
||||||
buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
|
buffer[mDNS_vsnprintf(buffer, sizeof(buffer), format, ptr)] = 0;
|
||||||
va_end(ptr);
|
va_end(ptr);
|
||||||
fprintf(stderr,"%s\n", buffer);
|
mDNSPlatformWriteDebugMsg(buffer);
|
||||||
fflush(stderr);
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mDNSlocal void WriteLogMsg(const char *ident, const char *buffer, int logoptflags, int logpriority)
|
// Log message with default "mDNSResponder" ident string at the start
|
||||||
{
|
mDNSlocal void LogMsgWithLevelv(mDNSLogLevel_t logLevel, const char *format, va_list ptr)
|
||||||
if (mDNS_DebugMode) // In debug mode we write to stderr
|
{
|
||||||
{
|
char buffer[512];
|
||||||
fprintf(stderr,"%s\n", buffer);
|
buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
|
||||||
fflush(stderr);
|
mDNSPlatformWriteLogMsg(ProgramName, buffer, logLevel);
|
||||||
}
|
}
|
||||||
else // else, in production mode, we write to syslog
|
|
||||||
{
|
#define LOG_HELPER_BODY(L) \
|
||||||
openlog(ident, LOG_PERROR | logoptflags, LOG_DAEMON);
|
{ \
|
||||||
syslog(logpriority, "%s", buffer);
|
va_list ptr; \
|
||||||
closelog();
|
va_start(ptr,format); \
|
||||||
}
|
LogMsgWithLevelv(L, format, ptr); \
|
||||||
}
|
va_end(ptr); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// see mDNSDebug.h
|
||||||
|
#if !MDNS_HAS_VA_ARG_MACROS
|
||||||
|
void LogMsg_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_MSG)
|
||||||
|
void LogOperation_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_OPERATION)
|
||||||
|
void LogSPS_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_SPS)
|
||||||
|
void LogInfo_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_INFO)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MDNS_DEBUGMSGS
|
||||||
|
void debugf_(const char *format, ...) LOG_HELPER_BODY(MDNS_LOG_DEBUG)
|
||||||
|
#endif
|
||||||
|
|
||||||
// Log message with default "mDNSResponder" ident string at the start
|
// Log message with default "mDNSResponder" ident string at the start
|
||||||
mDNSexport void LogMsg(const char *format, ...)
|
mDNSexport void LogMsgWithLevel(mDNSLogLevel_t logLevel, const char *format, ...)
|
||||||
{
|
LOG_HELPER_BODY(logLevel)
|
||||||
char buffer[512];
|
|
||||||
va_list ptr;
|
|
||||||
va_start(ptr,format);
|
|
||||||
buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
|
|
||||||
va_end(ptr);
|
|
||||||
WriteLogMsg("mDNSResponder", buffer, 0, LOG_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log message with specified ident string at the start
|
|
||||||
mDNSexport void LogMsgIdent(const char *ident, const char *format, ...)
|
|
||||||
{
|
|
||||||
char buffer[512];
|
|
||||||
va_list ptr;
|
|
||||||
va_start(ptr,format);
|
|
||||||
buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
|
|
||||||
va_end(ptr);
|
|
||||||
WriteLogMsg(ident, buffer, ident && *ident ? LOG_PID : 0, LOG_INFO);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log message with no ident string at the start
|
|
||||||
mDNSexport void LogMsgNoIdent(const char *format, ...)
|
|
||||||
{
|
|
||||||
char buffer[512];
|
|
||||||
va_list ptr;
|
|
||||||
va_start(ptr,format);
|
|
||||||
buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
|
|
||||||
va_end(ptr);
|
|
||||||
WriteLogMsg("", buffer, 0, LOG_INFO);
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,84 +5,15 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
*/
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: mDNSDebug.h,v $
|
|
||||||
Revision 1.26.2.1 2006/08/29 06:24:22 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.26 2005/07/04 22:40:26 cheshire
|
|
||||||
Additional debugging code to help catch memory corruption
|
|
||||||
|
|
||||||
Revision 1.25 2004/12/14 21:34:16 cheshire
|
|
||||||
Add "#define ANSWER_REMOTE_HOSTNAME_QUERIES 0" and comment
|
|
||||||
|
|
||||||
Revision 1.24 2004/09/16 01:58:21 cheshire
|
|
||||||
Fix compiler warnings
|
|
||||||
|
|
||||||
Revision 1.23 2004/05/18 23:51:25 cheshire
|
|
||||||
Tidy up all checkin comments to use consistent "<rdar://problem/xxxxxxx>" format for bug numbers
|
|
||||||
|
|
||||||
Revision 1.22 2004/04/22 04:27:42 cheshire
|
|
||||||
Spacing tidyup
|
|
||||||
|
|
||||||
Revision 1.21 2004/04/14 23:21:41 ksekar
|
|
||||||
Removed accidental checkin of MALLOC_DEBUGING flag in 1.20
|
|
||||||
|
|
||||||
Revision 1.20 2004/04/14 23:09:28 ksekar
|
|
||||||
Support for TSIG signed dynamic updates.
|
|
||||||
|
|
||||||
Revision 1.19 2004/03/15 18:57:59 cheshire
|
|
||||||
Undo last checkin that accidentally made verbose debugging the default for all targets
|
|
||||||
|
|
||||||
Revision 1.18 2004/03/13 01:57:33 ksekar
|
|
||||||
<rdar://problem/3192546>: DynDNS: Dynamic update of service records
|
|
||||||
|
|
||||||
Revision 1.17 2004/01/28 21:14:23 cheshire
|
|
||||||
Reconcile debug_mode and gDebugLogging into a single flag (mDNS_DebugMode)
|
|
||||||
|
|
||||||
Revision 1.16 2003/12/09 01:30:06 rpantos
|
|
||||||
Fix usage of ARGS... macros to build properly on Windows.
|
|
||||||
|
|
||||||
Revision 1.15 2003/12/08 20:55:26 rpantos
|
|
||||||
Move some definitions here from mDNSMacOSX.h.
|
|
||||||
|
|
||||||
Revision 1.14 2003/08/12 19:56:24 cheshire
|
|
||||||
Update to APSL 2.0
|
|
||||||
|
|
||||||
Revision 1.13 2003/07/02 21:19:46 cheshire
|
|
||||||
<rdar://problem/3313413> Update copyright notices, etc., in source code comments
|
|
||||||
|
|
||||||
Revision 1.12 2003/05/26 03:01:27 cheshire
|
|
||||||
<rdar://problem/3268904> sprintf/vsprintf-style functions are unsafe; use snprintf/vsnprintf instead
|
|
||||||
|
|
||||||
Revision 1.11 2003/05/21 17:48:10 cheshire
|
|
||||||
Add macro to enable GCC's printf format string checking
|
|
||||||
|
|
||||||
Revision 1.10 2003/04/26 02:32:57 cheshire
|
|
||||||
Add extern void LogMsg(const char *format, ...);
|
|
||||||
|
|
||||||
Revision 1.9 2002/09/21 20:44:49 zarzycki
|
|
||||||
Added APSL info
|
|
||||||
|
|
||||||
Revision 1.8 2002/09/19 04:20:43 cheshire
|
|
||||||
Remove high-ascii characters that confuse some systems
|
|
||||||
|
|
||||||
Revision 1.7 2002/09/16 18:41:42 cheshire
|
|
||||||
Merge in license terms from Quinn's copy, in preparation for Darwin release
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
#ifndef __mDNSDebug_h
|
#ifndef __mDNSDebug_h
|
||||||
#define __mDNSDebug_h
|
#define __mDNSDebug_h
|
||||||
|
@ -104,89 +35,132 @@ Merge in license terms from Quinn's copy, in preparation for Darwin release
|
||||||
// warning: repeated `#' flag in format (for %##s -- DNS name string format)
|
// warning: repeated `#' flag in format (for %##s -- DNS name string format)
|
||||||
// warning: double format, pointer arg (arg 2) (for %.4a, %.16a, %#a -- IP address formats)
|
// warning: double format, pointer arg (arg 2) (for %.4a, %.16a, %#a -- IP address formats)
|
||||||
#define MDNS_CHECK_PRINTF_STYLE_FUNCTIONS 0
|
#define MDNS_CHECK_PRINTF_STYLE_FUNCTIONS 0
|
||||||
#if MDNS_CHECK_PRINTF_STYLE_FUNCTIONS
|
|
||||||
#define IS_A_PRINTF_STYLE_FUNCTION(F,A) __attribute__ ((format(printf,F,A)))
|
|
||||||
#else
|
|
||||||
#define IS_A_PRINTF_STYLE_FUNCTION(F,A)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
typedef enum
|
||||||
extern "C" {
|
{
|
||||||
#endif
|
MDNS_LOG_MSG,
|
||||||
|
MDNS_LOG_OPERATION,
|
||||||
#if MDNS_DEBUGMSGS
|
MDNS_LOG_SPS,
|
||||||
#define debugf debugf_
|
MDNS_LOG_INFO,
|
||||||
extern void debugf_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
|
MDNS_LOG_DEBUG,
|
||||||
#else // If debug breaks are off, use a preprocessor trick to optimize those calls out of the code
|
} mDNSLogLevel_t;
|
||||||
#if (defined(__GNUC__))
|
|
||||||
#define debugf( ARGS... ) ((void)0)
|
|
||||||
#elif (defined(__MWERKS__))
|
|
||||||
#define debugf( ... )
|
|
||||||
#else
|
|
||||||
#define debugf 1 ? ((void)0) : (void)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MDNS_DEBUGMSGS > 1
|
|
||||||
#define verbosedebugf verbosedebugf_
|
|
||||||
extern void verbosedebugf_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
|
|
||||||
#else
|
|
||||||
#if (defined(__GNUC__))
|
|
||||||
#define verbosedebugf( ARGS... ) ((void)0)
|
|
||||||
#elif (defined(__MWERKS__))
|
|
||||||
#define verbosedebugf( ... )
|
|
||||||
#else
|
|
||||||
#define verbosedebugf 1 ? ((void)0) : (void)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// LogMsg is used even in shipping code, to write truly serious error messages to syslog (or equivalent)
|
|
||||||
extern int mDNS_DebugMode; // If non-zero, LogMsg() writes to stderr instead of syslog
|
|
||||||
extern void LogMsg(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
|
|
||||||
extern void LogMsgIdent(const char *ident, const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(2,3);
|
|
||||||
extern void LogMsgNoIdent(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
|
|
||||||
|
|
||||||
// Set this symbol to 1 to answer remote queries for our Address, reverse mapping PTR, and HINFO records
|
// Set this symbol to 1 to answer remote queries for our Address, reverse mapping PTR, and HINFO records
|
||||||
#define ANSWER_REMOTE_HOSTNAME_QUERIES 0
|
#define ANSWER_REMOTE_HOSTNAME_QUERIES 0
|
||||||
|
|
||||||
// Set this symbol to 1 to do extra debug checks on malloc() and free()
|
// Set this symbol to 1 to do extra debug checks on malloc() and free()
|
||||||
// Set this symbol to 2 to write a log message for every malloc() and free()
|
// Set this symbol to 2 to write a log message for every malloc() and free()
|
||||||
#define MACOSX_MDNS_MALLOC_DEBUGGING 0
|
//#define MACOSX_MDNS_MALLOC_DEBUGGING 1
|
||||||
|
|
||||||
#if MACOSX_MDNS_MALLOC_DEBUGGING >= 1
|
//#define ForceAlerts 1
|
||||||
|
//#define LogTimeStamps 1
|
||||||
|
|
||||||
|
// Developer-settings section ends here
|
||||||
|
|
||||||
|
#if MDNS_CHECK_PRINTF_STYLE_FUNCTIONS
|
||||||
|
#define IS_A_PRINTF_STYLE_FUNCTION(F,A) __attribute__ ((format(printf,F,A)))
|
||||||
|
#else
|
||||||
|
#define IS_A_PRINTF_STYLE_FUNCTION(F,A)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Variable argument macro support. Use ANSI C99 __VA_ARGS__ where possible. Otherwise, use the next best thing.
|
||||||
|
|
||||||
|
#if (defined(__GNUC__))
|
||||||
|
#if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)))
|
||||||
|
#define MDNS_C99_VA_ARGS 1
|
||||||
|
#define MDNS_GNU_VA_ARGS 0
|
||||||
|
#else
|
||||||
|
#define MDNS_C99_VA_ARGS 0
|
||||||
|
#define MDNS_GNU_VA_ARGS 1
|
||||||
|
#endif
|
||||||
|
#define MDNS_HAS_VA_ARG_MACROS 1
|
||||||
|
#elif (_MSC_VER >= 1400) // Visual Studio 2005 and later
|
||||||
|
#define MDNS_C99_VA_ARGS 1
|
||||||
|
#define MDNS_GNU_VA_ARGS 0
|
||||||
|
#define MDNS_HAS_VA_ARG_MACROS 1
|
||||||
|
#elif (defined(__MWERKS__))
|
||||||
|
#define MDNS_C99_VA_ARGS 1
|
||||||
|
#define MDNS_GNU_VA_ARGS 0
|
||||||
|
#define MDNS_HAS_VA_ARG_MACROS 1
|
||||||
|
#else
|
||||||
|
#define MDNS_C99_VA_ARGS 1
|
||||||
|
#define MDNS_GNU_VA_ARGS 0
|
||||||
|
#define MDNS_HAS_VA_ARG_MACROS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (MDNS_HAS_VA_ARG_MACROS)
|
||||||
|
#if (MDNS_C99_VA_ARGS)
|
||||||
|
#define debug_noop(... ) ((void)0)
|
||||||
|
#define LogMsg(... ) LogMsgWithLevel(MDNS_LOG_MSG, __VA_ARGS__)
|
||||||
|
#define LogOperation(... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_OPERATION, __VA_ARGS__);} while (0)
|
||||||
|
#define LogSPS(... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_SPS, __VA_ARGS__);} while (0)
|
||||||
|
#define LogInfo(... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_INFO, __VA_ARGS__);} while (0)
|
||||||
|
#elif (MDNS_GNU_VA_ARGS)
|
||||||
|
#define debug_noop( ARGS... ) ((void)0)
|
||||||
|
#define LogMsg( ARGS... ) LogMsgWithLevel(MDNS_LOG_MSG, ARGS)
|
||||||
|
#define LogOperation( ARGS... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_OPERATION, ARGS);} while (0)
|
||||||
|
#define LogSPS( ARGS... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_SPS, ARGS);} while (0)
|
||||||
|
#define LogInfo( ARGS... ) do { if (mDNS_LoggingEnabled) LogMsgWithLevel(MDNS_LOG_INFO, ARGS);} while (0)
|
||||||
|
#else
|
||||||
|
#error Unknown variadic macros
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
// If your platform does not support variadic macros, you need to define the following variadic functions.
|
||||||
|
// See mDNSShared/mDNSDebug.c for sample implementation
|
||||||
|
#define debug_noop 1 ? (void)0 : (void)
|
||||||
|
#define LogMsg LogMsg_
|
||||||
|
#define LogOperation (mDNS_LoggingEnabled == 0) ? ((void)0) : LogOperation_
|
||||||
|
#define LogSPS (mDNS_LoggingEnabled == 0) ? ((void)0) : LogSPS_
|
||||||
|
#define LogInfo (mDNS_LoggingEnabled == 0) ? ((void)0) : LogInfo_
|
||||||
|
extern void LogMsg_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
|
||||||
|
extern void LogOperation_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
|
||||||
|
extern void LogSPS_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
|
||||||
|
extern void LogInfo_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MDNS_DEBUGMSGS
|
||||||
|
#define debugf debugf_
|
||||||
|
extern void debugf_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
|
||||||
|
#else
|
||||||
|
#define debugf debug_noop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MDNS_DEBUGMSGS > 1
|
||||||
|
#define verbosedebugf verbosedebugf_
|
||||||
|
extern void verbosedebugf_(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
|
||||||
|
#else
|
||||||
|
#define verbosedebugf debug_noop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int mDNS_LoggingEnabled;
|
||||||
|
extern int mDNS_PacketLoggingEnabled;
|
||||||
|
extern int mDNS_McastLoggingEnabled;
|
||||||
|
extern int mDNS_McastTracingEnabled;
|
||||||
|
extern int mDNS_DebugMode; // If non-zero, LogMsg() writes to stderr instead of syslog
|
||||||
|
extern const char ProgramName[];
|
||||||
|
|
||||||
|
extern void LogMsgWithLevel(mDNSLogLevel_t logLevel, const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(2,3);
|
||||||
|
// LogMsgNoIdent needs to be fixed so that it logs without the ident prefix like it used to
|
||||||
|
// (or completely overhauled to use the new "log to a separate file" facility)
|
||||||
|
#define LogMsgNoIdent LogMsg
|
||||||
|
|
||||||
|
#if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING >= 1
|
||||||
extern void *mallocL(char *msg, unsigned int size);
|
extern void *mallocL(char *msg, unsigned int size);
|
||||||
extern void freeL(char *msg, void *x);
|
extern void freeL(char *msg, void *x);
|
||||||
extern void LogMemCorruption(const char *format, ...);
|
extern void LogMemCorruption(const char *format, ...);
|
||||||
extern void uds_validatelists(void);
|
extern void uds_validatelists(void);
|
||||||
|
extern void udns_validatelists(void *const v);
|
||||||
#else
|
#else
|
||||||
#define mallocL(X,Y) malloc(Y)
|
#define mallocL(X,Y) malloc(Y)
|
||||||
#define freeL(X,Y) free(Y)
|
#define freeL(X,Y) free(Y)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MACOSX_MDNS_MALLOC_DEBUGGING >= 2
|
#ifdef __cplusplus
|
||||||
#define LogMalloc LogMsg
|
}
|
||||||
#else
|
|
||||||
#if (defined( __GNUC__ ))
|
|
||||||
#define LogMalloc(ARGS...) ((void)0)
|
|
||||||
#elif (defined( __MWERKS__ ))
|
|
||||||
#define LogMalloc( ... )
|
|
||||||
#else
|
|
||||||
#define LogMalloc 1 ? ((void)0) : (void)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LogAllOperations 0
|
|
||||||
|
|
||||||
#if LogAllOperations
|
|
||||||
#define LogOperation LogMsg
|
|
||||||
#else
|
|
||||||
#define LogOperation debugf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ForceAlerts 0
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -5,77 +5,15 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
*/
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: mDNSPosix.h,v $
|
|
||||||
Revision 1.18 2006/08/14 23:24:47 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.17 2005/02/04 00:39:59 cheshire
|
|
||||||
Move ParseDNSServers() from PosixDaemon.c to mDNSPosix.c so all Posix client layers can use it
|
|
||||||
|
|
||||||
Revision 1.16 2004/11/30 22:37:01 cheshire
|
|
||||||
Update copyright dates and add "Mode: C; tab-width: 4" headers
|
|
||||||
|
|
||||||
Revision 1.15 2004/02/06 01:19:51 cheshire
|
|
||||||
Conditionally exclude IPv6 code unless HAVE_IPV6 is set
|
|
||||||
|
|
||||||
Revision 1.14 2004/01/28 21:12:15 cheshire
|
|
||||||
Reconcile mDNSIPv6Support & HAVE_IPV6 into a single flag (HAVE_IPV6)
|
|
||||||
|
|
||||||
Revision 1.13 2004/01/24 05:12:03 cheshire
|
|
||||||
<rdar://problem/3534352>: Need separate socket for issuing unicast queries
|
|
||||||
|
|
||||||
Revision 1.12 2004/01/23 21:37:08 cheshire
|
|
||||||
For consistency, rename multicastSocket to multicastSocket4, and multicastSocketv6 to multicastSocket6
|
|
||||||
|
|
||||||
Revision 1.11 2003/12/11 03:03:51 rpantos
|
|
||||||
Clean up mDNSPosix so that it builds on OS X again.
|
|
||||||
|
|
||||||
Revision 1.10 2003/12/08 20:47:02 rpantos
|
|
||||||
Add support for mDNSResponder on Linux.
|
|
||||||
|
|
||||||
Revision 1.9 2003/10/30 19:25:19 cheshire
|
|
||||||
Fix warning on certain compilers
|
|
||||||
|
|
||||||
Revision 1.8 2003/08/12 19:56:26 cheshire
|
|
||||||
Update to APSL 2.0
|
|
||||||
|
|
||||||
Revision 1.7 2003/07/02 21:19:59 cheshire
|
|
||||||
<rdar://problem/3313413> Update copyright notices, etc., in source code comments
|
|
||||||
|
|
||||||
Revision 1.6 2003/03/13 03:46:21 cheshire
|
|
||||||
Fixes to make the code build on Linux
|
|
||||||
|
|
||||||
Revision 1.5 2003/03/08 00:35:56 cheshire
|
|
||||||
Switched to using new "mDNS_Execute" model (see "mDNSCore/Implementer Notes.txt")
|
|
||||||
|
|
||||||
Revision 1.4 2002/12/23 22:13:31 jgraessl
|
|
||||||
|
|
||||||
Reviewed by: Stuart Cheshire
|
|
||||||
Initial IPv6 support for mDNSResponder.
|
|
||||||
|
|
||||||
Revision 1.3 2002/09/21 20:44:53 zarzycki
|
|
||||||
Added APSL info
|
|
||||||
|
|
||||||
Revision 1.2 2002/09/19 04:20:44 cheshire
|
|
||||||
Remove high-ascii characters that confuse some systems
|
|
||||||
|
|
||||||
Revision 1.1 2002/09/17 06:24:34 cheshire
|
|
||||||
First checkin
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
#ifndef __mDNSPlatformPosix_h
|
#ifndef __mDNSPlatformPosix_h
|
||||||
#define __mDNSPlatformPosix_h
|
#define __mDNSPlatformPosix_h
|
||||||
|
@ -84,7 +22,7 @@ First checkin
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// PosixNetworkInterface is a record extension of the core NetworkInterfaceInfo
|
// PosixNetworkInterface is a record extension of the core NetworkInterfaceInfo
|
||||||
|
@ -96,32 +34,33 @@ First checkin
|
||||||
typedef struct PosixNetworkInterface PosixNetworkInterface;
|
typedef struct PosixNetworkInterface PosixNetworkInterface;
|
||||||
|
|
||||||
struct PosixNetworkInterface
|
struct PosixNetworkInterface
|
||||||
{
|
{
|
||||||
NetworkInterfaceInfo coreIntf;
|
NetworkInterfaceInfo coreIntf; // MUST be the first element in this structure
|
||||||
const char * intfName;
|
mDNSs32 LastSeen;
|
||||||
PosixNetworkInterface * aliasIntf;
|
const char * intfName;
|
||||||
int index;
|
PosixNetworkInterface * aliasIntf;
|
||||||
int multicastSocket4;
|
int index;
|
||||||
|
int multicastSocket4;
|
||||||
#if HAVE_IPV6
|
#if HAVE_IPV6
|
||||||
int multicastSocket6;
|
int multicastSocket6;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is a global because debugf_() needs to be able to check its value
|
// This is a global because debugf_() needs to be able to check its value
|
||||||
extern int gMDNSPlatformPosixVerboseLevel;
|
extern int gMDNSPlatformPosixVerboseLevel;
|
||||||
|
|
||||||
struct mDNS_PlatformSupport_struct
|
struct mDNS_PlatformSupport_struct
|
||||||
{
|
{
|
||||||
int unicastSocket4;
|
int unicastSocket4;
|
||||||
#if HAVE_IPV6
|
#if HAVE_IPV6
|
||||||
int unicastSocket6;
|
int unicastSocket6;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define uDNS_SERVERS_FILE "/etc/resolv.conf"
|
#define uDNS_SERVERS_FILE "/etc/resolv.conf"
|
||||||
extern int ParseDNSServers(mDNS *m, const char *filePath);
|
extern int ParseDNSServers(mDNS *m, const char *filePath);
|
||||||
extern mStatus mDNSPlatformPosixRefreshInterfaceList(mDNS *const m);
|
extern mStatus mDNSPlatformPosixRefreshInterfaceList(mDNS *const m);
|
||||||
// See comment in implementation.
|
// See comment in implementation.
|
||||||
|
|
||||||
// Call mDNSPosixGetFDSet before calling select(), to update the parameters
|
// Call mDNSPosixGetFDSet before calling select(), to update the parameters
|
||||||
// as may be necessary to meet the needs of the mDNSCore code.
|
// as may be necessary to meet the needs of the mDNSCore code.
|
||||||
|
@ -132,7 +71,7 @@ extern mStatus mDNSPlatformPosixRefreshInterfaceList(mDNS *const m);
|
||||||
extern void mDNSPosixGetFDSet(mDNS *m, int *nfds, fd_set *readfds, struct timeval *timeout);
|
extern void mDNSPosixGetFDSet(mDNS *m, int *nfds, fd_set *readfds, struct timeval *timeout);
|
||||||
extern void mDNSPosixProcessFDSet(mDNS *const m, fd_set *readfds);
|
extern void mDNSPosixProcessFDSet(mDNS *const m, fd_set *readfds);
|
||||||
|
|
||||||
typedef void (*mDNSPosixEventCallback)( void *context);
|
typedef void (*mDNSPosixEventCallback)(int fd, short filter, void *context);
|
||||||
|
|
||||||
extern mStatus mDNSPosixAddFDToEventLoop( int fd, mDNSPosixEventCallback callback, void *context);
|
extern mStatus mDNSPosixAddFDToEventLoop( int fd, mDNSPosixEventCallback callback, void *context);
|
||||||
extern mStatus mDNSPosixRemoveFDFromEventLoop( int fd);
|
extern mStatus mDNSPosixRemoveFDFromEventLoop( int fd);
|
||||||
|
@ -141,7 +80,7 @@ extern mStatus mDNSPosixIgnoreSignalInEventLoop( int signum);
|
||||||
extern mStatus mDNSPosixRunEventLoopOnce( mDNS *m, const struct timeval *pTimeout, sigset_t *pSignalsReceived, mDNSBool *pDataDispatched);
|
extern mStatus mDNSPosixRunEventLoopOnce( mDNS *m, const struct timeval *pTimeout, sigset_t *pSignalsReceived, mDNSBool *pDataDispatched);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
/*
|
|
||||||
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
|
||||||
* Use is subject to license terms.
|
|
||||||
*/
|
|
||||||
/* -*- Mode: C; tab-width: 4 -*-
|
/* -*- Mode: C; tab-width: 4 -*-
|
||||||
*
|
*
|
||||||
* Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
|
* Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
|
||||||
|
@ -9,9 +5,9 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -21,14 +17,13 @@
|
||||||
|
|
||||||
#include "mDNSUNP.h"
|
#include "mDNSUNP.h"
|
||||||
|
|
||||||
#include "mDNSDebug.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
@ -36,24 +31,24 @@
|
||||||
macro, usually defined in <sys/param.h> or someplace like that, to make sure the
|
macro, usually defined in <sys/param.h> or someplace like that, to make sure the
|
||||||
CMSG_NXTHDR macro is well-formed. On such platforms, the symbol NEED_ALIGN_MACRO
|
CMSG_NXTHDR macro is well-formed. On such platforms, the symbol NEED_ALIGN_MACRO
|
||||||
should be set to the name of the header to include to get the ALIGN(P) macro.
|
should be set to the name of the header to include to get the ALIGN(P) macro.
|
||||||
*/
|
*/
|
||||||
#ifdef NEED_ALIGN_MACRO
|
#ifdef NEED_ALIGN_MACRO
|
||||||
#include NEED_ALIGN_MACRO
|
#include NEED_ALIGN_MACRO
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Solaris defined SIOCGIFCONF etc in <sys/sockio.h> but
|
/* Solaris defined SIOCGIFCONF etc in <sys/sockio.h> but
|
||||||
other platforms don't even have that include file. So,
|
other platforms don't even have that include file. So,
|
||||||
if we haven't yet got a definition, let's try to find
|
if we haven't yet got a definition, let's try to find
|
||||||
<sys/sockio.h>.
|
<sys/sockio.h>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SIOCGIFCONF
|
#ifndef SIOCGIFCONF
|
||||||
#include <sys/sockio.h>
|
#include <sys/sockio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* sockaddr_dl is only referenced if we're using IP_RECVIF,
|
/* sockaddr_dl is only referenced if we're using IP_RECVIF,
|
||||||
so only include the header in that case.
|
so only include the header in that case.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef IP_RECVIF
|
#ifdef IP_RECVIF
|
||||||
#include <net/if_dl.h>
|
#include <net/if_dl.h>
|
||||||
|
@ -64,138 +59,161 @@
|
||||||
#include <net/if_var.h>
|
#include <net/if_var.h>
|
||||||
#else
|
#else
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
#endif /* !HAVE_SOLARIS */
|
#endif /* !HAVE_SOLARIS */
|
||||||
#include <netinet/in_var.h>
|
#include <netinet/in_var.h>
|
||||||
// NOTE: netinet/in_var.h implicitly includes netinet6/in6_var.h for us
|
// Note: netinet/in_var.h implicitly includes netinet6/in6_var.h for us
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(AF_INET6) && HAVE_IPV6
|
#if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
|
||||||
|
|
||||||
#if HAVE_LINUX
|
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
/* Converts a prefix length to IPv6 network mask */
|
/* Converts a prefix length to IPv6 network mask */
|
||||||
void plen_to_mask(int plen, char *addr) {
|
void plen_to_mask(int plen, char *addr) {
|
||||||
int i;
|
int i;
|
||||||
int colons=7; /* Number of colons in IPv6 address */
|
int colons=7; /* Number of colons in IPv6 address */
|
||||||
int bits_in_block=16; /* Bits per IPv6 block */
|
int bits_in_block=16; /* Bits per IPv6 block */
|
||||||
for(i=0;i<=colons;i++) {
|
for(i=0; i<=colons; i++) {
|
||||||
int block, ones=0xffff, ones_in_block;
|
int block, ones=0xffff, ones_in_block;
|
||||||
if(plen>bits_in_block) ones_in_block=bits_in_block;
|
if (plen>bits_in_block) ones_in_block=bits_in_block;
|
||||||
else ones_in_block=plen;
|
else ones_in_block=plen;
|
||||||
block = ones & (ones << (bits_in_block-ones_in_block));
|
block = ones & (ones << (bits_in_block-ones_in_block));
|
||||||
i==0 ? sprintf(addr, "%x", block) : sprintf(addr, "%s:%x", addr, block);
|
i==0 ? sprintf(addr, "%x", block) : sprintf(addr, "%s:%x", addr, block);
|
||||||
plen -= ones_in_block;
|
plen -= ones_in_block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Gets IPv6 interface information from the /proc filesystem in linux*/
|
/* Gets IPv6 interface information from the /proc filesystem in linux*/
|
||||||
struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
|
struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
|
||||||
{
|
{
|
||||||
struct ifi_info *ifi, *ifihead, **ifipnext;
|
struct ifi_info *ifi, *ifihead, **ifipnext, *ifipold, **ifiptr;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char addr[8][5];
|
char addr[8][5];
|
||||||
int flags, myflags, index, plen, scope;
|
int flags, myflags, index, plen, scope;
|
||||||
char ifname[8], lastname[IFNAMSIZ];
|
char ifname[9], lastname[IFNAMSIZ];
|
||||||
char addr6[32+7+1]; /* don't forget the seven ':' */
|
char addr6[32+7+1]; /* don't forget the seven ':' */
|
||||||
struct addrinfo hints, *res0;
|
struct addrinfo hints, *res0;
|
||||||
struct sockaddr_in6 *sin6;
|
struct sockaddr_in6 *sin6;
|
||||||
struct in6_addr *addrptr;
|
struct in6_addr *addrptr;
|
||||||
int err;
|
int err;
|
||||||
|
int sockfd = -1;
|
||||||
|
struct ifreq ifr;
|
||||||
|
|
||||||
res0=NULL;
|
res0=NULL;
|
||||||
ifihead = NULL;
|
ifihead = NULL;
|
||||||
ifipnext = &ifihead;
|
ifipnext = &ifihead;
|
||||||
lastname[0] = 0;
|
lastname[0] = 0;
|
||||||
|
|
||||||
if ((fp = fopen(PROC_IFINET6_PATH, "r")) != NULL) {
|
if ((fp = fopen(PROC_IFINET6_PATH, "r")) != NULL) {
|
||||||
while (fscanf(fp,
|
sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||||
"%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %8s\n",
|
if (sockfd < 0) {
|
||||||
addr[0],addr[1],addr[2],addr[3],
|
goto gotError;
|
||||||
addr[4],addr[5],addr[6],addr[7],
|
}
|
||||||
&index, &plen, &scope, &flags, ifname) != EOF) {
|
while (fscanf(fp,
|
||||||
|
"%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %8s\n",
|
||||||
|
addr[0],addr[1],addr[2],addr[3],
|
||||||
|
addr[4],addr[5],addr[6],addr[7],
|
||||||
|
&index, &plen, &scope, &flags, ifname) != EOF) {
|
||||||
|
|
||||||
myflags = 0;
|
myflags = 0;
|
||||||
if (strncmp(lastname, ifname, IFNAMSIZ) == 0) {
|
if (strncmp(lastname, ifname, IFNAMSIZ) == 0) {
|
||||||
if (doaliases == 0)
|
if (doaliases == 0)
|
||||||
continue; /* already processed this interface */
|
continue; /* already processed this interface */
|
||||||
myflags = IFI_ALIAS;
|
myflags = IFI_ALIAS;
|
||||||
}
|
}
|
||||||
memcpy(lastname, ifname, IFNAMSIZ);
|
memcpy(lastname, ifname, IFNAMSIZ);
|
||||||
ifi = (struct ifi_info*)calloc(1, sizeof(struct ifi_info));
|
ifi = (struct ifi_info*)calloc(1, sizeof(struct ifi_info));
|
||||||
if (ifi == NULL) {
|
if (ifi == NULL) {
|
||||||
goto gotError;
|
goto gotError;
|
||||||
}
|
}
|
||||||
|
|
||||||
*ifipnext = ifi; /* prev points to this new one */
|
ifipold = *ifipnext; /* need this later */
|
||||||
ifipnext = &ifi->ifi_next; /* pointer to next one goes here */
|
ifiptr = ifipnext;
|
||||||
|
*ifipnext = ifi; /* prev points to this new one */
|
||||||
|
ifipnext = &ifi->ifi_next; /* pointer to next one goes here */
|
||||||
|
|
||||||
sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
|
sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
|
||||||
addr[0],addr[1],addr[2],addr[3],
|
addr[0],addr[1],addr[2],addr[3],
|
||||||
addr[4],addr[5],addr[6],addr[7]);
|
addr[4],addr[5],addr[6],addr[7]);
|
||||||
|
|
||||||
/* Add address of the interface */
|
/* Add address of the interface */
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = AF_INET6;
|
hints.ai_family = AF_INET6;
|
||||||
hints.ai_flags = AI_NUMERICHOST;
|
hints.ai_flags = AI_NUMERICHOST;
|
||||||
err = getaddrinfo(addr6, NULL, &hints, &res0);
|
err = getaddrinfo(addr6, NULL, &hints, &res0);
|
||||||
if (err) {
|
if (err) {
|
||||||
goto gotError;
|
goto gotError;
|
||||||
}
|
}
|
||||||
ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in6));
|
ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in6));
|
||||||
if (ifi->ifi_addr == NULL) {
|
if (ifi->ifi_addr == NULL) {
|
||||||
goto gotError;
|
goto gotError;
|
||||||
}
|
}
|
||||||
memcpy(ifi->ifi_addr, res0->ai_addr, sizeof(struct sockaddr_in6));
|
memcpy(ifi->ifi_addr, res0->ai_addr, sizeof(struct sockaddr_in6));
|
||||||
|
|
||||||
/* Add netmask of the interface */
|
/* Add netmask of the interface */
|
||||||
char ipv6addr[INET6_ADDRSTRLEN];
|
char ipv6addr[INET6_ADDRSTRLEN];
|
||||||
plen_to_mask(plen, ipv6addr);
|
plen_to_mask(plen, ipv6addr);
|
||||||
ifi->ifi_netmask = calloc(1, sizeof(struct sockaddr_in6));
|
ifi->ifi_netmask = calloc(1, sizeof(struct sockaddr_in6));
|
||||||
if (ifi->ifi_addr == NULL) {
|
if (ifi->ifi_addr == NULL) {
|
||||||
goto gotError;
|
goto gotError;
|
||||||
}
|
}
|
||||||
sin6=calloc(1, sizeof(struct sockaddr_in6));
|
sin6=calloc(1, sizeof(struct sockaddr_in6));
|
||||||
addrptr=calloc(1, sizeof(struct in6_addr));
|
addrptr=calloc(1, sizeof(struct in6_addr));
|
||||||
inet_pton(family, ipv6addr, addrptr);
|
inet_pton(family, ipv6addr, addrptr);
|
||||||
sin6->sin6_family=family;
|
sin6->sin6_family=family;
|
||||||
sin6->sin6_addr=*addrptr;
|
sin6->sin6_addr=*addrptr;
|
||||||
sin6->sin6_scope_id=scope;
|
sin6->sin6_scope_id=scope;
|
||||||
memcpy(ifi->ifi_netmask, sin6, sizeof(struct sockaddr_in6));
|
memcpy(ifi->ifi_netmask, sin6, sizeof(struct sockaddr_in6));
|
||||||
free(sin6);
|
free(sin6);
|
||||||
|
|
||||||
|
|
||||||
/* Add interface name */
|
/* Add interface name */
|
||||||
memcpy(ifi->ifi_name, ifname, IFI_NAME);
|
memcpy(ifi->ifi_name, ifname, IFI_NAME);
|
||||||
|
|
||||||
/* Add interface index */
|
/* Add interface index */
|
||||||
ifi->ifi_index = index;
|
ifi->ifi_index = index;
|
||||||
|
|
||||||
/* If interface is in /proc then it is up*/
|
/* Add interface flags*/
|
||||||
ifi->ifi_flags = IFF_UP;
|
memcpy(ifr.ifr_name, ifname, IFNAMSIZ);
|
||||||
|
if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
|
||||||
|
if (errno == EADDRNOTAVAIL) {
|
||||||
|
/*
|
||||||
|
* If the main interface is configured with no IP address but
|
||||||
|
* an alias interface exists with an IP address, you get
|
||||||
|
* EADDRNOTAVAIL for the main interface
|
||||||
|
*/
|
||||||
|
free(ifi->ifi_addr);
|
||||||
|
free(ifi);
|
||||||
|
ifipnext = ifiptr;
|
||||||
|
*ifipnext = ifipold;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
goto gotError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ifi->ifi_flags = ifr.ifr_flags;
|
||||||
|
freeaddrinfo(res0);
|
||||||
|
res0=NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto done;
|
||||||
|
|
||||||
freeaddrinfo(res0);
|
gotError:
|
||||||
res0=NULL;
|
if (ifihead != NULL) {
|
||||||
}
|
free_ifi_info(ifihead);
|
||||||
}
|
ifihead = NULL;
|
||||||
goto done;
|
}
|
||||||
|
if (res0 != NULL) {
|
||||||
gotError:
|
freeaddrinfo(res0);
|
||||||
if (ifihead != NULL) {
|
res0=NULL;
|
||||||
free_ifi_info(ifihead);
|
}
|
||||||
ifihead = NULL;
|
done:
|
||||||
}
|
if (sockfd != -1) {
|
||||||
if (res0 != NULL) {
|
assert(close(sockfd) == 0);
|
||||||
freeaddrinfo(res0);
|
}
|
||||||
res0=NULL;
|
return(ifihead); /* pointer to first structure in linked list */
|
||||||
}
|
}
|
||||||
done:
|
#endif // defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
|
||||||
return(ifihead); /* pointer to first structure in linked list */
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* LINUX */
|
|
||||||
#endif /* defined(AF_INET6) && HAVE_IPV6 */
|
|
||||||
|
|
||||||
#if HAVE_SOLARIS
|
#if HAVE_SOLARIS
|
||||||
|
|
||||||
|
@ -230,7 +248,7 @@ select_src_ifi_info_solaris(int sockfd, int numifs,
|
||||||
char *chptr;
|
char *chptr;
|
||||||
char cmpifname[LIFNAMSIZ];
|
char cmpifname[LIFNAMSIZ];
|
||||||
int i;
|
int i;
|
||||||
uint64_t best_lifrflags;
|
uint64_t best_lifrflags = 0;
|
||||||
uint64_t ifflags;
|
uint64_t ifflags;
|
||||||
|
|
||||||
*best_lifr = NULL;
|
*best_lifr = NULL;
|
||||||
|
@ -509,23 +527,23 @@ gotError:
|
||||||
|
|
||||||
struct ifi_info *get_ifi_info(int family, int doaliases)
|
struct ifi_info *get_ifi_info(int family, int doaliases)
|
||||||
{
|
{
|
||||||
int junk;
|
int junk;
|
||||||
struct ifi_info *ifi, *ifihead, **ifipnext;
|
struct ifi_info *ifi, *ifihead, **ifipnext, *ifipold, **ifiptr;
|
||||||
int sockfd, sockf6, len, lastlen, flags, myflags;
|
int sockfd, sockf6, len, lastlen, flags, myflags;
|
||||||
#ifdef NOT_HAVE_IF_NAMETOINDEX
|
#ifdef NOT_HAVE_IF_NAMETOINDEX
|
||||||
int index = 200;
|
int index = 200;
|
||||||
#endif
|
#endif
|
||||||
char *ptr, *buf, lastname[IFNAMSIZ], *cptr;
|
char *ptr, *buf, lastname[IFNAMSIZ], *cptr;
|
||||||
struct ifconf ifc;
|
struct ifconf ifc;
|
||||||
struct ifreq *ifr, ifrcopy;
|
struct ifreq *ifr, ifrcopy;
|
||||||
struct sockaddr_in *sinptr;
|
struct sockaddr_in *sinptr;
|
||||||
|
|
||||||
#if defined(AF_INET6) && HAVE_IPV6
|
#if defined(AF_INET6) && HAVE_IPV6
|
||||||
struct sockaddr_in6 *sinptr6;
|
struct sockaddr_in6 *sinptr6;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
|
#if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
|
||||||
if(family == AF_INET6) return get_ifi_info_linuxv6(family, doaliases);
|
if (family == AF_INET6) return get_ifi_info_linuxv6(family, doaliases);
|
||||||
#elif HAVE_SOLARIS
|
#elif HAVE_SOLARIS
|
||||||
return get_ifi_info_solaris(family);
|
return get_ifi_info_solaris(family);
|
||||||
#endif
|
#endif
|
||||||
|
@ -534,7 +552,7 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
|
||||||
sockf6 = -1;
|
sockf6 = -1;
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
ifihead = NULL;
|
ifihead = NULL;
|
||||||
|
|
||||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (sockfd < 0) {
|
if (sockfd < 0) {
|
||||||
goto gotError;
|
goto gotError;
|
||||||
|
@ -577,7 +595,7 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
|
||||||
ptr += sizeof(ifr->ifr_name) + GET_SA_LEN(ifr->ifr_addr);
|
ptr += sizeof(ifr->ifr_name) + GET_SA_LEN(ifr->ifr_addr);
|
||||||
|
|
||||||
// fprintf(stderr, "intf %p name=%s AF=%d\n", index, ifr->ifr_name, ifr->ifr_addr.sa_family);
|
// fprintf(stderr, "intf %p name=%s AF=%d\n", index, ifr->ifr_name, ifr->ifr_addr.sa_family);
|
||||||
|
|
||||||
if (ifr->ifr_addr.sa_family != family)
|
if (ifr->ifr_addr.sa_family != family)
|
||||||
continue; /* ignore if not desired address family */
|
continue; /* ignore if not desired address family */
|
||||||
|
|
||||||
|
@ -595,7 +613,7 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
|
||||||
if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0) {
|
if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0) {
|
||||||
goto gotError;
|
goto gotError;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = ifrcopy.ifr_flags;
|
flags = ifrcopy.ifr_flags;
|
||||||
if ((flags & IFF_UP) == 0)
|
if ((flags & IFF_UP) == 0)
|
||||||
continue; /* ignore if interface not up */
|
continue; /* ignore if interface not up */
|
||||||
|
@ -604,8 +622,10 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
|
||||||
if (ifi == NULL) {
|
if (ifi == NULL) {
|
||||||
goto gotError;
|
goto gotError;
|
||||||
}
|
}
|
||||||
*ifipnext = ifi; /* prev points to this new one */
|
ifipold = *ifipnext; /* need this later */
|
||||||
ifipnext = &ifi->ifi_next; /* pointer to next one goes here */
|
ifiptr = ifipnext;
|
||||||
|
*ifipnext = ifi; /* prev points to this new one */
|
||||||
|
ifipnext = &ifi->ifi_next; /* pointer to next one goes here */
|
||||||
|
|
||||||
ifi->ifi_flags = flags; /* IFF_xxx values */
|
ifi->ifi_flags = flags; /* IFF_xxx values */
|
||||||
ifi->ifi_myflags = myflags; /* IFI_xxx values */
|
ifi->ifi_myflags = myflags; /* IFI_xxx values */
|
||||||
|
@ -618,7 +638,7 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
|
||||||
ifi->ifi_index = ifrcopy.ifr_index;
|
ifi->ifi_index = ifrcopy.ifr_index;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
ifi->ifi_index = index++; /* SIOCGIFINDEX is broken on Solaris 2.5ish, so fake it */
|
ifi->ifi_index = index++; /* SIOCGIFINDEX is broken on Solaris 2.5ish, so fake it */
|
||||||
#endif
|
#endif
|
||||||
memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME);
|
memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME);
|
||||||
ifi->ifi_name[IFI_NAME-1] = '\0';
|
ifi->ifi_name[IFI_NAME-1] = '\0';
|
||||||
|
@ -635,16 +655,32 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
|
||||||
memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in));
|
memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in));
|
||||||
|
|
||||||
#ifdef SIOCGIFNETMASK
|
#ifdef SIOCGIFNETMASK
|
||||||
if (ioctl(sockfd, SIOCGIFNETMASK, &ifrcopy) < 0) goto gotError;
|
if (ioctl(sockfd, SIOCGIFNETMASK, &ifrcopy) < 0) {
|
||||||
ifi->ifi_netmask = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in));
|
if (errno == EADDRNOTAVAIL) {
|
||||||
if (ifi->ifi_netmask == NULL) goto gotError;
|
/*
|
||||||
sinptr = (struct sockaddr_in *) &ifrcopy.ifr_addr;
|
* If the main interface is configured with no IP address but
|
||||||
/* The BSD ioctls (including Mac OS X) stick some weird values in for sin_len and sin_family */
|
* an alias interface exists with an IP address, you get
|
||||||
|
* EADDRNOTAVAIL for the main interface
|
||||||
|
*/
|
||||||
|
free(ifi->ifi_addr);
|
||||||
|
free(ifi);
|
||||||
|
ifipnext = ifiptr;
|
||||||
|
*ifipnext = ifipold;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
goto gotError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ifi->ifi_netmask = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in));
|
||||||
|
if (ifi->ifi_netmask == NULL) goto gotError;
|
||||||
|
sinptr = (struct sockaddr_in *) &ifrcopy.ifr_addr;
|
||||||
|
/* The BSD ioctls (including Mac OS X) stick some weird values in for sin_len and sin_family */
|
||||||
#ifndef NOT_HAVE_SA_LEN
|
#ifndef NOT_HAVE_SA_LEN
|
||||||
sinptr->sin_len = sizeof(struct sockaddr_in);
|
sinptr->sin_len = sizeof(struct sockaddr_in);
|
||||||
#endif
|
#endif
|
||||||
sinptr->sin_family = AF_INET;
|
sinptr->sin_family = AF_INET;
|
||||||
memcpy(ifi->ifi_netmask, sinptr, sizeof(struct sockaddr_in));
|
memcpy(ifi->ifi_netmask, sinptr, sizeof(struct sockaddr_in));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SIOCGIFBRDADDR
|
#ifdef SIOCGIFBRDADDR
|
||||||
|
@ -653,11 +689,11 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
|
||||||
goto gotError;
|
goto gotError;
|
||||||
}
|
}
|
||||||
sinptr = (struct sockaddr_in *) &ifrcopy.ifr_broadaddr;
|
sinptr = (struct sockaddr_in *) &ifrcopy.ifr_broadaddr;
|
||||||
/* The BSD ioctls (including Mac OS X) stick some weird values in for sin_len and sin_family */
|
/* The BSD ioctls (including Mac OS X) stick some weird values in for sin_len and sin_family */
|
||||||
#ifndef NOT_HAVE_SA_LEN
|
#ifndef NOT_HAVE_SA_LEN
|
||||||
sinptr->sin_len = sizeof( struct sockaddr_in );
|
sinptr->sin_len = sizeof( struct sockaddr_in );
|
||||||
#endif
|
#endif
|
||||||
sinptr->sin_family = AF_INET;
|
sinptr->sin_family = AF_INET;
|
||||||
ifi->ifi_brdaddr = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in));
|
ifi->ifi_brdaddr = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in));
|
||||||
if (ifi->ifi_brdaddr == NULL) {
|
if (ifi->ifi_brdaddr == NULL) {
|
||||||
goto gotError;
|
goto gotError;
|
||||||
|
@ -674,9 +710,9 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
|
||||||
sinptr = (struct sockaddr_in *) &ifrcopy.ifr_dstaddr;
|
sinptr = (struct sockaddr_in *) &ifrcopy.ifr_dstaddr;
|
||||||
/* The BSD ioctls (including Mac OS X) stick some weird values in for sin_len and sin_family */
|
/* The BSD ioctls (including Mac OS X) stick some weird values in for sin_len and sin_family */
|
||||||
#ifndef NOT_HAVE_SA_LEN
|
#ifndef NOT_HAVE_SA_LEN
|
||||||
sinptr->sin_len = sizeof( struct sockaddr_in );
|
sinptr->sin_len = sizeof( struct sockaddr_in );
|
||||||
#endif
|
#endif
|
||||||
sinptr->sin_family = AF_INET;
|
sinptr->sin_family = AF_INET;
|
||||||
ifi->ifi_dstaddr = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in));
|
ifi->ifi_dstaddr = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in));
|
||||||
if (ifi->ifi_dstaddr == NULL) {
|
if (ifi->ifi_dstaddr == NULL) {
|
||||||
goto gotError;
|
goto gotError;
|
||||||
|
@ -695,27 +731,42 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
|
||||||
if (ifi->ifi_addr == NULL) {
|
if (ifi->ifi_addr == NULL) {
|
||||||
goto gotError;
|
goto gotError;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Some platforms (*BSD) inject the prefix in IPv6LL addresses */
|
/* Some platforms (*BSD) inject the prefix in IPv6LL addresses */
|
||||||
/* We need to strip that out */
|
/* We need to strip that out */
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(&sinptr6->sin6_addr))
|
if (IN6_IS_ADDR_LINKLOCAL(&sinptr6->sin6_addr))
|
||||||
sinptr6->sin6_addr.s6_addr[2] = sinptr6->sin6_addr.s6_addr[3] = 0;
|
sinptr6->sin6_addr.s6_addr[2] = sinptr6->sin6_addr.s6_addr[3] = 0;
|
||||||
memcpy(ifi->ifi_addr, sinptr6, sizeof(struct sockaddr_in6));
|
memcpy(ifi->ifi_addr, sinptr6, sizeof(struct sockaddr_in6));
|
||||||
|
|
||||||
#ifdef SIOCGIFNETMASK_IN6
|
#ifdef SIOCGIFNETMASK_IN6
|
||||||
{
|
{
|
||||||
struct in6_ifreq ifr6;
|
struct in6_ifreq ifr6;
|
||||||
if (sockf6 == -1)
|
if (sockf6 == -1)
|
||||||
sockf6 = socket(AF_INET6, SOCK_DGRAM, 0);
|
sockf6 = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||||
bzero(&ifr6, sizeof(ifr6));
|
memset(&ifr6, 0, sizeof(ifr6));
|
||||||
memcpy(&ifr6.ifr_name, &ifr->ifr_name, sizeof(ifr6.ifr_name ));
|
memcpy(&ifr6.ifr_name, &ifr->ifr_name, sizeof(ifr6.ifr_name ));
|
||||||
memcpy(&ifr6.ifr_ifru.ifru_addr, &ifr->ifr_addr, sizeof(ifr6.ifr_ifru.ifru_addr));
|
memcpy(&ifr6.ifr_ifru.ifru_addr, &ifr->ifr_addr, sizeof(ifr6.ifr_ifru.ifru_addr));
|
||||||
if (ioctl(sockf6, SIOCGIFNETMASK_IN6, &ifr6) < 0) goto gotError;
|
if (ioctl(sockf6, SIOCGIFNETMASK_IN6, &ifr6) < 0) {
|
||||||
ifi->ifi_netmask = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in6));
|
if (errno == EADDRNOTAVAIL) {
|
||||||
if (ifi->ifi_netmask == NULL) goto gotError;
|
/*
|
||||||
sinptr6 = (struct sockaddr_in6 *) &ifr6.ifr_ifru.ifru_addr;
|
* If the main interface is configured with no IP address but
|
||||||
memcpy(ifi->ifi_netmask, sinptr6, sizeof(struct sockaddr_in6));
|
* an alias interface exists with an IP address, you get
|
||||||
}
|
* EADDRNOTAVAIL for the main interface
|
||||||
|
*/
|
||||||
|
free(ifi->ifi_addr);
|
||||||
|
free(ifi);
|
||||||
|
ifipnext = ifiptr;
|
||||||
|
*ifipnext = ifipold;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
goto gotError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ifi->ifi_netmask = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in6));
|
||||||
|
if (ifi->ifi_netmask == NULL) goto gotError;
|
||||||
|
sinptr6 = (struct sockaddr_in6 *) &ifr6.ifr_ifru.ifru_addr;
|
||||||
|
memcpy(ifi->ifi_netmask, sinptr6, sizeof(struct sockaddr_in6));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -726,7 +777,7 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
gotError:
|
gotError:
|
||||||
if (ifihead != NULL) {
|
if (ifihead != NULL) {
|
||||||
free_ifi_info(ifihead);
|
free_ifi_info(ifihead);
|
||||||
|
@ -758,35 +809,35 @@ free_ifi_info(struct ifi_info *ifihead)
|
||||||
for (ifi = ifihead; ifi != NULL; ifi = ifinext) {
|
for (ifi = ifihead; ifi != NULL; ifi = ifinext) {
|
||||||
if (ifi->ifi_addr != NULL)
|
if (ifi->ifi_addr != NULL)
|
||||||
free(ifi->ifi_addr);
|
free(ifi->ifi_addr);
|
||||||
|
if (ifi->ifi_netmask != NULL)
|
||||||
|
free(ifi->ifi_netmask);
|
||||||
if (ifi->ifi_brdaddr != NULL)
|
if (ifi->ifi_brdaddr != NULL)
|
||||||
free(ifi->ifi_brdaddr);
|
free(ifi->ifi_brdaddr);
|
||||||
if (ifi->ifi_dstaddr != NULL)
|
if (ifi->ifi_dstaddr != NULL)
|
||||||
free(ifi->ifi_dstaddr);
|
free(ifi->ifi_dstaddr);
|
||||||
if (ifi->ifi_netmask != NULL)
|
|
||||||
free(ifi->ifi_netmask);
|
|
||||||
ifinext = ifi->ifi_next; /* can't fetch ifi_next after free() */
|
ifinext = ifi->ifi_next; /* can't fetch ifi_next after free() */
|
||||||
free(ifi); /* the ifi_info{} itself */
|
free(ifi); /* the ifi_info{} itself */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* end free_ifi_info */
|
/* end free_ifi_info */
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
|
recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
|
||||||
struct sockaddr *sa, socklen_t *salenptr, struct my_in_pktinfo *pktp, u_char *ttl)
|
struct sockaddr *sa, socklen_t *salenptr, struct my_in_pktinfo *pktp, u_char *ttl)
|
||||||
{
|
{
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct iovec iov[1];
|
struct iovec iov[1];
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
|
|
||||||
#ifdef CMSG_FIRSTHDR
|
#ifdef CMSG_FIRSTHDR
|
||||||
struct cmsghdr *cmptr;
|
struct cmsghdr *cmptr;
|
||||||
union {
|
union {
|
||||||
struct cmsghdr cm;
|
struct cmsghdr cm;
|
||||||
char control[1024];
|
char control[1024];
|
||||||
pad64_t align8; /* ensure structure is 8-byte aligned on sparc */
|
pad64_t align8; /* ensure structure is 8-byte aligned on sparc */
|
||||||
} control_un;
|
} control_un;
|
||||||
|
|
||||||
*ttl = 255; // If kernel fails to provide TTL data then assume the TTL was 255 as it should be
|
*ttl = 255; // If kernel fails to provide TTL data then assume the TTL was 255 as it should be
|
||||||
|
|
||||||
msg.msg_control = (void *) control_un.control;
|
msg.msg_control = (void *) control_un.control;
|
||||||
msg.msg_controllen = sizeof(control_un.control);
|
msg.msg_controllen = sizeof(control_un.control);
|
||||||
|
@ -808,12 +859,12 @@ recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
|
||||||
*salenptr = msg.msg_namelen; /* pass back results */
|
*salenptr = msg.msg_namelen; /* pass back results */
|
||||||
if (pktp) {
|
if (pktp) {
|
||||||
/* 0.0.0.0, i/f = -1 */
|
/* 0.0.0.0, i/f = -1 */
|
||||||
/* We set the interface to -1 so that the caller can
|
/* We set the interface to -1 so that the caller can
|
||||||
tell whether we returned a meaningful value or
|
tell whether we returned a meaningful value or
|
||||||
just some default. Previously this code just
|
just some default. Previously this code just
|
||||||
set the value to 0, but I'm concerned that 0
|
set the value to 0, but I'm concerned that 0
|
||||||
might be a valid interface value.
|
might be a valid interface value.
|
||||||
*/
|
*/
|
||||||
memset(pktp, 0, sizeof(struct my_in_pktinfo));
|
memset(pktp, 0, sizeof(struct my_in_pktinfo));
|
||||||
pktp->ipi_ifindex = -1;
|
pktp->ipi_ifindex = -1;
|
||||||
}
|
}
|
||||||
|
@ -821,7 +872,7 @@ recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
|
||||||
|
|
||||||
/* include recvfrom_flags2 */
|
/* include recvfrom_flags2 */
|
||||||
#ifndef CMSG_FIRSTHDR
|
#ifndef CMSG_FIRSTHDR
|
||||||
#warning CMSG_FIRSTHDR not defined. Will not be able to determine destination address, received interface, etc.
|
#warning CMSG_FIRSTHDR not defined. Will not be able to determine destination address, received interface, etc.
|
||||||
*flagsp = 0; /* pass back results */
|
*flagsp = 0; /* pass back results */
|
||||||
return(n);
|
return(n);
|
||||||
#else
|
#else
|
||||||
|
@ -836,18 +887,18 @@ recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
|
||||||
|
|
||||||
#ifdef IP_PKTINFO
|
#ifdef IP_PKTINFO
|
||||||
#if in_pktinfo_definition_is_missing
|
#if in_pktinfo_definition_is_missing
|
||||||
struct in_pktinfo
|
struct in_pktinfo
|
||||||
{
|
{
|
||||||
int ipi_ifindex;
|
int ipi_ifindex;
|
||||||
struct in_addr ipi_spec_dst;
|
struct in_addr ipi_spec_dst;
|
||||||
struct in_addr ipi_addr;
|
struct in_addr ipi_addr;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
if (cmptr->cmsg_level == IPPROTO_IP &&
|
if (cmptr->cmsg_level == IPPROTO_IP &&
|
||||||
cmptr->cmsg_type == IP_PKTINFO) {
|
cmptr->cmsg_type == IP_PKTINFO) {
|
||||||
struct in_pktinfo *tmp;
|
struct in_pktinfo *tmp;
|
||||||
struct sockaddr_in *sin = (struct sockaddr_in*)&pktp->ipi_addr;
|
struct sockaddr_in *sin = (struct sockaddr_in*)&pktp->ipi_addr;
|
||||||
|
|
||||||
tmp = (struct in_pktinfo *) CMSG_DATA(cmptr);
|
tmp = (struct in_pktinfo *) CMSG_DATA(cmptr);
|
||||||
sin->sin_family = AF_INET;
|
sin->sin_family = AF_INET;
|
||||||
sin->sin_addr = tmp->ipi_addr;
|
sin->sin_addr = tmp->ipi_addr;
|
||||||
|
@ -861,7 +912,7 @@ struct in_pktinfo
|
||||||
if (cmptr->cmsg_level == IPPROTO_IP &&
|
if (cmptr->cmsg_level == IPPROTO_IP &&
|
||||||
cmptr->cmsg_type == IP_RECVDSTADDR) {
|
cmptr->cmsg_type == IP_RECVDSTADDR) {
|
||||||
struct sockaddr_in *sin = (struct sockaddr_in*)&pktp->ipi_addr;
|
struct sockaddr_in *sin = (struct sockaddr_in*)&pktp->ipi_addr;
|
||||||
|
|
||||||
sin->sin_family = AF_INET;
|
sin->sin_family = AF_INET;
|
||||||
sin->sin_addr = *(struct in_addr*)CMSG_DATA(cmptr);
|
sin->sin_addr = *(struct in_addr*)CMSG_DATA(cmptr);
|
||||||
sin->sin_port = 0;
|
sin->sin_port = 0;
|
||||||
|
@ -877,7 +928,16 @@ struct in_pktinfo
|
||||||
int nameLen = (sdl->sdl_nlen < IFI_NAME - 1) ? sdl->sdl_nlen : (IFI_NAME - 1);
|
int nameLen = (sdl->sdl_nlen < IFI_NAME - 1) ? sdl->sdl_nlen : (IFI_NAME - 1);
|
||||||
strncpy(pktp->ipi_ifname, sdl->sdl_data, nameLen);
|
strncpy(pktp->ipi_ifname, sdl->sdl_data, nameLen);
|
||||||
#endif
|
#endif
|
||||||
(void) memcpy(&pktp->ipi_ifindex, CMSG_DATA(cmptr), sizeof(uint_t));
|
/*
|
||||||
|
* the is memcpy used for sparc? no idea;)
|
||||||
|
* pktp->ipi_ifindex = sdl->sdl_index;
|
||||||
|
*/
|
||||||
|
(void) memcpy(&pktp->ipi_ifindex, CMSG_DATA(cmptr), sizeof(uint_t));
|
||||||
|
#ifdef HAVE_BROKEN_RECVIF_NAME
|
||||||
|
if (sdl->sdl_index == 0) {
|
||||||
|
pktp->ipi_ifindex = *(uint_t*)sdl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
assert(pktp->ipi_ifname[IFI_NAME - 1] == 0);
|
assert(pktp->ipi_ifname[IFI_NAME - 1] == 0);
|
||||||
// null terminated because of memset above
|
// null terminated because of memset above
|
||||||
continue;
|
continue;
|
||||||
|
@ -887,22 +947,22 @@ struct in_pktinfo
|
||||||
#ifdef IP_RECVTTL
|
#ifdef IP_RECVTTL
|
||||||
if (cmptr->cmsg_level == IPPROTO_IP &&
|
if (cmptr->cmsg_level == IPPROTO_IP &&
|
||||||
cmptr->cmsg_type == IP_RECVTTL) {
|
cmptr->cmsg_type == IP_RECVTTL) {
|
||||||
*ttl = *(u_char*)CMSG_DATA(cmptr);
|
*ttl = *(u_char*)CMSG_DATA(cmptr);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (cmptr->cmsg_level == IPPROTO_IP &&
|
else if (cmptr->cmsg_level == IPPROTO_IP &&
|
||||||
cmptr->cmsg_type == IP_TTL) { // some implementations seem to send IP_TTL instead of IP_RECVTTL
|
cmptr->cmsg_type == IP_TTL) { // some implementations seem to send IP_TTL instead of IP_RECVTTL
|
||||||
*ttl = *(int*)CMSG_DATA(cmptr);
|
*ttl = *(int*)CMSG_DATA(cmptr);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(IPV6_PKTINFO) && HAVE_IPV6
|
#if defined(IPV6_PKTINFO) && HAVE_IPV6
|
||||||
if (cmptr->cmsg_level == IPPROTO_IPV6 &&
|
if (cmptr->cmsg_level == IPPROTO_IPV6 &&
|
||||||
cmptr->cmsg_type == IPV6_PKTINFO) {
|
cmptr->cmsg_type == IPV6_PKTINFO) {
|
||||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)&pktp->ipi_addr;
|
struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)&pktp->ipi_addr;
|
||||||
struct in6_pktinfo *ip6_info = (struct in6_pktinfo*)CMSG_DATA(cmptr);
|
struct in6_pktinfo *ip6_info = (struct in6_pktinfo*)CMSG_DATA(cmptr);
|
||||||
|
|
||||||
sin6->sin6_family = AF_INET6;
|
sin6->sin6_family = AF_INET6;
|
||||||
#ifndef NOT_HAVE_SA_LEN
|
#ifndef NOT_HAVE_SA_LEN
|
||||||
sin6->sin6_len = sizeof(*sin6);
|
sin6->sin6_len = sizeof(*sin6);
|
||||||
|
@ -911,15 +971,15 @@ struct in_pktinfo
|
||||||
sin6->sin6_flowinfo = 0;
|
sin6->sin6_flowinfo = 0;
|
||||||
sin6->sin6_scope_id = 0;
|
sin6->sin6_scope_id = 0;
|
||||||
sin6->sin6_port = 0;
|
sin6->sin6_port = 0;
|
||||||
pktp->ipi_ifindex = ip6_info->ipi6_ifindex;
|
pktp->ipi_ifindex = ip6_info->ipi6_ifindex;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(IPV6_HOPLIMIT) && HAVE_IPV6
|
#if defined(IPV6_HOPLIMIT) && HAVE_IPV6
|
||||||
if (cmptr->cmsg_level == IPPROTO_IPV6 &&
|
if (cmptr->cmsg_level == IPPROTO_IPV6 &&
|
||||||
cmptr->cmsg_type == IPV6_HOPLIMIT) {
|
cmptr->cmsg_type == IPV6_HOPLIMIT) {
|
||||||
*ttl = *(int*)CMSG_DATA(cmptr);
|
*ttl = *(int*)CMSG_DATA(cmptr);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -937,44 +997,44 @@ struct in_pktinfo
|
||||||
#ifdef NOT_HAVE_DAEMON
|
#ifdef NOT_HAVE_DAEMON
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <signal.h>
|
#include <sys/signal.h>
|
||||||
|
|
||||||
int daemon(int nochdir, int noclose)
|
int daemon(int nochdir, int noclose)
|
||||||
|
{
|
||||||
|
switch (fork())
|
||||||
{
|
{
|
||||||
switch (fork())
|
case -1: return (-1); // Fork failed
|
||||||
{
|
case 0: break; // Child -- continue
|
||||||
case -1: return (-1); // Fork failed
|
default: _exit(0); // Parent -- exit
|
||||||
case 0: break; // Child -- continue
|
|
||||||
default: _exit(0); // Parent -- exit
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setsid() == -1) return(-1);
|
|
||||||
|
|
||||||
signal(SIGHUP, SIG_IGN);
|
|
||||||
|
|
||||||
switch (fork()) // Fork again, primarily for reasons of Unix trivia
|
|
||||||
{
|
|
||||||
case -1: return (-1); // Fork failed
|
|
||||||
case 0: break; // Child -- continue
|
|
||||||
default: _exit(0); // Parent -- exit
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nochdir) (void)chdir("/");
|
|
||||||
umask(0);
|
|
||||||
|
|
||||||
if (!noclose)
|
|
||||||
{
|
|
||||||
int fd = open("/dev/null", O_RDWR, 0);
|
|
||||||
if (fd != -1)
|
|
||||||
{
|
|
||||||
// Avoid unnecessarily duplicating a file descriptor to itself
|
|
||||||
if (fd != STDIN_FILENO) (void)dup2(fd, STDIN_FILENO);
|
|
||||||
if (fd != STDOUT_FILENO) (void)dup2(fd, STDOUT_FILENO);
|
|
||||||
if (fd != STDERR_FILENO) (void)dup2(fd, STDERR_FILENO);
|
|
||||||
if (fd != STDIN_FILENO && fd != STDOUT_FILENO && fd != STDERR_FILENO)
|
|
||||||
(void)close (fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (setsid() == -1) return(-1);
|
||||||
|
|
||||||
|
signal(SIGHUP, SIG_IGN);
|
||||||
|
|
||||||
|
switch (fork()) // Fork again, primarily for reasons of Unix trivia
|
||||||
|
{
|
||||||
|
case -1: return (-1); // Fork failed
|
||||||
|
case 0: break; // Child -- continue
|
||||||
|
default: _exit(0); // Parent -- exit
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nochdir) (void)chdir("/");
|
||||||
|
umask(0);
|
||||||
|
|
||||||
|
if (!noclose)
|
||||||
|
{
|
||||||
|
int fd = open("/dev/null", O_RDWR, 0);
|
||||||
|
if (fd != -1)
|
||||||
|
{
|
||||||
|
// Avoid unnecessarily duplicating a file descriptor to itself
|
||||||
|
if (fd != STDIN_FILENO) (void)dup2(fd, STDIN_FILENO);
|
||||||
|
if (fd != STDOUT_FILENO) (void)dup2(fd, STDOUT_FILENO);
|
||||||
|
if (fd != STDERR_FILENO) (void)dup2(fd, STDERR_FILENO);
|
||||||
|
if (fd != STDIN_FILENO && fd != STDOUT_FILENO && fd != STDERR_FILENO)
|
||||||
|
(void)close (fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
#endif /* NOT_HAVE_DAEMON */
|
#endif /* NOT_HAVE_DAEMON */
|
||||||
|
|
|
@ -5,83 +5,15 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
*/
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: mDNSUNP.h,v $
|
|
||||||
Revision 1.19 2006/08/14 23:24:47 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.18 2005/04/08 21:37:57 ksekar
|
|
||||||
<rdar://problem/3792767> get_ifi_info doesn't return IPv6 interfaces on Linux
|
|
||||||
|
|
||||||
Revision 1.17 2004/12/17 19:32:43 cheshire
|
|
||||||
Add missing semicolon
|
|
||||||
|
|
||||||
Revision 1.16 2004/12/01 04:25:05 cheshire
|
|
||||||
<rdar://problem/3872803> Darwin patches for Solaris and Suse
|
|
||||||
Provide daemon() for platforms that don't have it
|
|
||||||
|
|
||||||
Revision 1.15 2004/11/30 22:37:01 cheshire
|
|
||||||
Update copyright dates and add "Mode: C; tab-width: 4" headers
|
|
||||||
|
|
||||||
Revision 1.14 2004/10/16 00:17:01 cheshire
|
|
||||||
<rdar://problem/3770558> Replace IP TTL 255 check with local subnet source address check
|
|
||||||
|
|
||||||
Revision 1.13 2004/03/20 05:37:09 cheshire
|
|
||||||
Fix contributed by Terry Lambert & Alfred Perlstein:
|
|
||||||
Don't use uint8_t -- it requires stdint.h, which doesn't exist on FreeBSD 4.x
|
|
||||||
|
|
||||||
Revision 1.12 2004/01/28 21:12:15 cheshire
|
|
||||||
Reconcile mDNSIPv6Support & HAVE_IPV6 into a single flag (HAVE_IPV6)
|
|
||||||
|
|
||||||
Revision 1.11 2003/12/13 05:43:09 bradley
|
|
||||||
Fixed non-sa_len and non-IPv6 version of GET_SA_LEN macro to cast as sockaddr to access
|
|
||||||
sa_family so it works with any sockaddr-compatible address structure (e.g. sockaddr_storage).
|
|
||||||
|
|
||||||
Revision 1.10 2003/12/11 03:03:51 rpantos
|
|
||||||
Clean up mDNSPosix so that it builds on OS X again.
|
|
||||||
|
|
||||||
Revision 1.9 2003/12/08 20:47:02 rpantos
|
|
||||||
Add support for mDNSResponder on Linux.
|
|
||||||
|
|
||||||
Revision 1.8 2003/08/12 19:56:26 cheshire
|
|
||||||
Update to APSL 2.0
|
|
||||||
|
|
||||||
Revision 1.7 2003/08/06 18:20:51 cheshire
|
|
||||||
Makefile cleanup
|
|
||||||
|
|
||||||
Revision 1.6 2003/07/02 21:19:59 cheshire
|
|
||||||
<rdar://problem/3313413> Update copyright notices, etc., in source code comments
|
|
||||||
|
|
||||||
Revision 1.5 2003/03/13 03:46:21 cheshire
|
|
||||||
Fixes to make the code build on Linux
|
|
||||||
|
|
||||||
Revision 1.4 2002/12/23 22:13:32 jgraessl
|
|
||||||
|
|
||||||
Reviewed by: Stuart Cheshire
|
|
||||||
Initial IPv6 support for mDNSResponder.
|
|
||||||
|
|
||||||
Revision 1.3 2002/09/21 20:44:53 zarzycki
|
|
||||||
Added APSL info
|
|
||||||
|
|
||||||
Revision 1.2 2002/09/19 04:20:44 cheshire
|
|
||||||
Remove high-ascii characters that confuse some systems
|
|
||||||
|
|
||||||
Revision 1.1 2002/09/17 06:24:35 cheshire
|
|
||||||
First checkin
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
#ifndef __mDNSUNP_h
|
#ifndef __mDNSUNP_h
|
||||||
#define __mDNSUNP_h
|
#define __mDNSUNP_h
|
||||||
|
@ -90,18 +22,26 @@ First checkin
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_LINUX
|
#ifdef HAVE_LINUX
|
||||||
#include <linux/socket.h>
|
#include <linux/socket.h>
|
||||||
|
#define IPV6_2292_PKTINFO IPV6_2292PKTINFO
|
||||||
|
#define IPV6_2292_HOPLIMIT IPV6_2292HOPLIMIT
|
||||||
|
#else
|
||||||
|
// The following are the supported non-linux posix OSes -
|
||||||
|
// netbsd, freebsd and openbsd.
|
||||||
|
#if HAVE_IPV6
|
||||||
|
#define IPV6_2292_PKTINFO 19
|
||||||
|
#define IPV6_2292_HOPLIMIT 20
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NOT_HAVE_SOCKLEN_T
|
#ifdef NOT_HAVE_SOCKLEN_T
|
||||||
typedef unsigned int socklen_t;
|
typedef unsigned int socklen_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(_SS_MAXSIZE)
|
#if !defined(_SS_MAXSIZE)
|
||||||
|
@ -109,7 +49,7 @@ First checkin
|
||||||
#define sockaddr_storage sockaddr_in6
|
#define sockaddr_storage sockaddr_in6
|
||||||
#else
|
#else
|
||||||
#define sockaddr_storage sockaddr
|
#define sockaddr_storage sockaddr
|
||||||
#endif // HAVE_IPV6
|
#endif // HAVE_IPV6
|
||||||
#endif // !defined(_SS_MAXSIZE)
|
#endif // !defined(_SS_MAXSIZE)
|
||||||
|
|
||||||
#ifndef NOT_HAVE_SA_LEN
|
#ifndef NOT_HAVE_SA_LEN
|
||||||
|
@ -129,8 +69,8 @@ First checkin
|
||||||
|
|
||||||
struct my_in_pktinfo {
|
struct my_in_pktinfo {
|
||||||
struct sockaddr_storage ipi_addr;
|
struct sockaddr_storage ipi_addr;
|
||||||
int ipi_ifindex; /* received interface index */
|
int ipi_ifindex; /* received interface index */
|
||||||
char ipi_ifname[IFI_NAME]; /* received interface name */
|
char ipi_ifname[IFI_NAME]; /* received interface name */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* From the text (Stevens, section 20.2): */
|
/* From the text (Stevens, section 20.2): */
|
||||||
|
@ -140,33 +80,33 @@ struct my_in_pktinfo {
|
||||||
/* 2. the destination addres of the received datagram (from the IP_RECVDSTADDR socket option, and */
|
/* 2. the destination addres of the received datagram (from the IP_RECVDSTADDR socket option, and */
|
||||||
/* 3. the index of the interface on which the datagram was received (the IP_RECVIF socket option).' */
|
/* 3. the index of the interface on which the datagram was received (the IP_RECVIF socket option).' */
|
||||||
extern ssize_t recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
|
extern ssize_t recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
|
||||||
struct sockaddr *sa, socklen_t *salenptr, struct my_in_pktinfo *pktp, u_char *ttl);
|
struct sockaddr *sa, socklen_t *salenptr, struct my_in_pktinfo *pktp, u_char *ttl);
|
||||||
|
|
||||||
struct ifi_info {
|
struct ifi_info {
|
||||||
char ifi_name[IFI_NAME]; /* interface name, null terminated */
|
char ifi_name[IFI_NAME]; /* interface name, null terminated */
|
||||||
u_char ifi_haddr[IFI_HADDR]; /* hardware address */
|
u_char ifi_haddr[IFI_HADDR]; /* hardware address */
|
||||||
u_short ifi_hlen; /* #bytes in hardware address: 0, 6, 8 */
|
u_short ifi_hlen; /* #bytes in hardware address: 0, 6, 8 */
|
||||||
short ifi_flags; /* IFF_xxx constants from <net/if.h> */
|
short ifi_flags; /* IFF_xxx constants from <net/if.h> */
|
||||||
short ifi_myflags; /* our own IFI_xxx flags */
|
short ifi_myflags; /* our own IFI_xxx flags */
|
||||||
int ifi_index; /* interface index */
|
int ifi_index; /* interface index */
|
||||||
struct sockaddr *ifi_addr; /* primary address */
|
struct sockaddr *ifi_addr; /* primary address */
|
||||||
struct sockaddr *ifi_netmask;
|
struct sockaddr *ifi_netmask;
|
||||||
struct sockaddr *ifi_brdaddr;/* broadcast address */
|
struct sockaddr *ifi_brdaddr; /* broadcast address */
|
||||||
struct sockaddr *ifi_dstaddr;/* destination address */
|
struct sockaddr *ifi_dstaddr; /* destination address */
|
||||||
struct ifi_info *ifi_next; /* next of these structures */
|
struct ifi_info *ifi_next; /* next of these structures */
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
|
#if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
|
||||||
#define PROC_IFINET6_PATH "/proc/net/if_inet6"
|
#define PROC_IFINET6_PATH "/proc/net/if_inet6"
|
||||||
extern struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases);
|
extern struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(AF_INET6) && HAVE_IPV6
|
#if defined(AF_INET6) && HAVE_IPV6
|
||||||
#define INET6_ADDRSTRLEN 46 /*Maximum length of IPv6 address */
|
#define INET6_ADDRSTRLEN 46 /*Maximum length of IPv6 address */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define IFI_ALIAS 1 /* ifi_addr is an alias */
|
#define IFI_ALIAS 1 /* ifi_addr is an alias */
|
||||||
|
|
||||||
/* From the text (Stevens, section 16.6): */
|
/* From the text (Stevens, section 16.6): */
|
||||||
|
@ -184,7 +124,7 @@ extern int daemon(int nochdir, int noclose);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef __NSEC_H
|
||||||
|
#define __NSEC_H
|
||||||
|
|
||||||
|
#include "dnssec.h"
|
||||||
|
|
||||||
|
extern mDNSBool AddNSECSForCacheRecord(mDNS *const m, CacheRecord *crlist, CacheRecord *negcr, mDNSu8 rcode);
|
||||||
|
extern void WildcardAnswerProof(mDNS *const m, DNSSECVerifier *dv);
|
||||||
|
extern void ValidateWithNSECS(mDNS *const m, DNSSECVerifier *dv, CacheRecord *rr);
|
||||||
|
extern mDNSBool NSECAnswersDS(mDNS *const m, ResourceRecord *rr, DNSQuestion *q);
|
||||||
|
extern int CountLabelsMatch(const domainname *const d1, const domainname *const d2);
|
||||||
|
extern void NameErrorNSECCallback(mDNS *const m, DNSSECVerifier *dv, DNSSECStatus status);
|
||||||
|
extern void VerifyNSEC(mDNS *const m, ResourceRecord *rr, RRVerifier *rv, DNSSECVerifier *pdv, CacheRecord *ncr,
|
||||||
|
DNSSECVerifierCallback callback);
|
||||||
|
extern CacheRecord *NSECRecordIsDelegation(mDNS *const m, domainname *name, mDNSu16 qtype);
|
||||||
|
extern void NoDataNSECCallback(mDNS *const m, DNSSECVerifier *dv, DNSSECStatus status);
|
||||||
|
|
||||||
|
#endif // __NSEC_H
|
File diff suppressed because it is too large
Load Diff
|
@ -1,192 +1,151 @@
|
||||||
/* -*- Mode: C; tab-width: 4 -*-
|
/* -*- Mode: C; tab-width: 4 -*-
|
||||||
*
|
*
|
||||||
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
|
* Copyright (c) 2002-2013 Apple Computer, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: uDNS.h,v $
|
|
||||||
Revision 1.32.2.1 2006/08/29 06:24:23 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.32 2005/07/29 19:46:10 ksekar
|
|
||||||
<rdar://problem/4191860> reduce polling period on failed LLQs to 15 minutes
|
|
||||||
|
|
||||||
Revision 1.31 2005/03/31 02:19:56 cheshire
|
|
||||||
<rdar://problem/4021486> Fix build warnings
|
|
||||||
Reviewed by: Scott Herscher
|
|
||||||
|
|
||||||
Revision 1.30 2005/03/04 03:00:03 ksekar
|
|
||||||
<rdar://problem/4026546> Retransmissions happen too early, causing registrations to conflict with themselves
|
|
||||||
|
|
||||||
Revision 1.29 2005/01/11 22:50:53 ksekar
|
|
||||||
Fixed constant naming (was using kLLQ_DefLease for update leases)
|
|
||||||
|
|
||||||
Revision 1.28 2004/12/22 00:13:49 ksekar
|
|
||||||
<rdar://problem/3873993> Change version, port, and polling interval for LLQ
|
|
||||||
|
|
||||||
Revision 1.27 2004/11/23 04:06:50 cheshire
|
|
||||||
Get rid of floating point constant -- in a small embedded device, bringing in all
|
|
||||||
the floating point libraries just to halve an integer value is a bit too heavyweight.
|
|
||||||
|
|
||||||
Revision 1.26 2004/11/22 17:49:15 ksekar
|
|
||||||
Changed INIT_REFRESH from fraction to decimal
|
|
||||||
|
|
||||||
Revision 1.25 2004/11/22 17:16:20 ksekar
|
|
||||||
<rdar://problem/3854298> Unicast services don't disappear when you disable all networking
|
|
||||||
|
|
||||||
Revision 1.24 2004/11/19 04:24:08 ksekar
|
|
||||||
<rdar://problem/3682609> Security: Enforce a "window" on one-shot wide-area queries
|
|
||||||
|
|
||||||
Revision 1.23 2004/11/18 18:04:21 ksekar
|
|
||||||
Add INIT_REFRESH constant
|
|
||||||
|
|
||||||
Revision 1.22 2004/11/15 20:09:24 ksekar
|
|
||||||
<rdar://problem/3719050> Wide Area support for Add/Remove record
|
|
||||||
|
|
||||||
Revision 1.21 2004/11/11 20:14:55 ksekar
|
|
||||||
<rdar://problem/3719574> Wide-Area registrations not deregistered on sleep
|
|
||||||
|
|
||||||
Revision 1.20 2004/10/16 00:16:59 cheshire
|
|
||||||
<rdar://problem/3770558> Replace IP TTL 255 check with local subnet source address check
|
|
||||||
|
|
||||||
Revision 1.19 2004/09/17 01:08:49 cheshire
|
|
||||||
Renamed mDNSClientAPI.h to mDNSEmbeddedAPI.h
|
|
||||||
The name "mDNSClientAPI.h" is misleading to new developers looking at this code. The interfaces
|
|
||||||
declared in that file are ONLY appropriate to single-address-space embedded applications.
|
|
||||||
For clients on general-purpose computers, the interfaces defined in dns_sd.h should be used.
|
|
||||||
|
|
||||||
Revision 1.18 2004/09/03 19:23:05 ksekar
|
|
||||||
<rdar://problem/3788460>: Need retransmission mechanism for wide-area service registrations
|
|
||||||
|
|
||||||
Revision 1.17 2004/09/01 03:59:29 ksekar
|
|
||||||
<rdar://problem/3783453>: Conditionally compile out uDNS code on Windows
|
|
||||||
|
|
||||||
Revision 1.16 2004/08/25 00:37:27 ksekar
|
|
||||||
<rdar://problem/3774635>: Cleanup DynDNS hostname registration code
|
|
||||||
|
|
||||||
Revision 1.15 2004/07/30 17:40:06 ksekar
|
|
||||||
<rdar://problem/3739115>: TXT Record updates not available for wide-area services
|
|
||||||
|
|
||||||
Revision 1.14 2004/07/29 19:27:15 ksekar
|
|
||||||
NATPMP Support - minor fixes and cleanup
|
|
||||||
|
|
||||||
Revision 1.13 2004/07/29 02:03:35 ksekar
|
|
||||||
Delete unused #define and structure field
|
|
||||||
|
|
||||||
Revision 1.12 2004/07/26 22:49:30 ksekar
|
|
||||||
<rdar://problem/3651409>: Feature #9516: Need support for NATPMP in client
|
|
||||||
|
|
||||||
Revision 1.11 2004/06/17 01:13:11 ksekar
|
|
||||||
<rdar://problem/3696616>: polling interval too short
|
|
||||||
|
|
||||||
Revision 1.10 2004/06/11 05:45:03 ksekar
|
|
||||||
<rdar://problem/3682397>: Change SRV names for LLQ/Update port lookups
|
|
||||||
|
|
||||||
Revision 1.9 2004/06/01 23:46:50 ksekar
|
|
||||||
<rdar://problem/3675149>: DynDNS: dynamically look up LLQ/Update ports
|
|
||||||
|
|
||||||
Revision 1.8 2004/05/28 23:42:37 ksekar
|
|
||||||
<rdar://problem/3258021>: Feature: DNS server->client notification on record changes (#7805)
|
|
||||||
|
|
||||||
Revision 1.7 2004/05/18 23:51:25 cheshire
|
|
||||||
Tidy up all checkin comments to use consistent "<rdar://problem/xxxxxxx>" format for bug numbers
|
|
||||||
|
|
||||||
Revision 1.6 2004/03/13 01:57:33 ksekar
|
|
||||||
<rdar://problem/3192546>: DynDNS: Dynamic update of service records
|
|
||||||
|
|
||||||
Revision 1.5 2004/02/21 08:56:58 bradley
|
|
||||||
Wrap prototypes with extern "C" for C++ builds.
|
|
||||||
|
|
||||||
Revision 1.4 2004/02/06 23:04:19 ksekar
|
|
||||||
Basic Dynamic Update support via mDNS_Register (dissabled via
|
|
||||||
UNICAST_REGISTRATION #define)
|
|
||||||
|
|
||||||
Revision 1.3 2004/01/24 03:38:27 cheshire
|
|
||||||
Fix minor syntactic error: Headers should use "extern" declarations, not "mDNSexport"
|
|
||||||
|
|
||||||
Revision 1.2 2004/01/23 23:23:15 ksekar
|
|
||||||
Added TCP support for truncated unicast messages.
|
|
||||||
|
|
||||||
Revision 1.1 2003/12/13 03:05:27 ksekar
|
|
||||||
<rdar://problem/3192548>: DynDNS: Unicast query of service records
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
#ifndef __UDNS_H_
|
#ifndef __UDNS_H_
|
||||||
#define __UDNS_H_
|
#define __UDNS_H_
|
||||||
|
|
||||||
#include "mDNSEmbeddedAPI.h"
|
#include "mDNSEmbeddedAPI.h"
|
||||||
#include "DNSCommon.h"
|
#include "DNSCommon.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RESTART_GOODBYE_DELAY (6 * mDNSPlatformOneSecond) // delay after restarting LLQ before nuking previous known answers (avoids flutter if we restart before we have networking up)
|
#define RESTART_GOODBYE_DELAY (6 * mDNSPlatformOneSecond) // delay after restarting LLQ before nuking previous known answers (avoids flutter if we restart before we have networking up)
|
||||||
#define MIN_UCAST_PERIODIC_EXEC (5 * mDNSPlatformOneSecond)
|
|
||||||
#define INIT_UCAST_POLL_INTERVAL (3 * mDNSPlatformOneSecond) // this interval is used after send failures on network transitions
|
#define INIT_UCAST_POLL_INTERVAL (3 * mDNSPlatformOneSecond) // this interval is used after send failures on network transitions
|
||||||
// which typically heal quickly, so we start agressively and exponentially back off
|
// which typically heal quickly, so we start agressively and exponentially back off
|
||||||
#define MAX_UCAST_POLL_INTERVAL (60 * 60 * mDNSPlatformOneSecond)
|
#define MAX_UCAST_POLL_INTERVAL (60 * 60 * mDNSPlatformOneSecond)
|
||||||
|
//#define MAX_UCAST_POLL_INTERVAL (1 * 60 * mDNSPlatformOneSecond)
|
||||||
#define LLQ_POLL_INTERVAL (15 * 60 * mDNSPlatformOneSecond) // Polling interval for zones w/ an advertised LLQ port (ie not static zones) if LLQ fails due to NAT, etc.
|
#define LLQ_POLL_INTERVAL (15 * 60 * mDNSPlatformOneSecond) // Polling interval for zones w/ an advertised LLQ port (ie not static zones) if LLQ fails due to NAT, etc.
|
||||||
#define RESPONSE_WINDOW (60 * mDNSPlatformOneSecond) // require server responses within one minute of request
|
#define RESPONSE_WINDOW (60 * mDNSPlatformOneSecond) // require server responses within one minute of request
|
||||||
#define UPDATE_PORT_NAME "_dns-update._udp."
|
#define MAX_DNSSEC_UNANSWERED_QUERIES 1 // number of unanswered queries from any one uDNS server before turning off DNSSEC Validation
|
||||||
#define LLQ_PORT_NAME "_dns-llq._udp"
|
#define MAX_UCAST_UNANSWERED_QUERIES 2 // number of unanswered queries from any one uDNS server before trying another server
|
||||||
|
#define DNSSERVER_PENALTY_TIME (60 * mDNSPlatformOneSecond) // number of seconds for which new questions don't pick this server
|
||||||
|
|
||||||
|
// On some interfaces, we want to delay the first retransmission to a minimum of 2 seconds
|
||||||
|
// rather than the default (1 second).
|
||||||
|
#define MIN_UCAST_RETRANS_TIMEOUT (2 * mDNSPlatformOneSecond)
|
||||||
|
|
||||||
#define DEFAULT_UPDATE_LEASE 7200
|
#define DEFAULT_UPDATE_LEASE 7200
|
||||||
|
|
||||||
|
#define QuestionIntervalStep 3
|
||||||
|
#define QuestionIntervalStep2 (QuestionIntervalStep*QuestionIntervalStep)
|
||||||
|
#define QuestionIntervalStep3 (QuestionIntervalStep*QuestionIntervalStep*QuestionIntervalStep)
|
||||||
|
#define InitialQuestionInterval ((mDNSPlatformOneSecond + QuestionIntervalStep-1) / QuestionIntervalStep)
|
||||||
|
#define MaxQuestionInterval (3600 * mDNSPlatformOneSecond)
|
||||||
|
|
||||||
|
// just move to MaxQuestionInterval once over this threshold
|
||||||
|
#define QuestionIntervalThreshold (QuestionIntervalStep3 * mDNSPlatformOneSecond)
|
||||||
|
|
||||||
|
// For Unicast record registrations, we initialize the interval to 1 second. When we send any query for
|
||||||
|
// the record registration e.g., GetZoneData, we always back off by QuestionIntervalStep
|
||||||
|
// so that the first retry does not happen until 3 seconds which should be enough for TCP/TLS to be done.
|
||||||
|
#define INIT_RECORD_REG_INTERVAL (1 * mDNSPlatformOneSecond)
|
||||||
|
#define MAX_RECORD_REG_INTERVAL (15 * 60 * mDNSPlatformOneSecond)
|
||||||
|
#define MERGE_DELAY_TIME (1 * mDNSPlatformOneSecond)
|
||||||
|
|
||||||
|
// If we are refreshing, we do it at least 5 times with a min update frequency of
|
||||||
|
// 5 minutes
|
||||||
|
#define MAX_UPDATE_REFRESH_COUNT 5
|
||||||
|
#define MIN_UPDATE_REFRESH_TIME (5 * 60 * mDNSPlatformOneSecond)
|
||||||
|
|
||||||
|
// For questions that use kDNSServiceFlagsTimeout and we don't have a matching resolver e.g., no dns servers,
|
||||||
|
// then use the default value of 30 seconds
|
||||||
|
#define DEFAULT_UDNS_TIMEOUT 30 // in seconds
|
||||||
|
|
||||||
|
// For questions that are validating responses (q->ValidatingResponse == 1), use 10 seconds
|
||||||
|
// which accomodates two DNS servers and two queries per DNS server.
|
||||||
|
#define DEFAULT_UDNSSEC_TIMEOUT 10 // in seconds
|
||||||
|
|
||||||
|
// If we are sending queries with EDNS0/DO option and we have no indications that the server
|
||||||
|
// is DNSSEC aware and we have already reached MAX_DNSSEC_RETRANSMISSIONS, we disable
|
||||||
|
// validation (for optional case only) for any questions that uses this server
|
||||||
|
#define MAX_DNSSEC_RETRANSMISSIONS 3
|
||||||
|
|
||||||
// Entry points into unicast-specific routines
|
// Entry points into unicast-specific routines
|
||||||
|
|
||||||
extern mStatus uDNS_StartQuery(mDNS *const m, DNSQuestion *const question);
|
extern void LLQGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneInfo);
|
||||||
extern mDNSBool uDNS_IsActiveQuery(DNSQuestion *const question, uDNS_GlobalInfo *u); // returns true if OK to call StopQuery
|
extern void startLLQHandshake(mDNS *m, DNSQuestion *q);
|
||||||
extern mStatus uDNS_StopQuery(mDNS *const m, DNSQuestion *const question);
|
extern void sendLLQRefresh(mDNS *m, DNSQuestion *q);
|
||||||
|
|
||||||
extern void uDNS_Init(mDNS *const m);
|
extern void SleepRecordRegistrations(mDNS *m);
|
||||||
extern void uDNS_Sleep(mDNS *const m);
|
|
||||||
extern void uDNS_Wake(mDNS *const m);
|
|
||||||
#define uDNS_Close uDNS_Sleep
|
|
||||||
|
|
||||||
// uDNS_UpdateRecord
|
// uDNS_UpdateRecord
|
||||||
// following fields must be set, and the update validated, upon entry.
|
// following fields must be set, and the update validated, upon entry.
|
||||||
// rr->NewRData
|
// rr->NewRData
|
||||||
// rr->newrdlength
|
// rr->newrdlength
|
||||||
// rr->UpdateCallback
|
// rr->UpdateCallback
|
||||||
|
|
||||||
extern mStatus uDNS_AddRecordToService(mDNS *const m, ServiceRecordSet *sr, ExtraResourceRecord *extra);
|
|
||||||
extern mStatus uDNS_UpdateRecord(mDNS *m, AuthRecord *rr);
|
extern mStatus uDNS_UpdateRecord(mDNS *m, AuthRecord *rr);
|
||||||
|
|
||||||
extern mStatus uDNS_RegisterRecord(mDNS *const m, AuthRecord *const rr);
|
|
||||||
extern mStatus uDNS_DeregisterRecord(mDNS *const m, AuthRecord *const rr);
|
|
||||||
|
|
||||||
extern mStatus uDNS_RegisterService(mDNS *const m, ServiceRecordSet *srs);
|
extern void SetNextQueryTime(mDNS *const m, const DNSQuestion *const q);
|
||||||
extern mStatus uDNS_DeregisterService(mDNS *const m, ServiceRecordSet *srs);
|
extern mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr);
|
||||||
|
extern mStatus mDNS_Deregister_internal(mDNS *const m, AuthRecord *const rr, mDNS_Dereg_type drt);
|
||||||
|
extern mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const question);
|
||||||
|
extern mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const question);
|
||||||
|
extern mStatus mDNS_StartNATOperation_internal(mDNS *const m, NATTraversalInfo *traversal);
|
||||||
|
|
||||||
|
extern void RecordRegistrationGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneData);
|
||||||
|
extern mStatus uDNS_DeregisterRecord(mDNS *const m, AuthRecord *const rr);
|
||||||
|
extern const domainname *GetServiceTarget(mDNS *m, AuthRecord *const rr);
|
||||||
|
extern void uDNS_CheckCurrentQuestion(mDNS *const m);
|
||||||
|
|
||||||
// integer fields of msg header must be in HOST byte order before calling this routine
|
// integer fields of msg header must be in HOST byte order before calling this routine
|
||||||
extern void uDNS_ReceiveMsg(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end,
|
extern void uDNS_ReceiveMsg(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end,
|
||||||
const mDNSAddr *const srcaddr, const mDNSIPPort srcport, const mDNSAddr *const dstaddr,
|
const mDNSAddr *const srcaddr, const mDNSIPPort srcport);
|
||||||
const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID);
|
|
||||||
|
|
||||||
extern void uDNS_ReceiveNATMap(mDNS *m, mDNSu8 *pkt, mDNSu16 len);
|
extern void uDNS_Tasks(mDNS *const m);
|
||||||
|
extern void UpdateAllSRVRecords(mDNS *m);
|
||||||
// returns time of next scheduled event
|
extern void CheckNATMappings(mDNS *m);
|
||||||
extern void uDNS_Execute(mDNS *const m);
|
|
||||||
|
|
||||||
|
extern mStatus uDNS_SetupDNSConfig(mDNS *const m);
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
// uDNS_SetupWABQueries reads search domains from the platform layer and starts the Wide Area Bonjour
|
||||||
|
// (WAB) domain enumeration queries if necessary.
|
||||||
|
|
||||||
|
#define UDNS_WAB_BROWSE_QUERY 0x00000001 // Browse queries (b, db)
|
||||||
|
#define UDNS_WAB_LBROWSE_QUERY 0x00000002 // Browse queries (lb)
|
||||||
|
#define UDNS_WAB_REG_QUERY 0x00000004 // Registration queries (r and dr)
|
||||||
|
|
||||||
|
extern void uDNS_SetupWABQueries(mDNS *const m);
|
||||||
|
extern void uDNS_StartWABQueries(mDNS *const m, int queryType);
|
||||||
|
extern void uDNS_StopWABQueries(mDNS *const m, int queryType);
|
||||||
|
extern domainname *uDNS_GetNextSearchDomain(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal);
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
uDNS_LLQ_Not = 0, // Normal uDNS answer: Flush any stale records from cache, and respect record TTL
|
||||||
|
uDNS_LLQ_Ignore, // LLQ initial challenge packet: ignore -- has no useful records for us
|
||||||
|
uDNS_LLQ_Entire, // LLQ initial set of answers: Flush any stale records from cache, but assume TTL is 2 x LLQ refresh interval
|
||||||
|
uDNS_LLQ_Events // LLQ event packet: don't flush cache; assume TTL is 2 x LLQ refresh interval
|
||||||
|
} uDNS_LLQType;
|
||||||
|
|
||||||
|
extern uDNS_LLQType uDNS_recvLLQResponse(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr, const mDNSIPPort srcport, DNSQuestion **matchQuestion);
|
||||||
|
extern DomainAuthInfo *GetAuthInfoForName_internal(mDNS *m, const domainname *const name);
|
||||||
|
extern DomainAuthInfo *GetAuthInfoForQuestion(mDNS *m, const DNSQuestion *const q);
|
||||||
|
extern void DisposeTCPConn(struct tcpInfo_t *tcp);
|
||||||
|
|
||||||
|
// NAT traversal
|
||||||
|
extern void uDNS_ReceiveNATPacket(mDNS *m, const mDNSInterfaceID InterfaceID, mDNSu8 *pkt, mDNSu16 len); // Called for each received PCP or NAT-PMP packet
|
||||||
|
extern void natTraversalHandleAddressReply(mDNS *const m, mDNSu16 err, mDNSv4Addr ExtAddr);
|
||||||
|
extern void natTraversalHandlePortMapReply(mDNS *const m, NATTraversalInfo *n, const mDNSInterfaceID InterfaceID, mDNSu16 err, mDNSIPPort extport, mDNSu32 lease, NATTProtocol protocol);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // __UDNS_H_
|
#endif // __UDNS_H_
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,114 +5,86 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
File: uds_daemon.h
|
File: uds_daemon.h
|
||||||
|
|
||||||
Contains: Interfaces necessary to talk to uds_daemon.c.
|
Contains: Interfaces necessary to talk to uds_daemon.c.
|
||||||
|
|
||||||
Version: 1.0
|
Version: 1.0
|
||||||
|
|
||||||
Change History (most recent first):
|
*/
|
||||||
|
|
||||||
$Log: uds_daemon.h,v $
|
|
||||||
Revision 1.15 2006/08/14 23:24:57 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.14 2005/01/27 17:48:39 cheshire
|
|
||||||
Added comment about CFSocketInvalidate closing the underlying socket
|
|
||||||
|
|
||||||
Revision 1.13 2004/12/10 05:27:26 cheshire
|
|
||||||
<rdar://problem/3909147> Guard against multiple autoname services of the same type on the same machine
|
|
||||||
|
|
||||||
Revision 1.12 2004/12/10 04:28:28 cheshire
|
|
||||||
<rdar://problem/3914406> User not notified of name changes for services using new UDS API
|
|
||||||
|
|
||||||
Revision 1.11 2004/12/06 21:15:23 ksekar
|
|
||||||
<rdar://problem/3884386> mDNSResponder crashed in CheckServiceRegistrations
|
|
||||||
|
|
||||||
Revision 1.10 2004/10/26 04:31:44 cheshire
|
|
||||||
Rename CountSubTypes() as ChopSubTypes()
|
|
||||||
|
|
||||||
Revision 1.9 2004/09/30 00:25:00 ksekar
|
|
||||||
<rdar://problem/3695802> Dynamically update default registration domains on config change
|
|
||||||
|
|
||||||
Revision 1.8 2004/09/21 21:05:11 cheshire
|
|
||||||
Move duplicate code out of mDNSMacOSX/daemon.c and mDNSPosix/PosixDaemon.c,
|
|
||||||
into mDNSShared/uds_daemon.c
|
|
||||||
|
|
||||||
Revision 1.7 2004/09/17 01:08:55 cheshire
|
|
||||||
Renamed mDNSClientAPI.h to mDNSEmbeddedAPI.h
|
|
||||||
The name "mDNSClientAPI.h" is misleading to new developers looking at this code. The interfaces
|
|
||||||
declared in that file are ONLY appropriate to single-address-space embedded applications.
|
|
||||||
For clients on general-purpose computers, the interfaces defined in dns_sd.h should be used.
|
|
||||||
|
|
||||||
Revision 1.6 2004/08/11 01:58:49 cheshire
|
|
||||||
Remove "mDNS *globalInstance" parameter from udsserver_init()
|
|
||||||
|
|
||||||
Revision 1.5 2004/06/18 04:44:58 rpantos
|
|
||||||
Use platform layer for socket types
|
|
||||||
|
|
||||||
Revision 1.4 2004/06/12 00:51:58 cheshire
|
|
||||||
Changes for Windows compatibility
|
|
||||||
|
|
||||||
Revision 1.3 2004/01/25 00:03:21 cheshire
|
|
||||||
Change to use mDNSVal16() instead of private PORT_AS_NUM() macro
|
|
||||||
|
|
||||||
Revision 1.2 2004/01/24 08:46:26 bradley
|
|
||||||
Added InterfaceID<->Index platform interfaces since they are now used by all platforms for the DNS-SD APIs.
|
|
||||||
|
|
||||||
Revision 1.1 2003/12/08 21:11:42 rpantos;
|
|
||||||
Changes necessary to support mDNSResponder on Linux.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
#include "mDNSEmbeddedAPI.h"
|
#include "mDNSEmbeddedAPI.h"
|
||||||
#include "dnssd_ipc.h"
|
#include "dnssd_ipc.h"
|
||||||
|
|
||||||
|
|
||||||
/* Client interface: */
|
/* Client interface: */
|
||||||
|
|
||||||
#define SRS_PORT(S) mDNSVal16((S)->RR_SRV.resrec.rdata->u.srv.port)
|
#define SRS_PORT(S) mDNSVal16((S)->RR_SRV.resrec.rdata->u.srv.port)
|
||||||
|
|
||||||
extern int udsserver_init(void);
|
extern int udsserver_init(dnssd_sock_t skts[], mDNSu32 count);
|
||||||
|
|
||||||
// takes the next scheduled event time, does idle work, and returns the updated nextevent time
|
|
||||||
extern mDNSs32 udsserver_idle(mDNSs32 nextevent);
|
extern mDNSs32 udsserver_idle(mDNSs32 nextevent);
|
||||||
|
extern void udsserver_info(mDNS *const m); // print out info about current state
|
||||||
extern void udsserver_info(mDNS *const m); // print out info about current state
|
extern void udsserver_handle_configchange(mDNS *const m);
|
||||||
|
extern int udsserver_exit(void); // should be called prior to app exit
|
||||||
extern void udsserver_handle_configchange(void);
|
extern void LogMcastStateInfo(mDNS *const m, mDNSBool mflag, mDNSBool start, mDNSBool mstatelog);
|
||||||
|
#define LogMcastQ (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMcastQuestion
|
||||||
extern int udsserver_exit(void); // should be called prior to app exit
|
#define LogMcastS (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMcastService
|
||||||
|
#define LogMcast (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMsg
|
||||||
extern void udsserver_default_reg_domain_changed(const domainname *d, mDNSBool add);
|
#define LogMcastNoIdent (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMsgNoIdent
|
||||||
extern void udsserver_default_browse_domain_changed(const domainname *d, mDNSBool add);
|
|
||||||
|
|
||||||
/* Routines that uds_daemon expects to link against: */
|
/* Routines that uds_daemon expects to link against: */
|
||||||
|
|
||||||
typedef void (*udsEventCallback)(void *context);
|
typedef void (*udsEventCallback)(int fd, short filter, void *context);
|
||||||
|
extern mStatus udsSupportAddFDToEventLoop(dnssd_sock_t fd, udsEventCallback callback, void *context, void **platform_data);
|
||||||
|
extern int udsSupportReadFD(dnssd_sock_t fd, char* buf, int len, int flags, void *platform_data);
|
||||||
|
extern mStatus udsSupportRemoveFDFromEventLoop(dnssd_sock_t fd, void *platform_data); // Note: This also CLOSES the file descriptor as well
|
||||||
|
|
||||||
extern mStatus udsSupportAddFDToEventLoop(dnssd_sock_t fd, udsEventCallback callback, void *context);
|
|
||||||
extern mStatus udsSupportRemoveFDFromEventLoop(dnssd_sock_t fd); // Note: This also CLOSES the file descriptor as well
|
|
||||||
|
|
||||||
// RecordUpdatedNiceLabel() can be a no-op on platforms that don't care about updating the machine's
|
|
||||||
// global default service name (was OS X calls the "Computer Name") in response to name conflicts.
|
|
||||||
extern void RecordUpdatedNiceLabel(mDNS *const m, mDNSs32 delay);
|
extern void RecordUpdatedNiceLabel(mDNS *const m, mDNSs32 delay);
|
||||||
|
|
||||||
// Globals and functions defined in uds_daemon.c and also shared with the old "daemon.c" on OS X
|
// Globals and functions defined in uds_daemon.c and also shared with the old "daemon.c" on OS X
|
||||||
|
|
||||||
extern mDNS mDNSStorage;
|
extern mDNS mDNSStorage;
|
||||||
extern mDNSs32 ChopSubTypes(char *regtype);
|
extern DNameListElem *AutoRegistrationDomains;
|
||||||
extern AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p);
|
extern DNameListElem *AutoBrowseDomains;
|
||||||
|
|
||||||
|
extern mDNSs32 ChopSubTypes(char *regtype, char **AnonData);
|
||||||
|
extern AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p, char **AnonData);
|
||||||
extern int CountExistingRegistrations(domainname *srv, mDNSIPPort port);
|
extern int CountExistingRegistrations(domainname *srv, mDNSIPPort port);
|
||||||
extern void FreeExtraRR(mDNS *const m, AuthRecord *const rr, mStatus result);
|
extern void FreeExtraRR(mDNS *const m, AuthRecord *const rr, mStatus result);
|
||||||
extern int CountPeerRegistrations(mDNS *const m, ServiceRecordSet *const srs);
|
extern int CountPeerRegistrations(mDNS *const m, ServiceRecordSet *const srs);
|
||||||
|
|
||||||
|
#if APPLE_OSX_mDNSResponder
|
||||||
|
|
||||||
|
extern void machserver_automatic_browse_domain_changed(const domainname *d, mDNSBool add);
|
||||||
|
extern void machserver_automatic_registration_domain_changed(const domainname *d, mDNSBool add);
|
||||||
|
// D2D interface support
|
||||||
|
extern void external_start_browsing_for_service(mDNSInterfaceID InterfaceID, const domainname *const type, DNS_TypeValues qtype, DNSServiceFlags flags);
|
||||||
|
extern void external_stop_browsing_for_service(mDNSInterfaceID InterfaceID, const domainname *const type, DNS_TypeValues qtype, DNSServiceFlags flags);
|
||||||
|
extern void external_start_advertising_service(const ResourceRecord *const resourceRecord, DNSServiceFlags flags);
|
||||||
|
extern void external_stop_advertising_service(const ResourceRecord *const resourceRecord, DNSServiceFlags flags);
|
||||||
|
extern void external_start_resolving_service(mDNSInterfaceID InterfaceID, const domainname *const fqdn, DNSServiceFlags flags);
|
||||||
|
extern void external_stop_resolving_service(mDNSInterfaceID InterfaceID, const domainname *const fqdn, DNSServiceFlags flags);
|
||||||
|
extern void external_connection_release(const domainname *instance);
|
||||||
|
|
||||||
|
#else // APPLE_OSX_mDNSResponder
|
||||||
|
|
||||||
|
#define external_start_browsing_for_service(A,B,C,D) (void)(A)
|
||||||
|
#define external_stop_browsing_for_service(A,B,C,D) (void)(A)
|
||||||
|
#define external_start_advertising_service(A,B) (void)(A)
|
||||||
|
#define external_stop_advertising_service(A,B) (void)(A)
|
||||||
|
#define external_start_resolving_service(A,B,C) (void)(A)
|
||||||
|
#define external_stop_resolving_service(A,B,C) (void)(A)
|
||||||
|
#define external_connection_release(A) (void)(A)
|
||||||
|
|
||||||
|
#endif // APPLE_OSX_mDNSResponder
|
||||||
|
|
||||||
|
extern const char mDNSResponderVersionString_SCCS[];
|
||||||
|
#define mDNSResponderVersionString (mDNSResponderVersionString_SCCS+5)
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#
|
#
|
||||||
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
|
||||||
# Use is subject to license terms.
|
# Use is subject to license terms.
|
||||||
|
# Copyright 2016 Toomas Soome <tsoome@me.com>
|
||||||
#
|
#
|
||||||
|
|
||||||
LIBRARY = libdns_sd.a
|
LIBRARY = libdns_sd.a
|
||||||
|
@ -33,14 +34,10 @@ $(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
|
||||||
|
|
||||||
SRCDIR = ../common
|
SRCDIR = ../common
|
||||||
|
|
||||||
LDLIBS += -lsocket -lc
|
LDLIBS += -lsocket -lnsl -lc
|
||||||
|
|
||||||
C99MODE = $(C99_ENABLE)
|
C99MODE = $(C99_ENABLE)
|
||||||
CPPFLAGS += -I$(SRCDIR) -DNOT_HAVE_SA_LEN
|
CPPFLAGS += -I$(SRCDIR) -DNOT_HAVE_SA_LEN -D_XPG4_2 -D__EXTENSIONS__
|
||||||
|
|
||||||
CERRWARN += -erroff=E_ASSIGNMENT_TYPE_MISMATCH
|
|
||||||
|
|
||||||
CERRWARN += -_gcc=-Wno-implicit-function-declaration
|
|
||||||
|
|
||||||
.PARALLEL = $(OBJECTS)
|
.PARALLEL = $(OBJECTS)
|
||||||
.KEEP_STATE:
|
.KEEP_STATE:
|
||||||
|
|
|
@ -21,8 +21,9 @@
|
||||||
#
|
#
|
||||||
# CDDL HEADER END
|
# CDDL HEADER END
|
||||||
#
|
#
|
||||||
#ident "%Z%%M% %I% %E% SMI"
|
# Copyright 2016 Toomas Soome <tsoome@me.com>
|
||||||
#
|
#
|
||||||
|
Updated from upstream version mDNSResponder-576.30.4
|
||||||
|
|
||||||
Multicast DNS and Service Discovery support in Solaris using the
|
Multicast DNS and Service Discovery support in Solaris using the
|
||||||
Apple Bonjour source code (v107.6). Apple Bonjour source can be
|
Apple Bonjour source code (v107.6). Apple Bonjour source can be
|
||||||
|
|
|
@ -1,24 +1,13 @@
|
||||||
* Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
|
The majority of the source code in the mDNSResponder project is licensed
|
||||||
*
|
under the terms of the Apache License, Version 2.0, available from:
|
||||||
* Redistribution and use in source and binary forms, with or without
|
<http://www.apache.org/licenses/LICENSE-2.0>
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
To accommodate license compatibility with the widest possible range
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
of client code licenses, the shared library code, which is linked
|
||||||
* this list of conditions and the following disclaimer.
|
at runtime into the same address space as the client using it, is
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
licensed under the terms of the "Three-Clause BSD License".
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
The Linux Name Service Switch code, contributed by National ICT
|
||||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
|
Australia Ltd (NICTA) is licensed under the terms of the NICTA Public
|
||||||
* contributors may be used to endorse or promote products derived from this
|
Software Licence (which is substantially similar to the "Three-Clause
|
||||||
* software without specific prior written permission.
|
BSD License", with some additional language pertaining to Australian law).
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,74 +2,30 @@
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004, Apple Computer, Inc. All rights reserved.
|
* Copyright (c) 2004, Apple Computer, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
*
|
*
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
|
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
|
||||||
* contributors may be used to endorse or promote products derived from this
|
* contributors may be used to endorse or promote products derived from this
|
||||||
* software without specific prior written permission.
|
* software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
|
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: dnssd_clientlib.c,v $
|
|
||||||
Revision 1.11 2006/08/14 23:05:53 cheshire
|
|
||||||
Added "tab-width" emacs header line
|
|
||||||
|
|
||||||
Revision 1.10 2005/04/06 02:06:56 shersche
|
|
||||||
Add DNSSD_API macro to TXTRecord API calls
|
|
||||||
|
|
||||||
Revision 1.9 2004/10/06 02:22:19 cheshire
|
|
||||||
Changed MacRoman copyright symbol (should have been UTF-8 in any case :-) to ASCII-compatible "(c)"
|
|
||||||
|
|
||||||
Revision 1.8 2004/10/01 22:15:55 rpantos
|
|
||||||
rdar://problem/3824265: Replace APSL in client lib with BSD license.
|
|
||||||
|
|
||||||
Revision 1.7 2004/06/26 03:16:34 shersche
|
|
||||||
clean up warning messages on Win32 platform
|
|
||||||
|
|
||||||
Submitted by: herscher
|
|
||||||
|
|
||||||
Revision 1.6 2004/06/12 01:09:45 cheshire
|
|
||||||
To be callable from the broadest range of clients on Windows (e.g. Visual Basic, C#, etc.)
|
|
||||||
API routines have to be declared as "__stdcall", instead of the C default, "__cdecl"
|
|
||||||
|
|
||||||
Revision 1.5 2004/05/25 18:29:33 cheshire
|
|
||||||
Move DNSServiceConstructFullName() from dnssd_clientstub.c to dnssd_clientlib.c,
|
|
||||||
so that it's also accessible to dnssd_clientshim.c (single address space) clients.
|
|
||||||
|
|
||||||
Revision 1.4 2004/05/25 17:08:55 cheshire
|
|
||||||
Fix compiler warning (doesn't make sense for function return type to be const)
|
|
||||||
|
|
||||||
Revision 1.3 2004/05/21 21:41:35 cheshire
|
|
||||||
Add TXT record building and parsing APIs
|
|
||||||
|
|
||||||
Revision 1.2 2004/05/20 22:22:21 cheshire
|
|
||||||
Enable code that was bracketed by "#if 0"
|
|
||||||
|
|
||||||
Revision 1.1 2004/03/12 21:30:29 cheshire
|
|
||||||
Build a System-Context Shared Library from mDNSCore, for the benefit of developers
|
|
||||||
like Muse Research who want to be able to use mDNS/DNS-SD from GPL-licensed code.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -82,292 +38,329 @@ like Muse Research who want to be able to use mDNS/DNS-SD from GPL-licensed code
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
// disable warning "conversion from <data> to uint16_t"
|
// disable warning "conversion from <data> to uint16_t"
|
||||||
#pragma warning(disable:4244)
|
#pragma warning(disable:4244)
|
||||||
|
#define strncasecmp _strnicmp
|
||||||
|
#define strcasecmp _stricmp
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*********************************************************************************************
|
/*********************************************************************************************
|
||||||
*
|
*
|
||||||
* Supporting Functions
|
* Supporting Functions
|
||||||
*
|
*
|
||||||
*********************************************************************************************/
|
*********************************************************************************************/
|
||||||
|
|
||||||
#define mdnsIsDigit(X) ((X) >= '0' && (X) <= '9')
|
#define mDNSIsDigit(X) ((X) >= '0' && (X) <= '9')
|
||||||
|
|
||||||
|
// DomainEndsInDot returns 1 if name ends with a dot, 0 otherwise
|
||||||
|
// (DNSServiceConstructFullName depends this returning 1 for true, rather than any non-zero value meaning true)
|
||||||
|
|
||||||
static int DomainEndsInDot(const char *dom)
|
static int DomainEndsInDot(const char *dom)
|
||||||
{
|
{
|
||||||
while (dom[0] && dom[1])
|
while (dom[0] && dom[1])
|
||||||
{
|
{
|
||||||
if (dom[0] == '\\') // advance past escaped byte sequence
|
if (dom[0] == '\\') // advance past escaped byte sequence
|
||||||
{
|
{
|
||||||
if (mdnsIsDigit(dom[1]) && mdnsIsDigit(dom[2]) && mdnsIsDigit(dom[3]))
|
if (mDNSIsDigit(dom[1]) && mDNSIsDigit(dom[2]) && mDNSIsDigit(dom[3]))
|
||||||
dom += 4; // If "\ddd" then skip four
|
dom += 4; // If "\ddd" then skip four
|
||||||
else dom += 2; // else if "\x" then skip two
|
else dom += 2; // else if "\x" then skip two
|
||||||
}
|
}
|
||||||
else dom++; // else goto next character
|
else dom++; // else goto next character
|
||||||
}
|
}
|
||||||
return (dom[0] == '.');
|
return (dom[0] == '.');
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t *InternalTXTRecordSearch
|
static uint8_t *InternalTXTRecordSearch
|
||||||
(
|
(
|
||||||
uint16_t txtLen,
|
uint16_t txtLen,
|
||||||
const void *txtRecord,
|
const void *txtRecord,
|
||||||
const char *key,
|
const char *key,
|
||||||
unsigned long *keylen
|
unsigned long *keylen
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint8_t *p = (uint8_t*)txtRecord;
|
uint8_t *p = (uint8_t*)txtRecord;
|
||||||
uint8_t *e = p + txtLen;
|
uint8_t *e = p + txtLen;
|
||||||
*keylen = (unsigned long) strlen(key);
|
*keylen = (unsigned long) strlen(key);
|
||||||
while (p<e)
|
while (p<e)
|
||||||
{
|
{
|
||||||
uint8_t *x = p;
|
uint8_t *x = p;
|
||||||
p += 1 + p[0];
|
p += 1 + p[0];
|
||||||
if (p <= e && *keylen <= x[0] && !strncmp(key, (char*)x+1, *keylen))
|
if (p <= e && *keylen <= x[0] && !strncasecmp(key, (char*)x+1, *keylen))
|
||||||
if (*keylen == x[0] || x[1+*keylen] == '=') return(x);
|
if (*keylen == x[0] || x[1+*keylen] == '=') return(x);
|
||||||
}
|
}
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************
|
/*********************************************************************************************
|
||||||
*
|
*
|
||||||
* General Utility Functions
|
* General Utility Functions
|
||||||
*
|
*
|
||||||
*********************************************************************************************/
|
*********************************************************************************************/
|
||||||
|
|
||||||
int DNSSD_API DNSServiceConstructFullName
|
// Note: Need to make sure we don't write more than kDNSServiceMaxDomainName (1009) bytes to fullName
|
||||||
(
|
// In earlier builds this constant was defined to be 1005, so to avoid buffer overruns on clients
|
||||||
char *fullName,
|
// compiled with that constant we'll actually limit the output to 1005 bytes.
|
||||||
const char *service, /* may be NULL */
|
|
||||||
const char *regtype,
|
|
||||||
const char *domain
|
|
||||||
)
|
|
||||||
{
|
|
||||||
unsigned long len;
|
|
||||||
unsigned char c;
|
|
||||||
char *fn = fullName;
|
|
||||||
const char *s = service;
|
|
||||||
const char *r = regtype;
|
|
||||||
const char *d = domain;
|
|
||||||
|
|
||||||
if (service)
|
DNSServiceErrorType DNSSD_API DNSServiceConstructFullName
|
||||||
{
|
(
|
||||||
while(*s)
|
char *const fullName,
|
||||||
{
|
const char *const service, // May be NULL
|
||||||
c = (unsigned char)*s++;
|
const char *const regtype,
|
||||||
if (c == '.' || (c == '\\')) *fn++ = '\\'; // escape dot and backslash literals
|
const char *const domain
|
||||||
else if (c <= ' ') // escape non-printable characters
|
)
|
||||||
{
|
{
|
||||||
*fn++ = '\\';
|
const size_t len = !regtype ? 0 : strlen(regtype) - DomainEndsInDot(regtype);
|
||||||
*fn++ = (char) ('0' + (c / 100));
|
char *fn = fullName;
|
||||||
*fn++ = (char) ('0' + (c / 10) % 10);
|
char *const lim = fullName + 1005;
|
||||||
c = (unsigned char)('0' + (c % 10));
|
const char *s = service;
|
||||||
}
|
const char *r = regtype;
|
||||||
*fn++ = (char)c;
|
const char *d = domain;
|
||||||
}
|
|
||||||
*fn++ = '.';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!regtype) return -1;
|
// regtype must be at least "x._udp" or "x._tcp"
|
||||||
len = (unsigned long) strlen(regtype);
|
if (len < 6 || !domain || !domain[0]) return kDNSServiceErr_BadParam;
|
||||||
if (DomainEndsInDot(regtype)) len--;
|
if (strncasecmp((regtype + len - 4), "_tcp", 4) && strncasecmp((regtype + len - 4), "_udp", 4)) return kDNSServiceErr_BadParam;
|
||||||
if (len < 6) return -1; // regtype must be at least "x._udp" or "x._tcp"
|
|
||||||
if (strncmp((regtype + len - 4), "_tcp", 4) && strncmp((regtype + len - 4), "_udp", 4)) return -1;
|
|
||||||
while(*r) *fn++ = *r++;
|
|
||||||
if (!DomainEndsInDot(regtype)) *fn++ = '.';
|
|
||||||
|
|
||||||
if (!domain || !domain[0]) return -1;
|
if (service && *service)
|
||||||
while(*d) *fn++ = *d++;
|
{
|
||||||
if (!DomainEndsInDot(domain)) *fn++ = '.';
|
while (*s)
|
||||||
*fn = '\0';
|
{
|
||||||
return 0;
|
unsigned char c = *s++; // Needs to be unsigned, or values like 0xFF will be interpreted as < 32
|
||||||
}
|
if (c <= ' ') // Escape non-printable characters
|
||||||
|
{
|
||||||
|
if (fn+4 >= lim) goto fail;
|
||||||
|
*fn++ = '\\';
|
||||||
|
*fn++ = '0' + (c / 100);
|
||||||
|
*fn++ = '0' + (c / 10) % 10;
|
||||||
|
c = '0' + (c ) % 10;
|
||||||
|
}
|
||||||
|
else if (c == '.' || (c == '\\')) // Escape dot and backslash literals
|
||||||
|
{
|
||||||
|
if (fn+2 >= lim) goto fail;
|
||||||
|
*fn++ = '\\';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (fn+1 >= lim) goto fail;
|
||||||
|
*fn++ = (char)c;
|
||||||
|
}
|
||||||
|
*fn++ = '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*r) if (fn+1 >= lim) goto fail;else *fn++ = *r++;
|
||||||
|
if (!DomainEndsInDot(regtype)) { if (fn+1 >= lim) goto fail;else *fn++ = '.';}
|
||||||
|
|
||||||
|
while (*d) if (fn+1 >= lim) goto fail;else *fn++ = *d++;
|
||||||
|
if (!DomainEndsInDot(domain)) { if (fn+1 >= lim) goto fail;else *fn++ = '.';}
|
||||||
|
|
||||||
|
*fn = '\0';
|
||||||
|
return kDNSServiceErr_NoError;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
*fn = '\0';
|
||||||
|
return kDNSServiceErr_BadParam;
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************
|
/*********************************************************************************************
|
||||||
*
|
*
|
||||||
* TXT Record Construction Functions
|
* TXT Record Construction Functions
|
||||||
*
|
*
|
||||||
*********************************************************************************************/
|
*********************************************************************************************/
|
||||||
|
|
||||||
typedef struct _TXTRecordRefRealType
|
typedef struct _TXTRecordRefRealType
|
||||||
{
|
{
|
||||||
uint8_t *buffer; // Pointer to data
|
uint8_t *buffer; // Pointer to data
|
||||||
uint16_t buflen; // Length of buffer
|
uint16_t buflen; // Length of buffer
|
||||||
uint16_t datalen; // Length currently in use
|
uint16_t datalen; // Length currently in use
|
||||||
uint16_t malloced; // Non-zero if buffer was allocated via malloc()
|
uint16_t malloced; // Non-zero if buffer was allocated via malloc()
|
||||||
} TXTRecordRefRealType;
|
} TXTRecordRefRealType;
|
||||||
|
|
||||||
#define txtRec ((TXTRecordRefRealType*)txtRecord)
|
#define txtRec ((TXTRecordRefRealType*)txtRecord)
|
||||||
|
|
||||||
// The opaque storage defined in the public dns_sd.h header is 16 bytes;
|
// The opaque storage defined in the public dns_sd.h header is 16 bytes;
|
||||||
// make sure we don't exceed that.
|
// make sure we don't exceed that.
|
||||||
struct dnssd_clientlib_CompileTimeAssertionCheck
|
struct CompileTimeAssertionCheck_dnssd_clientlib
|
||||||
{
|
{
|
||||||
char assert0[(sizeof(TXTRecordRefRealType) <= 16) ? 1 : -1];
|
char assert0[(sizeof(TXTRecordRefRealType) <= 16) ? 1 : -1];
|
||||||
};
|
};
|
||||||
|
|
||||||
void DNSSD_API TXTRecordCreate
|
void DNSSD_API TXTRecordCreate
|
||||||
(
|
(
|
||||||
TXTRecordRef *txtRecord,
|
TXTRecordRef *txtRecord,
|
||||||
uint16_t bufferLen,
|
uint16_t bufferLen,
|
||||||
void *buffer
|
void *buffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
txtRec->buffer = buffer;
|
txtRec->buffer = buffer;
|
||||||
txtRec->buflen = buffer ? bufferLen : (uint16_t)0;
|
txtRec->buflen = buffer ? bufferLen : (uint16_t)0;
|
||||||
txtRec->datalen = 0;
|
txtRec->datalen = 0;
|
||||||
txtRec->malloced = 0;
|
txtRec->malloced = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DNSSD_API TXTRecordDeallocate(TXTRecordRef *txtRecord)
|
void DNSSD_API TXTRecordDeallocate(TXTRecordRef *txtRecord)
|
||||||
{
|
{
|
||||||
if (txtRec->malloced) free(txtRec->buffer);
|
if (txtRec->malloced) free(txtRec->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
DNSServiceErrorType DNSSD_API TXTRecordSetValue
|
DNSServiceErrorType DNSSD_API TXTRecordSetValue
|
||||||
(
|
(
|
||||||
TXTRecordRef *txtRecord,
|
TXTRecordRef *txtRecord,
|
||||||
const char *key,
|
const char *key,
|
||||||
uint8_t valueSize,
|
uint8_t valueSize,
|
||||||
const void *value
|
const void *value
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint8_t *start, *p;
|
uint8_t *start, *p;
|
||||||
const char *k;
|
const char *k;
|
||||||
unsigned long keysize, keyvalsize;
|
unsigned long keysize, keyvalsize;
|
||||||
|
|
||||||
for (k = key; *k; k++) if (*k < 0x20 || *k > 0x7E || *k == '=') return(kDNSServiceErr_Invalid);
|
for (k = key; *k; k++) if (*k < 0x20 || *k > 0x7E || *k == '=') return(kDNSServiceErr_Invalid);
|
||||||
keysize = (unsigned long)(k - key);
|
keysize = (unsigned long)(k - key);
|
||||||
keyvalsize = 1 + keysize + (value ? (1 + valueSize) : 0);
|
keyvalsize = 1 + keysize + (value ? (1 + valueSize) : 0);
|
||||||
if (keysize < 1 || keyvalsize > 255) return(kDNSServiceErr_Invalid);
|
if (keysize < 1 || keyvalsize > 255) return(kDNSServiceErr_Invalid);
|
||||||
(void)TXTRecordRemoveValue(txtRecord, key);
|
(void)TXTRecordRemoveValue(txtRecord, key);
|
||||||
if (txtRec->datalen + keyvalsize > txtRec->buflen)
|
if (txtRec->datalen + keyvalsize > txtRec->buflen)
|
||||||
{
|
{
|
||||||
unsigned char *newbuf;
|
unsigned char *newbuf;
|
||||||
unsigned long newlen = txtRec->datalen + keyvalsize;
|
unsigned long newlen = txtRec->datalen + keyvalsize;
|
||||||
if (newlen > 0xFFFF) return(kDNSServiceErr_Invalid);
|
if (newlen > 0xFFFF) return(kDNSServiceErr_Invalid);
|
||||||
newbuf = malloc((size_t)newlen);
|
newbuf = malloc((size_t)newlen);
|
||||||
if (!newbuf) return(kDNSServiceErr_NoMemory);
|
if (!newbuf) return(kDNSServiceErr_NoMemory);
|
||||||
memcpy(newbuf, txtRec->buffer, txtRec->datalen);
|
memcpy(newbuf, txtRec->buffer, txtRec->datalen);
|
||||||
if (txtRec->malloced) free(txtRec->buffer);
|
if (txtRec->malloced) free(txtRec->buffer);
|
||||||
txtRec->buffer = newbuf;
|
txtRec->buffer = newbuf;
|
||||||
txtRec->buflen = (uint16_t)(newlen);
|
txtRec->buflen = (uint16_t)(newlen);
|
||||||
txtRec->malloced = 1;
|
txtRec->malloced = 1;
|
||||||
}
|
}
|
||||||
start = txtRec->buffer + txtRec->datalen;
|
start = txtRec->buffer + txtRec->datalen;
|
||||||
p = start + 1;
|
p = start + 1;
|
||||||
memcpy(p, key, keysize);
|
memcpy(p, key, keysize);
|
||||||
p += keysize;
|
p += keysize;
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
*p++ = '=';
|
*p++ = '=';
|
||||||
memcpy(p, value, valueSize);
|
memcpy(p, value, valueSize);
|
||||||
p += valueSize;
|
p += valueSize;
|
||||||
}
|
}
|
||||||
*start = (uint8_t)(p - start - 1);
|
*start = (uint8_t)(p - start - 1);
|
||||||
txtRec->datalen += p - start;
|
txtRec->datalen += p - start;
|
||||||
return(kDNSServiceErr_NoError);
|
return(kDNSServiceErr_NoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
DNSServiceErrorType DNSSD_API TXTRecordRemoveValue
|
DNSServiceErrorType DNSSD_API TXTRecordRemoveValue
|
||||||
(
|
(
|
||||||
TXTRecordRef *txtRecord,
|
TXTRecordRef *txtRecord,
|
||||||
const char *key
|
const char *key
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned long keylen, itemlen, remainder;
|
unsigned long keylen, itemlen, remainder;
|
||||||
uint8_t *item = InternalTXTRecordSearch(txtRec->datalen, txtRec->buffer, key, &keylen);
|
uint8_t *item = InternalTXTRecordSearch(txtRec->datalen, txtRec->buffer, key, &keylen);
|
||||||
if (!item) return(kDNSServiceErr_NoSuchKey);
|
if (!item) return(kDNSServiceErr_NoSuchKey);
|
||||||
itemlen = (unsigned long)(1 + item[0]);
|
itemlen = (unsigned long)(1 + item[0]);
|
||||||
remainder = (unsigned long)((txtRec->buffer + txtRec->datalen) - (item + itemlen));
|
remainder = (unsigned long)((txtRec->buffer + txtRec->datalen) - (item + itemlen));
|
||||||
// Use memmove because memcpy behaviour is undefined for overlapping regions
|
// Use memmove because memcpy behaviour is undefined for overlapping regions
|
||||||
memmove(item, item + itemlen, remainder);
|
memmove(item, item + itemlen, remainder);
|
||||||
txtRec->datalen -= itemlen;
|
txtRec->datalen -= itemlen;
|
||||||
return(kDNSServiceErr_NoError);
|
return(kDNSServiceErr_NoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t DNSSD_API TXTRecordGetLength (const TXTRecordRef *txtRecord) { return(txtRec->datalen); }
|
uint16_t DNSSD_API TXTRecordGetLength (const TXTRecordRef *txtRecord) { return(txtRec->datalen); }
|
||||||
const void * DNSSD_API TXTRecordGetBytesPtr(const TXTRecordRef *txtRecord) { return(txtRec->buffer); }
|
const void * DNSSD_API TXTRecordGetBytesPtr(const TXTRecordRef *txtRecord) { return(txtRec->buffer); }
|
||||||
|
|
||||||
/*********************************************************************************************
|
/*********************************************************************************************
|
||||||
*
|
*
|
||||||
* TXT Record Parsing Functions
|
* TXT Record Parsing Functions
|
||||||
*
|
*
|
||||||
*********************************************************************************************/
|
*********************************************************************************************/
|
||||||
|
|
||||||
int DNSSD_API TXTRecordContainsKey
|
int DNSSD_API TXTRecordContainsKey
|
||||||
(
|
(
|
||||||
uint16_t txtLen,
|
uint16_t txtLen,
|
||||||
const void *txtRecord,
|
const void *txtRecord,
|
||||||
const char *key
|
const char *key
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned long keylen;
|
unsigned long keylen;
|
||||||
return (InternalTXTRecordSearch(txtLen, txtRecord, key, &keylen) ? 1 : 0);
|
return (InternalTXTRecordSearch(txtLen, txtRecord, key, &keylen) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const void * DNSSD_API TXTRecordGetValuePtr
|
const void * DNSSD_API TXTRecordGetValuePtr
|
||||||
(
|
(
|
||||||
uint16_t txtLen,
|
uint16_t txtLen,
|
||||||
const void *txtRecord,
|
const void *txtRecord,
|
||||||
const char *key,
|
const char *key,
|
||||||
uint8_t *valueLen
|
uint8_t *valueLen
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned long keylen;
|
unsigned long keylen;
|
||||||
uint8_t *item = InternalTXTRecordSearch(txtLen, txtRecord, key, &keylen);
|
uint8_t *item = InternalTXTRecordSearch(txtLen, txtRecord, key, &keylen);
|
||||||
if (!item || item[0] <= keylen) return(NULL); // If key not found, or found with no value, return NULL
|
if (!item || item[0] <= keylen) return(NULL); // If key not found, or found with no value, return NULL
|
||||||
*valueLen = (uint8_t)(item[0] - (keylen + 1));
|
*valueLen = (uint8_t)(item[0] - (keylen + 1));
|
||||||
return (item + 1 + keylen + 1);
|
return (item + 1 + keylen + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t DNSSD_API TXTRecordGetCount
|
uint16_t DNSSD_API TXTRecordGetCount
|
||||||
(
|
(
|
||||||
uint16_t txtLen,
|
uint16_t txtLen,
|
||||||
const void *txtRecord
|
const void *txtRecord
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint16_t count = 0;
|
uint16_t count = 0;
|
||||||
uint8_t *p = (uint8_t*)txtRecord;
|
uint8_t *p = (uint8_t*)txtRecord;
|
||||||
uint8_t *e = p + txtLen;
|
uint8_t *e = p + txtLen;
|
||||||
while (p<e) { p += 1 + p[0]; count++; }
|
while (p<e) { p += 1 + p[0]; count++; }
|
||||||
return((p>e) ? (uint16_t)0 : count);
|
return((p>e) ? (uint16_t)0 : count);
|
||||||
}
|
}
|
||||||
|
|
||||||
DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex
|
DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex
|
||||||
(
|
(
|
||||||
uint16_t txtLen,
|
uint16_t txtLen,
|
||||||
const void *txtRecord,
|
const void *txtRecord,
|
||||||
uint16_t index,
|
uint16_t itemIndex,
|
||||||
uint16_t keyBufLen,
|
uint16_t keyBufLen,
|
||||||
char *key,
|
char *key,
|
||||||
uint8_t *valueLen,
|
uint8_t *valueLen,
|
||||||
const void **value
|
const void **value
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint16_t count = 0;
|
uint16_t count = 0;
|
||||||
uint8_t *p = (uint8_t*)txtRecord;
|
uint8_t *p = (uint8_t*)txtRecord;
|
||||||
uint8_t *e = p + txtLen;
|
uint8_t *e = p + txtLen;
|
||||||
while (p<e && count<index) { p += 1 + p[0]; count++; } // Find requested item
|
while (p<e && count<itemIndex) { p += 1 + p[0]; count++; } // Find requested item
|
||||||
if (p<e && p + 1 + p[0] <= e) // If valid
|
if (p<e && p + 1 + p[0] <= e) // If valid
|
||||||
{
|
{
|
||||||
uint8_t *x = p+1;
|
uint8_t *x = p+1;
|
||||||
unsigned long len = 0;
|
unsigned long len = 0;
|
||||||
e = p + 1 + p[0];
|
e = p + 1 + p[0];
|
||||||
while (x+len<e && x[len] != '=') len++;
|
while (x+len<e && x[len] != '=') len++;
|
||||||
if (len >= keyBufLen) return(kDNSServiceErr_NoMemory);
|
if (len >= keyBufLen) return(kDNSServiceErr_NoMemory);
|
||||||
memcpy(key, x, len);
|
memcpy(key, x, len);
|
||||||
key[len] = 0;
|
key[len] = 0;
|
||||||
if (x+len<e) // If we found '='
|
if (x+len<e) // If we found '='
|
||||||
{
|
{
|
||||||
*value = x + len + 1;
|
*value = x + len + 1;
|
||||||
*valueLen = (uint8_t)(p[0] - (len + 1));
|
*valueLen = (uint8_t)(p[0] - (len + 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*value = NULL;
|
*value = NULL;
|
||||||
*valueLen = 0;
|
*valueLen = 0;
|
||||||
}
|
}
|
||||||
return(kDNSServiceErr_NoError);
|
return(kDNSServiceErr_NoError);
|
||||||
}
|
}
|
||||||
return(kDNSServiceErr_Invalid);
|
return(kDNSServiceErr_Invalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************
|
||||||
|
*
|
||||||
|
* SCCS-compatible version string
|
||||||
|
*
|
||||||
|
*********************************************************************************************/
|
||||||
|
|
||||||
|
// For convenience when using the "strings" command, this is the last thing in the file
|
||||||
|
|
||||||
|
// Note: The C preprocessor stringify operator ('#') makes a string from its argument, without macro expansion
|
||||||
|
// e.g. If "version" is #define'd to be "4", then STRINGIFY_AWE(version) will return the string "version", not "4"
|
||||||
|
// To expand "version" to its value before making the string, use STRINGIFY(version) instead
|
||||||
|
#define STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) # s
|
||||||
|
#define STRINGIFY(s) STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s)
|
||||||
|
|
||||||
|
// NOT static -- otherwise the compiler may optimize it out
|
||||||
|
// The "@(#) " pattern is a special prefix the "what" command looks for
|
||||||
|
const char VersionString_SCCS_libdnssd[] = "@(#) libdns_sd " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,134 +2,160 @@
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
|
* Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
*
|
*
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
|
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
|
||||||
* contributors may be used to endorse or promote products derived from this
|
* contributors may be used to endorse or promote products derived from this
|
||||||
* software without specific prior written permission.
|
* software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
|
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: dnssd_ipc.c,v $
|
|
||||||
Revision 1.16 2006/08/14 23:05:53 cheshire
|
|
||||||
Added "tab-width" emacs header line
|
|
||||||
|
|
||||||
Revision 1.15 2005/01/27 22:57:56 cheshire
|
|
||||||
Fix compile errors on gcc4
|
|
||||||
|
|
||||||
Revision 1.14 2004/10/06 02:22:20 cheshire
|
|
||||||
Changed MacRoman copyright symbol (should have been UTF-8 in any case :-) to ASCII-compatible "(c)"
|
|
||||||
|
|
||||||
Revision 1.13 2004/10/01 22:15:55 rpantos
|
|
||||||
rdar://problem/3824265: Replace APSL in client lib with BSD license.
|
|
||||||
|
|
||||||
Revision 1.12 2004/09/16 23:14:24 cheshire
|
|
||||||
Changes for Windows compatibility
|
|
||||||
|
|
||||||
Revision 1.11 2004/06/18 04:56:09 rpantos
|
|
||||||
casting goodness
|
|
||||||
|
|
||||||
Revision 1.10 2004/06/12 01:08:14 cheshire
|
|
||||||
Changes for Windows compatibility
|
|
||||||
|
|
||||||
Revision 1.9 2004/05/18 23:51:27 cheshire
|
|
||||||
Tidy up all checkin comments to use consistent "<rdar://problem/xxxxxxx>" format for bug numbers
|
|
||||||
|
|
||||||
Revision 1.8 2003/11/05 22:44:57 ksekar
|
|
||||||
<rdar://problem/3335230>: No bounds checking when reading data from client
|
|
||||||
Reviewed by: Stuart Cheshire
|
|
||||||
|
|
||||||
Revision 1.7 2003/08/12 19:56:25 cheshire
|
|
||||||
Update to APSL 2.0
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
#include "dnssd_ipc.h"
|
#include "dnssd_ipc.h"
|
||||||
|
|
||||||
void put_long(const uint32_t l, char **ptr)
|
#if defined(_WIN32)
|
||||||
{
|
|
||||||
(*ptr)[0] = (char)((l >> 24) & 0xFF);
|
|
||||||
(*ptr)[1] = (char)((l >> 16) & 0xFF);
|
|
||||||
(*ptr)[2] = (char)((l >> 8) & 0xFF);
|
|
||||||
(*ptr)[3] = (char)((l ) & 0xFF);
|
|
||||||
*ptr += sizeof(uint32_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t get_long(char **ptr)
|
char *win32_strerror(int inErrorCode)
|
||||||
{
|
{
|
||||||
uint8_t *p = (uint8_t*) *ptr;
|
static char buffer[1024];
|
||||||
*ptr += sizeof(uint32_t);
|
DWORD n;
|
||||||
return((uint32_t) ((uint32_t)p[0] << 24 | (uint32_t)p[1] << 16 | (uint32_t)p[2] << 8 | p[3]));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
}
|
n = FormatMessageA(
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL,
|
||||||
|
(DWORD) inErrorCode,
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
buffer,
|
||||||
|
sizeof(buffer),
|
||||||
|
NULL);
|
||||||
|
if (n > 0)
|
||||||
|
{
|
||||||
|
// Remove any trailing CR's or LF's since some messages have them.
|
||||||
|
while ((n > 0) && isspace(((unsigned char *) buffer)[n - 1]))
|
||||||
|
buffer[--n] = '\0';
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
void put_short(uint16_t s, char **ptr)
|
#endif
|
||||||
{
|
|
||||||
(*ptr)[0] = (char)((s >> 8) & 0xFF);
|
|
||||||
(*ptr)[1] = (char)((s ) & 0xFF);
|
|
||||||
*ptr += sizeof(uint16_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t get_short(char **ptr)
|
void put_uint32(const uint32_t l, char **ptr)
|
||||||
{
|
{
|
||||||
uint8_t *p = (uint8_t*) *ptr;
|
(*ptr)[0] = (char)((l >> 24) & 0xFF);
|
||||||
*ptr += sizeof(uint16_t);
|
(*ptr)[1] = (char)((l >> 16) & 0xFF);
|
||||||
return((uint16_t) ((uint16_t)p[0] << 8 | p[1]));
|
(*ptr)[2] = (char)((l >> 8) & 0xFF);
|
||||||
}
|
(*ptr)[3] = (char)((l ) & 0xFF);
|
||||||
|
*ptr += sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t get_uint32(const char **ptr, const char *end)
|
||||||
|
{
|
||||||
|
if (!*ptr || *ptr + sizeof(uint32_t) > end)
|
||||||
|
{
|
||||||
|
*ptr = NULL;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint8_t *p = (uint8_t*) *ptr;
|
||||||
|
*ptr += sizeof(uint32_t);
|
||||||
|
return((uint32_t) ((uint32_t)p[0] << 24 | (uint32_t)p[1] << 16 | (uint32_t)p[2] << 8 | p[3]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void put_uint16(uint16_t s, char **ptr)
|
||||||
|
{
|
||||||
|
(*ptr)[0] = (char)((s >> 8) & 0xFF);
|
||||||
|
(*ptr)[1] = (char)((s ) & 0xFF);
|
||||||
|
*ptr += sizeof(uint16_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t get_uint16(const char **ptr, const char *end)
|
||||||
|
{
|
||||||
|
if (!*ptr || *ptr + sizeof(uint16_t) > end)
|
||||||
|
{
|
||||||
|
*ptr = NULL;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint8_t *p = (uint8_t*) *ptr;
|
||||||
|
*ptr += sizeof(uint16_t);
|
||||||
|
return((uint16_t) ((uint16_t)p[0] << 8 | p[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int put_string(const char *str, char **ptr)
|
int put_string(const char *str, char **ptr)
|
||||||
{
|
{
|
||||||
if (!str) str = "";
|
if (!str) str = "";
|
||||||
strcpy(*ptr, str);
|
strcpy(*ptr, str);
|
||||||
*ptr += strlen(str) + 1;
|
*ptr += strlen(str) + 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_string(char **ptr, char *buffer, int buflen)
|
int get_string(const char **ptr, const char *const end, char *buffer, int buflen)
|
||||||
{
|
{
|
||||||
int overrun = (int)strlen(*ptr) < buflen ? 0 : -1;
|
if (!*ptr)
|
||||||
strncpy(buffer, *ptr, buflen - 1);
|
{
|
||||||
buffer[buflen - 1] = '\0';
|
*buffer = 0;
|
||||||
*ptr += strlen(buffer) + 1;
|
return(-1);
|
||||||
return overrun;
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
char *lim = buffer + buflen; // Calculate limit
|
||||||
|
while (*ptr < end && buffer < lim)
|
||||||
|
{
|
||||||
|
char c = *buffer++ = *(*ptr)++;
|
||||||
|
if (c == 0) return(0); // Success
|
||||||
|
}
|
||||||
|
if (buffer == lim) buffer--;
|
||||||
|
*buffer = 0; // Failed, so terminate string,
|
||||||
|
*ptr = NULL; // clear pointer,
|
||||||
|
return(-1); // and return failure indication
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr)
|
void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr)
|
||||||
{
|
{
|
||||||
memcpy(*ptr, rdata, rdlen);
|
memcpy(*ptr, rdata, rdlen);
|
||||||
*ptr += rdlen;
|
*ptr += rdlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *get_rdata(char **ptr, int rdlen)
|
const char *get_rdata(const char **ptr, const char *end, int rdlen)
|
||||||
{
|
{
|
||||||
char *rd = *ptr;
|
if (!*ptr || *ptr + rdlen > end)
|
||||||
*ptr += rdlen;
|
{
|
||||||
return rd;
|
*ptr = NULL;
|
||||||
}
|
return(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char *rd = *ptr;
|
||||||
|
*ptr += rdlen;
|
||||||
|
return rd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ConvertHeaderBytes(ipc_msg_hdr *hdr)
|
void ConvertHeaderBytes(ipc_msg_hdr *hdr)
|
||||||
{
|
{
|
||||||
hdr->version = htonl(hdr->version);
|
hdr->version = htonl(hdr->version);
|
||||||
hdr->datalen = htonl(hdr->datalen);
|
hdr->datalen = htonl(hdr->datalen);
|
||||||
hdr->flags = htonl(hdr->flags);
|
hdr->ipc_flags = htonl(hdr->ipc_flags);
|
||||||
hdr->op = htonl(hdr->op );
|
hdr->op = htonl(hdr->op );
|
||||||
hdr->reg_index = htonl(hdr->reg_index);
|
hdr->reg_index = htonl(hdr->reg_index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,173 +2,126 @@
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
|
* Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
*
|
*
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
|
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
|
||||||
* contributors may be used to endorse or promote products derived from this
|
* contributors may be used to endorse or promote products derived from this
|
||||||
* software without specific prior written permission.
|
* software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
|
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: dnssd_ipc.h,v $
|
|
||||||
Revision 1.23 2006/08/14 23:05:53 cheshire
|
|
||||||
Added "tab-width" emacs header line
|
|
||||||
|
|
||||||
Revision 1.22 2006/06/28 08:56:26 cheshire
|
|
||||||
Added "_op" to the end of the operation code enum values,
|
|
||||||
to differentiate them from the routines with the same names
|
|
||||||
|
|
||||||
Revision 1.21 2005/09/29 06:38:13 herscher
|
|
||||||
Remove #define MSG_WAITALL on Windows. We don't use this macro anymore, and it's presence causes warnings to be emitted when compiling against the latest Microsoft Platform SDK.
|
|
||||||
|
|
||||||
Revision 1.20 2005/03/21 00:39:31 shersche
|
|
||||||
<rdar://problem/4021486> Fix build warnings on Win32 platform
|
|
||||||
|
|
||||||
Revision 1.19 2005/02/02 02:25:22 cheshire
|
|
||||||
<rdar://problem/3980388> /var/run/mDNSResponder should be /var/run/mdnsd on Linux
|
|
||||||
|
|
||||||
Revision 1.18 2005/01/27 22:57:56 cheshire
|
|
||||||
Fix compile errors on gcc4
|
|
||||||
|
|
||||||
Revision 1.17 2004/11/23 03:39:47 cheshire
|
|
||||||
Let interface name/index mapping capability live directly in JNISupport.c,
|
|
||||||
instead of having to call through to the daemon via IPC to get this information.
|
|
||||||
|
|
||||||
Revision 1.16 2004/11/12 03:21:41 rpantos
|
|
||||||
rdar://problem/3809541 Add DNSSDMapIfIndexToName, DNSSDMapNameToIfIndex.
|
|
||||||
|
|
||||||
Revision 1.15 2004/10/06 02:22:20 cheshire
|
|
||||||
Changed MacRoman copyright symbol (should have been UTF-8 in any case :-) to ASCII-compatible "(c)"
|
|
||||||
|
|
||||||
Revision 1.14 2004/10/01 22:15:55 rpantos
|
|
||||||
rdar://problem/3824265: Replace APSL in client lib with BSD license.
|
|
||||||
|
|
||||||
Revision 1.13 2004/09/16 23:14:25 cheshire
|
|
||||||
Changes for Windows compatibility
|
|
||||||
|
|
||||||
Revision 1.12 2004/09/16 21:46:38 ksekar
|
|
||||||
<rdar://problem/3665304> Need SPI for LoginWindow to associate a UID with a Wide Area domain
|
|
||||||
|
|
||||||
Revision 1.11 2004/08/10 06:24:56 cheshire
|
|
||||||
Use types with precisely defined sizes for 'op' and 'reg_index', for better
|
|
||||||
compatibility if the daemon and the client stub are built using different compilers
|
|
||||||
|
|
||||||
Revision 1.10 2004/07/07 17:39:25 shersche
|
|
||||||
Change MDNS_SERVERPORT from 5533 to 5354.
|
|
||||||
|
|
||||||
Revision 1.9 2004/06/25 00:26:27 rpantos
|
|
||||||
Changes to fix the Posix build on Solaris.
|
|
||||||
|
|
||||||
Revision 1.8 2004/06/18 04:56:51 rpantos
|
|
||||||
Add layer for platform code
|
|
||||||
|
|
||||||
Revision 1.7 2004/06/12 01:08:14 cheshire
|
|
||||||
Changes for Windows compatibility
|
|
||||||
|
|
||||||
Revision 1.6 2003/08/12 19:56:25 cheshire
|
|
||||||
Update to APSL 2.0
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
#ifndef DNSSD_IPC_H
|
#ifndef DNSSD_IPC_H
|
||||||
#define DNSSD_IPC_H
|
#define DNSSD_IPC_H
|
||||||
|
|
||||||
#include "dns_sd.h"
|
#include "dns_sd.h"
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Common cross platform services
|
// Common cross platform services
|
||||||
//
|
//
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
# define dnssd_InvalidSocket INVALID_SOCKET
|
# define dnssd_InvalidSocket INVALID_SOCKET
|
||||||
# define dnssd_EWOULDBLOCK WSAEWOULDBLOCK
|
# define dnssd_SocketValid(s) ((s) != INVALID_SOCKET)
|
||||||
# define dnssd_EINTR WSAEINTR
|
# define dnssd_EWOULDBLOCK WSAEWOULDBLOCK
|
||||||
# define dnssd_sock_t SOCKET
|
# define dnssd_EINTR WSAEINTR
|
||||||
# define dnssd_socklen_t int
|
# define dnssd_ECONNRESET WSAECONNRESET
|
||||||
# define dnssd_sockbuf_t const char*
|
# define dnssd_sock_t SOCKET
|
||||||
# define dnssd_close(sock) closesocket(sock)
|
# define dnssd_socklen_t int
|
||||||
# define dnssd_errno() WSAGetLastError()
|
# define dnssd_close(sock) closesocket(sock)
|
||||||
# define ssize_t int
|
# define dnssd_errno WSAGetLastError()
|
||||||
# define getpid _getpid
|
# define dnssd_strerror(X) win32_strerror(X)
|
||||||
|
# define ssize_t int
|
||||||
|
# define getpid _getpid
|
||||||
|
# define unlink _unlink
|
||||||
|
extern char *win32_strerror(int inErrorCode);
|
||||||
#else
|
#else
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
# include <sys/un.h>
|
# include <sys/un.h>
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
# include <sys/stat.h>
|
# include <sys/stat.h>
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
# define dnssd_InvalidSocket -1
|
# include <arpa/inet.h>
|
||||||
# define dnssd_EWOULDBLOCK EWOULDBLOCK
|
# define dnssd_InvalidSocket -1
|
||||||
# define dnssd_EINTR EINTR
|
# define dnssd_SocketValid(s) ((s) >= 0)
|
||||||
# define dnssd_EPIPE EPIPE
|
# define dnssd_EWOULDBLOCK EWOULDBLOCK
|
||||||
# define dnssd_sock_t int
|
# define dnssd_EINTR EINTR
|
||||||
# define dnssd_socklen_t unsigned int
|
# define dnssd_ECONNRESET ECONNRESET
|
||||||
# define dnssd_sockbuf_t const char*
|
# define dnssd_EPIPE EPIPE
|
||||||
# define dnssd_close(sock) close(sock)
|
# define dnssd_sock_t int
|
||||||
# define dnssd_errno() errno
|
# define dnssd_socklen_t unsigned int
|
||||||
|
# define dnssd_close(sock) close(sock)
|
||||||
|
# define dnssd_errno errno
|
||||||
|
# define dnssd_strerror(X) strerror(X)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_TCP_LOOPBACK)
|
#if defined(USE_TCP_LOOPBACK)
|
||||||
# define AF_DNSSD AF_INET
|
# define AF_DNSSD AF_INET
|
||||||
# define MDNS_TCP_SERVERADDR "127.0.0.1"
|
# define MDNS_TCP_SERVERADDR "127.0.0.1"
|
||||||
# define MDNS_TCP_SERVERPORT 5354
|
# define MDNS_TCP_SERVERPORT 5354
|
||||||
# define LISTENQ 5
|
# define LISTENQ 5
|
||||||
# define dnssd_sockaddr_t struct sockaddr_in
|
# define dnssd_sockaddr_t struct sockaddr_in
|
||||||
#else
|
#else
|
||||||
# define AF_DNSSD AF_LOCAL
|
# define AF_DNSSD AF_LOCAL
|
||||||
# ifndef MDNS_UDS_SERVERPATH
|
# ifndef MDNS_UDS_SERVERPATH
|
||||||
# define MDNS_UDS_SERVERPATH "/var/run/mDNSResponder"
|
# define MDNS_UDS_SERVERPATH "/var/run/mDNSResponder"
|
||||||
# endif
|
# endif
|
||||||
# define LISTENQ 100
|
# define MDNS_UDS_SERVERPATH_ENVVAR "DNSSD_UDS_PATH"
|
||||||
// longest legal control path length
|
# define LISTENQ 100
|
||||||
# define MAX_CTLPATH 256
|
// longest legal control path length
|
||||||
# define dnssd_sockaddr_t struct sockaddr_un
|
# define MAX_CTLPATH 256
|
||||||
|
# define dnssd_sockaddr_t struct sockaddr_un
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//#define UDSDEBUG // verbose debug output
|
|
||||||
|
|
||||||
// Compatibility workaround
|
// Compatibility workaround
|
||||||
#ifndef AF_LOCAL
|
#ifndef AF_LOCAL
|
||||||
#define AF_LOCAL AF_UNIX
|
#define AF_LOCAL AF_UNIX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// General UDS constants
|
// General UDS constants
|
||||||
#define TXT_RECORD_INDEX ((uint32_t)(-1)) // record index for default text record
|
#define TXT_RECORD_INDEX ((uint32_t)(-1)) // record index for default text record
|
||||||
|
|
||||||
// IPC data encoding constants and types
|
// IPC data encoding constants and types
|
||||||
#define VERSION 1
|
#define VERSION 1
|
||||||
#define IPC_FLAGS_NOREPLY 1 // set flag if no asynchronous replies are to be sent to client
|
#define IPC_FLAGS_NOREPLY 1 // set flag if no asynchronous replies are to be sent to client
|
||||||
#define IPC_FLAGS_REUSE_SOCKET 2 // set flag if synchronous errors are to be sent via the primary socket
|
|
||||||
// (if not set, first string in message buffer must be path to error socket
|
// Structure packing macro. If we're not using GNUC, it's not fatal. Most compilers naturally pack the on-the-wire
|
||||||
|
// structures correctly anyway, so a plain "struct" is usually fine. In the event that structures are not packed
|
||||||
|
// correctly, our compile-time assertion checks will catch it and prevent inadvertent generation of non-working code.
|
||||||
|
#ifndef packedstruct
|
||||||
|
#if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9)))
|
||||||
|
#define packedstruct struct __attribute__((__packed__))
|
||||||
|
#define packedunion union __attribute__((__packed__))
|
||||||
|
#else
|
||||||
|
#define packedstruct struct
|
||||||
|
#define packedunion union
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
connection = 1, // connected socket via DNSServiceConnect()
|
request_op_none = 0, // No request yet received on this connection
|
||||||
reg_record_request, // reg/remove record only valid for connected sockets
|
connection_request = 1, // connected socket via DNSServiceConnect()
|
||||||
|
reg_record_request, // reg/remove record only valid for connected sockets
|
||||||
remove_record_request,
|
remove_record_request,
|
||||||
enumeration_request,
|
enumeration_request,
|
||||||
reg_service_request,
|
reg_service_request,
|
||||||
|
@ -178,76 +131,96 @@ typedef enum
|
||||||
reconfirm_record_request,
|
reconfirm_record_request,
|
||||||
add_record_request,
|
add_record_request,
|
||||||
update_record_request,
|
update_record_request,
|
||||||
setdomain_request
|
setdomain_request, // Up to here is in Tiger and B4W 1.0.3
|
||||||
} request_op_t;
|
getproperty_request, // New in B4W 1.0.4
|
||||||
|
port_mapping_request, // New in Leopard and B4W 2.0
|
||||||
|
addrinfo_request,
|
||||||
|
send_bpf, // New in SL
|
||||||
|
getpid_request,
|
||||||
|
release_request,
|
||||||
|
connection_delegate_request,
|
||||||
|
|
||||||
|
cancel_request = 63
|
||||||
|
} request_op_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
enumeration_reply_op = 64,
|
enumeration_reply_op = 64,
|
||||||
reg_service_reply_op,
|
reg_service_reply_op,
|
||||||
browse_reply_op,
|
browse_reply_op,
|
||||||
resolve_reply_op,
|
resolve_reply_op,
|
||||||
query_reply_op,
|
query_reply_op,
|
||||||
reg_record_reply_op
|
reg_record_reply_op, // Up to here is in Tiger and B4W 1.0.3
|
||||||
} reply_op_t;
|
getproperty_reply_op, // New in B4W 1.0.4
|
||||||
|
port_mapping_reply_op, // New in Leopard and B4W 2.0
|
||||||
|
addrinfo_reply_op
|
||||||
|
} reply_op_t;
|
||||||
|
|
||||||
typedef struct ipc_msg_hdr_struct ipc_msg_hdr;
|
#if defined(_WIN64)
|
||||||
|
# pragma pack(push,4)
|
||||||
|
#elif !defined(__GNUC__)
|
||||||
|
# pragma pack(1)
|
||||||
|
#endif
|
||||||
|
|
||||||
// client stub callback to process message from server and deliver results to
|
// Define context object big enough to hold a 64-bit pointer,
|
||||||
// client application
|
// to accomodate 64-bit clients communicating with 32-bit daemon.
|
||||||
|
// There's no reason for the daemon to ever be a 64-bit process, but its clients might be
|
||||||
typedef void (*process_reply_callback)
|
typedef packedunion
|
||||||
(
|
{
|
||||||
DNSServiceRef sdr,
|
|
||||||
ipc_msg_hdr *hdr,
|
|
||||||
char *msg
|
|
||||||
);
|
|
||||||
|
|
||||||
// allow 64-bit client to interoperate w/ 32-bit daemon
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
void *context;
|
void *context;
|
||||||
uint32_t ptr64[2];
|
uint32_t u32[2];
|
||||||
} client_context_t;
|
} client_context_t;
|
||||||
|
|
||||||
typedef struct ipc_msg_hdr_struct
|
typedef packedstruct
|
||||||
{
|
{
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
uint32_t datalen;
|
uint32_t datalen;
|
||||||
uint32_t flags;
|
uint32_t ipc_flags;
|
||||||
uint32_t op; // request_op_t or reply_op_t
|
uint32_t op; // request_op_t or reply_op_t
|
||||||
client_context_t client_context; // context passed from client, returned by server in corresponding reply
|
client_context_t client_context; // context passed from client, returned by server in corresponding reply
|
||||||
uint32_t reg_index; // identifier for a record registered via DNSServiceRegisterRecord() on a
|
uint32_t reg_index; // identifier for a record registered via DNSServiceRegisterRecord() on a
|
||||||
// socket connected by DNSServiceConnect(). Must be unique in the scope of the connection, such that and
|
// socket connected by DNSServiceCreateConnection(). Must be unique in the scope of the connection, such that and
|
||||||
// index/socket pair uniquely identifies a record. (Used to select records for removal by DNSServiceRemoveRecord())
|
// index/socket pair uniquely identifies a record. (Used to select records for removal by DNSServiceRemoveRecord())
|
||||||
uint32_t padbytes;
|
} ipc_msg_hdr;
|
||||||
} ipc_msg_hdr_struct;
|
|
||||||
|
#if defined(_WIN64)
|
||||||
|
# pragma pack(pop)
|
||||||
|
#elif !defined(__GNUC__)
|
||||||
|
# pragma pack()
|
||||||
|
#endif
|
||||||
|
|
||||||
// it is advanced to point to the next field, or the end of the message
|
|
||||||
// routines to write to and extract data from message buffers.
|
// routines to write to and extract data from message buffers.
|
||||||
// caller responsible for bounds checking.
|
// caller responsible for bounds checking.
|
||||||
// ptr is the address of the pointer to the start of the field.
|
// ptr is the address of the pointer to the start of the field.
|
||||||
// it is advanced to point to the next field, or the end of the message
|
// it is advanced to point to the next field, or the end of the message
|
||||||
|
|
||||||
void put_long(const uint32_t l, char **ptr);
|
void put_uint32(const uint32_t l, char **ptr);
|
||||||
uint32_t get_long(char **ptr);
|
uint32_t get_uint32(const char **ptr, const char *end);
|
||||||
|
|
||||||
void put_short(uint16_t s, char **ptr);
|
void put_uint16(uint16_t s, char **ptr);
|
||||||
uint16_t get_short(char **ptr);
|
uint16_t get_uint16(const char **ptr, const char *end);
|
||||||
|
|
||||||
#define put_flags put_long
|
#define put_flags put_uint32
|
||||||
#define get_flags get_long
|
#define get_flags get_uint32
|
||||||
|
|
||||||
#define put_error_code put_long
|
#define put_error_code put_uint32
|
||||||
#define get_error_code get_long
|
#define get_error_code get_uint32
|
||||||
|
|
||||||
int put_string(const char *str, char **ptr);
|
int put_string(const char *str, char **ptr);
|
||||||
int get_string(char **ptr, char *buffer, int buflen);
|
int get_string(const char **ptr, const char *const end, char *buffer, int buflen);
|
||||||
|
|
||||||
void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr);
|
void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr);
|
||||||
char *get_rdata(char **ptr, int rdlen); // return value is rdata pointed to by *ptr -
|
const char *get_rdata(const char **ptr, const char *end, int rdlen); // return value is rdata pointed to by *ptr -
|
||||||
// rdata is not copied from buffer.
|
// rdata is not copied from buffer.
|
||||||
|
|
||||||
void ConvertHeaderBytes(ipc_msg_hdr *hdr);
|
void ConvertHeaderBytes(ipc_msg_hdr *hdr);
|
||||||
|
|
||||||
|
struct CompileTimeAssertionChecks_dnssd_ipc
|
||||||
|
{
|
||||||
|
// Check that the compiler generated our on-the-wire packet format structure definitions
|
||||||
|
// properly packed, without adding padding bytes to align fields on 32-bit or 64-bit boundaries.
|
||||||
|
char assert0[(sizeof(client_context_t) == 8) ? 1 : -1];
|
||||||
|
char assert1[(sizeof(ipc_msg_hdr) == 28) ? 1 : -1];
|
||||||
|
};
|
||||||
|
|
||||||
#endif // DNSSD_IPC_H
|
#endif // DNSSD_IPC_H
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#
|
#
|
||||||
# CDDL HEADER END
|
# CDDL HEADER END
|
||||||
#
|
#
|
||||||
#
|
# Copyright 2016 Toomas Soome <tsoome@me.com>
|
||||||
# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
@ -38,6 +38,14 @@
|
||||||
|
|
||||||
$mapfile_version 2
|
$mapfile_version 2
|
||||||
|
|
||||||
|
SYMBOL_VERSION ILLUMOS_0.1 { # mDNSResponder-576.30.4
|
||||||
|
global:
|
||||||
|
DNSServiceGetAddrInfo;
|
||||||
|
DNSServiceGetProperty;
|
||||||
|
DNSServiceNATPortMappingCreate;
|
||||||
|
DNSServiceSleepKeepalive;
|
||||||
|
} SUNW_1.1;
|
||||||
|
|
||||||
SYMBOL_VERSION SUNW_1.1 {
|
SYMBOL_VERSION SUNW_1.1 {
|
||||||
global:
|
global:
|
||||||
DNSServiceAddRecord;
|
DNSServiceAddRecord;
|
||||||
|
|
|
@ -13,21 +13,6 @@
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: BaseListener.java,v $
|
|
||||||
Revision 1.3 2006/08/14 23:25:08 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.2 2004/04/30 21:48:27 rpantos
|
|
||||||
Change line endings for CVS.
|
|
||||||
|
|
||||||
Revision 1.1 2004/04/30 16:29:35 rpantos
|
|
||||||
First checked in.
|
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,21 +13,6 @@
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: BrowseListener.java,v $
|
|
||||||
Revision 1.3 2006/08/14 23:25:08 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.2 2004/04/30 21:48:27 rpantos
|
|
||||||
Change line endings for CVS.
|
|
||||||
|
|
||||||
Revision 1.1 2004/04/30 16:29:35 rpantos
|
|
||||||
First checked in.
|
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,22 +13,6 @@
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: DNSRecord.java,v $
|
|
||||||
Revision 1.3 2006/08/14 23:25:08 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.2 2004/12/11 03:00:59 rpantos
|
|
||||||
<rdar://problem/3907498> Java DNSRecord API should be cleaned up
|
|
||||||
|
|
||||||
Revision 1.1 2004/04/30 16:32:34 rpantos
|
|
||||||
First checked in.
|
|
||||||
|
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,60 +5,20 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: DNSSD.java,v $
|
|
||||||
Revision 1.11 2006/08/14 23:25:08 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.10 2006/06/20 23:05:55 rpantos
|
|
||||||
<rdar://problem/3839132> Java needs to implement DNSServiceRegisterRecord equivalent
|
|
||||||
|
|
||||||
Revision 1.9 2005/10/26 01:52:24 cheshire
|
|
||||||
<rdar://problem/4316286> Race condition in Java code (doesn't work at all on Linux)
|
|
||||||
|
|
||||||
Revision 1.8 2005/07/11 01:55:21 cheshire
|
|
||||||
<rdar://problem/4175511> Race condition in Java API
|
|
||||||
|
|
||||||
Revision 1.7 2005/07/05 13:01:52 cheshire
|
|
||||||
<rdar://problem/4169791> If mDNSResponder daemon is stopped, Java API spins, burning CPU time
|
|
||||||
|
|
||||||
Revision 1.6 2005/07/05 00:02:25 cheshire
|
|
||||||
Add missing comma
|
|
||||||
|
|
||||||
Revision 1.5 2005/07/04 21:13:47 cheshire
|
|
||||||
Add missing error message strings
|
|
||||||
|
|
||||||
Revision 1.4 2004/12/11 03:00:59 rpantos
|
|
||||||
<rdar://problem/3907498> Java DNSRecord API should be cleaned up
|
|
||||||
|
|
||||||
Revision 1.3 2004/11/12 03:23:08 rpantos
|
|
||||||
rdar://problem/3809541 implement getIfIndexForName, getNameForIfIndex.
|
|
||||||
|
|
||||||
Revision 1.2 2004/05/20 17:43:18 cheshire
|
|
||||||
Fix invalid UTF-8 characters in file
|
|
||||||
|
|
||||||
Revision 1.1 2004/04/30 16:32:34 rpantos
|
|
||||||
First checked in.
|
|
||||||
|
|
||||||
|
|
||||||
This file declares and implements DNSSD, the central Java factory class
|
This file declares and implements DNSSD, the central Java factory class
|
||||||
for doing DNS Service Discovery. It includes the mostly-abstract public
|
for doing DNS Service Discovery. It includes the mostly-abstract public
|
||||||
interface, as well as the Apple* implementation subclasses.
|
interface, as well as the Apple* implementation subclasses.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* ident "%Z%%M% %I% %E% SMI"
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.apple.dnssd;
|
package com.apple.dnssd;
|
||||||
|
|
||||||
|
@ -67,19 +27,19 @@ package com.apple.dnssd;
|
||||||
DNSSD provides access to DNS Service Discovery features of ZeroConf networking.<P>
|
DNSSD provides access to DNS Service Discovery features of ZeroConf networking.<P>
|
||||||
|
|
||||||
It is a factory class that is used to invoke registration and discovery-related
|
It is a factory class that is used to invoke registration and discovery-related
|
||||||
operations. Most operations are non-blocking; clients are called back through an interface
|
operations. Most operations are non-blocking; clients are called back through an interface
|
||||||
with the result of an operation. Callbacks are made from a separate worker thread.<P>
|
with the result of an operation. Callbacks are made from a separate worker thread.<P>
|
||||||
|
|
||||||
For example, in this program<P>
|
For example, in this program<P>
|
||||||
<PRE><CODE>
|
<PRE><CODE>
|
||||||
class MyClient implements BrowseListener {
|
class MyClient implements BrowseListener {
|
||||||
void lookForWebServers() {
|
void lookForWebServers() {
|
||||||
myBrowser = DNSSD.browse("_http_.tcp", this);
|
myBrowser = DNSSD.browse("_http._tcp", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void serviceFound(DNSSDService browser, int flags, int ifIndex,
|
public void serviceFound(DNSSDService browser, int flags, int ifIndex,
|
||||||
String serviceName, String regType, String domain) {}
|
String serviceName, String regType, String domain) {}
|
||||||
...
|
...
|
||||||
}</CODE></PRE>
|
}</CODE></PRE>
|
||||||
<CODE>MyClient.serviceFound()</CODE> would be called for every HTTP server discovered in the
|
<CODE>MyClient.serviceFound()</CODE> would be called for every HTTP server discovered in the
|
||||||
default browse domain(s).
|
default browse domain(s).
|
||||||
|
@ -91,14 +51,14 @@ abstract public class DNSSD
|
||||||
queued. Applications should not update their UI to display browse
|
queued. Applications should not update their UI to display browse
|
||||||
results if the MORE_COMING flag is set; they will be called at least once
|
results if the MORE_COMING flag is set; they will be called at least once
|
||||||
more with the flag clear.
|
more with the flag clear.
|
||||||
*/
|
*/
|
||||||
public static final int MORE_COMING = ( 1 << 0 );
|
public static final int MORE_COMING = ( 1 << 0 );
|
||||||
|
|
||||||
/** If flag is set in a {@link DomainListener} callback, indicates that the result is the default domain. */
|
/** If flag is set in a {@link DomainListener} callback, indicates that the result is the default domain. */
|
||||||
public static final int DEFAULT = ( 1 << 2 );
|
public static final int DEFAULT = ( 1 << 2 );
|
||||||
|
|
||||||
/** If flag is set, a name conflict will trigger an exception when registering non-shared records.<P>
|
/** If flag is set, a name conflict will trigger an exception when registering non-shared records.<P>
|
||||||
A name must be explicitly specified when registering a service if this bit is set
|
A name must be explicitly specified when registering a service if this bit is set
|
||||||
(i.e. the default name may not not be used).
|
(i.e. the default name may not not be used).
|
||||||
*/
|
*/
|
||||||
public static final int NO_AUTO_RENAME = ( 1 << 3 );
|
public static final int NO_AUTO_RENAME = ( 1 << 3 );
|
||||||
|
@ -117,7 +77,7 @@ abstract public class DNSSD
|
||||||
public static final int REGISTRATION_DOMAINS = ( 1 << 7 );
|
public static final int REGISTRATION_DOMAINS = ( 1 << 7 );
|
||||||
|
|
||||||
/** Maximum length, in bytes, of a domain name represented as an escaped C-String. */
|
/** Maximum length, in bytes, of a domain name represented as an escaped C-String. */
|
||||||
public static final int MAX_DOMAIN_NAME = 1005;
|
public static final int MAX_DOMAIN_NAME = 1009;
|
||||||
|
|
||||||
/** Pass for ifIndex to specify all available interfaces. */
|
/** Pass for ifIndex to specify all available interfaces. */
|
||||||
public static final int ALL_INTERFACES = 0;
|
public static final int ALL_INTERFACES = 0;
|
||||||
|
@ -125,7 +85,7 @@ abstract public class DNSSD
|
||||||
/** Pass for ifIndex to specify the localhost interface. */
|
/** Pass for ifIndex to specify the localhost interface. */
|
||||||
public static final int LOCALHOST_ONLY = -1;
|
public static final int LOCALHOST_ONLY = -1;
|
||||||
|
|
||||||
/** Browse for instances of a service.<P>
|
/** Browse for instances of a service.<P>
|
||||||
|
|
||||||
Note: browsing consumes network bandwidth. Call {@link DNSSDService#stop} when you have finished browsing.<P>
|
Note: browsing consumes network bandwidth. Call {@link DNSSDService#stop} when you have finished browsing.<P>
|
||||||
|
|
||||||
|
@ -139,12 +99,12 @@ abstract public class DNSSD
|
||||||
interfaces. Pass -1 to only browse for services provided on the local host.
|
interfaces. Pass -1 to only browse for services provided on the local host.
|
||||||
<P>
|
<P>
|
||||||
@param regType
|
@param regType
|
||||||
The registration type being browsed for followed by the protocol, separated by a
|
The registration type being browsed for followed by the protocol, separated by a
|
||||||
dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
|
dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
|
||||||
<P>
|
<P>
|
||||||
@param domain
|
@param domain
|
||||||
If non-null, specifies the domain on which to browse for services.
|
If non-null, specifies the domain on which to browse for services.
|
||||||
Most applications will not specify a domain, instead browsing on the
|
Most applications will not specify a domain, instead browsing on the
|
||||||
default domain(s).
|
default domain(s).
|
||||||
<P>
|
<P>
|
||||||
@param listener
|
@param listener
|
||||||
|
@ -159,10 +119,10 @@ abstract public class DNSSD
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{ return getInstance()._makeBrowser( flags, ifIndex, regType, domain, listener); }
|
{ return getInstance()._makeBrowser( flags, ifIndex, regType, domain, listener); }
|
||||||
|
|
||||||
/** Browse for instances of a service. Use default flags, ifIndex and domain.<P>
|
/** Browse for instances of a service. Use default flags, ifIndex and domain.<P>
|
||||||
|
|
||||||
@param regType
|
@param regType
|
||||||
The registration type being browsed for followed by the protocol, separated by a
|
The registration type being browsed for followed by the protocol, separated by a
|
||||||
dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
|
dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
|
||||||
<P>
|
<P>
|
||||||
@param listener
|
@param listener
|
||||||
|
@ -177,16 +137,16 @@ abstract public class DNSSD
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{ return browse( 0, 0, regType, "", listener); }
|
{ return browse( 0, 0, regType, "", listener); }
|
||||||
|
|
||||||
/** Resolve a service name discovered via browse() to a target host name, port number, and txt record.<P>
|
/** Resolve a service name discovered via browse() to a target host name, port number, and txt record.<P>
|
||||||
|
|
||||||
Note: Applications should NOT use resolve() solely for txt record monitoring - use
|
Note: Applications should NOT use resolve() solely for txt record monitoring - use
|
||||||
queryRecord() instead, as it is more efficient for this task.<P>
|
queryRecord() instead, as it is more efficient for this task.<P>
|
||||||
|
|
||||||
Note: When the desired results have been returned, the client MUST terminate the resolve by
|
Note: When the desired results have been returned, the client MUST terminate the resolve by
|
||||||
calling {@link DNSSDService#stop}.<P>
|
calling {@link DNSSDService#stop}.<P>
|
||||||
|
|
||||||
Note: resolve() behaves correctly for typical services that have a single SRV record and
|
Note: resolve() behaves correctly for typical services that have a single SRV record and
|
||||||
a single TXT record (the TXT record may be empty.) To resolve non-standard services with
|
a single TXT record (the TXT record may be empty.) To resolve non-standard services with
|
||||||
multiple SRV or TXT records, use queryRecord().<P>
|
multiple SRV or TXT records, use queryRecord().<P>
|
||||||
|
|
||||||
@param flags
|
@param flags
|
||||||
|
@ -194,7 +154,7 @@ abstract public class DNSSD
|
||||||
<P>
|
<P>
|
||||||
@param ifIndex
|
@param ifIndex
|
||||||
The interface on which to resolve the service. The client should
|
The interface on which to resolve the service. The client should
|
||||||
pass the interface on which the serviceName was discovered (i.e.
|
pass the interface on which the serviceName was discovered (i.e.
|
||||||
the ifIndex passed to the serviceFound() callback)
|
the ifIndex passed to the serviceFound() callback)
|
||||||
or 0 to resolve the named service on all available interfaces.
|
or 0 to resolve the named service on all available interfaces.
|
||||||
<P>
|
<P>
|
||||||
|
@ -202,8 +162,8 @@ abstract public class DNSSD
|
||||||
The servicename to be resolved.
|
The servicename to be resolved.
|
||||||
<P>
|
<P>
|
||||||
@param regType
|
@param regType
|
||||||
The registration type being resolved followed by the protocol, separated by a
|
The registration type being resolved followed by the protocol, separated by a
|
||||||
dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
|
dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
|
||||||
<P>
|
<P>
|
||||||
@param domain
|
@param domain
|
||||||
The domain on which the service is registered, i.e. the domain passed
|
The domain on which the service is registered, i.e. the domain passed
|
||||||
|
@ -217,54 +177,54 @@ abstract public class DNSSD
|
||||||
@throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
|
@throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
|
||||||
@see RuntimePermission
|
@see RuntimePermission
|
||||||
*/
|
*/
|
||||||
public static DNSSDService resolve( int flags, int ifIndex, String serviceName, String regType,
|
public static DNSSDService resolve( int flags, int ifIndex, String serviceName, String regType,
|
||||||
String domain, ResolveListener listener)
|
String domain, ResolveListener listener)
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{ return getInstance()._resolve( flags, ifIndex, serviceName, regType, domain, listener); }
|
{ return getInstance()._resolve( flags, ifIndex, serviceName, regType, domain, listener); }
|
||||||
|
|
||||||
/** Register a service, to be discovered via browse() and resolve() calls.<P>
|
/** Register a service, to be discovered via browse() and resolve() calls.<P>
|
||||||
@param flags
|
@param flags
|
||||||
Possible values are: NO_AUTO_RENAME.
|
Possible values are: NO_AUTO_RENAME.
|
||||||
<P>
|
<P>
|
||||||
@param ifIndex
|
@param ifIndex
|
||||||
If non-zero, specifies the interface on which to register the service
|
If non-zero, specifies the interface on which to register the service
|
||||||
(the index for a given interface is determined via the if_nametoindex()
|
(the index for a given interface is determined via the if_nametoindex()
|
||||||
family of calls.) Most applications will pass 0 to register on all
|
family of calls.) Most applications will pass 0 to register on all
|
||||||
available interfaces. Pass -1 to register a service only on the local
|
available interfaces. Pass -1 to register a service only on the local
|
||||||
machine (service will not be visible to remote hosts).
|
machine (service will not be visible to remote hosts).
|
||||||
<P>
|
<P>
|
||||||
@param serviceName
|
@param serviceName
|
||||||
If non-null, specifies the service name to be registered.
|
If non-null, specifies the service name to be registered.
|
||||||
Applications need not specify a name, in which case the
|
Applications need not specify a name, in which case the
|
||||||
computer name is used (this name is communicated to the client via
|
computer name is used (this name is communicated to the client via
|
||||||
the serviceRegistered() callback).
|
the serviceRegistered() callback).
|
||||||
<P>
|
<P>
|
||||||
@param regType
|
@param regType
|
||||||
The registration type being registered followed by the protocol, separated by a
|
The registration type being registered followed by the protocol, separated by a
|
||||||
dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
|
dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
|
||||||
<P>
|
<P>
|
||||||
@param domain
|
@param domain
|
||||||
If non-null, specifies the domain on which to advertise the service.
|
If non-null, specifies the domain on which to advertise the service.
|
||||||
Most applications will not specify a domain, instead automatically
|
Most applications will not specify a domain, instead automatically
|
||||||
registering in the default domain(s).
|
registering in the default domain(s).
|
||||||
<P>
|
<P>
|
||||||
@param host
|
@param host
|
||||||
If non-null, specifies the SRV target host name. Most applications
|
If non-null, specifies the SRV target host name. Most applications
|
||||||
will not specify a host, instead automatically using the machine's
|
will not specify a host, instead automatically using the machine's
|
||||||
default host name(s). Note that specifying a non-null host does NOT
|
default host name(s). Note that specifying a non-null host does NOT
|
||||||
create an address record for that host - the application is responsible
|
create an address record for that host - the application is responsible
|
||||||
for ensuring that the appropriate address record exists, or creating it
|
for ensuring that the appropriate address record exists, or creating it
|
||||||
via {@link DNSSDRegistration#addRecord}.
|
via {@link DNSSDRegistration#addRecord}.
|
||||||
<P>
|
<P>
|
||||||
@param port
|
@param port
|
||||||
The port on which the service accepts connections. Pass 0 for a
|
The port on which the service accepts connections. Pass 0 for a
|
||||||
"placeholder" service (i.e. a service that will not be discovered by
|
"placeholder" service (i.e. a service that will not be discovered by
|
||||||
browsing, but will cause a name conflict if another client tries to
|
browsing, but will cause a name conflict if another client tries to
|
||||||
register that same name.) Most clients will not use placeholder services.
|
register that same name.) Most clients will not use placeholder services.
|
||||||
<P>
|
<P>
|
||||||
@param txtRecord
|
@param txtRecord
|
||||||
The txt record rdata. May be null. Note that a non-null txtRecord
|
The txt record rdata. May be null. Note that a non-null txtRecord
|
||||||
MUST be a properly formatted DNS TXT record, i.e. <length byte> <data>
|
MUST be a properly formatted DNS TXT record, i.e. <length byte> <data>
|
||||||
<length byte> <data> ...
|
<length byte> <data> ...
|
||||||
<P>
|
<P>
|
||||||
@param listener
|
@param listener
|
||||||
|
@ -275,26 +235,26 @@ abstract public class DNSSD
|
||||||
@throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
|
@throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
|
||||||
@see RuntimePermission
|
@see RuntimePermission
|
||||||
*/
|
*/
|
||||||
public static DNSSDRegistration register( int flags, int ifIndex, String serviceName, String regType,
|
public static DNSSDRegistration register( int flags, int ifIndex, String serviceName, String regType,
|
||||||
String domain, String host, int port, TXTRecord txtRecord, RegisterListener listener)
|
String domain, String host, int port, TXTRecord txtRecord, RegisterListener listener)
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{ return getInstance()._register( flags, ifIndex, serviceName, regType, domain, host, port, txtRecord, listener); }
|
{ return getInstance()._register( flags, ifIndex, serviceName, regType, domain, host, port, txtRecord, listener); }
|
||||||
|
|
||||||
/** Register a service, to be discovered via browse() and resolve() calls. Use default flags, ifIndex, domain, host and txtRecord.<P>
|
/** Register a service, to be discovered via browse() and resolve() calls. Use default flags, ifIndex, domain, host and txtRecord.<P>
|
||||||
@param serviceName
|
@param serviceName
|
||||||
If non-null, specifies the service name to be registered.
|
If non-null, specifies the service name to be registered.
|
||||||
Applications need not specify a name, in which case the
|
Applications need not specify a name, in which case the
|
||||||
computer name is used (this name is communicated to the client via
|
computer name is used (this name is communicated to the client via
|
||||||
the serviceRegistered() callback).
|
the serviceRegistered() callback).
|
||||||
<P>
|
<P>
|
||||||
@param regType
|
@param regType
|
||||||
The registration type being registered followed by the protocol, separated by a
|
The registration type being registered followed by the protocol, separated by a
|
||||||
dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
|
dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
|
||||||
<P>
|
<P>
|
||||||
@param port
|
@param port
|
||||||
The port on which the service accepts connections. Pass 0 for a
|
The port on which the service accepts connections. Pass 0 for a
|
||||||
"placeholder" service (i.e. a service that will not be discovered by
|
"placeholder" service (i.e. a service that will not be discovered by
|
||||||
browsing, but will cause a name conflict if another client tries to
|
browsing, but will cause a name conflict if another client tries to
|
||||||
register that same name.) Most clients will not use placeholder services.
|
register that same name.) Most clients will not use placeholder services.
|
||||||
<P>
|
<P>
|
||||||
@param listener
|
@param listener
|
||||||
|
@ -309,8 +269,8 @@ abstract public class DNSSD
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{ return register( 0, 0, serviceName, regType, null, null, port, null, listener); }
|
{ return register( 0, 0, serviceName, regType, null, null, port, null, listener); }
|
||||||
|
|
||||||
/** Create a {@link DNSSDRecordRegistrar} allowing efficient registration of
|
/** Create a {@link DNSSDRecordRegistrar} allowing efficient registration of
|
||||||
multiple individual records.<P>
|
multiple individual records.<P>
|
||||||
<P>
|
<P>
|
||||||
@return A {@link DNSSDRecordRegistrar} that can be used to register records.
|
@return A {@link DNSSDRecordRegistrar} that can be used to register records.
|
||||||
|
|
||||||
|
@ -321,14 +281,14 @@ abstract public class DNSSD
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{ return getInstance()._createRecordRegistrar( listener); }
|
{ return getInstance()._createRecordRegistrar( listener); }
|
||||||
|
|
||||||
/** Query for an arbitrary DNS record.<P>
|
/** Query for an arbitrary DNS record.<P>
|
||||||
@param flags
|
@param flags
|
||||||
Possible values are: MORE_COMING.
|
Possible values are: MORE_COMING.
|
||||||
<P>
|
<P>
|
||||||
@param ifIndex
|
@param ifIndex
|
||||||
If non-zero, specifies the interface on which to issue the query
|
If non-zero, specifies the interface on which to issue the query
|
||||||
(the index for a given interface is determined via the if_nametoindex()
|
(the index for a given interface is determined via the if_nametoindex()
|
||||||
family of calls.) Passing 0 causes the name to be queried for on all
|
family of calls.) Passing 0 causes the name to be queried for on all
|
||||||
interfaces. Passing -1 causes the name to be queried for only on the
|
interfaces. Passing -1 causes the name to be queried for only on the
|
||||||
local host.
|
local host.
|
||||||
<P>
|
<P>
|
||||||
|
@ -340,7 +300,7 @@ abstract public class DNSSD
|
||||||
as defined in nameser.h.
|
as defined in nameser.h.
|
||||||
<P>
|
<P>
|
||||||
@param rrclass
|
@param rrclass
|
||||||
The class of the resource record, as defined in nameser.h
|
The class of the resource record, as defined in nameser.h
|
||||||
(usually 1 for the Internet class).
|
(usually 1 for the Internet class).
|
||||||
<P>
|
<P>
|
||||||
@param listener
|
@param listener
|
||||||
|
@ -351,12 +311,12 @@ abstract public class DNSSD
|
||||||
@throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
|
@throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
|
||||||
@see RuntimePermission
|
@see RuntimePermission
|
||||||
*/
|
*/
|
||||||
public static DNSSDService queryRecord( int flags, int ifIndex, String serviceName, int rrtype,
|
public static DNSSDService queryRecord( int flags, int ifIndex, String serviceName, int rrtype,
|
||||||
int rrclass, QueryListener listener)
|
int rrclass, QueryListener listener)
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{ return getInstance()._queryRecord( flags, ifIndex, serviceName, rrtype, rrclass, listener); }
|
{ return getInstance()._queryRecord( flags, ifIndex, serviceName, rrtype, rrclass, listener); }
|
||||||
|
|
||||||
/** Asynchronously enumerate domains available for browsing and registration.<P>
|
/** Asynchronously enumerate domains available for browsing and registration.<P>
|
||||||
|
|
||||||
Currently, the only domain returned is "local.", but other domains will be returned in future.<P>
|
Currently, the only domain returned is "local.", but other domains will be returned in future.<P>
|
||||||
|
|
||||||
|
@ -368,8 +328,8 @@ abstract public class DNSSD
|
||||||
@param ifIndex
|
@param ifIndex
|
||||||
If non-zero, specifies the interface on which to look for domains.
|
If non-zero, specifies the interface on which to look for domains.
|
||||||
(the index for a given interface is determined via the if_nametoindex()
|
(the index for a given interface is determined via the if_nametoindex()
|
||||||
family of calls.) Most applications will pass 0 to enumerate domains on
|
family of calls.) Most applications will pass 0 to enumerate domains on
|
||||||
all interfaces.
|
all interfaces.
|
||||||
<P>
|
<P>
|
||||||
@param listener
|
@param listener
|
||||||
This object will get called when domains are found.
|
This object will get called when domains are found.
|
||||||
|
@ -383,15 +343,15 @@ abstract public class DNSSD
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{ return getInstance()._enumerateDomains( flags, ifIndex, listener); }
|
{ return getInstance()._enumerateDomains( flags, ifIndex, listener); }
|
||||||
|
|
||||||
/** Concatenate a three-part domain name (as provided to the listeners) into a
|
/** Concatenate a three-part domain name (as provided to the listeners) into a
|
||||||
properly-escaped full domain name. Note that strings passed to listeners are
|
properly-escaped full domain name. Note that strings passed to listeners are
|
||||||
ALREADY ESCAPED where necessary.<P>
|
ALREADY ESCAPED where necessary.<P>
|
||||||
@param serviceName
|
@param serviceName
|
||||||
The service name - any dots or slashes must NOT be escaped.
|
The service name - any dots or slashes must NOT be escaped.
|
||||||
May be null (to construct a PTR record name, e.g. "_ftp._tcp.apple.com").
|
May be null (to construct a PTR record name, e.g. "_ftp._tcp.apple.com").
|
||||||
<P>
|
<P>
|
||||||
@param regType
|
@param regType
|
||||||
The registration type followed by the protocol, separated by a dot (e.g. "_ftp._tcp").
|
The registration type followed by the protocol, separated by a dot (e.g. "_ftp._tcp").
|
||||||
<P>
|
<P>
|
||||||
@param domain
|
@param domain
|
||||||
The domain name, e.g. "apple.com". Any literal dots or backslashes must be escaped.
|
The domain name, e.g. "apple.com". Any literal dots or backslashes must be escaped.
|
||||||
|
@ -405,10 +365,10 @@ abstract public class DNSSD
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{ return getInstance()._constructFullName( serviceName, regType, domain); }
|
{ return getInstance()._constructFullName( serviceName, regType, domain); }
|
||||||
|
|
||||||
/** Instruct the daemon to verify the validity of a resource record that appears to
|
/** Instruct the daemon to verify the validity of a resource record that appears to
|
||||||
be out of date. (e.g. because tcp connection to a service's target failed.) <P>
|
be out of date. (e.g. because tcp connection to a service's target failed.) <P>
|
||||||
|
|
||||||
Causes the record to be flushed from the daemon's cache (as well as all other
|
Causes the record to be flushed from the daemon's cache (as well as all other
|
||||||
daemons' caches on the network) if the record is determined to be invalid.<P>
|
daemons' caches on the network) if the record is determined to be invalid.<P>
|
||||||
@param flags
|
@param flags
|
||||||
Currently unused, reserved for future use.
|
Currently unused, reserved for future use.
|
||||||
|
@ -416,7 +376,7 @@ abstract public class DNSSD
|
||||||
@param ifIndex
|
@param ifIndex
|
||||||
If non-zero, specifies the interface on which to reconfirm the record
|
If non-zero, specifies the interface on which to reconfirm the record
|
||||||
(the index for a given interface is determined via the if_nametoindex()
|
(the index for a given interface is determined via the if_nametoindex()
|
||||||
family of calls.) Passing 0 causes the name to be reconfirmed on all
|
family of calls.) Passing 0 causes the name to be reconfirmed on all
|
||||||
interfaces. Passing -1 causes the name to be reconfirmed only on the
|
interfaces. Passing -1 causes the name to be reconfirmed only on the
|
||||||
local host.
|
local host.
|
||||||
<P>
|
<P>
|
||||||
|
@ -435,11 +395,11 @@ abstract public class DNSSD
|
||||||
@throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
|
@throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
|
||||||
@see RuntimePermission
|
@see RuntimePermission
|
||||||
*/
|
*/
|
||||||
public static void reconfirmRecord( int flags, int ifIndex, String fullName, int rrtype,
|
public static void reconfirmRecord( int flags, int ifIndex, String fullName, int rrtype,
|
||||||
int rrclass, byte[] rdata)
|
int rrclass, byte[] rdata)
|
||||||
{ getInstance()._reconfirmRecord( flags, ifIndex, fullName, rrtype, rrclass, rdata); }
|
{ getInstance()._reconfirmRecord( flags, ifIndex, fullName, rrtype, rrclass, rdata); }
|
||||||
|
|
||||||
/** Return the canonical name of a particular interface index.<P>
|
/** Return the canonical name of a particular interface index.<P>
|
||||||
@param ifIndex
|
@param ifIndex
|
||||||
A valid interface index. Must not be ALL_INTERFACES.
|
A valid interface index. Must not be ALL_INTERFACES.
|
||||||
<P>
|
<P>
|
||||||
|
@ -451,7 +411,7 @@ abstract public class DNSSD
|
||||||
public static String getNameForIfIndex( int ifIndex)
|
public static String getNameForIfIndex( int ifIndex)
|
||||||
{ return getInstance()._getNameForIfIndex( ifIndex); }
|
{ return getInstance()._getNameForIfIndex( ifIndex); }
|
||||||
|
|
||||||
/** Return the index of a named interface.<P>
|
/** Return the index of a named interface.<P>
|
||||||
@param ifName
|
@param ifName
|
||||||
A valid interface name. An example is java.net.NetworkInterface.getName().
|
A valid interface name. An example is java.net.NetworkInterface.getName().
|
||||||
<P>
|
<P>
|
||||||
|
@ -466,29 +426,29 @@ abstract public class DNSSD
|
||||||
protected DNSSD() {} // prevent direct instantiation
|
protected DNSSD() {} // prevent direct instantiation
|
||||||
|
|
||||||
/** Return the single instance of DNSSD. */
|
/** Return the single instance of DNSSD. */
|
||||||
static protected final DNSSD getInstance()
|
static protected final DNSSD getInstance()
|
||||||
{
|
{
|
||||||
SecurityManager sm = System.getSecurityManager();
|
SecurityManager sm = System.getSecurityManager();
|
||||||
if ( sm != null)
|
if (sm != null)
|
||||||
sm.checkPermission( new RuntimePermission( "getDNSSDInstance"));
|
sm.checkPermission( new RuntimePermission( "getDNSSDInstance"));
|
||||||
return fInstance;
|
return fInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract protected DNSSDService _makeBrowser( int flags, int ifIndex, String regType, String domain, BrowseListener listener)
|
abstract protected DNSSDService _makeBrowser( int flags, int ifIndex, String regType, String domain, BrowseListener listener)
|
||||||
throws DNSSDException;
|
throws DNSSDException;
|
||||||
|
|
||||||
abstract protected DNSSDService _resolve( int flags, int ifIndex, String serviceName, String regType,
|
abstract protected DNSSDService _resolve( int flags, int ifIndex, String serviceName, String regType,
|
||||||
String domain, ResolveListener listener)
|
String domain, ResolveListener listener)
|
||||||
throws DNSSDException;
|
throws DNSSDException;
|
||||||
|
|
||||||
abstract protected DNSSDRegistration _register( int flags, int ifIndex, String serviceName, String regType,
|
abstract protected DNSSDRegistration _register( int flags, int ifIndex, String serviceName, String regType,
|
||||||
String domain, String host, int port, TXTRecord txtRecord, RegisterListener listener)
|
String domain, String host, int port, TXTRecord txtRecord, RegisterListener listener)
|
||||||
throws DNSSDException;
|
throws DNSSDException;
|
||||||
|
|
||||||
abstract protected DNSSDRecordRegistrar _createRecordRegistrar( RegisterRecordListener listener)
|
abstract protected DNSSDRecordRegistrar _createRecordRegistrar( RegisterRecordListener listener)
|
||||||
throws DNSSDException;
|
throws DNSSDException;
|
||||||
|
|
||||||
abstract protected DNSSDService _queryRecord( int flags, int ifIndex, String serviceName, int rrtype,
|
abstract protected DNSSDService _queryRecord( int flags, int ifIndex, String serviceName, int rrtype,
|
||||||
int rrclass, QueryListener listener)
|
int rrclass, QueryListener listener)
|
||||||
throws DNSSDException;
|
throws DNSSDException;
|
||||||
|
|
||||||
|
@ -498,7 +458,7 @@ abstract public class DNSSD
|
||||||
abstract protected String _constructFullName( String serviceName, String regType, String domain)
|
abstract protected String _constructFullName( String serviceName, String regType, String domain)
|
||||||
throws DNSSDException;
|
throws DNSSDException;
|
||||||
|
|
||||||
abstract protected void _reconfirmRecord( int flags, int ifIndex, String fullName, int rrtype,
|
abstract protected void _reconfirmRecord( int flags, int ifIndex, String fullName, int rrtype,
|
||||||
int rrclass, byte[] rdata);
|
int rrclass, byte[] rdata);
|
||||||
|
|
||||||
abstract protected String _getNameForIfIndex( int ifIndex);
|
abstract protected String _getNameForIfIndex( int ifIndex);
|
||||||
|
@ -510,11 +470,11 @@ abstract public class DNSSD
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String name = System.getProperty( "com.apple.dnssd.DNSSD" );
|
String name = System.getProperty( "com.apple.dnssd.DNSSD" );
|
||||||
if( name == null )
|
if (name == null)
|
||||||
name = "com.apple.dnssd.AppleDNSSD"; // Fall back to Apple-provided class.
|
name = "com.apple.dnssd.AppleDNSSD"; // Fall back to Apple-provided class.
|
||||||
fInstance = (DNSSD) Class.forName( name ).newInstance();
|
fInstance = (DNSSD) Class.forName(name).newInstance();
|
||||||
}
|
}
|
||||||
catch( Exception e )
|
catch( Exception e )
|
||||||
{
|
{
|
||||||
|
@ -559,10 +519,13 @@ class AppleDNSSDException extends DNSSDException
|
||||||
"BADTIME",
|
"BADTIME",
|
||||||
"BADSIG",
|
"BADSIG",
|
||||||
"BADKEY",
|
"BADKEY",
|
||||||
"TRANSIENT"
|
"TRANSIENT",
|
||||||
|
"SERVICENOTRUNNING",
|
||||||
|
"NATPORTMAPPINGUNSUPPORTED",
|
||||||
|
"NATPORTMAPPINGDISABLED"
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( fErrorCode <= UNKNOWN && fErrorCode > ( UNKNOWN - kMessages.length))
|
if (fErrorCode <= UNKNOWN && fErrorCode > ( UNKNOWN - kMessages.length))
|
||||||
{
|
{
|
||||||
return "DNS-SD Error " + String.valueOf( fErrorCode) + ": " + kMessages[ UNKNOWN - fErrorCode];
|
return "DNS-SD Error " + String.valueOf( fErrorCode) + ": " + kMessages[ UNKNOWN - fErrorCode];
|
||||||
}
|
}
|
||||||
|
@ -580,9 +543,9 @@ class AppleDNSSD extends DNSSD
|
||||||
{
|
{
|
||||||
System.loadLibrary( "jdns_sd");
|
System.loadLibrary( "jdns_sd");
|
||||||
|
|
||||||
int libInitResult = InitLibrary( 1);
|
int libInitResult = InitLibrary( 2); // Current version number (must be sync'd with jnilib version)
|
||||||
|
|
||||||
if ( libInitResult != DNSSDException.NO_ERROR)
|
if (libInitResult != DNSSDException.NO_ERROR)
|
||||||
throw new InternalError( "cannot instantiate DNSSD: " + new AppleDNSSDException( libInitResult).getMessage());
|
throw new InternalError( "cannot instantiate DNSSD: " + new AppleDNSSDException( libInitResult).getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,18 +557,18 @@ class AppleDNSSD extends DNSSD
|
||||||
return new AppleBrowser( flags, ifIndex, regType, domain, client);
|
return new AppleBrowser( flags, ifIndex, regType, domain, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DNSSDService _resolve( int flags, int ifIndex, String serviceName, String regType,
|
protected DNSSDService _resolve( int flags, int ifIndex, String serviceName, String regType,
|
||||||
String domain, ResolveListener client)
|
String domain, ResolveListener client)
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{
|
{
|
||||||
return new AppleResolver( flags, ifIndex, serviceName, regType, domain, client);
|
return new AppleResolver( flags, ifIndex, serviceName, regType, domain, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DNSSDRegistration _register( int flags, int ifIndex, String serviceName, String regType,
|
protected DNSSDRegistration _register( int flags, int ifIndex, String serviceName, String regType,
|
||||||
String domain, String host, int port, TXTRecord txtRecord, RegisterListener client)
|
String domain, String host, int port, TXTRecord txtRecord, RegisterListener client)
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{
|
{
|
||||||
return new AppleRegistration( flags, ifIndex, serviceName, regType, domain, host, port,
|
return new AppleRegistration( flags, ifIndex, serviceName, regType, domain, host, port,
|
||||||
( txtRecord != null) ? txtRecord.getRawBytes() : null, client);
|
( txtRecord != null) ? txtRecord.getRawBytes() : null, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,7 +578,7 @@ class AppleDNSSD extends DNSSD
|
||||||
return new AppleRecordRegistrar( listener);
|
return new AppleRecordRegistrar( listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DNSSDService _queryRecord( int flags, int ifIndex, String serviceName, int rrtype,
|
protected DNSSDService _queryRecord( int flags, int ifIndex, String serviceName, int rrtype,
|
||||||
int rrclass, QueryListener client)
|
int rrclass, QueryListener client)
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{
|
{
|
||||||
|
@ -634,13 +597,13 @@ class AppleDNSSD extends DNSSD
|
||||||
String[] responseHolder = new String[1]; // lame maneuver to get around Java's lack of reference parameters
|
String[] responseHolder = new String[1]; // lame maneuver to get around Java's lack of reference parameters
|
||||||
|
|
||||||
int rc = ConstructName( serviceName, regType, domain, responseHolder);
|
int rc = ConstructName( serviceName, regType, domain, responseHolder);
|
||||||
if ( rc != 0)
|
if (rc != 0)
|
||||||
throw new AppleDNSSDException( rc);
|
throw new AppleDNSSDException( rc);
|
||||||
|
|
||||||
return responseHolder[0];
|
return responseHolder[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void _reconfirmRecord( int flags, int ifIndex, String fullName, int rrtype,
|
protected void _reconfirmRecord( int flags, int ifIndex, String fullName, int rrtype,
|
||||||
int rrclass, byte[] rdata)
|
int rrclass, byte[] rdata)
|
||||||
{
|
{
|
||||||
ReconfirmRecord( flags, ifIndex, fullName, rrtype, rrclass, rdata);
|
ReconfirmRecord( flags, ifIndex, fullName, rrtype, rrclass, rdata);
|
||||||
|
@ -659,7 +622,7 @@ class AppleDNSSD extends DNSSD
|
||||||
|
|
||||||
protected native int ConstructName( String serviceName, String regType, String domain, String[] pOut);
|
protected native int ConstructName( String serviceName, String regType, String domain, String[] pOut);
|
||||||
|
|
||||||
protected native void ReconfirmRecord( int flags, int ifIndex, String fullName, int rrtype,
|
protected native void ReconfirmRecord( int flags, int ifIndex, String fullName, int rrtype,
|
||||||
int rrclass, byte[] rdata);
|
int rrclass, byte[] rdata);
|
||||||
|
|
||||||
protected native String GetNameForIfIndex( int ifIndex);
|
protected native String GetNameForIfIndex( int ifIndex);
|
||||||
|
@ -685,7 +648,7 @@ class AppleService implements DNSSDService, Runnable
|
||||||
|
|
||||||
protected void ThrowOnErr( int rc) throws DNSSDException
|
protected void ThrowOnErr( int rc) throws DNSSDException
|
||||||
{
|
{
|
||||||
if ( rc != 0)
|
if (rc != 0)
|
||||||
throw new AppleDNSSDException( rc);
|
throw new AppleDNSSDException( rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,12 +697,12 @@ class AppleService implements DNSSDService, Runnable
|
||||||
|
|
||||||
class AppleBrowser extends AppleService
|
class AppleBrowser extends AppleService
|
||||||
{
|
{
|
||||||
public AppleBrowser( int flags, int ifIndex, String regType, String domain, BrowseListener client)
|
public AppleBrowser( int flags, int ifIndex, String regType, String domain, BrowseListener client)
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{
|
{
|
||||||
super(client);
|
super(client);
|
||||||
this.ThrowOnErr( this.CreateBrowser( flags, ifIndex, regType, domain));
|
this.ThrowOnErr( this.CreateBrowser( flags, ifIndex, regType, domain));
|
||||||
if ( !AppleDNSSD.hasAutoCallbacks)
|
if (!AppleDNSSD.hasAutoCallbacks)
|
||||||
new Thread(this).start();
|
new Thread(this).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -749,27 +712,27 @@ class AppleBrowser extends AppleService
|
||||||
|
|
||||||
class AppleResolver extends AppleService
|
class AppleResolver extends AppleService
|
||||||
{
|
{
|
||||||
public AppleResolver( int flags, int ifIndex, String serviceName, String regType,
|
public AppleResolver( int flags, int ifIndex, String serviceName, String regType,
|
||||||
String domain, ResolveListener client)
|
String domain, ResolveListener client)
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{
|
{
|
||||||
super(client);
|
super(client);
|
||||||
this.ThrowOnErr( this.CreateResolver( flags, ifIndex, serviceName, regType, domain));
|
this.ThrowOnErr( this.CreateResolver( flags, ifIndex, serviceName, regType, domain));
|
||||||
if ( !AppleDNSSD.hasAutoCallbacks)
|
if (!AppleDNSSD.hasAutoCallbacks)
|
||||||
new Thread(this).start();
|
new Thread(this).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets fNativeContext. Returns non-zero on error.
|
// Sets fNativeContext. Returns non-zero on error.
|
||||||
protected native int CreateResolver( int flags, int ifIndex, String serviceName, String regType,
|
protected native int CreateResolver( int flags, int ifIndex, String serviceName, String regType,
|
||||||
String domain);
|
String domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
// An AppleDNSRecord is a simple wrapper around a dns_sd DNSRecord.
|
// An AppleDNSRecord is a simple wrapper around a dns_sd DNSRecord.
|
||||||
class AppleDNSRecord implements DNSRecord
|
class AppleDNSRecord implements DNSRecord
|
||||||
{
|
{
|
||||||
public AppleDNSRecord( AppleService owner)
|
public AppleDNSRecord( AppleService owner)
|
||||||
{
|
{
|
||||||
fOwner = owner;
|
fOwner = owner;
|
||||||
fRecord = 0; // record always starts out empty
|
fRecord = 0; // record always starts out empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -785,12 +748,12 @@ class AppleDNSRecord implements DNSRecord
|
||||||
this.ThrowOnErr( this.Remove());
|
this.ThrowOnErr( this.Remove());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected long fRecord; // Really a DNSRecord; sizeof(int) == sizeof(void*) ?
|
protected long fRecord; // Really a DNSRecord; sizeof(long) == sizeof(void*) ?
|
||||||
protected AppleService fOwner;
|
protected AppleService fOwner;
|
||||||
|
|
||||||
protected void ThrowOnErr( int rc) throws DNSSDException
|
protected void ThrowOnErr( int rc) throws DNSSDException
|
||||||
{
|
{
|
||||||
if ( rc != 0)
|
if (rc != 0)
|
||||||
throw new AppleDNSSDException( rc);
|
throw new AppleDNSSDException( rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,13 +764,13 @@ class AppleDNSRecord implements DNSRecord
|
||||||
|
|
||||||
class AppleRegistration extends AppleService implements DNSSDRegistration
|
class AppleRegistration extends AppleService implements DNSSDRegistration
|
||||||
{
|
{
|
||||||
public AppleRegistration( int flags, int ifIndex, String serviceName, String regType, String domain,
|
public AppleRegistration( int flags, int ifIndex, String serviceName, String regType, String domain,
|
||||||
String host, int port, byte[] txtRecord, RegisterListener client)
|
String host, int port, byte[] txtRecord, RegisterListener client)
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{
|
{
|
||||||
super(client);
|
super(client);
|
||||||
this.ThrowOnErr( this.BeginRegister( ifIndex, flags, serviceName, regType, domain, host, port, txtRecord));
|
this.ThrowOnErr( this.BeginRegister( ifIndex, flags, serviceName, regType, domain, host, port, txtRecord));
|
||||||
if ( !AppleDNSSD.hasAutoCallbacks)
|
if (!AppleDNSSD.hasAutoCallbacks)
|
||||||
new Thread(this).start();
|
new Thread(this).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -827,7 +790,7 @@ class AppleRegistration extends AppleService implements DNSSDRegistration
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets fNativeContext. Returns non-zero on error.
|
// Sets fNativeContext. Returns non-zero on error.
|
||||||
protected native int BeginRegister( int ifIndex, int flags, String serviceName, String regType,
|
protected native int BeginRegister( int ifIndex, int flags, String serviceName, String regType,
|
||||||
String domain, String host, int port, byte[] txtRecord);
|
String domain, String host, int port, byte[] txtRecord);
|
||||||
|
|
||||||
// Sets fNativeContext. Returns non-zero on error.
|
// Sets fNativeContext. Returns non-zero on error.
|
||||||
|
@ -836,16 +799,16 @@ class AppleRegistration extends AppleService implements DNSSDRegistration
|
||||||
|
|
||||||
class AppleRecordRegistrar extends AppleService implements DNSSDRecordRegistrar
|
class AppleRecordRegistrar extends AppleService implements DNSSDRecordRegistrar
|
||||||
{
|
{
|
||||||
public AppleRecordRegistrar( RegisterRecordListener listener)
|
public AppleRecordRegistrar( RegisterRecordListener listener)
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{
|
{
|
||||||
super(listener);
|
super(listener);
|
||||||
this.ThrowOnErr( this.CreateConnection());
|
this.ThrowOnErr( this.CreateConnection());
|
||||||
if ( !AppleDNSSD.hasAutoCallbacks)
|
if (!AppleDNSSD.hasAutoCallbacks)
|
||||||
new Thread(this).start();
|
new Thread(this).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DNSRecord registerRecord( int flags, int ifIndex, String fullname, int rrtype,
|
public DNSRecord registerRecord( int flags, int ifIndex, String fullname, int rrtype,
|
||||||
int rrclass, byte[] rdata, int ttl)
|
int rrclass, byte[] rdata, int ttl)
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{
|
{
|
||||||
|
@ -859,19 +822,19 @@ class AppleRecordRegistrar extends AppleService implements DNSSDRecordRegistrar
|
||||||
protected native int CreateConnection();
|
protected native int CreateConnection();
|
||||||
|
|
||||||
// Sets fNativeContext. Returns non-zero on error.
|
// Sets fNativeContext. Returns non-zero on error.
|
||||||
protected native int RegisterRecord( int flags, int ifIndex, String fullname, int rrtype,
|
protected native int RegisterRecord( int flags, int ifIndex, String fullname, int rrtype,
|
||||||
int rrclass, byte[] rdata, int ttl, AppleDNSRecord destObj);
|
int rrclass, byte[] rdata, int ttl, AppleDNSRecord destObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppleQuery extends AppleService
|
class AppleQuery extends AppleService
|
||||||
{
|
{
|
||||||
public AppleQuery( int flags, int ifIndex, String serviceName, int rrtype,
|
public AppleQuery( int flags, int ifIndex, String serviceName, int rrtype,
|
||||||
int rrclass, QueryListener client)
|
int rrclass, QueryListener client)
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{
|
{
|
||||||
super(client);
|
super(client);
|
||||||
this.ThrowOnErr( this.CreateQuery( flags, ifIndex, serviceName, rrtype, rrclass));
|
this.ThrowOnErr( this.CreateQuery( flags, ifIndex, serviceName, rrtype, rrclass));
|
||||||
if ( !AppleDNSSD.hasAutoCallbacks)
|
if (!AppleDNSSD.hasAutoCallbacks)
|
||||||
new Thread(this).start();
|
new Thread(this).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -881,12 +844,12 @@ class AppleQuery extends AppleService
|
||||||
|
|
||||||
class AppleDomainEnum extends AppleService
|
class AppleDomainEnum extends AppleService
|
||||||
{
|
{
|
||||||
public AppleDomainEnum( int flags, int ifIndex, DomainListener client)
|
public AppleDomainEnum( int flags, int ifIndex, DomainListener client)
|
||||||
throws DNSSDException
|
throws DNSSDException
|
||||||
{
|
{
|
||||||
super(client);
|
super(client);
|
||||||
this.ThrowOnErr( this.BeginEnum( flags, ifIndex));
|
this.ThrowOnErr( this.BeginEnum( flags, ifIndex));
|
||||||
if ( !AppleDNSSD.hasAutoCallbacks)
|
if (!AppleDNSSD.hasAutoCallbacks)
|
||||||
new Thread(this).start();
|
new Thread(this).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,25 +13,7 @@
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
*/
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: DNSSDException.java,v $
|
|
||||||
Revision 1.4 2006/08/14 23:25:08 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.3 2005/07/10 22:19:01 cheshire
|
|
||||||
Add missing error codes to list of public static final ints
|
|
||||||
|
|
||||||
Revision 1.2 2004/04/30 21:48:27 rpantos
|
|
||||||
Change line endings for CVS.
|
|
||||||
|
|
||||||
Revision 1.1 2004/04/30 16:29:35 rpantos
|
|
||||||
First checked in.
|
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.apple.dnssd;
|
package com.apple.dnssd;
|
||||||
|
|
||||||
|
@ -42,33 +24,39 @@ package com.apple.dnssd;
|
||||||
|
|
||||||
abstract public class DNSSDException extends Exception
|
abstract public class DNSSDException extends Exception
|
||||||
{
|
{
|
||||||
public static final int NO_ERROR = 0;
|
public static final int NO_ERROR = 0;
|
||||||
public static final int UNKNOWN = -65537;
|
public static final int UNKNOWN = -65537;
|
||||||
public static final int NO_SUCH_NAME = -65538;
|
public static final int NO_SUCH_NAME = -65538;
|
||||||
public static final int NO_MEMORY = -65539;
|
public static final int NO_MEMORY = -65539;
|
||||||
public static final int BAD_PARAM = -65540;
|
public static final int BAD_PARAM = -65540;
|
||||||
public static final int BAD_REFERENCE = -65541;
|
public static final int BAD_REFERENCE = -65541;
|
||||||
public static final int BAD_STATE = -65542;
|
public static final int BAD_STATE = -65542;
|
||||||
public static final int BAD_FLAGS = -65543;
|
public static final int BAD_FLAGS = -65543;
|
||||||
public static final int UNSUPPORTED = -65544;
|
public static final int UNSUPPORTED = -65544;
|
||||||
public static final int NOT_INITIALIZED = -65545;
|
public static final int NOT_INITIALIZED = -65545;
|
||||||
public static final int NO_CACHE = -65546;
|
public static final int NO_CACHE = -65546;
|
||||||
public static final int ALREADY_REGISTERED = -65547;
|
public static final int ALREADY_REGISTERED = -65547;
|
||||||
public static final int NAME_CONFLICT = -65548;
|
public static final int NAME_CONFLICT = -65548;
|
||||||
public static final int INVALID = -65549;
|
public static final int INVALID = -65549;
|
||||||
public static final int FIREWALL = -65550;
|
public static final int FIREWALL = -65550;
|
||||||
public static final int INCOMPATIBLE = -65551;
|
public static final int INCOMPATIBLE = -65551;
|
||||||
public static final int BAD_INTERFACE_INDEX = -65552;
|
public static final int BAD_INTERFACE_INDEX = -65552;
|
||||||
public static final int REFUSED = -65553;
|
public static final int REFUSED = -65553;
|
||||||
public static final int NOSUCHRECORD = -65554;
|
public static final int NOSUCHRECORD = -65554;
|
||||||
public static final int NOAUTH = -65555;
|
public static final int NOAUTH = -65555;
|
||||||
public static final int NOSUCHKEY = -65556;
|
public static final int NOSUCHKEY = -65556;
|
||||||
public static final int NATTRAVERSAL = -65557;
|
public static final int NATTRAVERSAL = -65557;
|
||||||
public static final int DOUBLENAT = -65558;
|
public static final int DOUBLENAT = -65558;
|
||||||
public static final int BADTIME = -65559;
|
public static final int BADTIME = -65559;
|
||||||
public static final int BADSIG = -65560;
|
public static final int BADSIG = -65560;
|
||||||
public static final int BADKEY = -65561;
|
public static final int BADKEY = -65561;
|
||||||
public static final int TRANSIENT = -65562;
|
public static final int TRANSIENT = -65562;
|
||||||
|
public static final int SERVICENOTRUNNING = -65563;
|
||||||
|
public static final int NATPORTMAPPINGUNSUPPORTED = -65564;
|
||||||
|
public static final int NATPORTMAPPINGDISABLED = -65565;
|
||||||
|
|
||||||
|
// Note: When adding new error values here, remember also
|
||||||
|
// to update the corresponding kMessages array in AppleDNSSDException (DNSSD.java)
|
||||||
|
|
||||||
/** Returns the sub-code that identifies the particular error. */
|
/** Returns the sub-code that identifies the particular error. */
|
||||||
abstract public int getErrorCode();
|
abstract public int getErrorCode();
|
||||||
|
|
|
@ -13,21 +13,6 @@
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
This file declares the public interface to DNSSDRecordRegistrar, a DNSSDService
|
|
||||||
subclass that allows efficient registration of multiple individual records.
|
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: DNSSDRecordRegistrar.java,v $
|
|
||||||
Revision 1.2 2006/08/14 23:25:08 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.1 2006/06/20 23:00:12 rpantos
|
|
||||||
<rdar://problem/3839132> Java needs to implement DNSServiceRegisterRecord equivalent
|
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,15 +43,12 @@ public interface DNSSDRecordRegistrar extends DNSSDService
|
||||||
The class of the resource record, as defined in nameser.h
|
The class of the resource record, as defined in nameser.h
|
||||||
(usually 1 for the Internet class).
|
(usually 1 for the Internet class).
|
||||||
<P>
|
<P>
|
||||||
@param rData
|
@param rdata
|
||||||
The new rdata as it is to appear in the DNS record.
|
The new rdata as it is to appear in the DNS record.
|
||||||
<P>
|
<P>
|
||||||
@param ttl
|
@param ttl
|
||||||
The time to live of the resource record, in seconds. Pass 0 to use a default value.
|
The time to live of the resource record, in seconds. Pass 0 to use a default value.
|
||||||
<P>
|
<P>
|
||||||
@param listener
|
|
||||||
This object will get called when the service is registered.
|
|
||||||
<P>
|
|
||||||
@return A {@link DNSSDService} that can be used to abort the record registration.
|
@return A {@link DNSSDService} that can be used to abort the record registration.
|
||||||
|
|
||||||
@throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
|
@throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
|
||||||
|
|
|
@ -13,23 +13,6 @@
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: DNSSDRegistration.java,v $
|
|
||||||
Revision 1.3 2006/08/14 23:25:08 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.2 2004/12/11 03:01:00 rpantos
|
|
||||||
<rdar://problem/3907498> Java DNSRecord API should be cleaned up
|
|
||||||
|
|
||||||
Revision 1.1 2004/04/30 16:32:34 rpantos
|
|
||||||
First checked in.
|
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
This file declares the public interface to DNSSDRegistration, a DNSSDService
|
|
||||||
subclass that allows a client to control a service registration.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,21 +13,6 @@
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: DNSSDService.java,v $
|
|
||||||
Revision 1.3 2006/08/14 23:25:08 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.2 2004/04/30 21:48:27 rpantos
|
|
||||||
Change line endings for CVS.
|
|
||||||
|
|
||||||
Revision 1.1 2004/04/30 16:32:34 rpantos
|
|
||||||
First checked in.
|
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,21 +13,6 @@
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: DomainListener.java,v $
|
|
||||||
Revision 1.3 2006/08/14 23:25:08 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.2 2004/04/30 21:48:27 rpantos
|
|
||||||
Change line endings for CVS.
|
|
||||||
|
|
||||||
Revision 1.1 2004/04/30 16:29:35 rpantos
|
|
||||||
First checked in.
|
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,21 +13,6 @@
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: QueryListener.java,v $
|
|
||||||
Revision 1.3 2006/08/14 23:25:08 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.2 2004/04/30 21:48:27 rpantos
|
|
||||||
Change line endings for CVS.
|
|
||||||
|
|
||||||
Revision 1.1 2004/04/30 16:29:35 rpantos
|
|
||||||
First checked in.
|
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,13 +23,16 @@ package com.apple.dnssd;
|
||||||
|
|
||||||
public interface QueryListener extends BaseListener
|
public interface QueryListener extends BaseListener
|
||||||
{
|
{
|
||||||
/** Called when a record query has been completed.<P>
|
/** Called when a record query has been completed. Inspect flags
|
||||||
|
parameter to determine nature of query event.<P>
|
||||||
|
|
||||||
@param query
|
@param query
|
||||||
The active query object.
|
The active query object.
|
||||||
<P>
|
<P>
|
||||||
@param flags
|
@param flags
|
||||||
Possible values are DNSSD.MORE_COMING.
|
If kDNSServiceFlagsAdd bit is set, this is a newly discovered answer;
|
||||||
|
otherwise this is a previously discovered answer which has expired.
|
||||||
|
Other possible values are DNSSD.MORE_COMING.
|
||||||
<P>
|
<P>
|
||||||
@param ifIndex
|
@param ifIndex
|
||||||
The interface on which the query was resolved. (The index for a given
|
The interface on which the query was resolved. (The index for a given
|
||||||
|
|
|
@ -13,21 +13,6 @@
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: RegisterListener.java,v $
|
|
||||||
Revision 1.3 2006/08/14 23:25:08 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.2 2004/04/30 21:48:27 rpantos
|
|
||||||
Change line endings for CVS.
|
|
||||||
|
|
||||||
Revision 1.1 2004/04/30 16:29:35 rpantos
|
|
||||||
First checked in.
|
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,18 +13,6 @@
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: RegisterRecordListener.java,v $
|
|
||||||
Revision 1.2 2006/08/14 23:25:08 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.1 2006/06/20 23:00:12 rpantos
|
|
||||||
<rdar://problem/3839132> Java needs to implement DNSServiceRegisterRecord equivalent
|
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,22 +13,7 @@
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
*/
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: ResolveListener.java,v $
|
|
||||||
Revision 1.3 2006/08/14 23:25:08 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.2 2004/04/30 21:48:27 rpantos
|
|
||||||
Change line endings for CVS.
|
|
||||||
|
|
||||||
Revision 1.1 2004/04/30 16:29:35 rpantos
|
|
||||||
First checked in.
|
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
package com.apple.dnssd;
|
package com.apple.dnssd;
|
||||||
|
|
|
@ -14,29 +14,6 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
|
|
||||||
Change History (most recent first):
|
|
||||||
|
|
||||||
$Log: TXTRecord.java,v $
|
|
||||||
Revision 1.6 2006/08/14 23:25:08 cheshire
|
|
||||||
Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
|
|
||||||
|
|
||||||
Revision 1.5 2004/08/25 21:54:36 rpantos
|
|
||||||
<rdar://problem/3773973> Fix getValue() for values containing '='.
|
|
||||||
|
|
||||||
Revision 1.4 2004/08/04 01:04:50 rpantos
|
|
||||||
<rdar://problems/3731579&3731582> Fix set(); add remove() & toString().
|
|
||||||
|
|
||||||
Revision 1.3 2004/07/13 21:24:25 rpantos
|
|
||||||
Fix for <rdar://problem/3701120>.
|
|
||||||
|
|
||||||
Revision 1.2 2004/04/30 21:48:27 rpantos
|
|
||||||
Change line endings for CVS.
|
|
||||||
|
|
||||||
Revision 1.1 2004/04/30 16:29:35 rpantos
|
|
||||||
First checked in.
|
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
To do:
|
To do:
|
||||||
- implement remove()
|
- implement remove()
|
||||||
- fix set() to replace existing values
|
- fix set() to replace existing values
|
||||||
|
@ -126,20 +103,20 @@ public class TXTRecord
|
||||||
byte[] oldBytes = fBytes;
|
byte[] oldBytes = fBytes;
|
||||||
int valLen = (value != null) ? value.length : 0;
|
int valLen = (value != null) ? value.length : 0;
|
||||||
int insertion = 0;
|
int insertion = 0;
|
||||||
byte newLen, avLen;
|
int newLen, avLen;
|
||||||
|
|
||||||
// locate the insertion point
|
// locate the insertion point
|
||||||
for ( int i=0; i < index && insertion < fBytes.length; i++)
|
for ( int i=0; i < index && insertion < fBytes.length; i++)
|
||||||
insertion += fBytes[ insertion] + 1;
|
insertion += (0xFF & (fBytes[ insertion] + 1));
|
||||||
|
|
||||||
avLen = (byte) ( keyBytes.length + valLen + (value != null ? 1 : 0));
|
avLen = keyBytes.length + valLen + (value != null ? 1 : 0);
|
||||||
newLen = (byte) ( avLen + oldBytes.length + 1);
|
newLen = avLen + oldBytes.length + 1;
|
||||||
|
|
||||||
fBytes = new byte[ newLen];
|
fBytes = new byte[ newLen];
|
||||||
System.arraycopy( oldBytes, 0, fBytes, 0, insertion);
|
System.arraycopy( oldBytes, 0, fBytes, 0, insertion);
|
||||||
int secondHalfLen = oldBytes.length - insertion;
|
int secondHalfLen = oldBytes.length - insertion;
|
||||||
System.arraycopy( oldBytes, insertion, fBytes, newLen - secondHalfLen, secondHalfLen);
|
System.arraycopy( oldBytes, insertion, fBytes, newLen - secondHalfLen, secondHalfLen);
|
||||||
fBytes[ insertion] = avLen;
|
fBytes[ insertion] = ( byte) avLen;
|
||||||
System.arraycopy( keyBytes, 0, fBytes, insertion + 1, keyBytes.length);
|
System.arraycopy( keyBytes, 0, fBytes, insertion + 1, keyBytes.length);
|
||||||
if ( value != null)
|
if ( value != null)
|
||||||
{
|
{
|
||||||
|
@ -169,7 +146,7 @@ public class TXTRecord
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
avStart += avLen + 1;
|
avStart += (0xFF & (avLen + 1));
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -180,7 +157,7 @@ public class TXTRecord
|
||||||
int i, avStart;
|
int i, avStart;
|
||||||
|
|
||||||
for ( i=0, avStart=0; avStart < fBytes.length; i++)
|
for ( i=0, avStart=0; avStart < fBytes.length; i++)
|
||||||
avStart += fBytes[ avStart] + 1;
|
avStart += (0xFF & (fBytes[ avStart] + 1));
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,9 +41,6 @@
|
||||||
|
|
||||||
To do:
|
To do:
|
||||||
- display resolved TXTRecord
|
- display resolved TXTRecord
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,7 +54,7 @@ import javax.swing.event.*;
|
||||||
import com.apple.dnssd.*;
|
import com.apple.dnssd.*;
|
||||||
|
|
||||||
|
|
||||||
class BrowserApp implements ListSelectionListener, ResolveListener
|
class BrowserApp implements ListSelectionListener, ResolveListener, Runnable
|
||||||
{
|
{
|
||||||
static BrowserApp app;
|
static BrowserApp app;
|
||||||
JFrame frame;
|
JFrame frame;
|
||||||
|
@ -66,6 +63,8 @@ class BrowserApp implements ListSelectionListener, ResolveListener
|
||||||
JList domainPane, servicesPane, servicePane;
|
JList domainPane, servicesPane, servicePane;
|
||||||
DNSSDService servicesBrowser, serviceBrowser, domainBrowser;
|
DNSSDService servicesBrowser, serviceBrowser, domainBrowser;
|
||||||
JLabel hostLabel, portLabel;
|
JLabel hostLabel, portLabel;
|
||||||
|
String hostNameForUpdate;
|
||||||
|
int portForUpdate;
|
||||||
|
|
||||||
public BrowserApp()
|
public BrowserApp()
|
||||||
{
|
{
|
||||||
|
@ -173,22 +172,43 @@ class BrowserApp implements ListSelectionListener, ResolveListener
|
||||||
serviceList.getNthServiceName( newSel),
|
serviceList.getNthServiceName( newSel),
|
||||||
serviceList.getNthRegType( newSel),
|
serviceList.getNthRegType( newSel),
|
||||||
serviceList.getNthDomain( newSel),
|
serviceList.getNthDomain( newSel),
|
||||||
new SwingResolveListener( this));
|
this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch ( Exception ex) { terminateWithException( ex); }
|
catch ( Exception ex) { terminateWithException( ex); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
hostLabel.setText( hostNameForUpdate);
|
||||||
|
portLabel.setText( String.valueOf( portForUpdate));
|
||||||
|
}
|
||||||
|
|
||||||
public void serviceResolved( DNSSDService resolver, int flags, int ifIndex, String fullName,
|
public void serviceResolved( DNSSDService resolver, int flags, int ifIndex, String fullName,
|
||||||
String hostName, int port, TXTRecord txtRecord)
|
String hostName, int port, TXTRecord txtRecord)
|
||||||
{
|
{
|
||||||
hostLabel.setText( hostName);
|
// We want to update GUI on the AWT event dispatching thread, but we can't stop
|
||||||
portLabel.setText( String.valueOf( port));
|
// the resolve from that thread, since stop() is synchronized with this callback.
|
||||||
|
// So, we stop the resolve on this thread, then invokeAndWait on the AWT event thread.
|
||||||
|
|
||||||
|
resolver.stop();
|
||||||
|
|
||||||
|
hostNameForUpdate = hostName;
|
||||||
|
portForUpdate = port;
|
||||||
|
|
||||||
|
try {
|
||||||
|
SwingUtilities.invokeAndWait(this);
|
||||||
|
}
|
||||||
|
catch ( Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void operationFailed( DNSSDService service, int errorCode)
|
public void operationFailed( DNSSDService service, int errorCode)
|
||||||
{
|
{
|
||||||
|
service.stop();
|
||||||
// handle failure here
|
// handle failure here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
Manifest-Version: 1.0
|
Manifest-Version: 1.0
|
||||||
Main-Class: BrowserApp
|
Main-Class: BrowserApp
|
||||||
Class-Path: /usr/share/lib/java/dnssd.jar
|
|
||||||
|
|
|
@ -42,9 +42,6 @@
|
||||||
|
|
||||||
To do:
|
To do:
|
||||||
- implement better coloring algorithm
|
- implement better coloring algorithm
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
Manifest-Version: 1.0
|
Manifest-Version: 1.0
|
||||||
Main-Class: SimpleChat
|
Main-Class: SimpleChat
|
||||||
Class-Path: /usr/share/lib/java/dnssd.jar
|
|
||||||
|
|
|
@ -36,11 +36,9 @@
|
||||||
* OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
* OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||||
* (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
* (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import com.apple.dnssd.*;
|
import com.apple.dnssd.*;
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,6 @@
|
||||||
* OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
* OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||||
* (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
* (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,6 @@
|
||||||
* OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
* OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||||
* (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
* (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,6 +13,7 @@
|
||||||
# Copyright 2011, Richard Lowe
|
# Copyright 2011, Richard Lowe
|
||||||
# Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
# Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||||
# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
|
# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
|
||||||
|
# Copyright 2016 Toomas Soome <tsoome@me.com>
|
||||||
#
|
#
|
||||||
|
|
||||||
include $(SRC)//Makefile.master
|
include $(SRC)//Makefile.master
|
||||||
|
@ -286,6 +287,7 @@ _MANFILES= 6to4relay.1m \
|
||||||
makedbm.1m \
|
makedbm.1m \
|
||||||
makemap.1m \
|
makemap.1m \
|
||||||
mdmonitord.1m \
|
mdmonitord.1m \
|
||||||
|
mdnsd.1m \
|
||||||
medstat.1m \
|
medstat.1m \
|
||||||
metaclear.1m \
|
metaclear.1m \
|
||||||
metadb.1m \
|
metadb.1m \
|
||||||
|
|
|
@ -1,335 +1,264 @@
|
||||||
'\" te
|
.\" -*- tab-width: 4 -*-
|
||||||
.\" Copyright (c) 2003-2004 Apple Computer, Inc. All Rights Reserved.
|
.\"
|
||||||
.\" Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing,
|
.\" Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
|
||||||
.\" software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
.\"
|
||||||
.\" Portions Copyright (c) 2007, Sun Microsystems, Inc. All Rights Reserved.
|
.\" Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
.TH DNS-SD 1M "Aug 21, 2007"
|
.\" you may not use this file except in compliance with the License.
|
||||||
.SH NAME
|
.\" You may obtain a copy of the License at
|
||||||
dns-sd \- Multicast DNS (mDNS) & DNS Service Discovery (DNS-SD) Test Tool
|
.\"
|
||||||
.SH SYNOPSIS
|
.\" http://www.apache.org/licenses/LICENSE-2.0
|
||||||
.LP
|
.\"
|
||||||
.nf
|
.\" Unless required by applicable law or agreed to in writing, software
|
||||||
\fBdns-sd\fR \fB-R\fR \fIname\fR \fItype\fR \fIdomain\fR \fIport\fR [\fIkey\fR=\fIvalue\fR ...]
|
.\" distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
.fi
|
.\" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
.\" See the License for the specific language governing permissions and
|
||||||
.LP
|
.\" limitations under the License.
|
||||||
.nf
|
.\"
|
||||||
\fBdns-sd\fR \fB-B\fR \fItype\fR \fIdomain\fR
|
.\" Copyright 2016 Toomas Soome <tsoome@me.com>
|
||||||
.fi
|
.\"
|
||||||
|
.Dd Jan 28, 2016 \" Date
|
||||||
.LP
|
.Dt DNS-SD 1M \" Document Title
|
||||||
.nf
|
.Os illumos \" Operating System
|
||||||
\fBdns-sd\fR \fB-L\fR \fIname\fR \fItype\fR \fIdomain\fR
|
.\"
|
||||||
.fi
|
.Sh NAME
|
||||||
|
.Nm dns-sd
|
||||||
.LP
|
.Nd Multicast DNS (mDNS) & DNS Service Discovery (DNS-SD) Test Tool \" For whatis
|
||||||
.nf
|
.\"
|
||||||
\fBdns-sd\fR \fB-Q\fR \fIFQDN\fR \fIrrtype\fR \fIrrclass\fR
|
.Sh SYNOPSIS
|
||||||
.fi
|
.Nm
|
||||||
|
.Op Fl E
|
||||||
.LP
|
.Pp
|
||||||
.nf
|
.Nm
|
||||||
\fBdns-sd\fR \fB-C\fR \fIFQDN\fR \fIrrtype\fR \fIrrclass\fR
|
.Op Fl F
|
||||||
.fi
|
.Pp
|
||||||
|
.Nm
|
||||||
.LP
|
.Op Fl R Ar name type domain port Op Ar key=value ...
|
||||||
.nf
|
.Pp
|
||||||
\fBdns-sd\fR \fB-P\fR \fIname\fR \fItype\fR \fIdomain\fR \fIport\fR \fIhost\fR \fIIP\fR [\fIkey\fR=\fIvalue\fR ...]
|
.Nm
|
||||||
.fi
|
.Op Fl B Ar type domain
|
||||||
|
.Pp
|
||||||
.LP
|
.Nm
|
||||||
.nf
|
.Op Fl L Ar name type domain
|
||||||
\fBdns-sd\fR \fB-E\fR | \fB-F\fR | \fB-A\fR | \fB-U\fR | \fB-N\fR | \fB-T\fR | \fB-M\fR | \fB-I\fR
|
.Pp
|
||||||
.fi
|
.Nm
|
||||||
|
.Op Fl P Ar name type domain port host IP Op Ar key=value ...
|
||||||
.SH DESCRIPTION
|
.Pp
|
||||||
.sp
|
.Nm
|
||||||
.LP
|
.Op Fl q Ar name rrtype rrclass
|
||||||
The \fBdns-sd\fR command is a network diagnostic tool, much like \fBping\fR(1M)
|
.Pp
|
||||||
or \fBtraceroute\fR(1M). However, unlike those tools, most of its functionality
|
.Nm
|
||||||
is not implemented in the \fBdns-sd\fR executable itself, but in library code
|
.Op Fl Z Ar type domain
|
||||||
that is available to any application. The library \fBAPI\fR that \fBdns-sd\fR
|
.Pp
|
||||||
uses is documented in \fB/usr/include/dns_sd.h\fR.
|
.Nm
|
||||||
.sp
|
.Op Fl G Ns \ v4/v6/v4v6 Ar name
|
||||||
.LP
|
.Pp
|
||||||
The \fBdns-sd\fR command is primarily intended for interactive use. Because its
|
.Nm
|
||||||
command-line arguments and output format are subject to change, invoking it
|
.Op Fl V
|
||||||
from a shell script can be unpredictable. Additionally, the asynchronous nature
|
.\"
|
||||||
of \fBDNS\fR Service Discovery does not easily lend itself to script-oriented
|
.Sh DESCRIPTION
|
||||||
programming. This style of asynchronous interaction works best with
|
The
|
||||||
applications that are either multi-threaded, or use a main event-handling loop
|
.Nm
|
||||||
to receive keystrokes, network data, and other asynchronous event notifications
|
command is a network diagnostic tool, much like
|
||||||
as they happen.
|
.Xr ping 8
|
||||||
.SH OPTIONS
|
or
|
||||||
.sp
|
.Xr traceroute 8 .
|
||||||
.LP
|
However, unlike those tools, most of its functionality is not implemented in the
|
||||||
The following options are supported:
|
.Nm
|
||||||
.sp
|
executable itself, but in library code that is available to any application.
|
||||||
.ne 2
|
The library API that
|
||||||
.na
|
.Nm
|
||||||
\fB\fB-R\fR \fIname\fR \fItype\fR \fIdomain\fR \fIport\fR
|
uses is documented in
|
||||||
[\fIkey\fR=\fIvalue\fR ...]\fR
|
.Pa /usr/include/dns_sd.h .
|
||||||
.ad
|
The
|
||||||
.sp .6
|
.Nm
|
||||||
.RS 4n
|
command replaces the older
|
||||||
Register (advertise) a service in the specified domain with the given
|
mDNS
|
||||||
\fIname\fR and \fItype\fR as listening (on the current machine) on the
|
command.
|
||||||
specified \fIport\fR.
|
.Pp
|
||||||
.sp
|
The
|
||||||
\fIname\fR can be any arbitrary unicode text, containing any legal unicode
|
.Nm
|
||||||
characters (including dots, spaces, slashes, colons, and so on without any
|
command is primarily intended for interactive use.
|
||||||
restrictions), up to 63 \fBUTF-8\fR bytes long.
|
Because its command-line arguments and output format are subject to change,
|
||||||
.sp
|
invoking it from a shell script will generally be fragile. Additionally,
|
||||||
\fItype\fR must be of the form "_app-proto._tcp" or "_app-proto._udp", where
|
the asynchronous nature of DNS Service Discovery does
|
||||||
|
not lend itself easily to script-oriented programming. For example,
|
||||||
|
calls like "browse" never complete; the action of performing a "browse"
|
||||||
|
sets in motion machinery to notify the client whenever instances of
|
||||||
|
that service type appear or disappear from the network. These
|
||||||
|
notifications continue to be delivered indefinitely, for minutes,
|
||||||
|
hours, or even days, as services come and go, until the client
|
||||||
|
explicitly terminates the call. This style of asynchronous interaction
|
||||||
|
works best with applications that are either multi-threaded, or use a
|
||||||
|
main event-handling loop to receive keystrokes, network data, and other
|
||||||
|
asynchronous event notifications as they happen.
|
||||||
|
.br
|
||||||
|
If you wish to perform DNS Service Discovery operations from a
|
||||||
|
scripting language, then the best way to do this is not to execute the
|
||||||
|
.Nm
|
||||||
|
command and then attempt to decipher the textual output, but instead to
|
||||||
|
directly call the DNS-SD APIs using a binding for your chosen language.
|
||||||
|
.br
|
||||||
|
For example, if you are programming in Ruby, then you can
|
||||||
|
directly call DNS-SD APIs using the dnssd package documented at
|
||||||
|
.Pa <http://rubyforge.org/projects/dnssd/> .
|
||||||
|
.br
|
||||||
|
Similar bindings for other languages are also in development.
|
||||||
|
.Bl -tag -width E
|
||||||
|
.It Nm Fl E
|
||||||
|
return a list of domains recommended for registering(advertising) services.
|
||||||
|
.It Nm Fl F
|
||||||
|
return a list of domains recommended for browsing services.
|
||||||
|
.Pp
|
||||||
|
Normally, on your home network, the only domain you are likely to see is "local".
|
||||||
|
However if your network administrator has created Domain Enumeration records,
|
||||||
|
then you may also see other recommended domains for registering and browsing.
|
||||||
|
.It Nm Fl R Ar name type domain port Op Ar key=value ...
|
||||||
|
register (advertise) a service in the specified
|
||||||
|
.Ar domain
|
||||||
|
with the given
|
||||||
|
.Ar name
|
||||||
|
and
|
||||||
|
.Ar type
|
||||||
|
as listening (on the current machine) on
|
||||||
|
.Ar port.
|
||||||
|
.Pp
|
||||||
|
.Ar name
|
||||||
|
can be arbitrary unicode text, containing any legal unicode characters
|
||||||
|
(including dots, spaces, slashes, colons, etc. without restriction),
|
||||||
|
up to 63 UTF-8 bytes long.
|
||||||
|
.Ar type
|
||||||
|
must be of the form "_app-proto._tcp" or "_app-proto._udp", where
|
||||||
"app-proto" is an application protocol name registered at
|
"app-proto" is an application protocol name registered at
|
||||||
http://www.dns-sd.org/ServiceTypes.html.
|
.Pa http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml .
|
||||||
.sp
|
.Pp
|
||||||
\fIdomain\fR is the domain in which to register the service. In current
|
.Ar domain
|
||||||
implementations, only the local multicast domain "local" is supported. In the
|
is the domain in which to register the service.
|
||||||
future, registering will be supported in any arbitrary domain that has a
|
In current implementations, only the local multicast domain "local" is
|
||||||
working \fBDNS\fR Update server [\fBRFC\fR 2136]. The domain "." is a synonym
|
supported. In the future, registering will be supported in any arbitrary
|
||||||
for "pick a sensible default", which currently means "local".
|
domain that has a working DNS Update server [RFC 2136]. The
|
||||||
.sp
|
.Ar domain
|
||||||
\fIport\fR is a number from 0 to 65535, and is the \fBTCP\fR or \fBUDP\fR port
|
"." is a synonym for "pick a sensible default" which today
|
||||||
number upon which the service is listening. Registering a service on port 0
|
means "local".
|
||||||
allows an application to explicitly advertise the non-availability of a
|
.Pp
|
||||||
service.
|
.Ar port
|
||||||
.sp
|
is a number from 0 to 65535, and is the TCP or UDP port number upon
|
||||||
|
which the service is listening.
|
||||||
|
.Pp
|
||||||
Additional attributes of the service may optionally be described by
|
Additional attributes of the service may optionally be described by
|
||||||
\fIkey/value\fR pairs, which are stored in the advertised service's \fBDNS\fR
|
key/value pairs, which are stored in the advertised service's DNS TXT
|
||||||
\fBTXT\fR record. Allowable keys and values are listed with the service
|
record. Allowable keys and values are listed with the service
|
||||||
registration at http://www.dns-sd.org/ServiceTypes.html
|
registration at
|
||||||
.RE
|
.Pa http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml .
|
||||||
|
.It Nm Fl B Ar type domain
|
||||||
.sp
|
browse for instances of service
|
||||||
.ne 2
|
.Ar type
|
||||||
.na
|
in
|
||||||
\fB\fB-B\fR \fItype\fR \fIdomain\fR\fR
|
.Ar domain .
|
||||||
.ad
|
.Pp
|
||||||
.sp .6
|
For valid
|
||||||
.RS 4n
|
.Ar type Ns s
|
||||||
Browse for instances of service \fItype\fR in \fIdomain\fR.
|
see
|
||||||
.sp
|
.Pa http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml .
|
||||||
For valid types, see http://www.dns-sd.org/ServiceTypes.html. Omitting the
|
as described above. Omitting the
|
||||||
domain name or using "." means "pick a sensible default."
|
.Ar domain
|
||||||
.RE
|
or using "." means "pick a sensible default."
|
||||||
|
.It Nm Fl L Ar name type domain
|
||||||
.sp
|
look up and display the information necessary to contact and use the
|
||||||
.ne 2
|
named service: the hostname of the machine where that service is
|
||||||
.na
|
available, the port number on which the service is listening, and (if
|
||||||
\fB\fB-L\fR \fIname\fR \fItype\fR \fIdomain\fR\fR
|
present) TXT record attributes describing properties of the service.
|
||||||
.ad
|
.Pp
|
||||||
.sp .6
|
Note that in a typical application, browsing may only happen rarely, while lookup
|
||||||
.RS 4n
|
(or "resolving") happens every time the service is used. For example, a
|
||||||
Look up and display the information necessary to contact and use the named
|
user browses the network to pick a default printer fairly rarely, but once
|
||||||
service. This information includes the hostname of the machine where that
|
a default printer has been picked, that named service is resolved to its
|
||||||
service is available, the port number on which the service is listening, and
|
current IP address and port number every time the user presses Cmd-P to
|
||||||
(if present) \fBTXT\fR record attributes describing properties of the service.
|
print.
|
||||||
.sp
|
.It Nm Fl P Ar name type domain port host IP Op Ar key=value ...
|
||||||
In a typical application, browsing happens rarely, while lookup (or
|
create a proxy advertisement for a service running on(offered by) some other machine.
|
||||||
"resolving") happens every time the service is used. For example, a user does
|
The two new options are Host, a name for the device and IP, the address of it.
|
||||||
not browse the network to pick a default printer that often, but once a default
|
.Pp
|
||||||
printer has been picked, that named service is resolved to its current IP
|
The service for which you create a proxy advertisement does not necessarily have to be on your local network.
|
||||||
address and port number every time the user presses Cmd-P to print.
|
You can set up a local proxy for a website on the Internet.
|
||||||
.RE
|
.It Nm Fl q Ar name rrtype rrclass
|
||||||
|
look up any DNS name, resource record type, and resource record class,
|
||||||
.sp
|
not necessarily DNS-SD names and record types.
|
||||||
.ne 2
|
If rrtype is not specified, it queries for the IPv4 address of the name,
|
||||||
.na
|
if rrclass is not specified, IN class is assumed. If the name is not a fully
|
||||||
\fB\fB-Q\fR \fIFQDN\fR \fIrrtype\fR \fIrrclass\fR\fR
|
qualified domain name, then search domains may be appended.
|
||||||
.ad
|
.It Nm Fl Z Ar type domain
|
||||||
.sp .6
|
browse for service instances and display output in zone file format.
|
||||||
.RS 4n
|
.It Nm Fl G Ns \ v4/v6/v4v6 Ar name
|
||||||
Generic query for any resource record type and class.
|
look up the IP address information of the name.
|
||||||
.RE
|
If v4 is specified, the IPv4 address of the name is looked up,
|
||||||
|
if v6 is specified the IPv6 address is looked up. If v4v6 is specified both the IPv4 and IPv6
|
||||||
.sp
|
address is looked up. If the name is not a fully qualified domain name,
|
||||||
.ne 2
|
then search domains may be appended.
|
||||||
.na
|
.It Nm Fl V
|
||||||
\fB\fB-C\fR \fIFQDN\fR \fIrrtype\fR \fIrrclass\fR\fR
|
return the version of the currently running daemon/system service.
|
||||||
.ad
|
.El
|
||||||
.sp .6
|
.Sh FILES
|
||||||
.RS 4n
|
.Pa /usr/bin/dns-sd \" Pathname
|
||||||
Generic query for any resource record type and class. This option also
|
.\"
|
||||||
reconfirms each result from the query. Reconfirming the record instructs
|
.Sh EXAMPLES
|
||||||
\fBmdnsd\fR(1M) to verify the validity of the record. If the record is not
|
To advertise the existence of LPR printing service on port 515 on this
|
||||||
valid \fBmdnsd\fR(1M) flushes the record from the daemon's cache and also from
|
machine, such that it will be discovered by the Mac OS X printing software
|
||||||
other \fBmdnsd\fR(1M) caches on the network.
|
and other DNS-SD compatible printing clients, use:
|
||||||
.RE
|
.Pp
|
||||||
|
.Dl Nm Fl R Ns \ \&"My Test\&" _printer._tcp. \&. 515 pdl=application/postscript
|
||||||
.sp
|
.Pp
|
||||||
.ne 2
|
For this registration to be useful, you need to actually have LPR service
|
||||||
.na
|
available on port 515. Advertising a service that does not exist is not
|
||||||
\fB\fB-P\fR \fIname\fR \fItype\fR \fIdomain\fR \fIport\fR \fIhost\fR \fIIP\fR
|
very useful, and will be confusing and annoying to other people on the
|
||||||
[\fIkey\fR=\fIvalue\fR ...]\fR
|
network.
|
||||||
.ad
|
.Pp
|
||||||
.sp .6
|
Similarly, to advertise a web page being served by an HTTP
|
||||||
.RS 4n
|
server on port 80 on this machine, such that it will show up in the
|
||||||
Register (advertise) a service in the specified domain with the given
|
Bonjour list in Safari and other DNS-SD compatible Web clients, use:
|
||||||
\fIname\fR and \fItype\fR listening on the specified port and accessible on
|
.Pp
|
||||||
another host. This option should be used to advertise by proxy a service
|
.Dl Nm Fl R Ns \ \&"My Test\&" _http._tcp \&. 80 path=/path-to-page.html
|
||||||
accessible on another host. The host name and \fBIPv4\fR address to access the
|
.Pp
|
||||||
service must be specified.
|
To find the advertised web pages on the local network (the same list that
|
||||||
.RE
|
Safari shows), use:
|
||||||
|
.Pp
|
||||||
.sp
|
.Dl Nm Fl B Ns \ _http._tcp
|
||||||
.ne 2
|
.Pp
|
||||||
.na
|
While that command is running, in another window, try the
|
||||||
\fB\fB-E\fR\fR
|
.Nm Fl R
|
||||||
.ad
|
example given above to advertise a web page, and you should see the
|
||||||
.sp .6
|
"Add" event reported to the
|
||||||
.RS 4n
|
.Nm Fl B
|
||||||
Discover recommended registration domains. This option returns the recommended
|
window. Now press Ctrl-C in the
|
||||||
domains to register a service. The recommended registration domains are
|
.Nm Fl R
|
||||||
returned by querying the name servers in \fBresolv.conf\fR(4).
|
window and you should see the "Remove" event reported to the
|
||||||
.RE
|
.Nm Fl B
|
||||||
|
window.
|
||||||
.sp
|
.Pp
|
||||||
.ne 2
|
In the example below, the www.apple.com web page is advertised as a service called "apple",
|
||||||
.na
|
running on a target host called apple.local, which resolves to 17.149.160.49.
|
||||||
\fB\fB-F\fR\fR
|
.Pp
|
||||||
.ad
|
.Dl Nm Fl P Ns \ apple _http._tcp \&"\&"\& 80 apple.local 17.149.160.49
|
||||||
.sp .6
|
.Pp
|
||||||
.RS 4n
|
The Bonjour menu in the Safari web browser will now show "apple".
|
||||||
Discover recommended browsing domains. This option returns the recommended
|
The same IP address can be reached by entering apple.local in the web browser.
|
||||||
domains for browsing services. The recommended browsing domains are returned by
|
In either case, the request will be resolved to the IP address and browser will show
|
||||||
querying the name servers in \fBresolv.conf\fR(4).
|
contents associated with www.apple.com.
|
||||||
.RE
|
.Pp
|
||||||
|
If a client wants to be notified of changes in server state, it can
|
||||||
.sp
|
initiate a query for the service's particular record and leave it running.
|
||||||
.ne 2
|
For example, to monitor the status of an iChat user you can use:
|
||||||
.na
|
.Pp
|
||||||
\fB\fB-A\fR\fR
|
.Dl Nm Fl q Ns \ someone@ex1._presence._tcp.local txt
|
||||||
.ad
|
.Pp
|
||||||
.sp .6
|
Everytime status of that user(someone) changes, you will see a new TXT record result reported.
|
||||||
.RS 4n
|
.Pp
|
||||||
Test registering service with Multicast \fBDNS\fR and test the add, update and
|
You can also query for a unicast name like www.apple.com and monitor its status.
|
||||||
delete operations of \fBDNS\fR records with Multicast \fBDNS\fR.
|
.Pp
|
||||||
.RE
|
.Dl Nm Fl q Ns \ www.apple.com
|
||||||
|
.Sh INTERFACE STABILITY
|
||||||
.sp
|
.Sy Volatile .
|
||||||
.ne 2
|
.Sh SEE ALSO
|
||||||
.na
|
.Xr mdnsd 1M ,
|
||||||
\fB\fB-U\fR\fR
|
.Xr ping 1M ,
|
||||||
.ad
|
.Xr traceroute 1M ,
|
||||||
.sp .6
|
.Xr resolv.conf 4
|
||||||
.RS 4n
|
|
||||||
Test registering service with Multicast \fBDNS\fR and test updating of
|
|
||||||
\fBDNS\fR \fBTXT\fR records for a service registered with Multicast \fBDNS\fR.
|
|
||||||
.RE
|
|
||||||
|
|
||||||
.sp
|
|
||||||
.ne 2
|
|
||||||
.na
|
|
||||||
\fB\fB-N\fR\fR
|
|
||||||
.ad
|
|
||||||
.sp .6
|
|
||||||
.RS 4n
|
|
||||||
Test adding a large \fBNULL\fR record for a service registered with Multicast
|
|
||||||
\fBDNS\fR.
|
|
||||||
.RE
|
|
||||||
|
|
||||||
.sp
|
|
||||||
.ne 2
|
|
||||||
.na
|
|
||||||
\fB\fB-T\fR\fR
|
|
||||||
.ad
|
|
||||||
.sp .6
|
|
||||||
.RS 4n
|
|
||||||
Test adding a large \fBTXT\fR record for a service registered with Multicast
|
|
||||||
\fBDNS\fR.
|
|
||||||
.RE
|
|
||||||
|
|
||||||
.sp
|
|
||||||
.ne 2
|
|
||||||
.na
|
|
||||||
\fB\fB-M\fR\fR
|
|
||||||
.ad
|
|
||||||
.sp .6
|
|
||||||
.RS 4n
|
|
||||||
Test creating a registration with multiple \fBTXT\fR records.
|
|
||||||
.RE
|
|
||||||
|
|
||||||
.sp
|
|
||||||
.ne 2
|
|
||||||
.na
|
|
||||||
\fB\fB-I\fR\fR
|
|
||||||
.ad
|
|
||||||
.sp .6
|
|
||||||
.RS 4n
|
|
||||||
Test registering and then immediately updating a \fBTXT\fR record.
|
|
||||||
.RE
|
|
||||||
|
|
||||||
.SH EXAMPLES
|
|
||||||
.LP
|
|
||||||
\fBExample 1 \fRAdvertising a printing service
|
|
||||||
.sp
|
|
||||||
.LP
|
|
||||||
The following command advertises the existence of \fBLPR\fR printing service on
|
|
||||||
port 515 on this machine, so that it will be available to \fBDNS-SD\fR
|
|
||||||
compatible printing clients:
|
|
||||||
|
|
||||||
.sp
|
|
||||||
.in +2
|
|
||||||
.nf
|
|
||||||
dns-sd -R "My Test" _printer._tcp. . 515 pdl=application/postscript
|
|
||||||
.fi
|
|
||||||
.in -2
|
|
||||||
.sp
|
|
||||||
|
|
||||||
.sp
|
|
||||||
.LP
|
|
||||||
For this registration to be useful, the LPR service should be available on port
|
|
||||||
515. Advertising a service that does not exist is not very useful.
|
|
||||||
.LP
|
|
||||||
\fBExample 2 \fRAdvertising a web page
|
|
||||||
.sp
|
|
||||||
.LP
|
|
||||||
The following command advertises a web page being served by an \fBHTTP\fR
|
|
||||||
server on port 80 on this machine, so that it will appear on the Bonjour list
|
|
||||||
in Safari and other DNS-SD compatible Web clients:
|
|
||||||
|
|
||||||
.sp
|
|
||||||
.in +2
|
|
||||||
.nf
|
|
||||||
dns-sd -R "My Test" _http._tcp . 80 path=/path-to-page.html
|
|
||||||
.fi
|
|
||||||
.in -2
|
|
||||||
.sp
|
|
||||||
|
|
||||||
.LP
|
|
||||||
\fBExample 3 \fRFinding the advertised web pages on the local network
|
|
||||||
.sp
|
|
||||||
.LP
|
|
||||||
The following command finds the advertised web pages on the local network (the
|
|
||||||
same list that Safari shows):
|
|
||||||
|
|
||||||
.sp
|
|
||||||
.in +2
|
|
||||||
.nf
|
|
||||||
dns-sd -B _http._tcp
|
|
||||||
.fi
|
|
||||||
.in -2
|
|
||||||
.sp
|
|
||||||
|
|
||||||
.SH ATTRIBUTES
|
|
||||||
.sp
|
|
||||||
.LP
|
|
||||||
See \fBattributes\fR(5) for descriptions of the following attributes:
|
|
||||||
.sp
|
|
||||||
|
|
||||||
.sp
|
|
||||||
.TS
|
|
||||||
box;
|
|
||||||
c | c
|
|
||||||
l | l .
|
|
||||||
ATTRIBUTE TYPE ATTRIBUTE VALUE
|
|
||||||
_
|
|
||||||
Interface Stability Volatile
|
|
||||||
.TE
|
|
||||||
|
|
||||||
.SH SEE ALSO
|
|
||||||
.sp
|
|
||||||
.LP
|
|
||||||
\fBmdnsd\fR(1M), \fBping\fR(1M), \fBtraceroute\fR(1M), \fBresolv.conf\fR(4),
|
|
||||||
\fBattributes\fR(5)
|
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
.\" -*- tab-width: 4 -*-
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 2003-2004 Apple Computer, Inc. All Rights Reserved.
|
||||||
|
.\"
|
||||||
|
.\" Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
.\" you may not use this file except in compliance with the License.
|
||||||
|
.\" You may obtain a copy of the License at
|
||||||
|
.\"
|
||||||
|
.\" http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
.\"
|
||||||
|
.\" Unless required by applicable law or agreed to in writing, software
|
||||||
|
.\" distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
.\" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
.\" See the License for the specific language governing permissions and
|
||||||
|
.\" limitations under the License.
|
||||||
|
.\"
|
||||||
|
.\" Copyright 2016 Toomas Soome <tsoome@me.com>
|
||||||
|
.\"
|
||||||
|
.Dd Jan 28, 2016 \" Date
|
||||||
|
.Dt MDNSD 1M \" Document Title
|
||||||
|
.Os illumos \" Operating System
|
||||||
|
.\"
|
||||||
|
.Sh NAME
|
||||||
|
.Nm mdnsd
|
||||||
|
.Nd Multicast and Unicast DNS daemon \" Name Description for whatis database
|
||||||
|
.\"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.\"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
.Nm
|
||||||
|
(also known as
|
||||||
|
.Nm mDNSResponder
|
||||||
|
on some systems)
|
||||||
|
is a daemon invoked at boot time to implement Multicast DNS and DNS Service Discovery.
|
||||||
|
.Pp
|
||||||
|
.Nm
|
||||||
|
listens on UDP port 5353 for Multicast DNS Query packets.
|
||||||
|
When it receives a query for which it knows an answer,
|
||||||
|
.Nm
|
||||||
|
issues the appropriate Multicast DNS Reply packet.
|
||||||
|
.Pp
|
||||||
|
.Nm
|
||||||
|
also performs Unicast and Multicast DNS Queries on behalf of client processes, and
|
||||||
|
maintains a cache of the replies.
|
||||||
|
.Pp
|
||||||
|
.Nm
|
||||||
|
has no user-specifiable command-line argument, and users should not run
|
||||||
|
.Nm
|
||||||
|
manually.
|
||||||
|
.Sh LOGGING
|
||||||
|
There are several methods with which to examine
|
||||||
|
.Nm Ns 's internal state for debugging and diagnostic purposes. The syslog(3C)
|
||||||
|
logging levels map as follows:
|
||||||
|
.Pp
|
||||||
|
.Dl Error - Error messages
|
||||||
|
.Dl Warning - Client-initiated operations
|
||||||
|
.Dl Notice - Sleep proxy operations
|
||||||
|
.Dl Info - Informational messages
|
||||||
|
.Pp
|
||||||
|
By default, only log level Error is logged.
|
||||||
|
.Pp
|
||||||
|
A SIGUSR1 signal toggles additional logging, with Warning and Notice
|
||||||
|
enabled by default:
|
||||||
|
.Pp
|
||||||
|
.Dl % sudo pkill -USR1 mdnsd
|
||||||
|
.Pp
|
||||||
|
A SIGUSR2 signal toggles packet logging:
|
||||||
|
.Pp
|
||||||
|
.Dl % sudo pkill -USR2 mdnsd
|
||||||
|
.Pp
|
||||||
|
A SIGINFO signal will dump a snapshot summary of the internal state:
|
||||||
|
.Pp
|
||||||
|
.Dl % sudo pkill -INFO mdnsd
|
||||||
|
.Sh FILES
|
||||||
|
.Pa /usr/lib/inet/mdnsd \" Pathname
|
||||||
|
.\"
|
||||||
|
.Sh INFO
|
||||||
|
For information on Multicast DNS, see
|
||||||
|
.Pa http://www.multicastdns.org/
|
||||||
|
.Pp
|
||||||
|
For information on DNS Service Discovery, see
|
||||||
|
.Pa http://www.dns-sd.org/
|
||||||
|
.Pp
|
||||||
|
For information on how to use the Multicast DNS and the
|
||||||
|
DNS Service Discovery APIs on Mac OS X and other platforms, see
|
||||||
|
.Pa http://developer.apple.com/bonjour/
|
||||||
|
.Pp
|
||||||
|
For the source code to
|
||||||
|
.Nm , see
|
||||||
|
.Pa http://developer.apple.com/darwin/projects/bonjour/
|
||||||
|
.\"
|
||||||
|
.Sh INTERFACE STABILITY
|
||||||
|
.Sy Volatile .
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr dns-sd 1M
|
||||||
|
.\"
|
||||||
|
.Sh NOTES
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
service is managed by the service management facility,
|
||||||
|
\fBsmf\fR(5), under the service identifier:
|
||||||
|
.sp
|
||||||
|
.Dl svc:/network/dns/multicast:default
|
||||||
|
.sp
|
||||||
|
Administrative actions on this service, such as enabling, disabling, or
|
||||||
|
requesting restart, can be performed using \fBsvcadm\fR(1M). The service's
|
||||||
|
status can be queried using the \fBsvcs\fR(1) command.
|
|
@ -22,6 +22,7 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
# Copyright 2012 Nexenta Systems, Inc. All rights reserved.
|
# Copyright 2012 Nexenta Systems, Inc. All rights reserved.
|
||||||
|
# Copyright 2016 Toomas Soome <tsoome@me.com>
|
||||||
#
|
#
|
||||||
|
|
||||||
set name=pkg.fmri value=pkg:/service/network/dns/mdns@$(PKGVERS)
|
set name=pkg.fmri value=pkg:/service/network/dns/mdns@$(PKGVERS)
|
||||||
|
@ -145,6 +146,7 @@ file path=usr/share/lib/java/javadoc/dnssd/api/stylesheet.css group=other
|
||||||
file path=usr/share/lib/java/javadoc/dnssd/examples/BrowserApp.jar group=sys
|
file path=usr/share/lib/java/javadoc/dnssd/examples/BrowserApp.jar group=sys
|
||||||
file path=usr/share/lib/java/javadoc/dnssd/examples/SimpleChat.jar group=sys
|
file path=usr/share/lib/java/javadoc/dnssd/examples/SimpleChat.jar group=sys
|
||||||
file path=usr/share/man/man1m/dns-sd.1m
|
file path=usr/share/man/man1m/dns-sd.1m
|
||||||
|
file path=usr/share/man/man1m/mdnsd.1m
|
||||||
file path=usr/share/man/man3dns_sd/DNSServiceBrowse.3dns_sd
|
file path=usr/share/man/man3dns_sd/DNSServiceBrowse.3dns_sd
|
||||||
file path=usr/share/man/man3dns_sd/DNSServiceConstructFullName.3dns_sd
|
file path=usr/share/man/man3dns_sd/DNSServiceConstructFullName.3dns_sd
|
||||||
file path=usr/share/man/man3dns_sd/DNSServiceCreateConnection.3dns_sd
|
file path=usr/share/man/man3dns_sd/DNSServiceCreateConnection.3dns_sd
|
||||||
|
|
Loading…
Reference in New Issue