import latest version
This commit is contained in:
parent
d3be8271c6
commit
ebf96090b3
|
@ -1,8 +1,8 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2008 Apple Inc. All rights reserved.
|
||||
* Copyright (c) 2008-2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 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,
|
||||
|
@ -16,7 +16,7 @@
|
|||
* 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 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
|
||||
|
@ -49,8 +49,9 @@ const char *GetNextLabel(const char *cstr, char label[64])
|
|||
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
|
||||
if (c == '\\') // If escape character, check next character
|
||||
{
|
||||
if (*cstr == '\0') break; // If this is the end of the string, then break
|
||||
c = *cstr++;
|
||||
if (isdigit(cstr[-1]) && isdigit(cstr[0]) && isdigit(cstr[1]))
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2012 Apple Inc. All rights reserved.
|
||||
* Copyright (c) 2012-2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* dnsctl.c
|
||||
* Command-line tool using libdns_services.dylib
|
||||
|
@ -17,38 +17,42 @@
|
|||
#include <sys/time.h>
|
||||
#include <net/if.h> // if_nametoindex()
|
||||
|
||||
#include <dispatch/dispatch.h>
|
||||
#include "dns_services.h"
|
||||
#include <xpc/xpc.h>
|
||||
#include "dns_xpc.h"
|
||||
|
||||
//*************************************************************************************************************
|
||||
// Globals:
|
||||
//*************************************************************************************************************
|
||||
|
||||
static const char kFilePathSep = '/';
|
||||
|
||||
static DNSXConnRef ClientRef = NULL;
|
||||
|
||||
static xpc_connection_t dnsctl_conn = NULL;
|
||||
|
||||
//*************************************************************************************************************
|
||||
// Utility Funcs:
|
||||
//*************************************************************************************************************
|
||||
|
||||
static void printtimestamp(void)
|
||||
static void printtimestamp(void)
|
||||
{
|
||||
struct tm tm;
|
||||
int ms;
|
||||
struct tm tm;
|
||||
int ms;
|
||||
static char date[16];
|
||||
static char new_date[16];
|
||||
struct timeval tv;
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
localtime_r((time_t*)&tv.tv_sec, &tm);
|
||||
ms = tv.tv_usec/1000;
|
||||
strftime(new_date, sizeof(new_date), "%a %d %b %Y", &tm);
|
||||
//display date only if it has changed
|
||||
if (strncmp(date, new_date, sizeof(new_date)))
|
||||
{
|
||||
{
|
||||
printf("DATE: ---%s---\n", new_date);
|
||||
strncpy(date, new_date, sizeof(date));
|
||||
}
|
||||
printf("%2d:%02d:%02d.%03d ", tm.tm_hour, tm.tm_min, tm.tm_sec, ms);
|
||||
strlcpy(date, new_date, sizeof(date));
|
||||
}
|
||||
printf("%2d:%02d:%02d.%03d ", tm.tm_hour, tm.tm_min, tm.tm_sec, ms);
|
||||
}
|
||||
|
||||
static void print_usage(const char *arg0)
|
||||
|
@ -56,12 +60,31 @@ static void print_usage(const char *arg0)
|
|||
fprintf(stderr, "%s USAGE: \n", arg0);
|
||||
fprintf(stderr, "%s -DP Enable DNS Proxy with Default Parameters \n", arg0);
|
||||
fprintf(stderr, "%s -DP [-o <output interface>] [-i <input interface(s)>] Enable DNS Proxy \n", arg0);
|
||||
fprintf(stderr, "%s -L [1/2/3/4] Change mDNSResponder Logging Level \n", arg0);
|
||||
fprintf(stderr, "%s -I Print mDNSResponder STATE INFO \n", arg0);
|
||||
}
|
||||
|
||||
|
||||
static bool DebugEnabled()
|
||||
{
|
||||
return true; // keep this true to debug the XPC msgs
|
||||
}
|
||||
|
||||
static void DebugLog(const char *prefix, xpc_object_t o)
|
||||
{
|
||||
if (!DebugEnabled())
|
||||
return;
|
||||
|
||||
char *desc = xpc_copy_description(o);
|
||||
printf("%s: %s \n", prefix, desc);
|
||||
free(desc);
|
||||
}
|
||||
|
||||
//*************************************************************************************************************
|
||||
// CallBack Funcs:
|
||||
//*************************************************************************************************************
|
||||
|
||||
|
||||
// DNSXEnableProxy Callback from the Daemon
|
||||
static void dnsproxy_reply(DNSXConnRef connRef, DNSXErrorType errCode)
|
||||
{
|
||||
|
@ -69,59 +92,108 @@ static void dnsproxy_reply(DNSXConnRef connRef, DNSXErrorType errCode)
|
|||
printtimestamp();
|
||||
switch (errCode)
|
||||
{
|
||||
case kDNSX_NoError : printf(" SUCCESS \n"); break;
|
||||
case kDNSX_DictError : printf(" DICT ERROR \n"); break;
|
||||
case kDNSX_NoError : printf(" SUCCESS \n");
|
||||
break;
|
||||
case kDNSX_DaemonNotRunning : printf(" NO DAEMON \n");
|
||||
DNSXRefDeAlloc(ClientRef); break;
|
||||
case kDNSX_Engaged : printf(" ENGAGED \n");
|
||||
DNSXRefDeAlloc(ClientRef); break;
|
||||
DNSXRefDeAlloc(ClientRef); break;
|
||||
case kDNSX_BadParam : printf(" BAD PARAMETER \n");
|
||||
DNSXRefDeAlloc(ClientRef); break;
|
||||
case kDNSX_Busy : printf(" BUSY \n");
|
||||
DNSXRefDeAlloc(ClientRef); break;
|
||||
case kDNSX_UnknownErr :
|
||||
default : printf("UNKNOWN ERR \n");
|
||||
DNSXRefDeAlloc(ClientRef); break;
|
||||
default : printf(" UNKNOWN ERR \n");
|
||||
DNSXRefDeAlloc(ClientRef); break;
|
||||
}
|
||||
fflush(NULL);
|
||||
|
||||
}
|
||||
|
||||
//*************************************************************************************************************
|
||||
// XPC Funcs:
|
||||
//*************************************************************************************************************
|
||||
|
||||
static void Init_Connection(const char *servname)
|
||||
{
|
||||
dnsctl_conn = xpc_connection_create_mach_service(servname, dispatch_get_main_queue(), XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
|
||||
|
||||
xpc_connection_set_event_handler(dnsctl_conn, ^(xpc_object_t event)
|
||||
{
|
||||
printf("InitConnection: [%s] \n", xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION));
|
||||
});
|
||||
|
||||
xpc_connection_resume(dnsctl_conn);
|
||||
}
|
||||
|
||||
static void SendDictToServer(xpc_object_t msg)
|
||||
{
|
||||
|
||||
DebugLog("SendDictToServer Sending msg to Daemon", msg);
|
||||
|
||||
xpc_connection_send_message_with_reply(dnsctl_conn, msg, dispatch_get_main_queue(), ^(xpc_object_t recv_msg)
|
||||
{
|
||||
xpc_type_t type = xpc_get_type(recv_msg);
|
||||
|
||||
if (type == XPC_TYPE_DICTIONARY)
|
||||
{
|
||||
DebugLog("SendDictToServer Received reply msg from Daemon", recv_msg);
|
||||
/*
|
||||
// If we ever want to do something based on the reply of the daemon
|
||||
switch (daemon_status)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
}
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("SendDictToServer Received unexpected reply from daemon [%s]",
|
||||
xpc_dictionary_get_string(recv_msg, XPC_ERROR_KEY_DESCRIPTION));
|
||||
DebugLog("SendDictToServer Unexpected Reply contents", recv_msg);
|
||||
}
|
||||
exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
//*************************************************************************************************************
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
DNSXErrorType err;
|
||||
|
||||
// Default i/p intf is lo0 and o/p intf is primary interface
|
||||
IfIndex Ipintfs[MaxInputIf] = {1, 0, 0, 0, 0};
|
||||
IfIndex Opintf = kDNSIfindexAny;
|
||||
|
||||
// Extract program name from argv[0], which by convention contains the path to this executable
|
||||
const char *a0 = strrchr(argv[0], kFilePathSep) + 1;
|
||||
const char *a0 = strrchr(argv[0], kFilePathSep) + 1;
|
||||
if (a0 == (const char *)1)
|
||||
a0 = argv[0];
|
||||
|
||||
|
||||
// Must run as root
|
||||
if (0 != geteuid())
|
||||
{
|
||||
fprintf(stderr, "%s MUST run as root!!\n", a0);
|
||||
exit(-1);
|
||||
if (0 != geteuid())
|
||||
{
|
||||
fprintf(stderr, "%s MUST run as root!!\n", a0);
|
||||
exit(-1);
|
||||
}
|
||||
if ((sizeof(argv) == 8))
|
||||
printf("dnsctl running in 64-bit mode\n");
|
||||
else if ((sizeof(argv) == 4))
|
||||
printf("dnsctl running in 32-bit mode\n");
|
||||
|
||||
|
||||
// expects atleast one argument
|
||||
if (argc < 2)
|
||||
goto Usage;
|
||||
|
||||
if ( !strcmp(argv[1], "-DP") || !strcmp(argv[1], "-dp") )
|
||||
|
||||
printtimestamp();
|
||||
if (!strcasecmp(argv[1], "-DP"))
|
||||
{
|
||||
DNSXErrorType err;
|
||||
// Default i/p intf is lo0 and o/p intf is primary interface
|
||||
IfIndex Ipintfs[MaxInputIf] = {1, 0, 0, 0, 0};
|
||||
IfIndex Opintf = kDNSIfindexAny;
|
||||
|
||||
if (argc == 2)
|
||||
{
|
||||
printtimestamp();
|
||||
printf("Proceeding to Enable DNSProxy on mDNSResponder with Default Parameters\n");
|
||||
dispatch_queue_t my_Q = dispatch_queue_create("com.apple.dnsctl.callback_queue", NULL);
|
||||
err = DNSXEnableProxy(&ClientRef, kDNSProxyEnable, Ipintfs, Opintf, my_Q, dnsproxy_reply);
|
||||
}
|
||||
if (err)
|
||||
fprintf(stderr, "DNSXEnableProxy returned %d\n", err);
|
||||
}
|
||||
else if (argc > 2)
|
||||
{
|
||||
argc--;
|
||||
|
@ -129,17 +201,17 @@ int main(int argc, char **argv)
|
|||
if (!strcmp(argv[1], "-o"))
|
||||
{
|
||||
Opintf = if_nametoindex(argv[2]);
|
||||
if (!Opintf)
|
||||
if (!Opintf)
|
||||
Opintf = atoi(argv[2]);
|
||||
if (!Opintf)
|
||||
{
|
||||
fprintf(stderr, "Could not parse o/p interface [%s]: Passing default primary \n", argv[2]);
|
||||
if (!Opintf)
|
||||
{
|
||||
fprintf(stderr, "Could not parse o/p interface [%s]: Passing default primary \n", argv[2]);
|
||||
Opintf = kDNSIfindexAny;
|
||||
}
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
}
|
||||
if (argc > 2 && !strcmp(argv[1], "-i"))
|
||||
if (argc > 2 && !strcmp(argv[1], "-i"))
|
||||
{
|
||||
int i;
|
||||
argc--;
|
||||
|
@ -148,31 +220,164 @@ int main(int argc, char **argv)
|
|||
{
|
||||
Ipintfs[i] = if_nametoindex(argv[1]);
|
||||
if (!Ipintfs[i])
|
||||
Ipintfs[i] = atoi(argv[1]);
|
||||
Ipintfs[i] = atoi(argv[1]);
|
||||
if (!Ipintfs[i])
|
||||
{
|
||||
fprintf(stderr, "Could not parse i/p interface [%s]: Passing default lo0 \n", argv[2]);
|
||||
fprintf(stderr, "Could not parse i/p interface [%s]: Passing default lo0 \n", argv[2]);
|
||||
Ipintfs[i] = 1;
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
}
|
||||
printtimestamp();
|
||||
printf("Proceeding to Enable DNSProxy on mDNSResponder \n");
|
||||
}
|
||||
printf("Enabling DNSProxy on mDNSResponder \n");
|
||||
dispatch_queue_t my_Q = dispatch_queue_create("com.apple.dnsctl.callback_queue", NULL);
|
||||
err = DNSXEnableProxy(&ClientRef, kDNSProxyEnable, Ipintfs, Opintf, my_Q, dnsproxy_reply);
|
||||
err = DNSXEnableProxy(&ClientRef, kDNSProxyEnable, Ipintfs, Opintf, my_Q, dnsproxy_reply);
|
||||
if (err)
|
||||
fprintf(stderr, "DNSXEnableProxy returned %d\n", err);
|
||||
}
|
||||
}
|
||||
else if (!strcasecmp(argv[1], "-l"))
|
||||
{
|
||||
printf("Changing loglevel of mDNSResponder \n");
|
||||
Init_Connection(kDNSCTLService);
|
||||
|
||||
// Create Dictionary To Send
|
||||
xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
|
||||
|
||||
if (argc == 2)
|
||||
{
|
||||
xpc_dictionary_set_uint64(dict, kDNSLogLevel, log_level1);
|
||||
|
||||
SendDictToServer(dict);
|
||||
xpc_release(dict);
|
||||
dict = NULL;
|
||||
}
|
||||
else if (argc > 2)
|
||||
{
|
||||
argc--;
|
||||
argv++;
|
||||
switch (atoi(argv[1]))
|
||||
{
|
||||
case log_level1:
|
||||
xpc_dictionary_set_uint64(dict, kDNSLogLevel, log_level1);
|
||||
break;
|
||||
|
||||
case log_level2:
|
||||
xpc_dictionary_set_uint64(dict, kDNSLogLevel, log_level2);
|
||||
break;
|
||||
|
||||
case log_level3:
|
||||
xpc_dictionary_set_uint64(dict, kDNSLogLevel, log_level3);
|
||||
break;
|
||||
|
||||
case log_level4:
|
||||
xpc_dictionary_set_uint64(dict, kDNSLogLevel, log_level4);
|
||||
break;
|
||||
|
||||
default:
|
||||
xpc_dictionary_set_uint64(dict, kDNSLogLevel, log_level1);
|
||||
break;
|
||||
}
|
||||
SendDictToServer(dict);
|
||||
xpc_release(dict);
|
||||
dict = NULL;
|
||||
}
|
||||
}
|
||||
else if(!strcasecmp(argv[1], "-i"))
|
||||
{
|
||||
printf("Get STATE INFO of mDNSResponder \n");
|
||||
Init_Connection(kDNSCTLService);
|
||||
|
||||
// Create Dictionary To Send
|
||||
xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
|
||||
xpc_dictionary_set_uint64(dict, kDNSStateInfo, full_state);
|
||||
SendDictToServer(dict);
|
||||
xpc_release(dict);
|
||||
dict = NULL;
|
||||
}
|
||||
else if(!strcasecmp(argv[1], "-th"))
|
||||
{
|
||||
printf("Sending Test message to mDNSResponder to forward to mDNSResponderHelper\n");
|
||||
Init_Connection(kDNSCTLService);
|
||||
|
||||
// Create Dictionary To Send
|
||||
xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
|
||||
xpc_dictionary_set_uint64(dict, kmDNSResponderTests, test_helper_ipc);
|
||||
SendDictToServer(dict);
|
||||
xpc_release(dict);
|
||||
dict = NULL;
|
||||
}
|
||||
else if(!strcasecmp(argv[1], "-tl"))
|
||||
{
|
||||
printf("Testing mDNSResponder Logging\n");
|
||||
Init_Connection(kDNSCTLService);
|
||||
|
||||
// Create Dictionary To Send
|
||||
xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
|
||||
xpc_dictionary_set_uint64(dict, kmDNSResponderTests, test_mDNS_log);
|
||||
SendDictToServer(dict);
|
||||
xpc_release(dict);
|
||||
dict = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto Usage;
|
||||
}
|
||||
|
||||
dispatch_main();
|
||||
|
||||
|
||||
dispatch_main();
|
||||
|
||||
Usage:
|
||||
print_usage(a0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
static int operation;
|
||||
|
||||
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.
|
||||
int o = getopt(argc, (char *const *)argv, optstr);
|
||||
*pOptInd = optind;
|
||||
return o;
|
||||
}
|
||||
|
||||
int opindex;
|
||||
operation = getfirstoption(argc, argv, "lLDdPp", &opindex);
|
||||
if (operation == -1)
|
||||
goto Usage;
|
||||
|
||||
|
||||
|
||||
switch (operation)
|
||||
{
|
||||
case 'L':
|
||||
case 'l':
|
||||
{
|
||||
printtimestamp();
|
||||
printf("Change Verbosity Level of mDNSResponder\n");
|
||||
|
||||
Init_Connection(kDNSCTLService);
|
||||
|
||||
// Create Dictionary To Send
|
||||
xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0);
|
||||
if (dict == NULL)
|
||||
printf("could not create the Msg Dict To Send! \n");
|
||||
xpc_dictionary_set_uint64(dict, kDNSLogLevel, log_level2);
|
||||
|
||||
SendDictToServer(dict);
|
||||
|
||||
xpc_release(dict);
|
||||
dict = NULL;
|
||||
break;
|
||||
}
|
||||
// exit(1);
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2011-2012 Apple 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.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2011-2012 Apple 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.
|
||||
|
@ -14,6 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CRYPTO_ALG_H
|
||||
#define __CRYPTO_ALG_H
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2002-2013 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2002-2015 Apple 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.
|
||||
|
@ -21,6 +21,10 @@
|
|||
#include "CryptoAlg.h"
|
||||
#include "anonymous.h"
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
#include "unittest.h"
|
||||
#endif
|
||||
|
||||
// Disable certain benign warnings with Microsoft compilers
|
||||
#if (defined(_MSC_VER))
|
||||
// Disable "conditional expression is constant" warning for debug macros.
|
||||
|
@ -43,6 +47,7 @@ mDNSexport const mDNSInterfaceID mDNSInterface_LocalOnly = (mDNSInterfaceID)-2;
|
|||
mDNSexport const mDNSInterfaceID mDNSInterface_Unicast = (mDNSInterfaceID)-3;
|
||||
mDNSexport const mDNSInterfaceID mDNSInterface_P2P = (mDNSInterfaceID)-4;
|
||||
mDNSexport const mDNSInterfaceID uDNSInterfaceMark = (mDNSInterfaceID)-5;
|
||||
mDNSexport const mDNSInterfaceID mDNSInterface_BLE = (mDNSInterfaceID)-6;
|
||||
|
||||
// Note: Microsoft's proposed "Link Local Multicast Name Resolution Protocol" (LLMNR) is essentially a limited version of
|
||||
// Multicast DNS, using the same packet formats, naming syntax, and record types as Multicast DNS, but on a different UDP
|
||||
|
@ -107,8 +112,11 @@ mDNSexport const mDNSOpaque16 DNSSecQFlags = { { kDNSFlag0_QR_Query | kDNS
|
|||
mDNSexport const mDNSOpaque16 ResponseFlags = { { kDNSFlag0_QR_Response | kDNSFlag0_OP_StdQuery | kDNSFlag0_AA, 0 } };
|
||||
mDNSexport const mDNSOpaque16 UpdateReqFlags = { { kDNSFlag0_QR_Query | kDNSFlag0_OP_Update, 0 } };
|
||||
mDNSexport const mDNSOpaque16 UpdateRespFlags = { { kDNSFlag0_QR_Response | kDNSFlag0_OP_Update, 0 } };
|
||||
mDNSexport const mDNSOpaque16 SubscribeFlags = { { kDNSFlag0_QR_Query | kDNSFlag0_OP_Subscribe, 0 } };
|
||||
mDNSexport const mDNSOpaque16 UnSubscribeFlags= { { kDNSFlag0_QR_Query | kDNSFlag0_OP_UnSubscribe, 0 } };
|
||||
|
||||
mDNSexport const mDNSOpaque64 zeroOpaque64 = { { 0 } };
|
||||
mDNSexport const mDNSOpaque64 zeroOpaque64 = { { 0 } };
|
||||
mDNSexport const mDNSOpaque128 zeroOpaque128 = { { 0 } };
|
||||
|
||||
// ***************************************************************************
|
||||
#if COMPILER_LIKES_PRAGMA_MARK
|
||||
|
@ -510,10 +518,10 @@ mDNSexport char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RD
|
|||
|
||||
length += mDNS_snprintf(buffer+length, RemSpc, "\t%s %s %d %d %s %s %d %##s ",
|
||||
DNSTypeName(swap16(rrsig->typeCovered)), DNSSECAlgName(rrsig->alg), rrsig->labels, swap32(rrsig->origTTL),
|
||||
expTimeBuf, inceptTimeBuf, swap16(rrsig->keyTag), ((domainname *)(&rrsig->signerName))->c);
|
||||
expTimeBuf, inceptTimeBuf, swap16(rrsig->keyTag), rrsig->signerName);
|
||||
|
||||
len = DomainNameLength((domainname *)&rrsig->signerName);
|
||||
length += baseEncode(buffer + length, RemSpc, (const mDNSu8 *)(rd->data + len + RRSIG_FIXED_SIZE),
|
||||
baseEncode(buffer + length, RemSpc, (const mDNSu8 *)(rd->data + len + RRSIG_FIXED_SIZE),
|
||||
rr->rdlength - (len + RRSIG_FIXED_SIZE), ENC_BASE64);
|
||||
}
|
||||
break;
|
||||
|
@ -521,7 +529,7 @@ mDNSexport char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RD
|
|||
rdataDNSKey *rrkey = (rdataDNSKey *)rd->data;
|
||||
length += mDNS_snprintf(buffer+length, RemSpc, "\t%d %d %s %u ", swap16(rrkey->flags), rrkey->proto,
|
||||
DNSSECAlgName(rrkey->alg), (unsigned int)keytag((mDNSu8 *)rrkey, rr->rdlength));
|
||||
length += baseEncode(buffer + length, RemSpc, (const mDNSu8 *)(rd->data + DNSKEY_FIXED_SIZE),
|
||||
baseEncode(buffer + length, RemSpc, (const mDNSu8 *)(rd->data + DNSKEY_FIXED_SIZE),
|
||||
rr->rdlength - DNSKEY_FIXED_SIZE, ENC_BASE64);
|
||||
}
|
||||
break;
|
||||
|
@ -541,7 +549,7 @@ mDNSexport char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RD
|
|||
}
|
||||
break;
|
||||
|
||||
default: mDNS_snprintf(buffer+length, RemSpc, "RDLen %d: %s", rr->rdlength, rd->data);
|
||||
default: mDNS_snprintf(buffer+length, RemSpc, "RDLen %d: %.*s", rr->rdlength, rr->rdlength, rd->data);
|
||||
// Really should scan buffer to check if text is valid UTF-8 and only replace with dots if not
|
||||
for (ptr = buffer; *ptr; ptr++) if (*ptr < ' ') *ptr = '.';
|
||||
break;
|
||||
|
@ -619,6 +627,8 @@ mDNSexport mDNSBool mDNSAddrIsDNSMulticast(const mDNSAddr *ip)
|
|||
#pragma mark - Domain Name Utility Functions
|
||||
#endif
|
||||
|
||||
#if !APPLE_OSX_mDNSResponder
|
||||
|
||||
mDNSexport mDNSBool SameDomainLabel(const mDNSu8 *a, const mDNSu8 *b)
|
||||
{
|
||||
int i;
|
||||
|
@ -639,6 +649,8 @@ mDNSexport mDNSBool SameDomainLabel(const mDNSu8 *a, const mDNSu8 *b)
|
|||
return(mDNStrue);
|
||||
}
|
||||
|
||||
#endif // !APPLE_OSX_mDNSResponder
|
||||
|
||||
mDNSexport mDNSBool SameDomainName(const domainname *const d1, const domainname *const d2)
|
||||
{
|
||||
const mDNSu8 * a = d1->c;
|
||||
|
@ -803,6 +815,7 @@ mDNSexport mDNSu8 *AppendDNSNameString(domainname *const name, const char *cstri
|
|||
mDNSu8 c = (mDNSu8)*cstr++; // Read the character
|
||||
if (c == '\\') // If escape character, check next character
|
||||
{
|
||||
if (*cstr == '\0') break; // If this is the end of the string, then break
|
||||
c = (mDNSu8)*cstr++; // Assume we'll just take the next character
|
||||
if (mDNSIsDigit(cstr[-1]) && mDNSIsDigit(cstr[0]) && mDNSIsDigit(cstr[1]))
|
||||
{ // If three decimal digits,
|
||||
|
@ -815,7 +828,7 @@ mDNSexport mDNSu8 *AppendDNSNameString(domainname *const name, const char *cstri
|
|||
}
|
||||
*ptr++ = c; // Write the character
|
||||
}
|
||||
if (*cstr) cstr++; // Skip over the trailing dot (if present)
|
||||
if (*cstr == '.') cstr++; // Skip over the trailing dot (if present)
|
||||
if (ptr - lengthbyte - 1 > MAX_DOMAIN_LABEL) // If illegal label, abort
|
||||
return(mDNSNULL);
|
||||
*lengthbyte = (mDNSu8)(ptr - lengthbyte - 1); // Fill in the length byte
|
||||
|
@ -967,10 +980,6 @@ mDNSexport void ConvertUTF8PstringToRFC1034HostLabel(const mDNSu8 UTF8Name[], do
|
|||
hostlabel->c[0] = (mDNSu8)(ptr - &hostlabel->c[1]);
|
||||
}
|
||||
|
||||
#define ValidTransportProtocol(X) ( (X)[0] == 4 && (X)[1] == '_' && \
|
||||
((((X)[2] | 0x20) == 'u' && ((X)[3] | 0x20) == 'd') || (((X)[2] | 0x20) == 't' && ((X)[3] | 0x20) == 'c')) && \
|
||||
((X)[4] | 0x20) == 'p')
|
||||
|
||||
mDNSexport mDNSu8 *ConstructServiceName(domainname *const fqdn,
|
||||
const domainlabel *name, const domainname *type, const domainname *const domain)
|
||||
{
|
||||
|
@ -1029,10 +1038,6 @@ mDNSexport mDNSu8 *ConstructServiceName(domainname *const fqdn,
|
|||
{
|
||||
LogMsg("Bad service type in %#s.%##s%##s Application protocol name must be underscore plus 1-15 characters. "
|
||||
"See <http://www.dns-sd.org/ServiceTypes.html>", name->c, type->c, domain->c);
|
||||
#if APPLE_OSX_mDNSResponder
|
||||
ConvertDomainNameToCString(type, typeBuf);
|
||||
mDNSASLLog(mDNSNULL, "serviceType.nameTooLong", "noop", typeBuf, "");
|
||||
#endif
|
||||
}
|
||||
if (len < 2 || len >= 0x40 || (len > 16 && !SameDomainName(domain, &localdomain))) return(mDNSNULL);
|
||||
if (src[1] != '_') { errormsg = "Application protocol name must begin with underscore"; goto fail; }
|
||||
|
@ -1049,19 +1054,13 @@ mDNSexport mDNSu8 *ConstructServiceName(domainname *const fqdn,
|
|||
if (src[i] == '_' && loggedUnderscore == mDNSfalse)
|
||||
{
|
||||
ConvertDomainNameToCString(type, typeBuf);
|
||||
mDNSASLLog(mDNSNULL, "serviceType.nameWithUnderscore", "noop", typeBuf, "");
|
||||
LogInfo("ConstructServiceName: Service type with non-leading underscore %s", typeBuf);
|
||||
loggedUnderscore = mDNStrue;
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
errormsg = "Application protocol name must contain only letters, digits, and hyphens";
|
||||
#if APPLE_OSX_mDNSResponder
|
||||
{
|
||||
ConvertDomainNameToCString(type, typeBuf);
|
||||
mDNSASLLog(mDNSNULL, "serviceType.nameWithIllegalCharacters", "noop", typeBuf, "");
|
||||
}
|
||||
#endif
|
||||
goto fail;
|
||||
}
|
||||
for (i=0; i<=len; i++) *dst++ = *src++;
|
||||
|
@ -1165,7 +1164,8 @@ mDNSexport const mDNSu8 *NSEC3HashName(const domainname *name, rdataNSEC3 *nsec3
|
|||
const mDNSu8 hash[NSEC3_MAX_HASH_LEN], int *dlen)
|
||||
{
|
||||
AlgContext *ctx;
|
||||
int i;
|
||||
unsigned int i;
|
||||
unsigned int iterations;
|
||||
domainname lname;
|
||||
mDNSu8 *p = (mDNSu8 *)&nsec3->salt;
|
||||
const mDNSu8 *digest;
|
||||
|
@ -1183,7 +1183,8 @@ mDNSexport const mDNSu8 *NSEC3HashName(const domainname *name, rdataNSEC3 *nsec3
|
|||
|
||||
// Note that it is "i <=". The first iteration is for digesting the name and salt.
|
||||
// The iteration count does not include that.
|
||||
for (i = 0; i <= swap16(nsec3->iterations); i++)
|
||||
iterations = swap16(nsec3->iterations);
|
||||
for (i = 0; i <= iterations; i++)
|
||||
{
|
||||
ctx = AlgCreate(DIGEST_ALG, nsec3->alg);
|
||||
if (!ctx)
|
||||
|
@ -1367,17 +1368,14 @@ mDNSexport void mDNS_SetupResourceRecord(AuthRecord *rr, RData *RDataStorage, mD
|
|||
if (InterfaceID == mDNSInterface_LocalOnly && artype != AuthRecordLocalOnly)
|
||||
{
|
||||
LogMsg("mDNS_SetupResourceRecord: ERROR!! Mismatch LocalOnly record InterfaceID %p called with artype %d", InterfaceID, artype);
|
||||
return;
|
||||
}
|
||||
else if (InterfaceID == mDNSInterface_P2P && artype != AuthRecordP2P)
|
||||
{
|
||||
LogMsg("mDNS_SetupResourceRecord: ERROR!! Mismatch P2P record InterfaceID %p called with artype %d", InterfaceID, artype);
|
||||
return;
|
||||
}
|
||||
else if (!InterfaceID && (artype == AuthRecordP2P || artype == AuthRecordLocalOnly))
|
||||
{
|
||||
LogMsg("mDNS_SetupResourceRecord: ERROR!! Mismatch InterfaceAny record InterfaceID %p called with artype %d", InterfaceID, artype);
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't try to store a TTL bigger than we can represent in platform time units
|
||||
|
@ -1467,8 +1465,6 @@ mDNSexport void mDNS_SetupQuestion(DNSQuestion *const q, const mDNSInterfaceID I
|
|||
q->ForceMCast = mDNSfalse;
|
||||
q->ReturnIntermed = mDNSfalse;
|
||||
q->SuppressUnusable = mDNSfalse;
|
||||
q->DenyOnCellInterface = mDNSfalse;
|
||||
q->DenyOnExpInterface = mDNSfalse;
|
||||
q->SearchListIndex = 0;
|
||||
q->AppendSearchDomains = 0;
|
||||
q->RetryWithSearchDomains = mDNSfalse;
|
||||
|
@ -1481,6 +1477,7 @@ mDNSexport void mDNS_SetupQuestion(DNSQuestion *const q, const mDNSInterfaceID I
|
|||
q->qnameOrig = mDNSNULL;
|
||||
q->AnonInfo = mDNSNULL;
|
||||
q->pid = mDNSPlatformGetPID();
|
||||
q->euid = 0;
|
||||
q->DisallowPID = mDNSfalse;
|
||||
q->ServiceID = -1;
|
||||
q->QuestionCallback = callback;
|
||||
|
@ -1778,7 +1775,7 @@ mDNSexport mDNSBool SameNameRecordAnswersQuestion(const ResourceRecord *const rr
|
|||
|
||||
// LocalOnly/P2P questions can be answered with AuthRecordAny in this function. LocalOnly/P2P records
|
||||
// are handled in LocalOnlyRecordAnswersQuestion
|
||||
if ((rr->InterfaceID == mDNSInterface_LocalOnly) || (rr->InterfaceID == mDNSInterface_P2P))
|
||||
if (LocalOnlyOrP2PInterface(rr->InterfaceID))
|
||||
{
|
||||
LogMsg("SameNameRecordAnswersQuestion: ERROR!! called with LocalOnly ResourceRecord %p, Question %p", rr->InterfaceID, q->InterfaceID);
|
||||
return mDNSfalse;
|
||||
|
@ -1913,7 +1910,7 @@ mDNSexport mDNSBool AnyTypeRecordAnswersQuestion(const ResourceRecord *const rr,
|
|||
{
|
||||
// LocalOnly/P2P questions can be answered with AuthRecordAny in this function. LocalOnly/P2P records
|
||||
// are handled in LocalOnlyRecordAnswersQuestion
|
||||
if ((rr->InterfaceID == mDNSInterface_LocalOnly) || (rr->InterfaceID == mDNSInterface_P2P))
|
||||
if (LocalOnlyOrP2PInterface(rr->InterfaceID))
|
||||
{
|
||||
LogMsg("AnyTypeRecordAnswersQuestion: ERROR!! called with LocalOnly ResourceRecord %p, Question %p", rr->InterfaceID, q->InterfaceID);
|
||||
return mDNSfalse;
|
||||
|
@ -2141,7 +2138,6 @@ mDNSexport const mDNSu8 *FindCompressionPointer(const mDNSu8 *const base, const
|
|||
return(mDNSNULL);
|
||||
}
|
||||
|
||||
// Put a string of dot-separated labels as length-prefixed labels
|
||||
// domainname is a fully-qualified name (i.e. assumed to be ending in a dot, even if it doesn't)
|
||||
// msg points to the message we're building (pass mDNSNULL if we don't want to use compression pointers)
|
||||
// end points to the end of the message so far
|
||||
|
@ -2357,13 +2353,9 @@ mDNSexport mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNS
|
|||
case kDNSType_NSEC: {
|
||||
// For NSEC records, rdlength represents the exact number of bytes
|
||||
// of in memory storage.
|
||||
int len = rr->rdlength;
|
||||
mDNSu8 *nsec = (mDNSu8 *)rdb->data;
|
||||
domainname *name = (domainname *)nsec;
|
||||
int dlen;
|
||||
|
||||
dlen = DomainNameLength(name);
|
||||
len -= dlen;
|
||||
const int dlen = DomainNameLength(name);
|
||||
nsec += dlen;
|
||||
// This function is called when we are sending a NSEC record as part of mDNS,
|
||||
// or to copy the data to any other buffer needed which could be a mDNS or uDNS
|
||||
|
@ -2376,7 +2368,6 @@ mDNSexport mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNS
|
|||
int i, j, wlen;
|
||||
wlen = *(nsec + 1);
|
||||
nsec += 2; // Skip the window number and len
|
||||
len -= 2;
|
||||
|
||||
// For our simplified use of NSEC synthetic records:
|
||||
//
|
||||
|
@ -2406,6 +2397,7 @@ mDNSexport mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNS
|
|||
else
|
||||
{
|
||||
int win, wlen;
|
||||
int len = rr->rdlength - dlen;
|
||||
|
||||
// Sanity check whether the bitmap is good
|
||||
while (len)
|
||||
|
@ -2607,7 +2599,7 @@ mDNSexport mDNSu8 *putDeleteAllRRSets(DNSMessage *msg, mDNSu8 *ptr, const domain
|
|||
}
|
||||
|
||||
// for dynamic updates
|
||||
mDNSexport mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease)
|
||||
mDNSexport mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *ptr, mDNSu32 lease)
|
||||
{
|
||||
AuthRecord rr;
|
||||
mDNS_SetupResourceRecord(&rr, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
|
||||
|
@ -2616,13 +2608,13 @@ mDNSexport mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease)
|
|||
rr.resrec.rdestimate = sizeof(rdataOPT);
|
||||
rr.resrec.rdata->u.opt[0].opt = kDNSOpt_Lease;
|
||||
rr.resrec.rdata->u.opt[0].u.updatelease = lease;
|
||||
end = PutResourceRecordTTLJumbo(msg, end, &msg->h.numAdditionals, &rr.resrec, 0);
|
||||
if (!end) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTL"); return mDNSNULL; }
|
||||
return end;
|
||||
ptr = PutResourceRecordTTLJumbo(msg, ptr, &msg->h.numAdditionals, &rr.resrec, 0);
|
||||
if (!ptr) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTL"); return mDNSNULL; }
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// for dynamic updates
|
||||
mDNSexport mDNSu8 *putUpdateLeaseWithLimit(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease, mDNSu8 *limit)
|
||||
mDNSexport mDNSu8 *putUpdateLeaseWithLimit(DNSMessage *msg, mDNSu8 *ptr, mDNSu32 lease, mDNSu8 *limit)
|
||||
{
|
||||
AuthRecord rr;
|
||||
mDNS_SetupResourceRecord(&rr, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
|
||||
|
@ -2631,9 +2623,9 @@ mDNSexport mDNSu8 *putUpdateLeaseWithLimit(DNSMessage *msg, mDNSu8 *end, mDNSu32
|
|||
rr.resrec.rdestimate = sizeof(rdataOPT);
|
||||
rr.resrec.rdata->u.opt[0].opt = kDNSOpt_Lease;
|
||||
rr.resrec.rdata->u.opt[0].u.updatelease = lease;
|
||||
end = PutResourceRecordTTLWithLimit(msg, end, &msg->h.numAdditionals, &rr.resrec, 0, limit);
|
||||
if (!end) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTLWithLimit"); return mDNSNULL; }
|
||||
return end;
|
||||
ptr = PutResourceRecordTTLWithLimit(msg, ptr, &msg->h.numAdditionals, &rr.resrec, 0, limit);
|
||||
if (!ptr) { LogMsg("ERROR: putUpdateLeaseWithLimit - PutResourceRecordTTLWithLimit"); return mDNSNULL; }
|
||||
return ptr;
|
||||
}
|
||||
|
||||
mDNSexport mDNSu8 *putDNSSECOption(DNSMessage *msg, mDNSu8 *end, mDNSu8 *limit)
|
||||
|
@ -2650,7 +2642,7 @@ mDNSexport mDNSu8 *putDNSSECOption(DNSMessage *msg, mDNSu8 *end, mDNSu8 *limit)
|
|||
// set the DO bit
|
||||
ttl |= 0x8000;
|
||||
end = PutResourceRecordTTLWithLimit(msg, end, &msg->h.numAdditionals, &rr.resrec, ttl, limit);
|
||||
if (!end) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTLWithLimit"); return mDNSNULL; }
|
||||
if (!end) { LogMsg("ERROR: putDNSSECOption - PutResourceRecordTTLWithLimit"); return mDNSNULL; }
|
||||
return end;
|
||||
}
|
||||
|
||||
|
@ -2757,12 +2749,12 @@ mDNSexport const mDNSu8 *getDomainName(const DNSMessage *const msg, const mDNSu8
|
|||
|
||||
while (1) // Read sequence of labels
|
||||
{
|
||||
int i;
|
||||
mDNSu16 offset;
|
||||
const mDNSu8 len = *ptr++; // Read length of this label
|
||||
if (len == 0) break; // If length is zero, that means this name is complete
|
||||
switch (len & 0xC0)
|
||||
{
|
||||
int i;
|
||||
mDNSu16 offset;
|
||||
|
||||
case 0x00: if (ptr + len >= end) // Remember: expect at least one more byte for the root label
|
||||
{ debugf("getDomainName: Malformed domain name (overruns packet end)"); return(mDNSNULL); }
|
||||
|
@ -2846,7 +2838,7 @@ mDNSlocal mDNSu8 *SanityCheckBitMap(const mDNSu8 *bmap, const mDNSu8 *end, int l
|
|||
// (domainnames are expanded to 255 bytes) when stored in memory.
|
||||
//
|
||||
// This function can also be called with "NULL" msg to parse a single resource record pointed to by ptr.
|
||||
// The caller can do this only if the names in the resource records are compressed and validity of the
|
||||
// The caller can do this only if the names in the resource records are not compressed and validity of the
|
||||
// resource record has already been done before. DNSSEC currently uses it this way.
|
||||
mDNSexport mDNSBool SetRData(const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *end,
|
||||
LargeCacheRecord *const largecr, mDNSu16 rdlength)
|
||||
|
@ -3351,6 +3343,12 @@ mDNSexport mDNSBool SetRData(const DNSMessage *const msg, const mDNSu8 *ptr, con
|
|||
dlen = DomainNameLength(&name);
|
||||
rlen = end - ptr;
|
||||
rr->resrec.rdlength = dlen + rlen;
|
||||
if (rr->resrec.rdlength > MaximumRDSize)
|
||||
{
|
||||
LogInfo("SetRData: Malformed TSIG/TKEY rdlength %d, rr->resrec.rdlength %d, "
|
||||
"bmaplen %d, name %##s", rdlength, rr->resrec.rdlength, name.c);
|
||||
goto fail;
|
||||
}
|
||||
AssignDomainName((domainname *)rdb->data, &name);
|
||||
mDNSPlatformMemCopy(rdb->data + dlen, ptr, rlen);
|
||||
break;
|
||||
|
@ -3441,12 +3439,7 @@ mDNSexport const mDNSu8 *GetLargeResourceRecord(mDNS *const m, const DNSMessage
|
|||
mDNSu16 pktrdlength;
|
||||
|
||||
if (largecr == &m->rec && m->rec.r.resrec.RecordType)
|
||||
{
|
||||
LogMsg("GetLargeResourceRecord: m->rec appears to be already in use for %s", CRDisplayString(m, &m->rec.r));
|
||||
#if ForceAlerts
|
||||
*(long*)0 = 0;
|
||||
#endif
|
||||
}
|
||||
LogFatalError("GetLargeResourceRecord: m->rec appears to be already in use for %s", CRDisplayString(m, &m->rec.r));
|
||||
|
||||
rr->next = mDNSNULL;
|
||||
rr->resrec.name = &largecr->namestorage;
|
||||
|
@ -3459,12 +3452,6 @@ mDNSexport const mDNSu8 *GetLargeResourceRecord(mDNS *const m, const DNSMessage
|
|||
rr->CRActiveQuestion = mDNSNULL;
|
||||
rr->UnansweredQueries = 0;
|
||||
rr->LastUnansweredTime= 0;
|
||||
#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
|
||||
rr->MPUnansweredQ = 0;
|
||||
rr->MPLastUnansweredQT= 0;
|
||||
rr->MPUnansweredKA = 0;
|
||||
rr->MPExpectingKA = mDNSfalse;
|
||||
#endif
|
||||
rr->NextInCFList = mDNSNULL;
|
||||
|
||||
rr->resrec.InterfaceID = InterfaceID;
|
||||
|
@ -3619,22 +3606,33 @@ mDNSexport const rdataOPT *GetLLQOptData(mDNS *const m, const DNSMessage *const
|
|||
}
|
||||
|
||||
// Get the lease life of records in a dynamic update
|
||||
// returns 0 on error or if no lease present
|
||||
mDNSexport mDNSu32 GetPktLease(mDNS *m, DNSMessage *msg, const mDNSu8 *end)
|
||||
mDNSexport mDNSBool GetPktLease(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end, mDNSu32 *const lease)
|
||||
{
|
||||
mDNSu32 result = 0;
|
||||
const mDNSu8 *ptr = LocateOptRR(msg, end, DNSOpt_LeaseData_Space);
|
||||
if (ptr) ptr = GetLargeResourceRecord(m, msg, ptr, end, 0, kDNSRecordTypePacketAdd, &m->rec);
|
||||
if (ptr && m->rec.r.resrec.rdlength >= DNSOpt_LeaseData_Space && m->rec.r.resrec.rdata->u.opt[0].opt == kDNSOpt_Lease)
|
||||
result = m->rec.r.resrec.rdata->u.opt[0].u.updatelease;
|
||||
m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
|
||||
return(result);
|
||||
if (ptr)
|
||||
{
|
||||
ptr = GetLargeResourceRecord(m, msg, ptr, end, 0, kDNSRecordTypePacketAdd, &m->rec);
|
||||
if (ptr && m->rec.r.resrec.RecordType != kDNSRecordTypePacketNegative && m->rec.r.resrec.rrtype == kDNSType_OPT)
|
||||
{
|
||||
const rdataOPT *o;
|
||||
const rdataOPT *const e = (const rdataOPT *)&m->rec.r.resrec.rdata->u.data[m->rec.r.resrec.rdlength];
|
||||
for (o = &m->rec.r.resrec.rdata->u.opt[0]; o < e; o++)
|
||||
if (o->opt == kDNSOpt_Lease)
|
||||
{
|
||||
*lease = o->u.updatelease;
|
||||
m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
|
||||
return mDNStrue;
|
||||
}
|
||||
}
|
||||
m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
|
||||
}
|
||||
return mDNSfalse;
|
||||
}
|
||||
|
||||
mDNSlocal const mDNSu8 *DumpRecords(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end, int count, char *label)
|
||||
{
|
||||
int i;
|
||||
LogMsg("%2d %s", count, label);
|
||||
LogInfo("%2d %s", count, label);
|
||||
for (i = 0; i < count && ptr; i++)
|
||||
{
|
||||
// This puts a LargeCacheRecord on the stack instead of using the shared m->rec storage,
|
||||
|
@ -3642,9 +3640,11 @@ mDNSlocal const mDNSu8 *DumpRecords(mDNS *const m, const DNSMessage *const msg,
|
|||
// embedded systems) putting a 9kB object on the stack isn't a big problem.
|
||||
LargeCacheRecord largecr;
|
||||
ptr = GetLargeResourceRecord(m, msg, ptr, end, mDNSInterface_Any, kDNSRecordTypePacketAns, &largecr);
|
||||
if (ptr) LogMsg("%2d TTL%8d %s", i, largecr.r.resrec.rroriginalttl, CRDisplayString(m, &largecr.r));
|
||||
if (ptr)
|
||||
LogInfo("%2d TTL%8d %s", i, largecr.r.resrec.rroriginalttl, CRDisplayString(m, &largecr.r));
|
||||
}
|
||||
if (!ptr) LogMsg("DumpRecords: ERROR: Premature end of packet data");
|
||||
if (!ptr)
|
||||
LogInfo("DumpRecords: ERROR: Premature end of packet data");
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
|
@ -3654,7 +3654,9 @@ mDNSlocal const mDNSu8 *DumpRecords(mDNS *const m, const DNSMessage *const msg,
|
|||
(X) == kDNSFlag0_OP_Status ? "Status " : \
|
||||
(X) == kDNSFlag0_OP_Unused3 ? "Unused3 " : \
|
||||
(X) == kDNSFlag0_OP_Notify ? "Notify " : \
|
||||
(X) == kDNSFlag0_OP_Update ? "Update " : "?? " )
|
||||
(X) == kDNSFlag0_OP_Update ? "Update " : \
|
||||
(X) == kDNSFlag0_OP_Subscribe? "Subscribe": \
|
||||
(X) == kDNSFlag0_OP_UnSubscribe? "UnSubscribe" : "?? " )
|
||||
|
||||
#define DNS_RC_Name(X) ( \
|
||||
(X) == kDNSFlag1_RC_NoErr ? "NoErr" : \
|
||||
|
@ -3686,7 +3688,7 @@ mDNSexport void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *t
|
|||
if (dstaddr || !mDNSIPPortIsZero(dstport))
|
||||
dbuffer[mDNS_snprintf(dbuffer, sizeof(dbuffer), " to %#a:%d", dstaddr, mDNSVal16(dstport))] = 0;
|
||||
|
||||
LogMsg("-- %s %s DNS %s%s (flags %02X%02X) RCODE: %s (%d) %s%s%s%s%s%sID: %d %d bytes from %s%d%s%s --",
|
||||
LogInfo("-- %s %s DNS %s%s (flags %02X%02X) RCODE: %s (%d) %s%s%s%s%s%sID: %d %d bytes from %s%d%s%s --",
|
||||
tbuffer, transport,
|
||||
DNS_OP_Name(msg->h.flags.b[0] & kDNSFlag0_OP_Mask),
|
||||
msg->h.flags.b[0] & kDNSFlag0_QR_Response ? "Response" : "Query",
|
||||
|
@ -3705,16 +3707,16 @@ mDNSexport void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *t
|
|||
(msg->h.flags.b[0] & kDNSFlag0_TC) ? " (truncated)" : ""
|
||||
);
|
||||
|
||||
LogMsg("%2d %s", msg->h.numQuestions, IsUpdate ? "Zone" : "Questions");
|
||||
LogInfo("%2d %s", msg->h.numQuestions, IsUpdate ? "Zone" : "Questions");
|
||||
for (i = 0; i < msg->h.numQuestions && ptr; i++)
|
||||
{
|
||||
ptr = getQuestion(msg, ptr, end, mDNSInterface_Any, &q);
|
||||
if (ptr) LogMsg("%2d %##s %s", i, q.qname.c, DNSTypeName(q.qtype));
|
||||
if (ptr) LogInfo("%2d %##s %s", i, q.qname.c, DNSTypeName(q.qtype));
|
||||
}
|
||||
ptr = DumpRecords(m, msg, ptr, end, msg->h.numAnswers, IsUpdate ? "Prerequisites" : "Answers");
|
||||
ptr = DumpRecords(m, msg, ptr, end, msg->h.numAuthorities, IsUpdate ? "Updates" : "Authorities");
|
||||
ptr = DumpRecords(m, msg, ptr, end, msg->h.numAdditionals, "Additionals");
|
||||
LogMsg("--------------");
|
||||
DumpRecords(m, msg, ptr, end, msg->h.numAdditionals, "Additionals");
|
||||
LogInfo("--------------");
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
@ -3723,13 +3725,14 @@ mDNSexport void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *t
|
|||
#pragma mark - Packet Sending Functions
|
||||
#endif
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
// Run the unit test of mDNSSendDNSMessage
|
||||
UNITTEST_SENDDNSMESSAGE
|
||||
#else
|
||||
// Stub definition of TCPSocket_struct so we can access flags field. (Rest of TCPSocket_struct is platform-dependent.)
|
||||
struct TCPSocket_struct { TCPSocketFlags flags; /* ... */ };
|
||||
|
||||
struct UDPSocket_struct
|
||||
{
|
||||
mDNSIPPort port; // MUST BE FIRST FIELD -- mDNSCoreReceive expects every UDPSocket_struct to begin with mDNSIPPort port
|
||||
};
|
||||
// Stub definition of UDPSocket_struct so we can access port field. (Rest of UDPSocket_struct is platform-dependent.)
|
||||
struct UDPSocket_struct { mDNSIPPort port; /* ... */ };
|
||||
|
||||
// Note: When we sign a DNS message using DNSDigest_SignMessage(), the current real-time clock value is used, which
|
||||
// is why we generally defer signing until we send the message, to ensure the signature is as fresh as possible.
|
||||
|
@ -3827,6 +3830,7 @@ mDNSexport mStatus mDNSSendDNSMessage(mDNS *const m, DNSMessage *const msg, mDNS
|
|||
|
||||
return(status);
|
||||
}
|
||||
#endif // UNIT_TEST
|
||||
|
||||
// ***************************************************************************
|
||||
#if COMPILER_LIKES_PRAGMA_MARK
|
||||
|
@ -3844,12 +3848,7 @@ mDNSexport void mDNS_Lock_(mDNS *const m, const char * const functionname)
|
|||
// If that client callback does mDNS API calls, mDNS_reentrancy and mDNS_busy will both be one
|
||||
// If mDNS_busy != mDNS_reentrancy that's a bad sign
|
||||
if (m->mDNS_busy != m->mDNS_reentrancy)
|
||||
{
|
||||
LogMsg("%s: mDNS_Lock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", functionname, m->mDNS_busy, m->mDNS_reentrancy);
|
||||
#if ForceAlerts
|
||||
*(long*)0 = 0;
|
||||
#endif
|
||||
}
|
||||
LogFatalError("%s: mDNS_Lock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", functionname, m->mDNS_busy, m->mDNS_reentrancy);
|
||||
|
||||
// If this is an initial entry into the mDNSCore code, set m->timenow
|
||||
// else, if this is a re-entrant entry into the mDNSCore code, m->timenow should already be set
|
||||
|
@ -3889,7 +3888,7 @@ mDNSlocal AuthRecord *AnyLocalRecordReady(const mDNS *const m)
|
|||
|
||||
mDNSlocal mDNSs32 GetNextScheduledEvent(const mDNS *const m)
|
||||
{
|
||||
mDNSs32 e = m->timenow + 0x78000000;
|
||||
mDNSs32 e = m->timenow + FutureTime;
|
||||
if (m->mDNSPlatformStatus != mStatus_NoError) return(e);
|
||||
if (m->NewQuestions)
|
||||
{
|
||||
|
@ -3912,6 +3911,10 @@ mDNSlocal mDNSs32 GetNextScheduledEvent(const mDNS *const m)
|
|||
if (e - m->NextScheduledSPS > 0) e = m->NextScheduledSPS;
|
||||
if (e - m->NextScheduledKA > 0) e = m->NextScheduledKA;
|
||||
|
||||
#if BONJOUR_ON_DEMAND
|
||||
if (m->NextBonjourDisableTime && (e - m->NextBonjourDisableTime > 0)) e = m->NextBonjourDisableTime;
|
||||
#endif // BONJOUR_ON_DEMAND
|
||||
|
||||
// NextScheduledSPRetry only valid when DelaySleep not set
|
||||
if (!m->DelaySleep && m->SleepLimit && e - m->NextScheduledSPRetry > 0) e = m->NextScheduledSPRetry;
|
||||
if (m->DelaySleep && e - m->DelaySleep > 0) e = m->DelaySleep;
|
||||
|
@ -3927,85 +3930,95 @@ mDNSlocal mDNSs32 GetNextScheduledEvent(const mDNS *const m)
|
|||
if (e - m->NextScheduledResponse > 0) e = m->NextScheduledResponse;
|
||||
}
|
||||
if (e - m->NextScheduledStopTime > 0) e = m->NextScheduledStopTime;
|
||||
|
||||
if (m->NextBLEServiceTime && (e - m->NextBLEServiceTime > 0)) e = m->NextBLEServiceTime;
|
||||
|
||||
return(e);
|
||||
}
|
||||
|
||||
#define LogTSE TSE++,LogMsg
|
||||
|
||||
mDNSexport void ShowTaskSchedulingError(mDNS *const m)
|
||||
{
|
||||
int TSE = 0;
|
||||
AuthRecord *rr;
|
||||
mDNS_Lock(m);
|
||||
|
||||
LogMsg("Task Scheduling Error: Continuously busy for more than a second");
|
||||
LogMsg("Task Scheduling Error: *** Continuously busy for more than a second");
|
||||
|
||||
// Note: To accurately diagnose *why* we're busy, the debugging code here needs to mirror the logic in GetNextScheduledEvent above
|
||||
|
||||
if (m->NewQuestions && (!m->NewQuestions->DelayAnswering || m->timenow - m->NewQuestions->DelayAnswering >= 0))
|
||||
LogMsg("Task Scheduling Error: NewQuestion %##s (%s)",
|
||||
LogTSE("Task Scheduling Error: NewQuestion %##s (%s)",
|
||||
m->NewQuestions->qname.c, DNSTypeName(m->NewQuestions->qtype));
|
||||
|
||||
if (m->NewLocalOnlyQuestions)
|
||||
LogMsg("Task Scheduling Error: NewLocalOnlyQuestions %##s (%s)",
|
||||
LogTSE("Task Scheduling Error: NewLocalOnlyQuestions %##s (%s)",
|
||||
m->NewLocalOnlyQuestions->qname.c, DNSTypeName(m->NewLocalOnlyQuestions->qtype));
|
||||
|
||||
if (m->NewLocalRecords)
|
||||
{
|
||||
rr = AnyLocalRecordReady(m);
|
||||
if (rr) LogMsg("Task Scheduling Error: NewLocalRecords %s", ARDisplayString(m, rr));
|
||||
if (rr) LogTSE("Task Scheduling Error: NewLocalRecords %s", ARDisplayString(m, rr));
|
||||
}
|
||||
|
||||
if (m->NewLocalOnlyRecords) LogMsg("Task Scheduling Error: NewLocalOnlyRecords");
|
||||
if (m->NewLocalOnlyRecords) LogTSE("Task Scheduling Error: NewLocalOnlyRecords");
|
||||
|
||||
if (m->SPSProxyListChanged) LogMsg("Task Scheduling Error: SPSProxyListChanged");
|
||||
if (m->LocalRemoveEvents) LogMsg("Task Scheduling Error: LocalRemoveEvents");
|
||||
if (m->SPSProxyListChanged) LogTSE("Task Scheduling Error: SPSProxyListChanged");
|
||||
|
||||
if (m->timenow - m->NextScheduledEvent >= 0)
|
||||
LogMsg("Task Scheduling Error: m->NextScheduledEvent %d", m->timenow - m->NextScheduledEvent);
|
||||
if (m->LocalRemoveEvents) LogTSE("Task Scheduling Error: LocalRemoveEvents");
|
||||
|
||||
#ifndef UNICAST_DISABLED
|
||||
if (m->timenow - m->NextuDNSEvent >= 0)
|
||||
LogMsg("Task Scheduling Error: m->NextuDNSEvent %d", m->timenow - m->NextuDNSEvent);
|
||||
LogTSE("Task Scheduling Error: m->NextuDNSEvent %d", m->timenow - m->NextuDNSEvent);
|
||||
if (m->timenow - m->NextScheduledNATOp >= 0)
|
||||
LogMsg("Task Scheduling Error: m->NextScheduledNATOp %d", m->timenow - m->NextScheduledNATOp);
|
||||
LogTSE("Task Scheduling Error: m->NextScheduledNATOp %d", m->timenow - m->NextScheduledNATOp);
|
||||
if (m->NextSRVUpdate && m->timenow - m->NextSRVUpdate >= 0)
|
||||
LogMsg("Task Scheduling Error: m->NextSRVUpdate %d", m->timenow - m->NextSRVUpdate);
|
||||
LogTSE("Task Scheduling Error: m->NextSRVUpdate %d", m->timenow - m->NextSRVUpdate);
|
||||
#endif
|
||||
|
||||
if (m->timenow - m->NextCacheCheck >= 0)
|
||||
LogMsg("Task Scheduling Error: m->NextCacheCheck %d", m->timenow - m->NextCacheCheck);
|
||||
LogTSE("Task Scheduling Error: m->NextCacheCheck %d", m->timenow - m->NextCacheCheck);
|
||||
if (m->timenow - m->NextScheduledSPS >= 0)
|
||||
LogMsg("Task Scheduling Error: m->NextScheduledSPS %d", m->timenow - m->NextScheduledSPS);
|
||||
LogTSE("Task Scheduling Error: m->NextScheduledSPS %d", m->timenow - m->NextScheduledSPS);
|
||||
if (m->timenow - m->NextScheduledKA >= 0)
|
||||
LogMsg("Task Scheduling Error: m->NextScheduledKA %d", m->timenow - m->NextScheduledKA);
|
||||
LogTSE("Task Scheduling Error: m->NextScheduledKA %d", m->timenow - m->NextScheduledKA);
|
||||
if (!m->DelaySleep && m->SleepLimit && m->timenow - m->NextScheduledSPRetry >= 0)
|
||||
LogMsg("Task Scheduling Error: m->NextScheduledSPRetry %d", m->timenow - m->NextScheduledSPRetry);
|
||||
LogTSE("Task Scheduling Error: m->NextScheduledSPRetry %d", m->timenow - m->NextScheduledSPRetry);
|
||||
if (m->DelaySleep && m->timenow - m->DelaySleep >= 0)
|
||||
LogMsg("Task Scheduling Error: m->DelaySleep %d", m->timenow - m->DelaySleep);
|
||||
LogTSE("Task Scheduling Error: m->DelaySleep %d", m->timenow - m->DelaySleep);
|
||||
|
||||
if (m->SuppressSending && m->timenow - m->SuppressSending >= 0)
|
||||
LogMsg("Task Scheduling Error: m->SuppressSending %d", m->timenow - m->SuppressSending);
|
||||
LogTSE("Task Scheduling Error: m->SuppressSending %d", m->timenow - m->SuppressSending);
|
||||
if (m->timenow - m->NextScheduledQuery >= 0)
|
||||
LogMsg("Task Scheduling Error: m->NextScheduledQuery %d", m->timenow - m->NextScheduledQuery);
|
||||
LogTSE("Task Scheduling Error: m->NextScheduledQuery %d", m->timenow - m->NextScheduledQuery);
|
||||
if (m->timenow - m->NextScheduledProbe >= 0)
|
||||
LogMsg("Task Scheduling Error: m->NextScheduledProbe %d", m->timenow - m->NextScheduledProbe);
|
||||
LogTSE("Task Scheduling Error: m->NextScheduledProbe %d", m->timenow - m->NextScheduledProbe);
|
||||
if (m->timenow - m->NextScheduledResponse >= 0)
|
||||
LogMsg("Task Scheduling Error: m->NextScheduledResponse %d", m->timenow - m->NextScheduledResponse);
|
||||
LogTSE("Task Scheduling Error: m->NextScheduledResponse %d", m->timenow - m->NextScheduledResponse);
|
||||
if (m->timenow - m->NextScheduledStopTime >= 0)
|
||||
LogTSE("Task Scheduling Error: m->NextScheduledStopTime %d", m->timenow - m->NextScheduledStopTime);
|
||||
|
||||
if (m->timenow - m->NextScheduledEvent >= 0)
|
||||
LogTSE("Task Scheduling Error: m->NextScheduledEvent %d", m->timenow - m->NextScheduledEvent);
|
||||
|
||||
if (m->NetworkChanged && m->timenow - m->NetworkChanged >= 0)
|
||||
LogTSE("Task Scheduling Error: NetworkChanged %d", m->timenow - m->NetworkChanged);
|
||||
|
||||
if (!TSE) LogMsg("Task Scheduling Error: *** No likely causes identified");
|
||||
else LogMsg("Task Scheduling Error: *** %d potential cause%s identified (significant only if the same cause consistently appears)", TSE, TSE > 1 ? "s" : "");
|
||||
|
||||
mDNS_Unlock(m);
|
||||
}
|
||||
|
||||
mDNSexport void mDNS_Unlock_(mDNS *const m, const char * const functionname)
|
||||
mDNSexport void mDNS_Unlock_(mDNS *const m, const char *const functionname)
|
||||
{
|
||||
// Decrement mDNS_busy
|
||||
m->mDNS_busy--;
|
||||
|
||||
// Check for locking failures
|
||||
if (m->mDNS_busy != m->mDNS_reentrancy)
|
||||
{
|
||||
LogMsg("%s: mDNS_Unlock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", functionname, m->mDNS_busy, m->mDNS_reentrancy);
|
||||
#if ForceAlerts
|
||||
*(long*)0 = 0;
|
||||
#endif
|
||||
}
|
||||
LogFatalError("%s: mDNS_Unlock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", functionname, m->mDNS_busy, m->mDNS_reentrancy);
|
||||
|
||||
// If this is a final exit from the mDNSCore code, set m->NextScheduledEvent and clear m->timenow
|
||||
if (m->mDNS_busy == 0)
|
||||
|
@ -4049,7 +4062,8 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
|
|||
|
||||
for (c = *fmt; c != 0; c = *++fmt)
|
||||
{
|
||||
if (c != '%')
|
||||
unsigned long n;
|
||||
if (c != '%')
|
||||
{
|
||||
*sbuffer++ = (char)c;
|
||||
if (++nwritten >= buflen) goto exit;
|
||||
|
@ -4105,7 +4119,6 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
|
|||
conv:
|
||||
switch (c) // perform appropriate conversion
|
||||
{
|
||||
unsigned long n;
|
||||
case 'h': F.hSize = 1; c = *++fmt; goto conv;
|
||||
case 'l': // fall through
|
||||
case 'L': F.lSize = 1; c = *++fmt; goto conv;
|
||||
|
|
|
@ -40,17 +40,19 @@ extern "C" {
|
|||
|
||||
typedef enum
|
||||
{
|
||||
kDNSFlag0_QR_Mask = 0x80, // Query or response?
|
||||
kDNSFlag0_QR_Query = 0x00,
|
||||
kDNSFlag0_QR_Response = 0x80,
|
||||
kDNSFlag0_QR_Mask = 0x80, // Query or response?
|
||||
kDNSFlag0_QR_Query = 0x00,
|
||||
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_OP_Mask = 0x78, // Operation type
|
||||
kDNSFlag0_OP_StdQuery = 0x00,
|
||||
kDNSFlag0_OP_Subscribe = 0x06,
|
||||
kDNSFlag0_OP_UnSubscribe = 0x07,
|
||||
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,
|
||||
|
||||
|
@ -84,6 +86,7 @@ typedef enum
|
|||
TSIG_ErrBadTime = 18
|
||||
} TSIG_ErrorCode;
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
#if COMPILER_LIKES_PRAGMA_MARK
|
||||
#pragma mark -
|
||||
|
@ -220,7 +223,7 @@ extern mDNSu8 *putDeletionRecord(DNSMessage *msg, mDNSu8 *ptr, ResourceRecord *r
|
|||
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 *putUpdateLease(DNSMessage *msg, mDNSu8 *ptr, 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);
|
||||
|
@ -237,8 +240,7 @@ extern const mDNSu8 *NSEC3HashName(const domainname *name, rdataNSEC3 *nsec3, co
|
|||
#pragma mark - DNS Message Parsing Functions
|
||||
#endif
|
||||
|
||||
#define AuthHashSlot(X) (DomainNameHashValue(X) % AUTH_HASH_SLOTS)
|
||||
#define HashSlot(X) (DomainNameHashValue(X) % CACHE_HASH_SLOTS)
|
||||
#define HashSlotFromNameHash(X) ((X) % CACHE_HASH_SLOTS)
|
||||
extern mDNSu32 DomainNameHashValue(const domainname *const name);
|
||||
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);
|
||||
|
@ -257,7 +259,7 @@ extern const mDNSu8 *LocateAuthorities(const DNSMessage *const msg, const mDNSu8
|
|||
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 mDNSBool GetPktLease(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end, mDNSu32 *const lease);
|
||||
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);
|
||||
|
@ -297,16 +299,16 @@ extern void mDNS_Unlock_(mDNS *const m, const char * const functionname);
|
|||
|
||||
#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_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)
|
||||
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)
|
||||
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
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2002-2011 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2002-2011 Apple 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.
|
||||
|
@ -15,7 +15,6 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2012 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2012-2013 Apple 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.
|
||||
|
@ -27,6 +27,14 @@
|
|||
|
||||
#define ANON_NSEC3_ITERATIONS 1
|
||||
|
||||
struct AnonInfoResourceRecord_struct
|
||||
{
|
||||
ResourceRecord resrec;
|
||||
RData rdatastorage;
|
||||
};
|
||||
|
||||
typedef struct AnonInfoResourceRecord_struct AnonInfoResourceRecord;
|
||||
|
||||
mDNSlocal mDNSBool InitializeNSEC3Record(ResourceRecord *rr, const mDNSu8 *AnonData, int len, mDNSu32 salt)
|
||||
{
|
||||
const mDNSu8 *ptr;
|
||||
|
@ -63,7 +71,7 @@ mDNSlocal mDNSBool InitializeNSEC3Record(ResourceRecord *rr, const mDNSu8 *AnonD
|
|||
// 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);
|
||||
LogMsg("InitializeNSEC3Record: NSEC3HashName failed for %##s", rr->name->c);
|
||||
return mDNSfalse;
|
||||
}
|
||||
if (hlen != SHA1_HASH_LENGTH)
|
||||
|
@ -118,9 +126,10 @@ mDNSlocal ResourceRecord *ConstructNSEC3Record(const domainname *service, const
|
|||
|
||||
mDNSlocal ResourceRecord *CopyNSEC3ResourceRecord(AnonymousInfo *si, const ResourceRecord *rr)
|
||||
{
|
||||
int len;
|
||||
AnonInfoResourceRecord *anonRR;
|
||||
domainname *name;
|
||||
ResourceRecord *nsec3rr;
|
||||
mDNSu32 neededLen;
|
||||
mDNSu32 extraLen;
|
||||
|
||||
if (rr->rdlength < MCAST_NSEC3_RDLENGTH)
|
||||
{
|
||||
|
@ -128,22 +137,26 @@ mDNSlocal ResourceRecord *CopyNSEC3ResourceRecord(AnonymousInfo *si, const Resou
|
|||
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)
|
||||
neededLen = rr->rdlength + DomainNameLength(rr->name);
|
||||
extraLen = (neededLen > sizeof(RDataBody)) ? (neededLen - sizeof(RDataBody)) : 0;
|
||||
anonRR = (AnonInfoResourceRecord *)mDNSPlatformMemAllocate(sizeof(AnonInfoResourceRecord) + extraLen);
|
||||
if (!anonRR)
|
||||
return mDNSNULL;
|
||||
|
||||
*nsec3rr = *rr;
|
||||
name = (domainname *)((mDNSu8 *)nsec3rr + sizeof(ResourceRecord));
|
||||
nsec3rr->name = (const domainname *)name;
|
||||
anonRR->resrec = *rr;
|
||||
|
||||
anonRR->rdatastorage.MaxRDLength = rr->rdlength;
|
||||
mDNSPlatformMemCopy(anonRR->rdatastorage.u.data, rr->rdata->u.data, rr->rdlength);
|
||||
|
||||
name = (domainname *)(anonRR->rdatastorage.u.data + rr->rdlength);
|
||||
AssignDomainName(name, rr->name);
|
||||
|
||||
nsec3rr->rdata = (RData *)((mDNSu8 *)nsec3rr->name + len);
|
||||
mDNSPlatformMemCopy(nsec3rr->rdata->u.data, rr->rdata->u.data, rr->rdlength);
|
||||
anonRR->resrec.name = name;
|
||||
anonRR->resrec.rdata = &anonRR->rdatastorage;
|
||||
|
||||
si->nsec3RR = nsec3rr;
|
||||
si->nsec3RR = (ResourceRecord *)anonRR;
|
||||
|
||||
return nsec3rr;
|
||||
return si->nsec3RR;
|
||||
}
|
||||
|
||||
// When a service is started or a browse is started with the Anonymous data, we allocate a new random
|
||||
|
@ -227,6 +240,12 @@ mDNSexport void SetAnonData(DNSQuestion *q, ResourceRecord *rr, mDNSBool ForQues
|
|||
debugf("SetAnonData: question %##s(%p), rr %##s(%p)", q->qname.c, q->AnonInfo, rr->name->c, rr->AnonInfo);
|
||||
if (ForQuestion)
|
||||
{
|
||||
if (q->AnonInfo->AnonDataLen < rr->AnonInfo->AnonDataLen)
|
||||
{
|
||||
mDNSPlatformMemFree(q->AnonInfo->AnonData);
|
||||
q->AnonInfo->AnonData = mDNSNULL;
|
||||
}
|
||||
|
||||
if (!q->AnonInfo->AnonData)
|
||||
{
|
||||
q->AnonInfo->AnonData = mDNSPlatformMemAllocate(rr->AnonInfo->AnonDataLen);
|
||||
|
@ -238,6 +257,12 @@ mDNSexport void SetAnonData(DNSQuestion *q, ResourceRecord *rr, mDNSBool ForQues
|
|||
}
|
||||
else
|
||||
{
|
||||
if (rr->AnonInfo->AnonDataLen < q->AnonInfo->AnonDataLen)
|
||||
{
|
||||
mDNSPlatformMemFree(rr->AnonInfo->AnonData);
|
||||
rr->AnonInfo->AnonData = mDNSNULL;
|
||||
}
|
||||
|
||||
if (!rr->AnonInfo->AnonData)
|
||||
{
|
||||
rr->AnonInfo->AnonData = mDNSPlatformMemAllocate(q->AnonInfo->AnonDataLen);
|
||||
|
@ -262,9 +287,10 @@ mDNSexport int AnonInfoAnswersQuestion(const ResourceRecord *const rr, const DNS
|
|||
int AnonDataLen;
|
||||
rdataNSEC3 *nsec3;
|
||||
int hlen;
|
||||
const mDNSu8 hashName[NSEC3_MAX_HASH_LEN];
|
||||
int nxtLength;
|
||||
mDNSu8 *nxtName;
|
||||
mDNSu8 hashName[NSEC3_MAX_HASH_LEN];
|
||||
mDNSPlatformMemZero(hashName, sizeof(hashName));
|
||||
|
||||
debugf("AnonInfoAnswersQuestion: question qname %##s", q->qname.c);
|
||||
|
||||
|
@ -385,7 +411,7 @@ mDNSexport int AnonInfoAnswersQuestion(const ResourceRecord *const rr, const DNS
|
|||
|
||||
if (!NSEC3HashName(nsec3RR->name, nsec3, AnonData, AnonDataLen, hashName, &hlen))
|
||||
{
|
||||
LogMsg("AnonInfoAnswersQuestion: NSEC3HashName failed for ##s", nsec3RR->name->c);
|
||||
LogMsg("AnonInfoAnswersQuestion: NSEC3HashName failed for %##s", nsec3RR->name->c);
|
||||
return mDNSfalse;
|
||||
}
|
||||
if (hlen != SHA1_HASH_LENGTH)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2012 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2012 Apple 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.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2011-2013 Apple 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.
|
||||
|
@ -19,6 +19,8 @@
|
|||
|
||||
#ifndef UNICAST_DISABLED
|
||||
|
||||
mDNSexport mDNS mDNSStorage;
|
||||
|
||||
// Implementation Notes
|
||||
//
|
||||
// DNS Proxy listens on port 53 (UDPv4v6 & TCPv4v6) for DNS queries. It handles only
|
||||
|
@ -72,7 +74,7 @@ struct DNSProxyClient_struct {
|
|||
};
|
||||
|
||||
#define MIN_DNS_MESSAGE_SIZE 512
|
||||
DNSProxyClient *DNSProxyClients;
|
||||
static DNSProxyClient *DNSProxyClients;
|
||||
|
||||
mDNSlocal void FreeDNSProxyClient(DNSProxyClient *pc)
|
||||
{
|
||||
|
@ -83,10 +85,6 @@ mDNSlocal void FreeDNSProxyClient(DNSProxyClient *pc)
|
|||
|
||||
mDNSlocal mDNSBool ParseEDNS0(DNSProxyClient *pc, const mDNSu8 *ptr, int length, const mDNSu8 *limit)
|
||||
{
|
||||
mDNSu16 rrtype, rrclass;
|
||||
mDNSu8 rcode, version;
|
||||
mDNSu16 flag;
|
||||
|
||||
if (ptr + length > limit)
|
||||
{
|
||||
LogInfo("ParseEDNS0: Not enough space in the packet");
|
||||
|
@ -94,18 +92,19 @@ mDNSlocal mDNSBool ParseEDNS0(DNSProxyClient *pc, const mDNSu8 *ptr, int length,
|
|||
}
|
||||
// Skip the root label
|
||||
ptr++;
|
||||
rrtype = (mDNSu16) ((mDNSu16)ptr[0] << 8 | ptr[1]);
|
||||
mDNSu16 rrtype = (mDNSu16) ((mDNSu16)ptr[0] << 8 | ptr[1]);
|
||||
if (rrtype != kDNSType_OPT)
|
||||
{
|
||||
LogInfo("ParseEDNS0: Not the right type %d", rrtype);
|
||||
return mDNSfalse;
|
||||
}
|
||||
rrclass = (mDNSu16) ((mDNSu16)ptr[2] << 8 | ptr[3]);
|
||||
rcode = ptr[4];
|
||||
version = ptr[5];
|
||||
flag = (mDNSu16) ((mDNSu16)ptr[6] << 8 | ptr[7]);
|
||||
|
||||
mDNSu16 rrclass = (mDNSu16) ((mDNSu16)ptr[2] << 8 | ptr[3]);
|
||||
#if MDNS_DEBUGMSGS
|
||||
mDNSu8 rcode = ptr[4];
|
||||
mDNSu8 version = ptr[5];
|
||||
mDNSu16 flag = (mDNSu16) ((mDNSu16)ptr[6] << 8 | ptr[7]);
|
||||
debugf("rrtype is %s, length is %d, rcode %d, version %d, flag 0x%x", DNSTypeName(rrtype), rrclass, rcode, version, flag);
|
||||
#endif
|
||||
pc->rcvBufSize = rrclass;
|
||||
pc->DNSSECOK = ptr[6] & 0x80;
|
||||
|
||||
|
@ -133,7 +132,7 @@ mDNSexport mDNSu8 *DNSProxySetAttributes(DNSQuestion *q, DNSMessageHeader *h, DN
|
|||
return ptr;
|
||||
}
|
||||
|
||||
mDNSlocal mDNSu8 *AddEDNS0Option(mDNS *const m, mDNSu8 *ptr, mDNSu8 *limit)
|
||||
mDNSlocal mDNSu8 *AddEDNS0Option(mDNSu8 *ptr, mDNSu8 *limit)
|
||||
{
|
||||
int len = 4096;
|
||||
|
||||
|
@ -142,7 +141,7 @@ mDNSlocal mDNSu8 *AddEDNS0Option(mDNS *const m, mDNSu8 *ptr, mDNSu8 *limit)
|
|||
LogInfo("AddEDNS0Option: not enough space");
|
||||
return mDNSNULL;
|
||||
}
|
||||
m->omsg.h.numAdditionals++;
|
||||
mDNSStorage.omsg.h.numAdditionals++;
|
||||
ptr[0] = 0;
|
||||
ptr[1] = (mDNSu8) (kDNSType_OPT >> 8);
|
||||
ptr[2] = (mDNSu8) (kDNSType_OPT & 0xFF);
|
||||
|
@ -183,9 +182,9 @@ mDNSlocal mDNSOpaque16 SetResponseFlags(DNSProxyClient *pc, const mDNSOpaque16 r
|
|||
return rFlags;
|
||||
}
|
||||
|
||||
mDNSlocal mDNSu8 *AddResourceRecords(mDNS *const m, DNSProxyClient *pc, mDNSu8 **prevptr, mStatus *error)
|
||||
mDNSlocal mDNSu8 *AddResourceRecords(DNSProxyClient *pc, mDNSu8 **prevptr, mStatus *error)
|
||||
{
|
||||
mDNSu32 slot;
|
||||
mDNS *const m = &mDNSStorage;
|
||||
CacheGroup *cg;
|
||||
CacheRecord *cr;
|
||||
int len = sizeof(DNSMessageHeader);
|
||||
|
@ -198,6 +197,8 @@ mDNSlocal mDNSu8 *AddResourceRecords(mDNS *const m, DNSProxyClient *pc, mDNSu8 *
|
|||
CacheRecord *soa = mDNSNULL;
|
||||
CacheRecord *cname = mDNSNULL;
|
||||
mDNSu8 *limit;
|
||||
domainname tempQName;
|
||||
mDNSu32 tempQNameHash;
|
||||
|
||||
*error = mStatus_NoError;
|
||||
*prevptr = mDNSNULL;
|
||||
|
@ -225,20 +226,16 @@ mDNSlocal mDNSu8 *AddResourceRecords(mDNS *const m, DNSProxyClient *pc, mDNSu8 *
|
|||
}
|
||||
LogInfo("AddResourceRecords: Limit is %d", limit - m->omsg.data);
|
||||
|
||||
if (!SameDomainName(&pc->qname, &pc->q.qname))
|
||||
{
|
||||
AssignDomainName(&pc->q.qname, &pc->qname);
|
||||
pc->q.qnamehash = DomainNameHashValue(&pc->q.qname);
|
||||
}
|
||||
AssignDomainName(&tempQName, &pc->qname);
|
||||
tempQNameHash = DomainNameHashValue(&tempQName);
|
||||
|
||||
again:
|
||||
nsec = soa = cname = mDNSNULL;
|
||||
slot = HashSlot(&pc->q.qname);
|
||||
|
||||
cg = CacheGroupForName(m, slot, pc->q.qnamehash, &pc->q.qname);
|
||||
|
||||
cg = CacheGroupForName(m, tempQNameHash, &tempQName);
|
||||
if (!cg)
|
||||
{
|
||||
LogInfo("AddResourceRecords: CacheGroup not found");
|
||||
LogInfo("AddResourceRecords: CacheGroup not found for %##s", tempQName.c);
|
||||
*error = mStatus_NoSuchRecord;
|
||||
return mDNSNULL;
|
||||
}
|
||||
|
@ -347,8 +344,8 @@ again:
|
|||
}
|
||||
if (cname)
|
||||
{
|
||||
AssignDomainName(&pc->q.qname, &cname->resrec.rdata->u.name);
|
||||
pc->q.qnamehash = DomainNameHashValue(&pc->q.qname);
|
||||
AssignDomainName(&tempQName, &cname->resrec.rdata->u.name);
|
||||
tempQNameHash = DomainNameHashValue(&tempQName);
|
||||
goto again;
|
||||
}
|
||||
if (!ptr)
|
||||
|
@ -359,14 +356,14 @@ again:
|
|||
}
|
||||
if (pc->rcvBufSize)
|
||||
{
|
||||
ptr = AddEDNS0Option(m, ptr, limit);
|
||||
ptr = AddEDNS0Option(ptr, limit);
|
||||
if (!ptr)
|
||||
{
|
||||
*prevptr = orig;
|
||||
return mDNSNULL;
|
||||
}
|
||||
len += (ptr - orig);
|
||||
orig = ptr;
|
||||
// orig = ptr; Commented out to avoid ‘value never read’ error message
|
||||
}
|
||||
LogInfo("AddResourceRecord: Added %d bytes to the packet", len);
|
||||
return ptr;
|
||||
|
@ -412,7 +409,7 @@ mDNSlocal void ProxyClientCallback(mDNS *const m, DNSQuestion *question, const R
|
|||
return;
|
||||
}
|
||||
}
|
||||
ptr = AddResourceRecords(m, pc, &prevptr, &error);
|
||||
ptr = AddResourceRecords(pc, &prevptr, &error);
|
||||
if (!ptr)
|
||||
{
|
||||
LogInfo("ProxyClientCallback: AddResourceRecords NULL for %##s (%s)", &pc->qname.c, DNSTypeName(pc->q.qtype));
|
||||
|
@ -471,14 +468,16 @@ mDNSlocal void ProxyClientCallback(mDNS *const m, DNSQuestion *question, const R
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
debugf("ProxyClientCallback: InterfaceID is %p for response to client", pc->interfaceID);
|
||||
|
||||
if (!pc->tcp)
|
||||
{
|
||||
mDNSSendDNSMessage(m, &m->omsg, ptr, mDNSInterface_Any, (UDPSocket *)pc->socket, &pc->addr, pc->port, mDNSNULL, mDNSNULL, mDNSfalse);
|
||||
mDNSSendDNSMessage(m, &m->omsg, ptr, pc->interfaceID, (UDPSocket *)pc->socket, &pc->addr, pc->port, mDNSNULL, mDNSNULL, mDNSfalse);
|
||||
}
|
||||
else
|
||||
{
|
||||
mDNSSendDNSMessage(m, &m->omsg, ptr, mDNSInterface_Any, mDNSNULL, &pc->addr, pc->port, (TCPSocket *)pc->socket, mDNSNULL, mDNSfalse);
|
||||
mDNSSendDNSMessage(m, &m->omsg, ptr, pc->interfaceID, mDNSNULL, &pc->addr, pc->port, (TCPSocket *)pc->socket, mDNSNULL, mDNSfalse);
|
||||
}
|
||||
|
||||
done:
|
||||
|
@ -496,13 +495,11 @@ done:
|
|||
FreeDNSProxyClient(pc);
|
||||
}
|
||||
|
||||
mDNSlocal void SendError(mDNS *const m, void *socket, void *const pkt, const mDNSu8 *const end, const mDNSAddr *dstaddr,
|
||||
mDNSlocal void SendError(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *dstaddr,
|
||||
const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, mDNSBool tcp, void *context, mDNSu8 rcode)
|
||||
{
|
||||
int pktlen = (int)(end - (mDNSu8 *)pkt);
|
||||
DNSMessage *msg = (DNSMessage *)pkt;
|
||||
|
||||
(void) InterfaceID;
|
||||
mDNS *const m = &mDNSStorage;
|
||||
int pktlen = (int)(end - (mDNSu8 *)msg);
|
||||
|
||||
// RFC 1035 requires that we copy the question back and RFC 2136 is okay with sending nothing
|
||||
// in the body or send back whatever we get for updates. It is easy to return whatever we get
|
||||
|
@ -514,28 +511,27 @@ mDNSlocal void SendError(mDNS *const m, void *socket, void *const pkt, const mDN
|
|||
mDNSPlatformMemCopy(&m->omsg.h, &msg->h, sizeof(DNSMessageHeader));
|
||||
m->omsg.h.flags.b[0] |= kDNSFlag0_QR_Response;
|
||||
m->omsg.h.flags.b[1] = rcode;
|
||||
mDNSPlatformMemCopy(m->omsg.data, (mDNSu8 *)&msg->h.numQuestions, pktlen);
|
||||
mDNSPlatformMemCopy(m->omsg.data, (mDNSu8 *)&msg->data, (pktlen - sizeof(DNSMessageHeader)));
|
||||
|
||||
if (!tcp)
|
||||
{
|
||||
mDNSSendDNSMessage(m, &m->omsg, (mDNSu8 *)&m->omsg + pktlen, mDNSInterface_Any, socket, dstaddr, dstport, mDNSNULL, mDNSNULL,
|
||||
mDNSSendDNSMessage(m, &m->omsg, (mDNSu8 *)&m->omsg + pktlen, InterfaceID, socket, dstaddr, dstport, mDNSNULL, mDNSNULL,
|
||||
mDNSfalse);
|
||||
}
|
||||
else
|
||||
{
|
||||
mDNSSendDNSMessage(m, &m->omsg, (mDNSu8 *)&m->omsg + pktlen, mDNSInterface_Any, mDNSNULL, dstaddr, dstport, (TCPSocket *)socket,
|
||||
mDNSSendDNSMessage(m, &m->omsg, (mDNSu8 *)&m->omsg + pktlen, InterfaceID, mDNSNULL, dstaddr, dstport, (TCPSocket *)socket,
|
||||
mDNSNULL, mDNSfalse);
|
||||
}
|
||||
mDNSPlatformDisposeProxyContext(context);
|
||||
}
|
||||
|
||||
mDNSlocal DNSQuestion *IsDuplicateClient(const mDNS *const m, const mDNSAddr *const addr, const mDNSIPPort port, const mDNSOpaque16 id,
|
||||
mDNSlocal DNSQuestion *IsDuplicateClient(const mDNSAddr *const addr, const mDNSIPPort port, const mDNSOpaque16 id,
|
||||
const DNSQuestion *const question)
|
||||
{
|
||||
DNSProxyClient *pc;
|
||||
|
||||
(void) m; // unused
|
||||
|
||||
for (pc = DNSProxyClients; pc; pc = pc->next)
|
||||
for (pc = DNSProxyClients; pc; pc = pc->next)
|
||||
{
|
||||
if (mDNSSameAddress(&pc->addr, addr) &&
|
||||
mDNSSameIPPort(pc->port, port) &&
|
||||
|
@ -551,32 +547,40 @@ mDNSlocal DNSQuestion *IsDuplicateClient(const mDNS *const m, const mDNSAddr *co
|
|||
return(mDNSNULL);
|
||||
}
|
||||
|
||||
mDNSlocal mDNSBool CheckDNSProxyIpIntf(const mDNS *const m, mDNSInterfaceID InterfaceID)
|
||||
mDNSlocal mDNSBool CheckDNSProxyIpIntf(mDNSInterfaceID InterfaceID)
|
||||
{
|
||||
mDNS *const m = &mDNSStorage;
|
||||
int i;
|
||||
mDNSu32 ip_ifindex = (mDNSu32)(unsigned long)InterfaceID;
|
||||
|
||||
LogInfo("CheckDNSProxyIpIntf: Stored Input Interface List: [%d] [%d] [%d] [%d] [%d]", m->dp_ipintf[0], m->dp_ipintf[1], m->dp_ipintf[2],
|
||||
m->dp_ipintf[3], m->dp_ipintf[4]);
|
||||
LogInfo("CheckDNSProxyIpIntf: Check for ifindex[%d] in stored input interface list: [%d] [%d] [%d] [%d] [%d]",
|
||||
ip_ifindex, m->dp_ipintf[0], m->dp_ipintf[1], m->dp_ipintf[2], m->dp_ipintf[3], m->dp_ipintf[4]);
|
||||
|
||||
for (i = 0; i < MaxIp; i++)
|
||||
if (ip_ifindex > 0)
|
||||
{
|
||||
if (ip_ifindex == m->dp_ipintf[i])
|
||||
return mDNStrue;
|
||||
for (i = 0; i < MaxIp; i++)
|
||||
{
|
||||
if (ip_ifindex == m->dp_ipintf[i])
|
||||
return mDNStrue;
|
||||
}
|
||||
}
|
||||
|
||||
LogMsg("CheckDNSProxyIpIntf: ifindex[%d] not in stored input interface list: [%d] [%d] [%d] [%d] [%d]",
|
||||
ip_ifindex, m->dp_ipintf[0], m->dp_ipintf[1], m->dp_ipintf[2], m->dp_ipintf[3], m->dp_ipintf[4]);
|
||||
|
||||
return mDNSfalse;
|
||||
|
||||
}
|
||||
|
||||
mDNSlocal void ProxyCallbackCommon(mDNS *const m, void *socket, void *const pkt, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
|
||||
mDNSlocal void ProxyCallbackCommon(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
|
||||
const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, mDNSBool tcp, void *context)
|
||||
{
|
||||
DNSMessage *msg = (DNSMessage *)pkt;
|
||||
mDNS *const m = &mDNSStorage;
|
||||
mDNSu8 QR_OP;
|
||||
const mDNSu8 *ptr;
|
||||
DNSQuestion q, *qptr;
|
||||
DNSProxyClient *pc;
|
||||
const mDNSu8 *optRR;
|
||||
const mDNSu8 *optRR = mDNSNULL;
|
||||
int optLen = 0;
|
||||
DNSProxyClient **ppc = &DNSProxyClients;
|
||||
|
||||
|
@ -585,20 +589,15 @@ mDNSlocal void ProxyCallbackCommon(mDNS *const m, void *socket, void *const pkt,
|
|||
|
||||
debugf("ProxyCallbackCommon: DNS Query coming from InterfaceID %p", InterfaceID);
|
||||
// Ignore if the DNS Query is not from a Valid Input InterfaceID
|
||||
if (!CheckDNSProxyIpIntf(m, InterfaceID))
|
||||
return;
|
||||
|
||||
if ((unsigned)(end - (mDNSu8 *)pkt) < sizeof(DNSMessageHeader))
|
||||
if (!CheckDNSProxyIpIntf(InterfaceID))
|
||||
{
|
||||
debugf("ProxyCallbackCommon: DNS Message from %#a:%d to %#a:%d length %d too short", srcaddr, mDNSVal16(srcport), dstaddr, mDNSVal16(dstport), end - (mDNSu8 *)pkt);
|
||||
LogMsg("ProxyCallbackCommon: Rejecting DNS Query coming from InterfaceID %p", InterfaceID);
|
||||
return;
|
||||
}
|
||||
|
||||
QR_OP = (mDNSu8)(msg->h.flags.b[0] & kDNSFlag0_QROP_Mask);
|
||||
if (QR_OP != kDNSFlag0_QR_Query)
|
||||
|
||||
if ((unsigned)(end - (mDNSu8 *)msg) < sizeof(DNSMessageHeader))
|
||||
{
|
||||
LogInfo("ProxyCallbackCommon: Not a query(%d) for pkt from %#a:%d", QR_OP, srcaddr, mDNSVal16(srcport));
|
||||
SendError(m, socket, pkt, end, srcaddr, srcport, InterfaceID, tcp, context, kDNSFlag1_RC_NotImpl);
|
||||
debugf("ProxyCallbackCommon: DNS Message from %#a:%d to %#a:%d length %d too short", srcaddr, mDNSVal16(srcport), dstaddr, mDNSVal16(dstport), (int)(end - (mDNSu8 *)msg));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -609,11 +608,19 @@ mDNSlocal void ProxyCallbackCommon(mDNS *const m, void *socket, void *const pkt,
|
|||
msg->h.numAuthorities = (mDNSu16)((mDNSu16)ptr[4] << 8 | ptr[5]);
|
||||
msg->h.numAdditionals = (mDNSu16)((mDNSu16)ptr[6] << 8 | ptr[7]);
|
||||
|
||||
QR_OP = (mDNSu8)(msg->h.flags.b[0] & kDNSFlag0_QROP_Mask);
|
||||
if (QR_OP != kDNSFlag0_QR_Query)
|
||||
{
|
||||
LogInfo("ProxyCallbackCommon: Not a query(%d) for pkt from %#a:%d", QR_OP, srcaddr, mDNSVal16(srcport));
|
||||
SendError(socket, msg, end, srcaddr, srcport, InterfaceID, tcp, context, kDNSFlag1_RC_NotImpl);
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg->h.numQuestions != 1 || msg->h.numAnswers || msg->h.numAuthorities)
|
||||
{
|
||||
LogInfo("ProxyCallbackCommon: Malformed pkt from %#a:%d, Q:%d, An:%d, Au:%d", srcaddr, mDNSVal16(srcport),
|
||||
msg->h.numQuestions, msg->h.numAnswers, msg->h.numAuthorities);
|
||||
SendError(m, socket, pkt, end, srcaddr, srcport, InterfaceID, tcp, context, kDNSFlag1_RC_FormErr);
|
||||
SendError(socket, msg, end, srcaddr, srcport, InterfaceID, tcp, context, kDNSFlag1_RC_FormErr);
|
||||
return;
|
||||
}
|
||||
ptr = msg->data;
|
||||
|
@ -621,7 +628,7 @@ mDNSlocal void ProxyCallbackCommon(mDNS *const m, void *socket, void *const pkt,
|
|||
if (!ptr)
|
||||
{
|
||||
LogInfo("ProxyCallbackCommon: Question cannot be parsed for pkt from %#a:%d", srcaddr, mDNSVal16(srcport));
|
||||
SendError(m, socket, pkt, end, srcaddr, srcport, InterfaceID, tcp, context, kDNSFlag1_RC_FormErr);
|
||||
SendError(socket, msg, end, srcaddr, srcport, InterfaceID, tcp, context, kDNSFlag1_RC_FormErr);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
@ -649,7 +656,7 @@ mDNSlocal void ProxyCallbackCommon(mDNS *const m, void *socket, void *const pkt,
|
|||
LogInfo("ProxyCallbackCommon: EDNS0 opt not present in Question %##s (%s), ptr %p", q.qname.c, DNSTypeName(q.qtype), ptr);
|
||||
}
|
||||
|
||||
qptr = IsDuplicateClient(m, srcaddr, srcport, msg->h.id, &q);
|
||||
qptr = IsDuplicateClient(srcaddr, srcport, msg->h.id, &q);
|
||||
if (qptr)
|
||||
{
|
||||
LogInfo("ProxyCallbackCommon: Found a duplicate for pkt from %#a:%d, ignoring this", srcaddr, mDNSVal16(srcport));
|
||||
|
@ -694,8 +701,7 @@ mDNSlocal void ProxyCallbackCommon(mDNS *const m, void *socket, void *const pkt,
|
|||
debugf("ProxyCallbackCommon: DNS Query forwarding to interface index %d", m->dp_opintf);
|
||||
mDNS_SetupQuestion(&pc->q, (mDNSInterfaceID)(unsigned long)m->dp_opintf, &q.qname, q.qtype, ProxyClientCallback, pc);
|
||||
pc->q.TimeoutQuestion = 1;
|
||||
// Even though we don't care about intermediate responses, set ReturnIntermed so that
|
||||
// we get the negative responses
|
||||
// Set ReturnIntermed so that we get the negative responses
|
||||
pc->q.ReturnIntermed = mDNStrue;
|
||||
pc->q.ProxyQuestion = mDNStrue;
|
||||
pc->q.ProxyDNSSECOK = pc->DNSSECOK;
|
||||
|
@ -727,20 +733,21 @@ mDNSlocal void ProxyCallbackCommon(mDNS *const m, void *socket, void *const pkt,
|
|||
mDNS_StartQuery(m, &pc->q);
|
||||
}
|
||||
|
||||
mDNSexport void ProxyUDPCallback(mDNS *const m, void *socket, void *const pkt, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
|
||||
mDNSexport void ProxyUDPCallback(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
|
||||
const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context)
|
||||
{
|
||||
LogInfo("ProxyUDPCallback: DNS Message from %#a:%d to %#a:%d length %d", srcaddr, mDNSVal16(srcport), dstaddr, mDNSVal16(dstport), end - (mDNSu8 *)pkt);
|
||||
ProxyCallbackCommon(m, socket, pkt, end, srcaddr, srcport, dstaddr, dstport, InterfaceID, mDNSfalse, context);
|
||||
LogInfo("ProxyUDPCallback: DNS Message from %#a:%d to %#a:%d length %d", srcaddr, mDNSVal16(srcport), dstaddr, mDNSVal16(dstport), (int)(end - (mDNSu8 *)msg));
|
||||
ProxyCallbackCommon(socket, msg, end, srcaddr, srcport, dstaddr, dstport, InterfaceID, mDNSfalse, context);
|
||||
}
|
||||
|
||||
mDNSexport void ProxyTCPCallback(mDNS *const m, void *socket, void *const pkt, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
|
||||
mDNSexport void ProxyTCPCallback(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
|
||||
const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context)
|
||||
{
|
||||
LogInfo("ProxyTCPCallback: DNS Message from %#a:%d to %#a:%d length %d", srcaddr, mDNSVal16(srcport), dstaddr, mDNSVal16(dstport), end - (mDNSu8 *)pkt);
|
||||
// If the connection was closed from the other side, locate the client
|
||||
LogInfo("ProxyTCPCallback: DNS Message from %#a:%d to %#a:%d length %d", srcaddr, mDNSVal16(srcport), dstaddr, mDNSVal16(dstport), (int)(end - (mDNSu8 *)msg));
|
||||
|
||||
// If the connection was closed from the other side or incoming packet does not match stored input interface list, locate the client
|
||||
// state and free it.
|
||||
if ((end - (mDNSu8 *)pkt) == 0)
|
||||
if (((end - (mDNSu8 *)msg) == 0) || (!CheckDNSProxyIpIntf(InterfaceID)))
|
||||
{
|
||||
DNSProxyClient **ppc = &DNSProxyClients;
|
||||
DNSProxyClient **prevpc;
|
||||
|
@ -763,11 +770,12 @@ mDNSexport void ProxyTCPCallback(mDNS *const m, void *socket, void *const pkt, c
|
|||
FreeDNSProxyClient(*ppc);
|
||||
return;
|
||||
}
|
||||
ProxyCallbackCommon(m, socket, pkt, end, srcaddr, srcport, dstaddr, dstport, InterfaceID, mDNStrue, context);
|
||||
ProxyCallbackCommon(socket, msg, end, srcaddr, srcport, dstaddr, dstport, InterfaceID, mDNStrue, context);
|
||||
}
|
||||
|
||||
mDNSexport void DNSProxyInit(mDNS *const m, mDNSu32 IpIfArr[MaxIp], mDNSu32 OpIf)
|
||||
mDNSexport void DNSProxyInit(mDNSu32 IpIfArr[MaxIp], mDNSu32 OpIf)
|
||||
{
|
||||
mDNS *const m = &mDNSStorage;
|
||||
int i;
|
||||
|
||||
// Store DNSProxy Interface fields in mDNS struct
|
||||
|
@ -779,8 +787,9 @@ mDNSexport void DNSProxyInit(mDNS *const m, mDNSu32 IpIfArr[MaxIp], mDNSu32 OpIf
|
|||
m->dp_ipintf[1], m->dp_ipintf[2], m->dp_ipintf[3], m->dp_ipintf[4], m->dp_opintf);
|
||||
}
|
||||
|
||||
mDNSexport void DNSProxyTerminate(mDNS *const m)
|
||||
mDNSexport void DNSProxyTerminate(void)
|
||||
{
|
||||
mDNS *const m = &mDNSStorage;
|
||||
int i;
|
||||
|
||||
// Clear DNSProxy Interface fields from mDNS struct
|
||||
|
@ -793,11 +802,10 @@ mDNSexport void DNSProxyTerminate(mDNS *const m)
|
|||
}
|
||||
#else // UNICAST_DISABLED
|
||||
|
||||
mDNSexport void ProxyUDPCallback(mDNS *const m, void *socket, void *const pkt, const mDNSu8 *const end, const mDNSAddr *const srcaddr, const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context)
|
||||
mDNSexport void ProxyUDPCallback(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr, const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context)
|
||||
{
|
||||
(void) m;
|
||||
(void) socket;
|
||||
(void) pkt;
|
||||
(void) msg;
|
||||
(void) end;
|
||||
(void) srcaddr;
|
||||
(void) srcport;
|
||||
|
@ -807,11 +815,10 @@ mDNSexport void ProxyUDPCallback(mDNS *const m, void *socket, void *const pkt, c
|
|||
(void) context;
|
||||
}
|
||||
|
||||
mDNSexport void ProxyTCPCallback(mDNS *const m, void *socket, void *const pkt, const mDNSu8 *const end, const mDNSAddr *const srcaddr, const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context)
|
||||
mDNSexport void ProxyTCPCallback(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr, const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context)
|
||||
{
|
||||
(void) m;
|
||||
(void) socket;
|
||||
(void) pkt;
|
||||
(void) msg;
|
||||
(void) end;
|
||||
(void) srcaddr;
|
||||
(void) srcport;
|
||||
|
@ -821,15 +828,13 @@ mDNSexport void ProxyTCPCallback(mDNS *const m, void *socket, void *const pkt, c
|
|||
(void) context;
|
||||
}
|
||||
|
||||
mDNSexport void DNSProxyInit(mDNS *const m, mDNSu32 IpIfArr[MaxIp], mDNSu32 OpIf)
|
||||
mDNSexport void DNSProxyInit(mDNSu32 IpIfArr[MaxIp], mDNSu32 OpIf)
|
||||
{
|
||||
(void) m;
|
||||
(void) IpIfArr;
|
||||
(void) OpIf;
|
||||
}
|
||||
extern void DNSProxyTerminate(mDNS *const m)
|
||||
extern void DNSProxyTerminate(void)
|
||||
{
|
||||
(void) m;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2011-2013 Apple 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.
|
||||
|
@ -14,17 +14,18 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __DNS_PROXY_H
|
||||
#define __DNS_PROXY_H
|
||||
|
||||
#include "mDNSEmbeddedAPI.h"
|
||||
#include "DNSCommon.h"
|
||||
|
||||
extern void ProxyUDPCallback(mDNS *const m, void *socket, void *const pkt, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
|
||||
extern void ProxyUDPCallback(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
|
||||
const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context);
|
||||
extern void ProxyTCPCallback(mDNS *const m, void *socket, void *const pkt, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
|
||||
extern void ProxyTCPCallback(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
|
||||
const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context);
|
||||
extern void DNSProxyInit(mDNS *const m, mDNSu32 IpIfArr[MaxIp], mDNSu32 OpIf);
|
||||
extern void DNSProxyTerminate(mDNS *const m);
|
||||
extern void DNSProxyInit(mDNSu32 IpIfArr[MaxIp], mDNSu32 OpIf);
|
||||
extern void DNSProxyTerminate(void);
|
||||
|
||||
#endif // __DNS_PROXY_H
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2011-2013 Apple 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.
|
||||
|
@ -14,6 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mDNSEmbeddedAPI.h"
|
||||
#include "DNSSECSupport.h"
|
||||
#include "DNSCommon.h"
|
||||
|
@ -86,6 +87,7 @@ mDNSlocal mDNSBool TrustedKeyPresent(mDNS *const m, DNSSECVerifier *dv);
|
|||
mDNSlocal mStatus ValidateDS(DNSSECVerifier *dv);
|
||||
mDNSlocal void DNSSECNegativeValidationCB(mDNS *const m, DNSSECVerifier *dv, CacheGroup *cg, ResourceRecord *answer, DNSSECStatus status);
|
||||
mDNSlocal RRVerifier* CopyRRVerifier(RRVerifier *from);
|
||||
mDNSlocal void FreeDNSSECAuthChainInfo(AuthChain *ac);
|
||||
|
||||
// Currently we use this to convert a RRVerifier to resource record so that we can
|
||||
// use the standard DNS utility functions
|
||||
|
@ -299,6 +301,8 @@ mDNSlocal AuthChain *AuthChainCopy(AuthChain *ae)
|
|||
if (!ac)
|
||||
{
|
||||
LogMsg("AuthChainCopy: AuthChain alloc failure");
|
||||
if (retac)
|
||||
FreeDNSSECAuthChainInfo(retac);
|
||||
return mDNSfalse;
|
||||
}
|
||||
|
||||
|
@ -309,7 +313,7 @@ mDNSlocal AuthChain *AuthChainCopy(AuthChain *ae)
|
|||
|
||||
rvfrom = ae->rrset;
|
||||
rvto = &ac->rrset;
|
||||
while (rvfrom)
|
||||
while (rvfrom && rvto)
|
||||
{
|
||||
*rvto = CopyRRVerifier(rvfrom);
|
||||
rvfrom = rvfrom->next;
|
||||
|
@ -318,7 +322,7 @@ mDNSlocal AuthChain *AuthChainCopy(AuthChain *ae)
|
|||
|
||||
rvfrom = ae->rrsig;
|
||||
rvto = &ac->rrsig;
|
||||
while (rvfrom)
|
||||
while (rvfrom && rvto)
|
||||
{
|
||||
*rvto = CopyRRVerifier(rvfrom);
|
||||
rvfrom = rvfrom->next;
|
||||
|
@ -327,7 +331,7 @@ mDNSlocal AuthChain *AuthChainCopy(AuthChain *ae)
|
|||
|
||||
rvfrom = ae->key;
|
||||
rvto = &ac->key;
|
||||
while (rvfrom)
|
||||
while (rvfrom && rvto)
|
||||
{
|
||||
*rvto = CopyRRVerifier(rvfrom);
|
||||
rvfrom = rvfrom->next;
|
||||
|
@ -703,7 +707,6 @@ mDNSexport void ValidateRRSIG(DNSSECVerifier *dv, RRVerifierSet type, const Reso
|
|||
|
||||
mDNSlocal mStatus CheckRRSIGForRRSet(mDNS *const m, DNSSECVerifier *dv, CacheRecord **negcr)
|
||||
{
|
||||
mDNSu32 slot;
|
||||
CacheGroup *cg;
|
||||
CacheRecord *cr;
|
||||
RRVerifier *rv;
|
||||
|
@ -718,8 +721,7 @@ mDNSlocal mStatus CheckRRSIGForRRSet(mDNS *const m, DNSSECVerifier *dv, CacheRec
|
|||
}
|
||||
|
||||
rv = dv->rrset;
|
||||
slot = HashSlot(&rv->name);
|
||||
cg = CacheGroupForName(m, slot, rv->namehash, &rv->name);
|
||||
cg = CacheGroupForName(m, rv->namehash, &rv->name);
|
||||
if (!cg)
|
||||
{
|
||||
debugdnssec("CheckRRSIGForRRSet: cg null");
|
||||
|
@ -803,7 +805,6 @@ mDNSlocal void CheckOneKeyForRRSIG(DNSSECVerifier *dv, const ResourceRecord *con
|
|||
|
||||
mDNSlocal mStatus CheckKeyForRRSIG(mDNS *const m, DNSSECVerifier *dv, CacheRecord **negcr)
|
||||
{
|
||||
mDNSu32 slot;
|
||||
mDNSu32 namehash;
|
||||
CacheGroup *cg;
|
||||
CacheRecord *cr;
|
||||
|
@ -821,9 +822,8 @@ mDNSlocal mStatus CheckKeyForRRSIG(mDNS *const m, DNSSECVerifier *dv, CacheRecor
|
|||
rrsig = (rdataRRSig *)dv->rrsig->rdata;
|
||||
name = (domainname *)&rrsig->signerName;
|
||||
|
||||
slot = HashSlot(name);
|
||||
namehash = DomainNameHashValue(name);
|
||||
cg = CacheGroupForName(m, slot, namehash, name);
|
||||
cg = CacheGroupForName(m, namehash, name);
|
||||
if (!cg)
|
||||
{
|
||||
debugdnssec("CheckKeyForRRSIG: cg null for %##s", name->c);
|
||||
|
@ -883,7 +883,6 @@ mDNSlocal void CheckOneRRSIGForKey(DNSSECVerifier *dv, const ResourceRecord *con
|
|||
|
||||
mDNSlocal mStatus CheckRRSIGForKey(mDNS *const m, DNSSECVerifier *dv, CacheRecord **negcr)
|
||||
{
|
||||
mDNSu32 slot;
|
||||
mDNSu32 namehash;
|
||||
CacheGroup *cg;
|
||||
CacheRecord *cr;
|
||||
|
@ -905,9 +904,8 @@ mDNSlocal mStatus CheckRRSIGForKey(mDNS *const m, DNSSECVerifier *dv, CacheRecor
|
|||
rrsig = (rdataRRSig *)dv->rrsig->rdata;
|
||||
name = (domainname *)&rrsig->signerName;
|
||||
|
||||
slot = HashSlot(name);
|
||||
namehash = DomainNameHashValue(name);
|
||||
cg = CacheGroupForName(m, slot, namehash, name);
|
||||
cg = CacheGroupForName(m, namehash, name);
|
||||
if (!cg)
|
||||
{
|
||||
debugdnssec("CheckRRSIGForKey: cg null %##s", name->c);
|
||||
|
@ -1006,7 +1004,6 @@ mDNSlocal void CheckOneDSForKey(DNSSECVerifier *dv, const ResourceRecord *const
|
|||
|
||||
mDNSlocal mStatus CheckDSForKey(mDNS *const m, DNSSECVerifier *dv, CacheRecord **negcr)
|
||||
{
|
||||
mDNSu32 slot;
|
||||
mDNSu32 namehash;
|
||||
CacheGroup *cg;
|
||||
CacheRecord *cr;
|
||||
|
@ -1026,9 +1023,8 @@ mDNSlocal mStatus CheckDSForKey(mDNS *const m, DNSSECVerifier *dv, CacheRecord *
|
|||
}
|
||||
rrsig = (rdataRRSig *)dv->rrsig->rdata;
|
||||
name = (domainname *)&rrsig->signerName;
|
||||
slot = HashSlot(name);
|
||||
namehash = DomainNameHashValue(name);
|
||||
cg = CacheGroupForName(m, slot, namehash, name);
|
||||
cg = CacheGroupForName(m, namehash, name);
|
||||
if (!cg)
|
||||
{
|
||||
debugdnssec("CheckDSForKey: cg null for %s", name->c);
|
||||
|
@ -1065,7 +1061,6 @@ mDNSlocal mStatus CheckDSForKey(mDNS *const m, DNSSECVerifier *dv, CacheRecord *
|
|||
return mStatus_NoError;
|
||||
else
|
||||
return mStatus_NoSuchRecord;
|
||||
return (dv->ds ? mStatus_NoError : mStatus_NoSuchRecord);
|
||||
}
|
||||
|
||||
// It returns mDNStrue if we have all the rrsets for verification and mDNSfalse otherwise.
|
||||
|
@ -2333,10 +2328,7 @@ mDNSlocal void SetTTLRRSet(mDNS *const m, DNSSECVerifier *dv, DNSSECStatus statu
|
|||
CacheRecord *rr;
|
||||
RRVerifier *rrsigv;
|
||||
rdataRRSig *rrsig;
|
||||
mDNSu32 slot;
|
||||
CacheGroup *cg;
|
||||
int sigNameLen, len;
|
||||
mDNSu8 *ptr;
|
||||
mDNSu32 rrTTL, rrsigTTL, rrsigOrigTTL, rrsigTimeTTL;
|
||||
domainname *qname;
|
||||
mDNSu16 qtype;
|
||||
|
@ -2367,8 +2359,7 @@ mDNSlocal void SetTTLRRSet(mDNS *const m, DNSSECVerifier *dv, DNSSECStatus statu
|
|||
|
||||
question.ThisQInterval = -1;
|
||||
InitializeQuestion(m, &question, dv->InterfaceID, qname, qtype, mDNSNULL, mDNSNULL);
|
||||
slot = HashSlot(&question.qname);
|
||||
cg = CacheGroupForName(m, slot, question.qnamehash, &question.qname);
|
||||
cg = CacheGroupForName(m, question.qnamehash, &question.qname);
|
||||
|
||||
if (!cg)
|
||||
{
|
||||
|
@ -2400,17 +2391,11 @@ mDNSlocal void SetTTLRRSet(mDNS *const m, DNSSECVerifier *dv, DNSSECStatus statu
|
|||
{
|
||||
rrsigv = dv->ac->rrsig;
|
||||
rrsig = (rdataRRSig *)rrsigv->rdata;
|
||||
sigNameLen = DomainNameLength((domainname *)&rrsig->signerName);
|
||||
// pointer to signature and the length
|
||||
ptr = (mDNSu8 *)(rrsigv->rdata + sigNameLen + RRSIG_FIXED_SIZE);
|
||||
len = rrsigv->rdlength - RRSIG_FIXED_SIZE - sigNameLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
rrsigv = mDNSNULL;
|
||||
rrsig = mDNSNULL;
|
||||
ptr = mDNSNULL;
|
||||
sigNameLen = len = 0;
|
||||
}
|
||||
|
||||
rrsigRR = mDNSNULL;
|
||||
|
@ -2531,7 +2516,9 @@ mDNSlocal void FinishDNSSECVerification(mDNS *const m, DNSSECVerifier *dv)
|
|||
LogDNSSEC("FinishDNSSECVerification: all rdata sets available for sig verification for %##s (%s)",
|
||||
dv->origName.c, DNSTypeName(dv->origType));
|
||||
|
||||
mDNS_StopQuery(m, &dv->q);
|
||||
// Stop outstanding query if one exists
|
||||
if (dv->q.ThisQInterval != -1)
|
||||
mDNS_StopQuery(m, &dv->q);
|
||||
if (ValidateSignature(dv, &resultKey, &resultRRSig) == mStatus_NoError)
|
||||
{
|
||||
rdataDNSKey *key;
|
||||
|
@ -2694,7 +2681,7 @@ mDNSlocal void DNSSECNoResponse(mDNS *const m, DNSSECVerifier *dv)
|
|||
{
|
||||
CacheGroup *cg;
|
||||
CacheRecord *cr;
|
||||
mDNSu32 slot, namehash;
|
||||
mDNSu32 namehash;
|
||||
ResourceRecord *answer = mDNSNULL;
|
||||
|
||||
LogDNSSEC("DNSSECNoResponse: called");
|
||||
|
@ -2707,10 +2694,9 @@ mDNSlocal void DNSSECNoResponse(mDNS *const m, DNSSECVerifier *dv)
|
|||
|
||||
BumpDNSSECStats(m, kStatsActionSet, kStatsTypeStatus, DNSSEC_NoResponse);
|
||||
|
||||
slot = HashSlot(&dv->origName);
|
||||
namehash = DomainNameHashValue(&dv->origName);
|
||||
|
||||
cg = CacheGroupForName(m, (const mDNSu32)slot, namehash, &dv->origName);
|
||||
cg = CacheGroupForName(m, namehash, &dv->origName);
|
||||
if (!cg)
|
||||
{
|
||||
LogDNSSEC("DNSSECNoResponse: cg NULL for %##s (%s)", dv->origName.c, DNSTypeName(dv->origType));
|
||||
|
@ -3036,7 +3022,7 @@ done:
|
|||
|
||||
mDNSlocal void DNSSECValidationCB(mDNS *const m, DNSSECVerifier *dv, DNSSECStatus status)
|
||||
{
|
||||
mDNSu32 slot, namehash;
|
||||
mDNSu32 namehash;
|
||||
CacheGroup *cg;
|
||||
CacheRecord *cr;
|
||||
|
||||
|
@ -3056,10 +3042,9 @@ mDNSlocal void DNSSECValidationCB(mDNS *const m, DNSSECVerifier *dv, DNSSECStatu
|
|||
ProveInsecure(m, dv, mDNSNULL, mDNSNULL);
|
||||
return;
|
||||
}
|
||||
slot = HashSlot(&dv->origName);
|
||||
namehash = DomainNameHashValue(&dv->origName);
|
||||
|
||||
cg = CacheGroupForName(m, (const mDNSu32)slot, namehash, &dv->origName);
|
||||
cg = CacheGroupForName(m, namehash, &dv->origName);
|
||||
if (!cg)
|
||||
{
|
||||
LogDNSSEC("DNSSECValidationCB: cg NULL for %##s (%s)", dv->origName.c, DNSTypeName(dv->origType));
|
||||
|
@ -3085,8 +3070,7 @@ mDNSlocal void DNSSECValidationCB(mDNS *const m, DNSSECVerifier *dv, DNSSECStatu
|
|||
|
||||
mDNSexport void VerifySignature(mDNS *const m, DNSSECVerifier *dv, DNSQuestion *q)
|
||||
{
|
||||
mDNSu32 slot = HashSlot(&q->qname);
|
||||
CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
|
||||
CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
|
||||
CacheRecord *rr;
|
||||
mDNSBool first = mDNSfalse;
|
||||
static mDNSBool TrustAnchorsUpdated = mDNSfalse;
|
||||
|
@ -3187,14 +3171,11 @@ mDNSexport void VerifySignature(mDNS *const m, DNSSECVerifier *dv, DNSQuestion *
|
|||
|
||||
mDNSlocal mDNSBool TrustedKeyPresent(mDNS *const m, DNSSECVerifier *dv)
|
||||
{
|
||||
rdataRRSig *rrsig;
|
||||
rdataDS *ds;
|
||||
rdataDNSKey *key;
|
||||
TrustAnchor *ta;
|
||||
RRVerifier *keyv;
|
||||
|
||||
rrsig = (rdataRRSig *)dv->rrsig->rdata;
|
||||
|
||||
// Walk all our trusted DS Records to see if we have a matching DNS KEY record that verifies
|
||||
// the hash. If we find one, verify that this key was used to sign the KEY rrsets in
|
||||
// this zone. Loop till we find one.
|
||||
|
@ -3325,14 +3306,12 @@ mDNSlocal mStatus TrustedKey(mDNS *const m, DNSSECVerifier *dv)
|
|||
|
||||
mDNSlocal CacheRecord* NegativeCacheRecordForRR(mDNS *const m, const ResourceRecord *const rr)
|
||||
{
|
||||
mDNSu32 slot;
|
||||
mDNSu32 namehash;
|
||||
CacheGroup *cg;
|
||||
CacheRecord *cr;
|
||||
|
||||
slot = HashSlot(rr->name);
|
||||
namehash = DomainNameHashValue(rr->name);
|
||||
cg = CacheGroupForName(m, slot, namehash, rr->name);
|
||||
cg = CacheGroupForName(m, namehash, rr->name);
|
||||
if (!cg)
|
||||
{
|
||||
LogMsg("NegativeCacheRecordForRR: cg null %##s", rr->name->c);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2011-2013 Apple 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.
|
||||
|
@ -14,6 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __DNSSEC_H
|
||||
#define __DNSSEC_H
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2002-2015 Apple 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.
|
||||
|
@ -148,12 +148,18 @@ extern void LogMsgWithLevel(mDNSLogLevel_t logLevel, const char *format, ...) IS
|
|||
// (or completely overhauled to use the new "log to a separate file" facility)
|
||||
#define LogMsgNoIdent LogMsg
|
||||
|
||||
#if APPLE_OSX_mDNSResponder
|
||||
extern void LogFatalError(const char *format, ...);
|
||||
#else
|
||||
#define LogFatalError LogMsg
|
||||
#endif
|
||||
|
||||
#if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING >= 1
|
||||
extern void *mallocL(char *msg, unsigned int size);
|
||||
extern void freeL(char *msg, void *x);
|
||||
extern void LogMemCorruption(const char *format, ...);
|
||||
extern void uds_validatelists(void);
|
||||
extern void udns_validatelists(void *const v);
|
||||
extern void LogMemCorruption(const char *format, ...);
|
||||
#else
|
||||
#define mallocL(X,Y) malloc(Y)
|
||||
#define freeL(X,Y) free(Y)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2002-2013 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2002-2015 Apple 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.
|
||||
|
@ -70,6 +70,7 @@
|
|||
#include "mDNSDebug.h"
|
||||
#if APPLE_OSX_mDNSResponder
|
||||
#include <uuid/uuid.h>
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -90,20 +91,14 @@ extern "C" {
|
|||
|
||||
// In order to disable the above features pass the option to your compiler, e.g. -D UNICAST_DISABLED
|
||||
|
||||
// Additionally, the LIMITED_RESOURCES_TARGET compile option will eliminate caching and
|
||||
// and reduce the maximum DNS message sizes.
|
||||
// Additionally, the LIMITED_RESOURCES_TARGET compile option will reduce the maximum DNS message sizes.
|
||||
|
||||
#ifdef LIMITED_RESOURCES_TARGET
|
||||
// Don't support jumbo frames
|
||||
#define AbsoluteMaxDNSMessageData 1500
|
||||
// By the time you add IPv6 header (40 bytes) UDP header (8 bytes) and DNS message header (12 bytes)
|
||||
// this makes 1560 which is 60 bytes over the standard Ethernet MTU. D'oh!
|
||||
|
||||
// 40 (IPv6 header) + 8 (UDP header) + 12 (DNS message header) + 1440 (DNS message body) = 1500 total
|
||||
#define AbsoluteMaxDNSMessageData 1440
|
||||
// StandardAuthRDSize is 264 (256+8), which is large enough to hold a maximum-sized SRV record (6 + 256 bytes)
|
||||
#define MaximumRDSize 264
|
||||
// Don't cache anything
|
||||
#define AUTH_HASH_SLOTS 1
|
||||
#define CACHE_HASH_SLOTS 1
|
||||
#define MaximumRDSize 264
|
||||
#endif
|
||||
|
||||
// ***************************************************************************
|
||||
|
@ -301,21 +296,26 @@ typedef mDNSOpaque48 mDNSEthAddr; // An Ethernet address is a six-byte opa
|
|||
#define bit_set_opaque64(op64, index) (op64.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] |= (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
|
||||
#define bit_clr_opaque64(op64, index) (op64.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] &= ~(1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
|
||||
#define bit_get_opaque64(op64, index) (op64.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] & (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
|
||||
|
||||
// Bit operations for opaque 128 bit quantity. Uses the 32 bit quantity(l[4]) to set and clear bits
|
||||
#define bit_set_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] |= (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
|
||||
#define bit_clr_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] &= ~(1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
|
||||
#define bit_get_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] & (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
|
||||
|
||||
enum
|
||||
typedef enum
|
||||
{
|
||||
mDNSAddrType_None = 0,
|
||||
mDNSAddrType_IPv4 = 4,
|
||||
mDNSAddrType_IPv6 = 6,
|
||||
mDNSAddrType_Unknown = ~0 // Special marker value used in known answer list recording
|
||||
};
|
||||
} mDNSAddr_Type;
|
||||
|
||||
enum
|
||||
typedef enum
|
||||
{
|
||||
mDNSTransport_None = 0,
|
||||
mDNSTransport_UDP = 1,
|
||||
mDNSTransport_TCP = 2
|
||||
};
|
||||
} mDNSTransport_Type;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -369,7 +369,8 @@ enum
|
|||
mStatus_NoRouter = -65566,
|
||||
mStatus_PollingMode = -65567,
|
||||
mStatus_Timeout = -65568,
|
||||
// -65568 to -65786 currently unused; available for allocation
|
||||
mStatus_HostUnreachErr = -65569,
|
||||
// -65570 to -65786 currently unused; available for allocation
|
||||
|
||||
// tcp connection status
|
||||
mStatus_ConnPending = -65787,
|
||||
|
@ -486,7 +487,7 @@ typedef struct UDPSocket_struct UDPSocket;
|
|||
#define mDNS_numPrereqs numAnswers
|
||||
#define mDNS_numUpdates numAuthorities
|
||||
|
||||
typedef packedstruct
|
||||
typedef struct
|
||||
{
|
||||
mDNSOpaque16 id;
|
||||
mDNSOpaque16 flags;
|
||||
|
@ -503,7 +504,7 @@ typedef packedstruct
|
|||
#define AbsoluteMaxDNSMessageData 8940
|
||||
#endif
|
||||
#define NormalMaxDNSMessageData 1440
|
||||
typedef packedstruct
|
||||
typedef struct
|
||||
{
|
||||
DNSMessageHeader h; // Note: Size 12 bytes
|
||||
mDNSu8 data[AbsoluteMaxDNSMessageData]; // 40 (IPv6) + 8 (UDP) + 12 (DNS header) + 8940 (data) = 9000
|
||||
|
@ -556,7 +557,7 @@ typedef packedstruct
|
|||
{
|
||||
mDNSu8 vlen;
|
||||
mDNSu8 tos;
|
||||
mDNSu16 totlen;
|
||||
mDNSOpaque16 totlen;
|
||||
mDNSOpaque16 id;
|
||||
mDNSOpaque16 flagsfrags;
|
||||
mDNSu8 ttl;
|
||||
|
@ -621,7 +622,7 @@ typedef packedstruct
|
|||
mDNSu16 checksum;
|
||||
} UDPHeader; // 8 bytes; IP protocol type 0x11
|
||||
|
||||
typedef packedstruct
|
||||
typedef struct
|
||||
{
|
||||
mDNSu8 type; // 0x87 == Neighbor Solicitation, 0x88 == Neighbor Advertisement
|
||||
mDNSu8 code;
|
||||
|
@ -726,7 +727,7 @@ typedef packedstruct
|
|||
// Bit 6 (value 0x40) is set for answer records; clear for authority/additional records
|
||||
// Bit 5 (value 0x20) is set for records received with the kDNSClass_UniqueRRSet
|
||||
|
||||
enum
|
||||
typedef enum
|
||||
{
|
||||
kDNSRecordTypeUnregistered = 0x00, // Not currently in any list
|
||||
kDNSRecordTypeDeregistering = 0x01, // Shared record about to announce its departure and leave the list
|
||||
|
@ -754,7 +755,7 @@ enum
|
|||
kDNSRecordTypePacketNegative = 0xF0, // Pseudo-RR generated to cache non-existence results like NXDomain
|
||||
|
||||
kDNSRecordTypePacketUniqueMask = 0x10 // True for PacketAddUnique, PacketAnsUnique, PacketAuthUnique, kDNSRecordTypePacketNegative
|
||||
};
|
||||
} kDNSRecordTypes;
|
||||
|
||||
typedef packedstruct { mDNSu16 priority; mDNSu16 weight; mDNSIPPort port; domainname target; } rdataSRV;
|
||||
typedef packedstruct { mDNSu16 preference; domainname exchange; } rdataMX;
|
||||
|
@ -813,14 +814,14 @@ typedef struct TrustAnchor
|
|||
struct TrustAnchor *next;
|
||||
int digestLen;
|
||||
mDNSu32 validFrom;
|
||||
mDNSu32 validUntil;
|
||||
mDNSu32 validUntil;
|
||||
domainname zone;
|
||||
rdataDS rds;
|
||||
} TrustAnchor;
|
||||
|
||||
//size of rdataRRSIG excluding signerName and signature (which are variable fields)
|
||||
#define RRSIG_FIXED_SIZE 18
|
||||
typedef packedstruct
|
||||
typedef struct
|
||||
{
|
||||
mDNSu16 typeCovered;
|
||||
mDNSu8 alg;
|
||||
|
@ -829,7 +830,7 @@ typedef packedstruct
|
|||
mDNSu32 sigExpireTime;
|
||||
mDNSu32 sigInceptTime;
|
||||
mDNSu16 keyTag;
|
||||
mDNSu8 *signerName;
|
||||
mDNSu8 signerName[1]; // signerName is a dynamically-sized array
|
||||
// mDNSu8 *signature
|
||||
} rdataRRSig;
|
||||
|
||||
|
@ -880,10 +881,10 @@ typedef packedstruct
|
|||
// For example, SHA-1 hash of 20 bytes will be encoded as 20/5 * 8 = 32 base32
|
||||
// bytes. For a max domain name size of 255 bytes of base32 encoding : (255/8)*5
|
||||
// is the max hash length possible.
|
||||
#define NSEC3_MAX_HASH_LEN 155
|
||||
#define NSEC3_MAX_HASH_LEN 155
|
||||
// In NSEC3, the names are hashed and stored in the first label and hence cannot exceed label
|
||||
// size.
|
||||
#define NSEC3_MAX_B32_LEN MAX_DOMAIN_LABEL
|
||||
#define NSEC3_MAX_B32_LEN MAX_DOMAIN_LABEL
|
||||
|
||||
// We define it here instead of dnssec.h so that these values can be used
|
||||
// in files without bringing in all of dnssec.h unnecessarily.
|
||||
|
@ -942,7 +943,7 @@ typedef struct
|
|||
} TracerOptData;
|
||||
|
||||
// Note: rdataOPT format may be repeated an arbitrary number of times in a single resource record
|
||||
typedef packedstruct
|
||||
typedef struct
|
||||
{
|
||||
mDNSu16 opt;
|
||||
mDNSu16 optlen;
|
||||
|
@ -1186,7 +1187,7 @@ typedef enum
|
|||
PCPResult_ExcesRemotePeer = 13
|
||||
} PCPResult_t;
|
||||
|
||||
typedef packedstruct
|
||||
typedef struct
|
||||
{
|
||||
mDNSu8 version;
|
||||
mDNSu8 opCode;
|
||||
|
@ -1201,7 +1202,7 @@ typedef packedstruct
|
|||
mDNSv6Addr extAddress;
|
||||
} PCPMapRequest;
|
||||
|
||||
typedef packedstruct
|
||||
typedef struct
|
||||
{
|
||||
mDNSu8 version;
|
||||
mDNSu8 opCode;
|
||||
|
@ -1312,16 +1313,11 @@ struct NATTraversalInfo_struct
|
|||
|
||||
enum
|
||||
{
|
||||
DNSServer_Untested = 0,
|
||||
DNSServer_Passed = 1,
|
||||
DNSServer_Failed = 2,
|
||||
DNSServer_Disabled = 3
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DNSServer_FlagDelete = 1,
|
||||
DNSServer_FlagNew = 2
|
||||
DNSServer_FlagDelete = 0x1,
|
||||
DNSServer_FlagNew = 0x2,
|
||||
#if APPLE_OSX_mDNSResponder
|
||||
DNSServer_FlagUnreachable = 0x4,
|
||||
#endif
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -1344,8 +1340,9 @@ enum
|
|||
{
|
||||
kScopeNone = 0, // DNS server used by unscoped questions
|
||||
kScopeInterfaceID = 1, // Scoped DNS server used only by scoped questions
|
||||
kScopeServiceID = 2 // Service specific DNS server used only by questions
|
||||
kScopeServiceID = 2, // Service specific DNS server used only by questions
|
||||
// have a matching serviceID
|
||||
kScopesMaxCount = 3 // Max count for scopes enum
|
||||
};
|
||||
|
||||
// Note: DNSSECAware is set if we are able to get a valid response to
|
||||
|
@ -1362,22 +1359,19 @@ typedef struct DNSServer
|
|||
mDNSs32 serviceID;
|
||||
mDNSAddr addr;
|
||||
mDNSIPPort port;
|
||||
mDNSOpaque16 testid;
|
||||
mDNSu32 flags; // Set when we're planning to delete this from the list
|
||||
mDNSu32 teststate; // Have we sent bug-detection query to this server?
|
||||
mDNSs32 lasttest; // Time we sent last bug-detection query to this server
|
||||
domainname domain; // name->server matching for "split dns"
|
||||
mDNSs32 penaltyTime; // amount of time this server is penalized
|
||||
mDNSu32 scoped; // See the scoped enum above
|
||||
mDNSu32 timeout; // timeout value for questions
|
||||
mDNSBool cellIntf; // Resolver from Cellular Interface ?
|
||||
mDNSu16 resGroupID; // ID of the resolver group that contains this DNSServer
|
||||
mDNSu8 retransDO; // Total Retransmissions for queries sent with DO option
|
||||
mDNSBool cellIntf; // Resolver from Cellular Interface?
|
||||
mDNSBool req_A; // If set, send v4 query (DNSConfig allows A queries)
|
||||
mDNSBool req_AAAA; // If set, send v6 query (DNSConfig allows AAAA queries)
|
||||
mDNSBool req_DO; // If set, okay to send DNSSEC queries (EDNS DO bit is supported)
|
||||
mDNSBool retransDO; // Total Retransmissions for queries sent with DO option
|
||||
mDNSBool DNSSECAware; // set if we are able to receive a response to a request
|
||||
// sent with DO option.
|
||||
mDNSBool DNSSECAware; // Set if we are able to receive a response to a request sent with DO option.
|
||||
mDNSBool isExpensive; // True if the interface to this server is expensive.
|
||||
} DNSServer;
|
||||
|
||||
typedef struct
|
||||
|
@ -1391,9 +1385,9 @@ typedef struct
|
|||
|
||||
struct ResourceRecord_struct
|
||||
{
|
||||
mDNSu8 RecordType; // See enum above
|
||||
mDNSu16 rrtype;
|
||||
mDNSu16 rrclass;
|
||||
mDNSu8 RecordType; // See kDNSRecordTypes enum.
|
||||
mDNSu16 rrtype; // See DNS_TypeValues enum.
|
||||
mDNSu16 rrclass; // See DNS_ClassValues enum.
|
||||
mDNSu32 rroriginalttl; // In seconds
|
||||
mDNSu16 rdlength; // Size of the raw rdata, in bytes, in the on-the-wire format
|
||||
// (In-memory storage may be larger, for structures containing 'holes', like SOA)
|
||||
|
@ -1413,7 +1407,7 @@ struct ResourceRecord_struct
|
|||
// that are interface-specific (e.g. address records, especially linklocal addresses)
|
||||
const domainname *name;
|
||||
RData *rdata; // Pointer to storage for this rdata
|
||||
DNSServer *rDNSServer; // Unicast DNS server authoritative for this entry;null for multicast
|
||||
DNSServer *rDNSServer; // Unicast DNS server authoritative for this entry; null for multicast
|
||||
AnonymousInfo *AnonInfo; // Anonymous Information
|
||||
};
|
||||
|
||||
|
@ -1502,7 +1496,7 @@ struct AuthRecord_struct
|
|||
|
||||
AuthRecord *next; // Next in list; first element of structure for efficiency reasons
|
||||
// Field Group 1: Common ResourceRecord fields
|
||||
ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit
|
||||
ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit (now 44/64)
|
||||
|
||||
// Field Group 2: Persistent metadata for Authoritative Records
|
||||
AuthRecord *Additional1; // Recommended additional record to include in response (e.g. SRV for PTR record)
|
||||
|
@ -1606,10 +1600,13 @@ struct AuthRecord_struct
|
|||
// Everywhere else in the code, the determination of whether a question is unicast is made by checking to see if TargetQID is nonzero.
|
||||
#define AuthRecord_uDNS(R) ((R)->resrec.InterfaceID == mDNSInterface_Any && !(R)->ForceMCast && !IsLocalDomain((R)->resrec.name))
|
||||
#define Question_uDNS(Q) ((Q)->InterfaceID == mDNSInterface_Unicast || (Q)->ProxyQuestion || \
|
||||
((Q)->InterfaceID != mDNSInterface_LocalOnly && (Q)->InterfaceID != mDNSInterface_P2P && !(Q)->ForceMCast && !IsLocalDomain(&(Q)->qname)))
|
||||
((Q)->InterfaceID != mDNSInterface_LocalOnly && (Q)->InterfaceID != mDNSInterface_P2P && (Q)->InterfaceID != mDNSInterface_BLE && !(Q)->ForceMCast && !IsLocalDomain(&(Q)->qname)))
|
||||
|
||||
// AuthRecordLocalOnly records are registered using mDNSInterface_LocalOnly and
|
||||
// AuthRecordP2P records are created by D2DServiceFound events. Both record types are kept on the same list.
|
||||
#define RRLocalOnly(rr) ((rr)->ARType == AuthRecordLocalOnly || (rr)->ARType == AuthRecordP2P)
|
||||
|
||||
// All other auth records, not including those defined as RRLocalOnly().
|
||||
#define RRAny(rr) ((rr)->ARType == AuthRecordAny || (rr)->ARType == AuthRecordAnyIncludeP2P || (rr)->ARType == AuthRecordAnyIncludeAWDL || (rr)->ARType == AuthRecordAnyIncludeAWDLandP2P)
|
||||
|
||||
// Question (A or AAAA) that is suppressed currently because IPv4 or IPv6 address
|
||||
|
@ -1634,7 +1631,7 @@ typedef struct ARListElem
|
|||
struct CacheRecord_struct
|
||||
{
|
||||
CacheRecord *next; // Next in list; first element of structure for efficiency reasons
|
||||
ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit
|
||||
ResourceRecord resrec; // 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit (now 44/64)
|
||||
|
||||
// Transient state for Cache Records
|
||||
CacheRecord *NextInKAList; // Link to the next element in the chain of known answers to send
|
||||
|
@ -1647,24 +1644,17 @@ struct CacheRecord_struct
|
|||
mDNSu8 UnansweredQueries; // Number of times we've issued a query for this record without getting an answer
|
||||
mDNSu8 CRDNSSECQuestion; // Set to 1 if this was created in response to a DNSSEC question
|
||||
mDNSOpaque16 responseFlags; // Second 16 bit in the DNS response
|
||||
#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
|
||||
mDNSu32 MPUnansweredQ; // Multi-packet query handling: Number of times we've seen a query for this record
|
||||
mDNSs32 MPLastUnansweredQT; // Multi-packet query handling: Last time we incremented MPUnansweredQ
|
||||
mDNSu32 MPUnansweredKA; // Multi-packet query handling: Number of times we've seen this record in a KA list
|
||||
mDNSBool MPExpectingKA; // Multi-packet query handling: Set when we increment MPUnansweredQ; allows one KA
|
||||
#endif
|
||||
CacheRecord *NextInCFList; // Set if this is in the list of records we just received with the cache flush bit set
|
||||
CacheRecord *nsec; // NSEC records needed for non-existence proofs
|
||||
CacheRecord *soa; // SOA record to return for proxy questions
|
||||
|
||||
mDNSAddr sourceAddress; // node from which we received this record
|
||||
// Size to here is 76 bytes when compiling 32-bit; 104 bytes when compiling 64-bit
|
||||
// Size to here is 76 bytes when compiling 32-bit; 104 bytes when compiling 64-bit (now 160 bytes for 64-bit)
|
||||
RData_small smallrdatastorage; // Storage for small records is right here (4 bytes header + 68 bytes data = 72 bytes)
|
||||
};
|
||||
|
||||
// Should match the CacheGroup_struct members, except namestorage[]. Only used to calculate
|
||||
// the size of the namestorage array in CacheGroup_struct so that
|
||||
// sizeof(CacheGroup) == sizeof(CacheRecord)
|
||||
// the size of the namestorage array in CacheGroup_struct so that sizeof(CacheGroup) == sizeof(CacheRecord)
|
||||
struct CacheGroup_base
|
||||
{
|
||||
CacheGroup *next;
|
||||
|
@ -1805,6 +1795,25 @@ enum
|
|||
|
||||
enum { NoAnswer_Normal = 0, NoAnswer_Suspended = 1, NoAnswer_Fail = 2 };
|
||||
|
||||
// DNS Push Notification
|
||||
typedef enum
|
||||
{
|
||||
DNSPUSH_NOERROR = 0,
|
||||
DNSPUSH_FORMERR = 1,
|
||||
DNSPUSH_SERVFAIL = 2,
|
||||
DNSPUSH_NOTIMP = 4,
|
||||
DNSPUSH_REFUSED = 5
|
||||
} DNSPUSH_ErrorCode;
|
||||
|
||||
typedef enum {
|
||||
DNSPUSH_INIT = 1,
|
||||
DNSPUSH_NOSERVER = 2,
|
||||
DNSPUSH_SERVERFOUND = 3,
|
||||
DNSPUSH_ESTABLISHED = 4
|
||||
} DNSPush_State;
|
||||
|
||||
|
||||
|
||||
#define HMAC_LEN 64
|
||||
#define HMAC_IPAD 0x36
|
||||
#define HMAC_OPAD 0x5c
|
||||
|
@ -1887,6 +1896,31 @@ typedef enum { DNSSECValNotRequired = 0, DNSSECValRequired, DNSSECValInProgress,
|
|||
// RFC 4122 defines it to be 16 bytes
|
||||
#define UUID_SIZE 16
|
||||
|
||||
#define AWD_METRICS (USE_AWD && TARGET_OS_EMBEDDED)
|
||||
|
||||
#if AWD_METRICS
|
||||
typedef struct
|
||||
{
|
||||
domainname * originalQName; // Name of original A/AAAA record if this question is for a CNAME record.
|
||||
mDNSu32 querySendCount; // Number of queries that have been sent to DNS servers so far.
|
||||
mDNSs32 firstQueryTime; // The time when the first query was sent to a DNS server.
|
||||
mDNSBool answered; // Has this question been answered?
|
||||
|
||||
} uDNSMetrics;
|
||||
#endif
|
||||
|
||||
// DNS64 code is only for iOS, which is currently the only Apple OS that supports DNS proxy network extensions.
|
||||
#define USE_DNS64 (HAVE_DNS64 && TARGET_OS_IOS)
|
||||
|
||||
#if USE_DNS64
|
||||
#include "DNS64State.h"
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_EMBEDDED
|
||||
extern mDNSu32 curr_num_regservices; // tracks the current number of services registered
|
||||
extern mDNSu32 max_num_regservices; // tracks the max number of simultaneous services registered by the device
|
||||
#endif
|
||||
|
||||
struct DNSQuestion_struct
|
||||
{
|
||||
// Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them.
|
||||
|
@ -1939,7 +1973,7 @@ struct DNSQuestion_struct
|
|||
|
||||
// |-> DNS Configuration related fields used in uDNS (Subset of Wide Area/Unicast fields)
|
||||
DNSServer *qDNSServer; // Caching server for this query (in the absence of an SRV saying otherwise)
|
||||
mDNSOpaque64 validDNSServers; // Valid DNSServers for this question
|
||||
mDNSOpaque128 validDNSServers; // Valid DNSServers for this question
|
||||
mDNSu16 noServerResponse; // At least one server did not respond.
|
||||
mDNSu16 triedAllServersOnce; // Tried all DNS servers once
|
||||
mDNSu8 unansweredQueries; // The number of unanswered queries to this server
|
||||
|
@ -1961,6 +1995,12 @@ struct DNSQuestion_struct
|
|||
// for TCP: there is some ambiguity in the use of this variable, but in general, it is
|
||||
// the number of TCP/TLS connection attempts for this LLQ state, or
|
||||
// the number of packets sent for this TCP/TLS connection
|
||||
|
||||
// DNS Push Notification fields. These fields are only meaningful when LongLived flag is set
|
||||
DNSPush_State dnsPushState; // The state of the DNS push notification negotiation
|
||||
mDNSAddr dnsPushServerAddr; // Address of the system acting as the DNS Push Server
|
||||
mDNSIPPort dnsPushServerPort; // Port on which the DNS Push Server is being advertised.
|
||||
|
||||
mDNSOpaque64 id;
|
||||
|
||||
// DNS Proxy fields
|
||||
|
@ -1968,7 +2008,7 @@ struct DNSQuestion_struct
|
|||
// till we populate in the cache
|
||||
mDNSBool DisallowPID; // Is the query allowed for the "PID" that we are sending on behalf of ?
|
||||
mDNSs32 ServiceID; // Service identifier to match against the DNS server
|
||||
|
||||
|
||||
// Client API fields: The client must set up these fields *before* calling mDNS_StartQuery()
|
||||
mDNSInterfaceID InterfaceID; // Non-zero if you want to issue queries only on a single specific IP interface
|
||||
mDNSu32 flags; // flags from original DNSService*() API request.
|
||||
|
@ -1983,8 +2023,6 @@ struct DNSQuestion_struct
|
|||
mDNSBool ForceMCast; // Set by client to force mDNS query, even for apparently uDNS names
|
||||
mDNSBool ReturnIntermed; // Set by client to request callbacks for intermediate CNAME/NXDOMAIN results
|
||||
mDNSBool SuppressUnusable; // Set by client to suppress unusable queries to be sent on the wire
|
||||
mDNSBool DenyOnCellInterface; // Set by client to suppress uDNS queries on cellular interface
|
||||
mDNSBool DenyOnExpInterface; // Set by client to suppress uDNS queries on expensive interface
|
||||
mDNSu8 RetryWithSearchDomains; // Retry with search domains if there is no entry in the cache or AuthRecords
|
||||
mDNSu8 TimeoutQuestion; // Timeout this question if there is no reply in configured time
|
||||
mDNSu8 WakeOnResolve; // Send wakeup on resolve
|
||||
|
@ -1997,48 +2035,19 @@ struct DNSQuestion_struct
|
|||
mDNSu8 ProxyDNSSECOK; // Proxy Question with EDNS0 DNSSEC OK bit set
|
||||
mDNSs32 pid; // Process ID of the client that is requesting the question
|
||||
mDNSu8 uuid[UUID_SIZE]; // Unique ID of the client that is requesting the question (valid only if pid is zero)
|
||||
mDNSu32 euid; // Effective User Id of the client that is requesting the question
|
||||
domainname *qnameOrig; // Copy of the original question name if it is not fully qualified
|
||||
mDNSQuestionCallback *QuestionCallback;
|
||||
void *QuestionContext;
|
||||
#if TARGET_OS_EMBEDDED
|
||||
uDNSMetrics metrics; // Data used for collecting unicast DNS query metrics.
|
||||
#endif
|
||||
#if USE_DNS64
|
||||
DNS64 dns64; // DNS64 state for performing IPv6 address synthesis on networks with NAT64.
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// Client API fields: The client must set up name and InterfaceID *before* calling mDNS_StartResolveService()
|
||||
// When the callback is invoked, ip, port, TXTlen and TXTinfo will have been filled in with the results learned from the network.
|
||||
domainname name;
|
||||
mDNSInterfaceID InterfaceID; // ID of the interface the response was received on
|
||||
mDNSAddr ip; // Remote (destination) IP address where this service can be accessed
|
||||
mDNSIPPort port; // Port where this service can be accessed
|
||||
mDNSu16 TXTlen;
|
||||
mDNSu8 TXTinfo[2048]; // Additional demultiplexing information (e.g. LPR queue name)
|
||||
} ServiceInfo;
|
||||
|
||||
// Note: Within an mDNSServiceInfoQueryCallback mDNS all API calls are legal except mDNS_Init(), mDNS_Exit(), mDNS_Execute()
|
||||
typedef struct ServiceInfoQuery_struct ServiceInfoQuery;
|
||||
typedef void mDNSServiceInfoQueryCallback (mDNS *const m, ServiceInfoQuery *query);
|
||||
struct ServiceInfoQuery_struct
|
||||
{
|
||||
// Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them.
|
||||
// No fields need to be set up by the client prior to calling mDNS_StartResolveService();
|
||||
// all required data is passed as parameters to that function.
|
||||
// The ServiceInfoQuery structure memory is working storage for mDNSCore to discover the requested information
|
||||
// and place it in the ServiceInfo structure. After the client has called mDNS_StopResolveService(), it may
|
||||
// dispose of the ServiceInfoQuery structure while retaining the results in the ServiceInfo structure.
|
||||
DNSQuestion qSRV;
|
||||
DNSQuestion qTXT;
|
||||
DNSQuestion qAv4;
|
||||
DNSQuestion qAv6;
|
||||
mDNSu8 GotSRV;
|
||||
mDNSu8 GotTXT;
|
||||
mDNSu8 GotADD;
|
||||
mDNSu32 Answers;
|
||||
ServiceInfo *info;
|
||||
mDNSServiceInfoQueryCallback *ServiceInfoQueryCallback;
|
||||
void *ServiceInfoQueryContext;
|
||||
};
|
||||
|
||||
typedef enum { ZoneServiceUpdate, ZoneServiceQuery, ZoneServiceLLQ } ZoneService;
|
||||
typedef enum { ZoneServiceUpdate, ZoneServiceQuery, ZoneServiceLLQ, ZoneServiceDNSPush } ZoneService;
|
||||
|
||||
typedef void ZoneDataCallback (mDNS *const m, mStatus err, const ZoneData *result);
|
||||
|
||||
|
@ -2145,6 +2154,8 @@ struct NetworkInterfaceInfo_struct
|
|||
mDNSu8 SendGoodbyes; // Send goodbyes on this interface while sleeping
|
||||
mDNSBool DirectLink; // a direct link, indicating we can skip the probe for
|
||||
// address records
|
||||
mDNSBool SupportsUnicastMDNSResponse; // Indicates that the interface supports unicast responses
|
||||
// to Bonjour queries. Generally true for an interface.
|
||||
};
|
||||
|
||||
#define SLE_DELETE 0x00000001
|
||||
|
@ -2259,8 +2270,33 @@ typedef struct
|
|||
mDNSu32 CacheRefreshed; // Number of times the cache was refreshed due to a response
|
||||
mDNSu32 WakeOnResolves; // Number of times we did a wake on resolve
|
||||
} mDNSStatistics;
|
||||
|
||||
extern void LogMDNSStatistics(mDNS *const m);
|
||||
|
||||
typedef struct mDNS_DNSPushNotificationServer DNSPushNotificationServer;
|
||||
typedef struct mDNS_DNSPushNotificationZone DNSPushNotificationZone;
|
||||
|
||||
struct mDNS_DNSPushNotificationServer
|
||||
{
|
||||
mDNSAddr serverAddr; // Server Address
|
||||
tcpInfo_t *connection; // TCP Connection pointer
|
||||
mDNSu32 numberOfQuestions; // Number of questions for this server
|
||||
DNSPushNotificationServer *next;
|
||||
} ;
|
||||
|
||||
struct mDNS_DNSPushNotificationZone
|
||||
{
|
||||
domainname zoneName;
|
||||
DNSPushNotificationServer *servers; // DNS Push Notification Servers for this zone
|
||||
mDNSu32 numberOfQuestions; // Number of questions for this zone
|
||||
DNSPushNotificationZone *next;
|
||||
} ;
|
||||
|
||||
|
||||
// Time constant (~= 260 hours ~= 10 days and 21 hours) used to set
|
||||
// various time values to a point well into the future.
|
||||
#define FutureTime 0x38000000
|
||||
|
||||
struct mDNS_struct
|
||||
{
|
||||
// Internal state fields. These hold the main internal state of mDNSCore;
|
||||
|
@ -2269,6 +2305,7 @@ struct mDNS_struct
|
|||
// all required data is passed as parameters to that function.
|
||||
|
||||
mDNS_PlatformSupport *p; // Pointer to platform-specific data of indeterminite size
|
||||
mDNSs32 NetworkChanged;
|
||||
mDNSBool CanReceiveUnicastOn5353;
|
||||
mDNSBool AdvertiseLocalAddresses;
|
||||
mDNSBool DivertMulticastAdvertisements; // from interfaces that do not advertise local addresses to local-only
|
||||
|
@ -2304,6 +2341,11 @@ struct mDNS_struct
|
|||
mDNSs32 NextScheduledNATOp; // Next time to send NAT-traversal packets
|
||||
mDNSs32 NextScheduledSPS; // Next time to purge expiring Sleep Proxy records
|
||||
mDNSs32 NextScheduledKA; // Next time to send Keepalive packets (SPS)
|
||||
#if BONJOUR_ON_DEMAND
|
||||
mDNSs32 NextBonjourDisableTime; // Next time to leave multicast group if Bonjour on Demand is enabled
|
||||
mDNSu8 BonjourEnabled; // Non zero if Bonjour is currently enabled by the Bonjour on Demand logic
|
||||
#endif // BONJOUR_ON_DEMAND
|
||||
mDNSs32 DelayConflictProcessing; // To prevent spurious confilcts due to stale packets on the wire/air.
|
||||
mDNSs32 RandomQueryDelay; // For de-synchronization of query packets on the wire
|
||||
mDNSu32 RandomReconfirmDelay; // For de-synchronization of reconfirmation queries on the wire
|
||||
mDNSs32 PktNum; // Unique sequence number assigned to each received packet
|
||||
|
@ -2320,9 +2362,6 @@ struct mDNS_struct
|
|||
// during which underying platform layer should inhibit system sleep
|
||||
mDNSs32 TimeSlept; // Time we went to sleep.
|
||||
|
||||
mDNSs32 StatStartTime; // Time we started gathering statistics during this interval.
|
||||
mDNSs32 NextStatLogTime; // Next time to log statistics.
|
||||
mDNSs32 ActiveStatTime; // Total time awake/gathering statistics for this log period.
|
||||
mDNSs32 UnicastPacketsSent; // Number of unicast packets sent.
|
||||
mDNSs32 MulticastPacketsSent; // Number of multicast packets sent.
|
||||
mDNSs32 RemoteSubnet; // Multicast packets received from outside our subnet.
|
||||
|
@ -2332,6 +2371,7 @@ struct mDNS_struct
|
|||
|
||||
mDNSs32 NextScheduledStopTime; // Next time to stop a question
|
||||
|
||||
mDNSs32 NextBLEServiceTime; // Next time to call the BLE discovery management layer. Non zero when active.
|
||||
|
||||
// These fields only required for mDNS Searcher...
|
||||
DNSQuestion *Questions; // List of all registered questions, active and inactive
|
||||
|
@ -2368,7 +2408,7 @@ struct mDNS_struct
|
|||
mDNSs32 ProbeFailTime;
|
||||
mDNSu32 NumFailedProbes;
|
||||
mDNSs32 SuppressProbes;
|
||||
Platform_t mDNS_plat;
|
||||
Platform_t mDNS_plat; // Why is this here in the “only required for mDNS Responder” section? -- SC
|
||||
|
||||
// Unicast-specific data
|
||||
mDNSs32 NextuDNSEvent; // uDNS next event
|
||||
|
@ -2418,11 +2458,15 @@ struct mDNS_struct
|
|||
mDNSBool SSDPWANPPPConnection; // whether we should send the SSDP query for WANIPConnection or WANPPPConnection
|
||||
mDNSIPPort UPnPRouterPort; // port we send discovery messages to
|
||||
mDNSIPPort UPnPSOAPPort; // port we send SOAP messages to
|
||||
mDNSu8 *UPnPRouterURL; // router's URL string
|
||||
char *UPnPRouterURL; // router's URL string
|
||||
mDNSBool UPnPWANPPPConnection; // whether we're using WANIPConnection or WANPPPConnection
|
||||
mDNSu8 *UPnPSOAPURL; // router's SOAP control URL string
|
||||
mDNSu8 *UPnPRouterAddressString; // holds both the router's address and port
|
||||
mDNSu8 *UPnPSOAPAddressString; // holds both address and port for SOAP messages
|
||||
char *UPnPSOAPURL; // router's SOAP control URL string
|
||||
char *UPnPRouterAddressString; // holds both the router's address and port
|
||||
char *UPnPSOAPAddressString; // holds both address and port for SOAP messages
|
||||
|
||||
// DNS Push Notification fields
|
||||
DNSPushNotificationServer *DNSPushServers; // DNS Push Notification Servers
|
||||
DNSPushNotificationZone *DNSPushZones;
|
||||
|
||||
// Sleep Proxy client fields
|
||||
AuthRecord *SPSRRSet; // To help the client keep track of the records registered with the sleep proxy
|
||||
|
@ -2445,7 +2489,6 @@ struct mDNS_struct
|
|||
|
||||
#if APPLE_OSX_mDNSResponder
|
||||
ClientTunnel *TunnelClients;
|
||||
uuid_t asl_uuid; // uuid for ASL logging
|
||||
void *WCF;
|
||||
#endif
|
||||
// DNS Proxy fields
|
||||
|
@ -2454,9 +2497,15 @@ struct mDNS_struct
|
|||
|
||||
TrustAnchor *TrustAnchors;
|
||||
int notifyToken;
|
||||
int uds_listener_skt; // Listening socket for incoming UDS clients
|
||||
mDNSBool mDNSOppCaching; // Opportunistic Caching
|
||||
int uds_listener_skt; // Listening socket for incoming UDS clients. This should not be here -- it's private to uds_daemon.c and nothing to do with mDNSCore -- SC
|
||||
mDNSu32 AutoTargetServices; // # of services that have AutoTarget set
|
||||
|
||||
#if BONJOUR_ON_DEMAND
|
||||
// Counters used in Bonjour on Demand logic.
|
||||
mDNSu32 NumAllInterfaceRecords; // Right now we count *all* multicast records here. Later we may want to change to count interface-specific records separately. (This count includes records on the DuplicateRecords list too.)
|
||||
mDNSu32 NumAllInterfaceQuestions; // Right now we count *all* multicast questions here. Later we may want to change to count interface-specific questions separately.
|
||||
#endif // BONJOUR_ON_DEMAND
|
||||
|
||||
DNSSECStatistics DNSSECStats;
|
||||
mDNSStatistics mDNSStats;
|
||||
|
||||
|
@ -2468,8 +2517,8 @@ struct mDNS_struct
|
|||
};
|
||||
|
||||
#define FORALL_CACHERECORDS(SLOT,CG,CR) \
|
||||
for ((SLOT) = 0; (SLOT) < CACHE_HASH_SLOTS; (SLOT)++) \
|
||||
for ((CG)=m->rrcache_hash[(SLOT)]; (CG); (CG)=(CG)->next) \
|
||||
for ((SLOT) = 0; (SLOT) < CACHE_HASH_SLOTS; (SLOT)++) \
|
||||
for ((CG)=m->rrcache_hash[(SLOT)]; (CG); (CG)=(CG)->next) \
|
||||
for ((CR) = (CG)->members; (CR); (CR)=(CR)->next)
|
||||
|
||||
// ***************************************************************************
|
||||
|
@ -2484,6 +2533,9 @@ extern const mDNSInterfaceID mDNSInterface_Unicast; // Special value
|
|||
extern const mDNSInterfaceID mDNSInterfaceMark; // Special value
|
||||
extern const mDNSInterfaceID mDNSInterface_P2P; // Special value
|
||||
extern const mDNSInterfaceID uDNSInterfaceMark; // Special value
|
||||
extern const mDNSInterfaceID mDNSInterface_BLE; // Special value
|
||||
|
||||
#define LocalOnlyOrP2PInterface(INTERFACE) ((INTERFACE == mDNSInterface_LocalOnly) || (INTERFACE == mDNSInterface_P2P) || (INTERFACE == mDNSInterface_BLE))
|
||||
|
||||
extern const mDNSIPPort DiscardPort;
|
||||
extern const mDNSIPPort SSHPort;
|
||||
|
@ -2525,11 +2577,17 @@ extern const mDNSOpaque16 DNSSecQFlags;
|
|||
extern const mDNSOpaque16 ResponseFlags;
|
||||
extern const mDNSOpaque16 UpdateReqFlags;
|
||||
extern const mDNSOpaque16 UpdateRespFlags;
|
||||
extern const mDNSOpaque16 SubscribeFlags;
|
||||
extern const mDNSOpaque16 UnSubscribeFlags;
|
||||
|
||||
extern const mDNSOpaque64 zeroOpaque64;
|
||||
|
||||
extern const mDNSOpaque128 zeroOpaque128;
|
||||
|
||||
extern mDNSBool StrictUnicastOrdering;
|
||||
extern mDNSu8 NumUnicastDNSServers;
|
||||
#if APPLE_OSX_mDNSResponder
|
||||
extern mDNSu8 NumUnreachableDNSServers;
|
||||
#endif
|
||||
|
||||
#define localdomain (*(const domainname *)"\x5" "local")
|
||||
#define DeviceInfoName (*(const domainname *)"\xC" "_device-info" "\x4" "_tcp")
|
||||
|
@ -2586,7 +2644,7 @@ mDNSinline mDNSOpaque16 mDNSOpaque16fromIntVal(mDNSu16 v)
|
|||
// Every client should call mDNS_Init, passing in storage for the mDNS object and the mDNS_PlatformSupport object.
|
||||
//
|
||||
// Clients that are only advertising services should use mDNS_Init_NoCache and mDNS_Init_ZeroCacheSize.
|
||||
// Clients that plan to perform queries (mDNS_StartQuery, mDNS_StartBrowse, mDNS_StartResolveService, etc.)
|
||||
// Clients that plan to perform queries (mDNS_StartQuery, mDNS_StartBrowse, etc.)
|
||||
// need to provide storage for the resource record cache, or the query calls will return 'mStatus_NoCache'.
|
||||
// The rrcachestorage parameter is the address of memory for the resource record cache, and
|
||||
// the rrcachesize parameter is the number of entries in the CacheRecord array passed in.
|
||||
|
@ -2648,7 +2706,6 @@ extern mStatus mDNS_Init (mDNS *const m, mDNS_PlatformSupport *const p,
|
|||
|
||||
extern void mDNS_ConfigChanged(mDNS *const m);
|
||||
extern void mDNS_GrowCache (mDNS *const m, CacheEntity *storage, mDNSu32 numrecords);
|
||||
extern void mDNS_GrowAuth (mDNS *const m, AuthEntity *storage, mDNSu32 numrecords);
|
||||
extern void mDNS_StartExit (mDNS *const m);
|
||||
extern void mDNS_FinalExit (mDNS *const m);
|
||||
#define mDNS_Close(m) do { mDNS_StartExit(m); mDNS_FinalExit(m); } while(0)
|
||||
|
@ -2700,11 +2757,6 @@ typedef enum { mDNS_Dereg_normal, mDNS_Dereg_rapid, mDNS_Dereg_conflict, mDNS_De
|
|||
|
||||
// mDNS_RegisterService is a single call to register the set of resource records associated with a given named service.
|
||||
//
|
||||
// mDNS_StartResolveService is single call which is equivalent to multiple calls to mDNS_StartQuery,
|
||||
// to find the IP address, port number, and demultiplexing information for a given named service.
|
||||
// As with mDNS_StartQuery, it executes asynchronously, and calls the ServiceInfoQueryCallback when the answer is
|
||||
// found. After the service is resolved, the client should call mDNS_StopResolveService to complete the transaction.
|
||||
// The client can also call mDNS_StopResolveService at any time to abort the transaction.
|
||||
//
|
||||
// mDNS_AddRecordToService adds an additional record to a Service Record Set. This record may be deregistered
|
||||
// via mDNS_RemoveRecordFromService, or by deregistering the service. mDNS_RemoveRecordFromService is passed a
|
||||
|
@ -2723,17 +2775,7 @@ typedef enum { mDNS_Dereg_normal, mDNS_Dereg_rapid, mDNS_Dereg_conflict, mDNS_De
|
|||
extern void mDNS_SetupResourceRecord(AuthRecord *rr, RData *RDataStorage, mDNSInterfaceID InterfaceID,
|
||||
mDNSu16 rrtype, mDNSu32 ttl, mDNSu8 RecordType, AuthRecType artype, mDNSRecordCallback Callback, void *Context);
|
||||
|
||||
// mDNS_RegisterService() flags parameter bit definitions.
|
||||
// Note these are only defined to transfer the corresponding DNSServiceFlags settings into mDNSCore routines,
|
||||
// since code in mDNSCore does not include the DNSServiceFlags definitions in dns_sd.h.
|
||||
enum
|
||||
{
|
||||
coreFlagIncludeP2P = 0x1, // include P2P interfaces when using mDNSInterface_Any
|
||||
coreFlagIncludeAWDL = 0x2, // include AWDL interface when using mDNSInterface_Any
|
||||
coreFlagKnownUnique = 0x4, // client guarantees that SRV and TXT record names are unique
|
||||
coreFlagWakeOnly = 0x8 // Service won't be registered with sleep proxy
|
||||
};
|
||||
|
||||
extern mDNSu32 deriveD2DFlagsFromAuthRecType(AuthRecType authRecType);
|
||||
extern mStatus mDNS_RegisterService (mDNS *const m, ServiceRecordSet *sr,
|
||||
const domainlabel *const name, const domainname *const type, const domainname *const domain,
|
||||
const domainname *const host, mDNSIPPort port, const mDNSu8 txtinfo[], mDNSu16 txtlen,
|
||||
|
@ -2761,8 +2803,6 @@ extern mStatus mDNS_StartBrowse(mDNS *const m, DNSQuestion *const question,
|
|||
mDNSQuestionCallback *Callback, void *Context);
|
||||
#define mDNS_StopBrowse mDNS_StopQuery
|
||||
|
||||
extern mStatus mDNS_StartResolveService(mDNS *const m, ServiceInfoQuery *query, ServiceInfo *info, mDNSServiceInfoQueryCallback *Callback, void *Context);
|
||||
extern void mDNS_StopResolveService (mDNS *const m, ServiceInfoQuery *query);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -2784,7 +2824,7 @@ extern mStatus mDNS_AdvertiseDomains(mDNS *const m, AuthRecord *rr, mDNS_DomainT
|
|||
#define mDNS_StopAdvertiseDomains mDNS_Deregister
|
||||
|
||||
extern mDNSOpaque16 mDNS_NewMessageID(mDNS *const m);
|
||||
extern mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr, mDNSBool *myself);
|
||||
extern mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr);
|
||||
|
||||
extern DNSServer *GetServerForQuestion(mDNS *m, DNSQuestion *question);
|
||||
extern mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question);
|
||||
|
@ -2805,7 +2845,7 @@ extern mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question);
|
|||
// because that object is defined to be 256 bytes long, but not all domainname objects are truly the full size.
|
||||
// This macro uses mDNSPlatformMemCopy() to make sure it only touches the actual bytes that are valid.
|
||||
#define AssignDomainName(DST, SRC) do { mDNSu16 len__ = DomainNameLength((SRC)); \
|
||||
if (len__ <= MAX_DOMAIN_NAME) mDNSPlatformMemCopy((DST)->c, (SRC)->c, len__);else (DST)->c[0] = 0;} while(0)
|
||||
if (len__ <= MAX_DOMAIN_NAME) mDNSPlatformMemCopy((DST)->c, (SRC)->c, len__); else (DST)->c[0] = 0; } while(0)
|
||||
|
||||
// Comparison functions
|
||||
#define SameDomainLabelCS(A,B) ((A)[0] == (B)[0] && mDNSPlatformMemSame((A)+1, (B)+1, (A)[0]))
|
||||
|
@ -2862,6 +2902,10 @@ extern char *ConvertDomainNameToCString_withescape(const domainname *const na
|
|||
|
||||
extern void ConvertUTF8PstringToRFC1034HostLabel(const mDNSu8 UTF8Name[], domainlabel *const hostlabel);
|
||||
|
||||
#define ValidTransportProtocol(X) ( (X)[0] == 4 && (X)[1] == '_' && \
|
||||
((((X)[2] | 0x20) == 'u' && ((X)[3] | 0x20) == 'd') || (((X)[2] | 0x20) == 't' && ((X)[3] | 0x20) == 'c')) && \
|
||||
((X)[4] | 0x20) == 'p')
|
||||
|
||||
extern mDNSu8 *ConstructServiceName(domainname *const fqdn, const domainlabel *name, const domainname *type, const domainname *const domain);
|
||||
extern mDNSBool DeconstructServiceName(const domainname *const fqdn, domainlabel *const name, domainname *const type, domainname *const domain);
|
||||
|
||||
|
@ -2887,7 +2931,7 @@ extern mDNSBool DeconstructServiceName(const domainname *const fqdn, domainlabel
|
|||
// then the output will be truncated by one character to allow space for the terminating null.
|
||||
// Unlike standard C vsnprintf/snprintf, they return the number of characters *actually* written,
|
||||
// not the number of characters that *would* have been printed were buflen unlimited.
|
||||
extern mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, va_list arg);
|
||||
extern mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, va_list arg) IS_A_PRINTF_STYLE_FUNCTION(3,0);
|
||||
extern mDNSu32 mDNS_snprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, ...) IS_A_PRINTF_STYLE_FUNCTION(3,4);
|
||||
extern mDNSu32 NumCacheRecordsForInterfaceID(const mDNS *const m, mDNSInterfaceID id);
|
||||
extern char *DNSTypeName(mDNSu16 rrtype);
|
||||
|
@ -2917,6 +2961,7 @@ extern mDNSBool mDNSAddrIPv4FromMappedIPv6(mDNSv6Addr *in, mDNSv4Addr *out);
|
|||
#define mDNSIPPortIsZero(A) ((A).NotAnInteger == 0)
|
||||
#define mDNSOpaque16IsZero(A) ((A).NotAnInteger == 0)
|
||||
#define mDNSOpaque64IsZero(A) (((A)->l[0] | (A)->l[1] ) == 0)
|
||||
#define mDNSOpaque128IsZero(A) (((A)->l[0] | (A)->l[1] | (A)->l[2] | (A)->l[3]) == 0)
|
||||
#define mDNSIPv4AddressIsZero(A) ((A).NotAnInteger == 0)
|
||||
#define mDNSIPv6AddressIsZero(A) (((A).l[0] | (A).l[1] | (A).l[2] | (A).l[3]) == 0)
|
||||
#define mDNSEthAddressIsZero(A) (((A).w[0] | (A).w[1] | (A).w[2] ) == 0)
|
||||
|
@ -2951,12 +2996,6 @@ extern mDNSBool mDNSAddrIPv4FromMappedIPv6(mDNSv6Addr *in, mDNSv4Addr *out);
|
|||
((X)->type == mDNSAddrType_IPv4) ? mDNSv4AddressIsLinkLocal(&(X)->ip.v4) : \
|
||||
((X)->type == mDNSAddrType_IPv6) ? mDNSv6AddressIsLinkLocal(&(X)->ip.v6) : mDNSfalse)
|
||||
|
||||
#define mDNSv4AddressIsLoopback(X) ((X)->b[0] == 127 && (X)->b[1] == 0 && (X)->b[2] == 0 && (X)->b[3] == 1)
|
||||
#define mDNSv6AddressIsLoopback(X) ((((X)->l[0] | (X)->l[1] | (X)->l[2]) == 0) && ((X)->b[12] == 0 && (X)->b[13] == 0 && (X)->b[14] == 0 && (X)->b[15] == 1))
|
||||
|
||||
#define mDNSAddressIsLoopback(X) ( \
|
||||
((X)->type == mDNSAddrType_IPv4) ? mDNSv4AddressIsLoopback(&(X)->ip.v4) : \
|
||||
((X)->type == mDNSAddrType_IPv6) ? mDNSv6AddressIsLoopback(&(X)->ip.v6) : mDNSfalse)
|
||||
|
||||
// ***************************************************************************
|
||||
#if 0
|
||||
|
@ -3000,8 +3039,8 @@ extern void mDNS_AddDynDNSHostName(mDNS *m, const domainname *fqdn, mDNSRecordCa
|
|||
extern void mDNS_RemoveDynDNSHostName(mDNS *m, const domainname *fqdn);
|
||||
extern void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr, const mDNSAddr *v6addr, const mDNSAddr *router);
|
||||
extern DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, mDNSs32 serviceID, const mDNSAddr *addr,
|
||||
const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSu16 resGroupID, mDNSBool reqA,
|
||||
mDNSBool reqAAAA, mDNSBool reqDO);
|
||||
const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSBool isExpensive, mDNSu16 resGroupID,
|
||||
mDNSBool reqA, mDNSBool reqAAAA, mDNSBool reqDO);
|
||||
extern void PenalizeDNSServer(mDNS *const m, DNSQuestion *q, mDNSOpaque16 responseFlags);
|
||||
extern void mDNS_AddSearchDomain(const domainname *const domain, mDNSInterfaceID InterfaceID);
|
||||
|
||||
|
@ -3076,14 +3115,14 @@ extern mDNSBool DNSDigest_VerifyMessage(DNSMessage *msg, mDNSu8 *end, LargeCache
|
|||
extern mStatus mDNSPlatformInit (mDNS *const m);
|
||||
extern void mDNSPlatformClose (mDNS *const m);
|
||||
extern mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const msg, const mDNSu8 *const end,
|
||||
mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst,
|
||||
mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst,
|
||||
mDNSIPPort dstport, mDNSBool useBackgroundTrafficClass);
|
||||
|
||||
extern mDNSBool mDNSPlatformPeekUDP (mDNS *const m, UDPSocket *src);
|
||||
extern void mDNSPlatformLock (const mDNS *const m);
|
||||
extern void mDNSPlatformUnlock (const mDNS *const m);
|
||||
|
||||
extern void mDNSPlatformStrCopy ( void *dst, const void *src);
|
||||
extern mDNSu32 mDNSPlatformStrLCopy ( void *dst, const void *src, mDNSu32 len);
|
||||
extern mDNSu32 mDNSPlatformStrLen ( const void *src);
|
||||
extern void mDNSPlatformMemCopy ( void *dst, const void *src, mDNSu32 len);
|
||||
extern mDNSBool mDNSPlatformMemSame (const void *dst, const void *src, mDNSu32 len);
|
||||
|
@ -3119,17 +3158,6 @@ extern void mDNSPlatformWriteDebugMsg(const char *msg);
|
|||
#endif
|
||||
extern void mDNSPlatformWriteLogMsg(const char *ident, const char *msg, mDNSLogLevel_t loglevel);
|
||||
|
||||
#if APPLE_OSX_mDNSResponder
|
||||
// Utility function for ASL logging
|
||||
mDNSexport void mDNSASLLog(uuid_t *uuid, const char *subdomain, const char *result, const char *signature, const char *fmt, ...);
|
||||
|
||||
// Log unicast and multicast traffic statistics once a day. Also used for DNSSEC statistics.
|
||||
#define kDefaultNextStatsticsLogTime (24 * 60 * 60)
|
||||
|
||||
extern void mDNSLogStatistics(mDNS *const m);
|
||||
|
||||
#endif // APPLE_OSX_mDNSResponder
|
||||
|
||||
// Platform support modules should provide the following functions to map between opaque interface IDs
|
||||
// and interface indexes in order to support the DNS-SD API. If your target platform does not support
|
||||
// multiple interfaces and/or does not support the DNS-SD API, these functions can be empty.
|
||||
|
@ -3160,7 +3188,7 @@ typedef enum
|
|||
} TCPSocketFlags;
|
||||
|
||||
typedef void (*TCPConnectionCallback)(TCPSocket *sock, void *context, mDNSBool ConnectionEstablished, mStatus err);
|
||||
extern TCPSocket *mDNSPlatformTCPSocket(mDNS *const m, TCPSocketFlags flags, mDNSIPPort *port, mDNSBool useBackgroundTrafficClass); // creates a TCP socket
|
||||
extern TCPSocket *mDNSPlatformTCPSocket(TCPSocketFlags flags, mDNSIPPort *port, mDNSBool useBackgroundTrafficClass); // creates a TCP socket
|
||||
extern TCPSocket *mDNSPlatformTCPAccept(TCPSocketFlags flags, int sd);
|
||||
extern int mDNSPlatformTCPGetFD(TCPSocket *sock);
|
||||
extern mStatus mDNSPlatformTCPConnect(TCPSocket *sock, const mDNSAddr *dst, mDNSOpaque16 dstport, domainname *hostname,
|
||||
|
@ -3168,19 +3196,21 @@ extern mStatus mDNSPlatformTCPConnect(TCPSocket *sock, const mDNSAddr *dst, m
|
|||
extern void mDNSPlatformTCPCloseConnection(TCPSocket *sock);
|
||||
extern long mDNSPlatformReadTCP(TCPSocket *sock, void *buf, unsigned long buflen, mDNSBool *closed);
|
||||
extern long mDNSPlatformWriteTCP(TCPSocket *sock, const char *msg, unsigned long len);
|
||||
extern UDPSocket *mDNSPlatformUDPSocket(mDNS *const m, const mDNSIPPort requestedport);
|
||||
extern UDPSocket *mDNSPlatformUDPSocket(const mDNSIPPort requestedport);
|
||||
extern mDNSu16 mDNSPlatformGetUDPPort(UDPSocket *sock);
|
||||
extern void mDNSPlatformUDPClose(UDPSocket *sock);
|
||||
extern void mDNSPlatformReceiveBPF_fd(mDNS *const m, int fd);
|
||||
extern void mDNSPlatformUpdateProxyList(mDNS *const m, const mDNSInterfaceID InterfaceID);
|
||||
extern mDNSBool mDNSPlatformUDPSocketEncounteredEOF(const UDPSocket *sock);
|
||||
extern void mDNSPlatformReceiveBPF_fd(int fd);
|
||||
extern void mDNSPlatformUpdateProxyList(const mDNSInterfaceID InterfaceID);
|
||||
extern void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID);
|
||||
extern void mDNSPlatformSetLocalAddressCacheEntry(mDNS *const m, const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID);
|
||||
extern void mDNSPlatformSetLocalAddressCacheEntry(const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID);
|
||||
extern void mDNSPlatformSourceAddrForDest(mDNSAddr *const src, const mDNSAddr *const dst);
|
||||
extern void mDNSPlatformSendKeepalive(mDNSAddr *sadd, mDNSAddr *dadd, mDNSIPPort *lport, mDNSIPPort *rport, mDNSu32 seq, mDNSu32 ack, mDNSu16 win);
|
||||
extern mStatus mDNSPlatformRetrieveTCPInfo(mDNS *const m, mDNSAddr *laddr, mDNSIPPort *lport, mDNSAddr *raddr, mDNSIPPort *rport, mDNSTCPInfo *mti);
|
||||
extern mStatus mDNSPlatformGetRemoteMacAddr(mDNS *const m, mDNSAddr *raddr);
|
||||
extern mStatus mDNSPlatformRetrieveTCPInfo(mDNSAddr *laddr, mDNSIPPort *lport, mDNSAddr *raddr, mDNSIPPort *rport, mDNSTCPInfo *mti);
|
||||
extern mStatus mDNSPlatformGetRemoteMacAddr(mDNSAddr *raddr);
|
||||
extern mStatus mDNSPlatformStoreSPSMACAddr(mDNSAddr *spsaddr, char *ifname);
|
||||
extern mStatus mDNSPlatformClearSPSMACAddr(void);
|
||||
extern mStatus mDNSPlatformClearSPSData(void);
|
||||
extern mStatus mDNSPlatformStoreOwnerOptRecord(char *ifname, DNSMessage *msg, int length);
|
||||
|
||||
// mDNSPlatformTLSSetupCerts/mDNSPlatformTLSTearDownCerts used by dnsextd
|
||||
extern mStatus mDNSPlatformTLSSetupCerts(void);
|
||||
|
@ -3189,18 +3219,19 @@ extern void mDNSPlatformTLSTearDownCerts(void);
|
|||
// Platforms that support unicast browsing and dynamic update registration for clients who do not specify a domain
|
||||
// in browse/registration calls must implement these routines to get the "default" browse/registration list.
|
||||
|
||||
extern mDNSBool mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains,
|
||||
extern mDNSBool mDNSPlatformSetDNSConfig(mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains,
|
||||
DNameListElem **BrowseDomains, mDNSBool ackConfig);
|
||||
extern mStatus mDNSPlatformGetPrimaryInterface(mDNS *const m, mDNSAddr *v4, mDNSAddr *v6, mDNSAddr *router);
|
||||
extern mStatus mDNSPlatformGetPrimaryInterface(mDNSAddr *v4, mDNSAddr *v6, mDNSAddr *router);
|
||||
extern void mDNSPlatformDynDNSHostNameStatusChanged(const domainname *const dname, const mStatus status);
|
||||
|
||||
extern void mDNSPlatformSetAllowSleep(mDNS *const m, mDNSBool allowSleep, const char *reason);
|
||||
extern void mDNSPlatformSendWakeupPacket(mDNS *const m, mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration);
|
||||
extern void mDNSPlatformSetAllowSleep(mDNSBool allowSleep, const char *reason);
|
||||
extern void mDNSPlatformPreventSleep(mDNSu32 timeout, const char *reason);
|
||||
extern void mDNSPlatformSendWakeupPacket(mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration);
|
||||
|
||||
extern mDNSBool mDNSPlatformInterfaceIsD2D(mDNSInterfaceID InterfaceID);
|
||||
extern mDNSBool mDNSPlatformInterfaceIsAWDL(const NetworkInterfaceInfo *intf);
|
||||
extern mDNSBool mDNSPlatformValidRecordForQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
|
||||
extern mDNSBool mDNSPlatformValidRecordForInterface(AuthRecord *rr, const NetworkInterfaceInfo *intf);
|
||||
extern mDNSBool mDNSPlatformValidRecordForInterface(const AuthRecord *rr, mDNSInterfaceID InterfaceID);
|
||||
extern mDNSBool mDNSPlatformValidQuestionForInterface(DNSQuestion *q, const NetworkInterfaceInfo *intf);
|
||||
|
||||
extern void mDNSPlatformFormatTime(unsigned long t, mDNSu8 *buf, int bufsize);
|
||||
|
@ -3253,10 +3284,19 @@ extern void LNT_ClearState(mDNS *const m);
|
|||
extern void mDNS_SetFQDN(mDNS *const m);
|
||||
extern void mDNS_ActivateNetWake_internal (mDNS *const m, NetworkInterfaceInfo *set);
|
||||
extern void mDNS_DeactivateNetWake_internal(mDNS *const m, NetworkInterfaceInfo *set);
|
||||
extern mStatus mDNS_RegisterInterface (mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping);
|
||||
extern void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping);
|
||||
|
||||
// Attributes that controls the Bonjour operation initiation and response speed for an interface.
|
||||
typedef enum
|
||||
{
|
||||
FastActivation, // For p2p* and DirectLink type interfaces
|
||||
NormalActivation, // For standard interface timing
|
||||
SlowActivation // For flapping interfaces
|
||||
} InterfaceActivationSpeed;
|
||||
|
||||
extern mStatus mDNS_RegisterInterface (mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed probeDelay);
|
||||
extern void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed probeDelay);
|
||||
extern void mDNSCoreInitComplete(mDNS *const m, mStatus result);
|
||||
extern void mDNSCoreReceive(mDNS *const m, void *const msg, const mDNSu8 *const end,
|
||||
extern void mDNSCoreReceive(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end,
|
||||
const mDNSAddr *const srcaddr, const mDNSIPPort srcport,
|
||||
const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID);
|
||||
extern void mDNSCoreRestartQueries(mDNS *const m);
|
||||
|
@ -3276,7 +3316,7 @@ extern void mDNSCoreReceiveRawPacket (mDNS *const m, const mDNSu8 *const p,
|
|||
extern mDNSBool mDNSAddrIsDNSMulticast(const mDNSAddr *ip);
|
||||
|
||||
extern CacheRecord *CreateNewCacheEntry(mDNS *const m, const mDNSu32 slot, CacheGroup *cg, mDNSs32 delay, mDNSBool Add, const mDNSAddr *sourceAddress);
|
||||
extern CacheGroup *CacheGroupForName(const mDNS *const m, const mDNSu32 slot, const mDNSu32 namehash, const domainname *const name);
|
||||
extern CacheGroup *CacheGroupForName(const mDNS *const m, const mDNSu32 namehash, const domainname *const name);
|
||||
extern void ReleaseCacheRecord(mDNS *const m, CacheRecord *r);
|
||||
extern void ScheduleNextCacheCheckTime(mDNS *const m, const mDNSu32 slot, const mDNSs32 event);
|
||||
extern void SetNextCacheCheckTimeForRecord(mDNS *const m, CacheRecord *const rr);
|
||||
|
@ -3295,13 +3335,13 @@ extern void RetrySearchDomainQuestions(mDNS *const m);
|
|||
extern mDNSBool DomainEnumQuery(const domainname *qname);
|
||||
extern mStatus UpdateKeepaliveRData(mDNS *const m, AuthRecord *rr, NetworkInterfaceInfo *const intf, mDNSBool updateMac, char *ethAddr);
|
||||
extern void UpdateKeepaliveRMACAsync(mDNS *const m, void *context);
|
||||
extern void UpdateRMACCallback(mDNS *const m, void *context);
|
||||
extern void UpdateRMAC(mDNS *const m, void *context);
|
||||
|
||||
// Used only in logging to restrict the number of /etc/hosts entries printed
|
||||
extern void FreeEtcHosts(mDNS *const m, AuthRecord *const rr, mStatus result);
|
||||
// exported for using the hash for /etc/hosts AuthRecords
|
||||
extern AuthGroup *AuthGroupForName(AuthHash *r, const mDNSu32 slot, const mDNSu32 namehash, const domainname *const name);
|
||||
extern AuthGroup *AuthGroupForRecord(AuthHash *r, const mDNSu32 slot, const ResourceRecord *const rr);
|
||||
extern AuthGroup *AuthGroupForName(AuthHash *r, const mDNSu32 namehash, const domainname *const name);
|
||||
extern AuthGroup *AuthGroupForRecord(AuthHash *r, const ResourceRecord *const rr);
|
||||
extern AuthGroup *InsertAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *rr);
|
||||
extern AuthGroup *RemoveAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *rr);
|
||||
extern mDNSBool mDNS_CheckForCacheRecord(mDNS *const m, DNSQuestion *q, mDNSu16 qtype);
|
||||
|
@ -3310,36 +3350,36 @@ extern mDNSBool mDNS_CheckForCacheRecord(mDNS *const m, DNSQuestion *q, mDNSu16
|
|||
// In the future, if there's demand, we may see if we can abstract it out cleanly into the platform layer
|
||||
#if APPLE_OSX_mDNSResponder
|
||||
extern void AutoTunnelCallback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord);
|
||||
extern void AddNewClientTunnel(mDNS *const m, DNSQuestion *const q);
|
||||
extern void StartServerTunnel(mDNS *const m, DomainAuthInfo *const info);
|
||||
extern void AddNewClientTunnel(DNSQuestion *const q);
|
||||
extern void StartServerTunnel(DomainAuthInfo *const info);
|
||||
extern void UpdateAutoTunnelDomainStatuses(const mDNS *const m);
|
||||
extern void RemoveAutoTunnel6Record(mDNS *const m);
|
||||
extern mDNSBool RecordReadyForSleep(mDNS *const m, AuthRecord *rr);
|
||||
extern mDNSBool RecordReadyForSleep(AuthRecord *rr);
|
||||
// For now this LocalSleepProxy stuff is specific to Mac OS X.
|
||||
// In the future, if there's demand, we may see if we can abstract it out cleanly into the platform layer
|
||||
extern mStatus ActivateLocalProxy(mDNS *const m, NetworkInterfaceInfo *const intf);
|
||||
extern void mDNSPlatformUpdateDNSStatus(mDNS *const m, DNSQuestion *q);
|
||||
extern void mDNSPlatformTriggerDNSRetry(mDNS *const m, DNSQuestion *v4q, DNSQuestion *v6q);
|
||||
extern mStatus ActivateLocalProxy(NetworkInterfaceInfo *const intf, mDNSBool *keepaliveOnly);
|
||||
extern void mDNSPlatformUpdateDNSStatus(DNSQuestion *q);
|
||||
extern void mDNSPlatformTriggerDNSRetry(DNSQuestion *v4q, DNSQuestion *v6q);
|
||||
extern void mDNSPlatformLogToFile(int log_level, const char *buffer);
|
||||
extern mDNSBool SupportsInNICProxy(NetworkInterfaceInfo *const intf);
|
||||
extern mStatus SymptomReporterDNSServerReachable(mDNS *const m, const mDNSAddr *addr);
|
||||
extern mStatus SymptomReporterDNSServerUnreachable(DNSServer *s);
|
||||
#endif
|
||||
|
||||
typedef void ProxyCallback (mDNS *const m, void *socket, void *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
|
||||
typedef void ProxyCallback (void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
|
||||
const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context);
|
||||
extern void mDNSPlatformInitDNSProxySkts(mDNS *const m, ProxyCallback *UDPCallback, ProxyCallback *TCPCallback);
|
||||
extern void mDNSPlatformInitDNSProxySkts(ProxyCallback *UDPCallback, ProxyCallback *TCPCallback);
|
||||
extern void mDNSPlatformCloseDNSProxySkts(mDNS *const m);
|
||||
extern void mDNSPlatformDisposeProxyContext(void *context);
|
||||
extern mDNSu8 *DNSProxySetAttributes(DNSQuestion *q, DNSMessageHeader *h, DNSMessage *msg, mDNSu8 *start, mDNSu8 *limit);
|
||||
|
||||
// Sleep Assertions are specific to Mac OS X
|
||||
#if APPLE_OSX_mDNSResponder
|
||||
extern void mDNSPlatformSleepAssertion(mDNS *const m, double timeout);
|
||||
extern void mDNSPlatformGetDNSRoutePolicy(DNSQuestion *q, mDNSBool *isBlocked);
|
||||
#endif
|
||||
|
||||
extern mDNSBool mDNSPlatformAllowPID(mDNS *const m, DNSQuestion *q);
|
||||
extern mDNSs32 mDNSPlatformGetServiceID(mDNS *const m, DNSQuestion *q);
|
||||
extern void mDNSPlatformSetuDNSSocktOpt(UDPSocket *src, const mDNSAddr *dst, DNSQuestion *q);
|
||||
extern void mDNSPlatformSetSocktOpt(void *sock, mDNSTransport_Type transType, mDNSAddr_Type addrType, const DNSQuestion *q);
|
||||
extern mDNSs32 mDNSPlatformGetPID(void);
|
||||
extern mDNSBool mDNSValidKeepAliveRecord(AuthRecord *rr);
|
||||
extern mDNSBool CacheRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q);
|
||||
|
||||
// ***************************************************************************
|
||||
#if 0
|
||||
|
@ -3547,6 +3587,11 @@ struct CompileTimeAssertionChecks_mDNS
|
|||
char assertK[(sizeof(UDPHeader ) == 8 ) ? 1 : -1];
|
||||
char assertL[(sizeof(IKEHeader ) == 28 ) ? 1 : -1];
|
||||
char assertM[(sizeof(TCPHeader ) == 20 ) ? 1 : -1];
|
||||
char assertN[(sizeof(rdataOPT) == 24 ) ? 1 : -1];
|
||||
char assertO[(sizeof(rdataRRSig) == 20 ) ? 1 : -1];
|
||||
char assertP[(sizeof(PCPMapRequest) == 60 ) ? 1 : -1];
|
||||
char assertQ[(sizeof(PCPMapReply) == 60 ) ? 1 : -1];
|
||||
|
||||
|
||||
// Check our structures are reasonable sizes. Including overly-large buffers, or embedding
|
||||
// other overly-large structures instead of having a pointer to them, can inadvertently
|
||||
|
@ -3556,21 +3601,17 @@ struct CompileTimeAssertionChecks_mDNS
|
|||
char sizecheck_AuthRecord [(sizeof(AuthRecord) <= 1208) ? 1 : -1];
|
||||
char sizecheck_CacheRecord [(sizeof(CacheRecord) <= 232) ? 1 : -1];
|
||||
char sizecheck_CacheGroup [(sizeof(CacheGroup) <= 232) ? 1 : -1];
|
||||
char sizecheck_DNSQuestion [(sizeof(DNSQuestion) <= 832) ? 1 : -1];
|
||||
char sizecheck_DNSQuestion [(sizeof(DNSQuestion) <= 912) ? 1 : -1];
|
||||
|
||||
// Checks commented out when sizeof(DNSQuestion) change cascaded into having to change yet another
|
||||
// set of hardcoded size values because these structures contain one or more DNSQuestion
|
||||
// instances.
|
||||
// char sizecheck_ZoneData [(sizeof(ZoneData) <= 1648) ? 1 : -1];
|
||||
char sizecheck_ZoneData [(sizeof(ZoneData) <= 1744) ? 1 : -1];
|
||||
char sizecheck_NATTraversalInfo [(sizeof(NATTraversalInfo) <= 200) ? 1 : -1];
|
||||
char sizecheck_HostnameInfo [(sizeof(HostnameInfo) <= 3050) ? 1 : -1];
|
||||
char sizecheck_DNSServer [(sizeof(DNSServer) <= 340) ? 1 : -1];
|
||||
// char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <= 6988) ? 1 : -1];
|
||||
char sizecheck_DNSServer [(sizeof(DNSServer) <= 330) ? 1 : -1];
|
||||
char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <= 7376) ? 1 : -1];
|
||||
char sizecheck_ServiceRecordSet [(sizeof(ServiceRecordSet) <= 5540) ? 1 : -1];
|
||||
char sizecheck_DomainAuthInfo [(sizeof(DomainAuthInfo) <= 7888) ? 1 : -1];
|
||||
// char sizecheck_ServiceInfoQuery [(sizeof(ServiceInfoQuery) <= 3302) ? 1 : -1];
|
||||
#if APPLE_OSX_mDNSResponder
|
||||
// char sizecheck_ClientTunnel [(sizeof(ClientTunnel) <= 1160) ? 1 : -1];
|
||||
char sizecheck_ClientTunnel [(sizeof(ClientTunnel) <= 1256) ? 1 : -1];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -3580,6 +3621,13 @@ mDNSu32 initializeDeviceInfoTXT(mDNS *m, mDNSu8 *ptr);
|
|||
#if APPLE_OSX_mDNSResponder
|
||||
extern void D2D_start_advertising_interface(NetworkInterfaceInfo *interface);
|
||||
extern void D2D_stop_advertising_interface(NetworkInterfaceInfo *interface);
|
||||
extern void D2D_start_advertising_record(AuthRecord *ar);
|
||||
extern void D2D_stop_advertising_record(AuthRecord *ar);
|
||||
#else
|
||||
#define D2D_start_advertising_interface(X)
|
||||
#define D2D_stop_advertising_interface(X)
|
||||
#define D2D_start_advertising_record(X)
|
||||
#define D2D_stop_advertising_record(X)
|
||||
#endif
|
||||
|
||||
// ***************************************************************************
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2011-2013 Apple 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.
|
||||
|
@ -56,12 +56,10 @@ mDNSlocal CacheRecord *NSECParentForQuestion(mDNS *const m, DNSQuestion *q)
|
|||
{
|
||||
CacheGroup *cg;
|
||||
CacheRecord *cr;
|
||||
mDNSu32 slot;
|
||||
mDNSu32 namehash;
|
||||
|
||||
slot = HashSlot(&q->qname);
|
||||
namehash = DomainNameHashValue(&q->qname);
|
||||
cg = CacheGroupForName(m, slot, namehash, &q->qname);
|
||||
cg = CacheGroupForName(m, namehash, &q->qname);
|
||||
if (!cg)
|
||||
{
|
||||
LogDNSSEC("NSECParentForQuestion: Cannot find cg for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
|
||||
|
@ -611,7 +609,7 @@ mDNSlocal mDNSBool NSECNoDataError(mDNS *const m, ResourceRecord *rr, domainname
|
|||
{
|
||||
const domainname *oname = rr->name; // owner name
|
||||
|
||||
if (wildcard) *wildcard = mDNSNULL;
|
||||
*wildcard = mDNSNULL;
|
||||
// RFC 4035
|
||||
//
|
||||
// section 3.1.3.1 : Name matches. Prove that the type does not exist and also CNAME is
|
||||
|
@ -676,10 +674,10 @@ mDNSlocal mDNSBool NSECNoDataError(mDNS *const m, ResourceRecord *rr, domainname
|
|||
// a subdomain e.g., y.x.example or z.y.x.example and so on.
|
||||
if (oname->c[0] == 1 && oname->c[1] == '*')
|
||||
{
|
||||
int r, s;
|
||||
int s;
|
||||
const domainname *ce = SkipLeadingLabels(oname, 1);
|
||||
|
||||
r = DNSSECCanonicalOrder(name, ce, &s);
|
||||
DNSSECCanonicalOrder(name, ce, &s);
|
||||
if (s)
|
||||
{
|
||||
if (RRAssertsExistence(rr, qtype) || RRAssertsExistence(rr, kDNSType_CNAME))
|
||||
|
@ -912,18 +910,18 @@ mDNSlocal void NoDataProof(mDNS *const m, DNSSECVerifier *dv, CacheRecord *ncr)
|
|||
// First verify wildcard NSEC and then when we are done, we
|
||||
// will verify the noname nsec
|
||||
dv->pendingNSEC = r;
|
||||
LogDNSSEC("NoDataProof: Verifying wild and noname %s", RRDisplayString(m, nsec_wild));
|
||||
LogDNSSEC("NoDataProof: Verifying wild and noname %s", nsec_wild ? RRDisplayString(m, nsec_wild) : "NULL");
|
||||
VerifyNSEC(m, nsec_wild, mDNSNULL, dv, ncr, NoDataNSECCallback);
|
||||
}
|
||||
else if ((dv->flags & WILDCARD_PROVES_NONAME_EXISTS) ||
|
||||
(dv->flags & NSEC_PROVES_NOTYPE_EXISTS))
|
||||
{
|
||||
LogDNSSEC("NoDataProof: Verifying wild %s", RRDisplayString(m, nsec_wild));
|
||||
LogDNSSEC("NoDataProof: Verifying wild %s", nsec_wild ? RRDisplayString(m, nsec_wild) : "NULL");
|
||||
VerifyNSEC(m, nsec_wild, mDNSNULL, dv, ncr, mDNSNULL);
|
||||
}
|
||||
else if (dv->flags & NSEC_PROVES_NONAME_EXISTS)
|
||||
{
|
||||
LogDNSSEC("NoDataProof: Verifying noname %s", RRDisplayString(m, nsec_noname));
|
||||
LogDNSSEC("NoDataProof: Verifying noname %s", nsec_noname ? RRDisplayString(m, nsec_noname) : "NULL");
|
||||
VerifyNSEC(m, nsec_noname, mDNSNULL, dv, ncr, mDNSNULL);
|
||||
}
|
||||
return;
|
||||
|
@ -1050,12 +1048,11 @@ mDNSexport CacheRecord *NSECRecordIsDelegation(mDNS *const m, domainname *name,
|
|||
{
|
||||
CacheGroup *cg;
|
||||
CacheRecord *cr;
|
||||
mDNSu32 slot, namehash;
|
||||
mDNSu32 namehash;
|
||||
|
||||
slot = HashSlot(name);
|
||||
namehash = DomainNameHashValue(name);
|
||||
|
||||
cg = CacheGroupForName(m, (const mDNSu32)slot, namehash, name);
|
||||
cg = CacheGroupForName(m, namehash, name);
|
||||
if (!cg)
|
||||
{
|
||||
LogDNSSEC("NSECRecordForName: cg NULL for %##s", name);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2011-2012 Apple 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.
|
||||
|
@ -14,6 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __NSEC_H
|
||||
#define __NSEC_H
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2011-2013 Apple 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.
|
||||
|
@ -238,7 +238,7 @@ mDNSlocal mDNSBool NSEC3Find(mDNS *const m, NSEC3FindValues val, CacheRecord *nc
|
|||
name = SkipLeadingLabels(origName, i);
|
||||
if (!NSEC3HashName(name, nsec3, mDNSNULL, 0, hashName, &hlen))
|
||||
{
|
||||
LogMsg("NSEC3Find: NSEC3HashName failed for ##s", name->c);
|
||||
LogMsg("NSEC3Find: NSEC3HashName failed for %##s", name->c);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -332,7 +332,7 @@ mDNSlocal mDNSBool NSEC3Find(mDNS *const m, NSEC3FindValues val, CacheRecord *nc
|
|||
}
|
||||
}
|
||||
|
||||
if ((val == NSEC3Covers || val == NSEC3CEProof) && !(*closerEncloser))
|
||||
if ((val == NSEC3Covers || val == NSEC3CEProof) && (!closerEncloser || !(*closerEncloser)))
|
||||
{
|
||||
if (NSEC3CoversName(m, cr, hashName, hlen, b32Name, b32len))
|
||||
{
|
||||
|
@ -349,23 +349,22 @@ mDNSlocal mDNSBool NSEC3Find(mDNS *const m, NSEC3FindValues val, CacheRecord *nc
|
|||
// 2.3) If there is a matching NSEC3 RR in the response and the flag
|
||||
// was set, then the proof is complete, and SNAME is the closest
|
||||
// encloser.
|
||||
if (val == NSEC3CEProof)
|
||||
if (val == NSEC3CEProof && closestEncloser && *closestEncloser)
|
||||
{
|
||||
if (*closestEncloser && *closerEncloser)
|
||||
if (closerEncloser && *closerEncloser)
|
||||
{
|
||||
LogDNSSEC("NSEC3Find: Found closest and closer encloser");
|
||||
return mDNStrue;
|
||||
}
|
||||
|
||||
// 2.4) If there is a matching NSEC3 RR in the response, but the flag
|
||||
// is not set, then the response is bogus.
|
||||
//
|
||||
// Note: We don't have to wait till we finish trying all the names. If the matchName
|
||||
// happens, we found the closest encloser which means we should have found the closer
|
||||
// encloser before.
|
||||
|
||||
if (*closestEncloser && !(*closerEncloser))
|
||||
else
|
||||
{
|
||||
// 2.4) If there is a matching NSEC3 RR in the response, but the flag
|
||||
// is not set, then the response is bogus.
|
||||
//
|
||||
// Note: We don't have to wait till we finish trying all the names. If the matchName
|
||||
// happens, we found the closest encloser which means we should have found the closer
|
||||
// encloser before.
|
||||
|
||||
LogDNSSEC("NSEC3Find: Found closest, but not closer encloser");
|
||||
return mDNSfalse;
|
||||
}
|
||||
|
@ -388,8 +387,7 @@ mDNSlocal mDNSBool NSEC3ClosestEncloserProof(mDNS *const m, CacheRecord *ncr, do
|
|||
// Note: It is possible that closestEncloser and closerEncloser are the same.
|
||||
if (!closestEncloser || !closerEncloser || !ce)
|
||||
{
|
||||
LogMsg("NSEC3ClosestEncloserProof: ClosestEncloser %p or CloserEncloser %p ce %p, something is NULL", *closestEncloser,
|
||||
*closerEncloser, *ce);
|
||||
LogMsg("NSEC3ClosestEncloserProof: ClosestEncloser %p or CloserEncloser %p ce %p, something is NULL", closestEncloser, closerEncloser, ce);
|
||||
return mDNSfalse;
|
||||
}
|
||||
|
||||
|
@ -677,12 +675,11 @@ mDNSexport CacheRecord *NSEC3RecordIsDelegation(mDNS *const m, domainname *name,
|
|||
CacheGroup *cg;
|
||||
CacheRecord *cr;
|
||||
CacheRecord *ncr;
|
||||
mDNSu32 slot, namehash;
|
||||
mDNSu32 namehash;
|
||||
|
||||
slot = HashSlot(name);
|
||||
namehash = DomainNameHashValue(name);
|
||||
|
||||
cg = CacheGroupForName(m, (const mDNSu32)slot, namehash, name);
|
||||
cg = CacheGroupForName(m, namehash, name);
|
||||
if (!cg)
|
||||
{
|
||||
LogDNSSEC("NSEC3RecordForName: cg NULL for %##s", name);
|
||||
|
@ -710,7 +707,7 @@ mDNSexport CacheRecord *NSEC3RecordIsDelegation(mDNS *const m, domainname *name,
|
|||
|
||||
if (!NSEC3HashName(name, nsec3, mDNSNULL, 0, hashName, &hlen))
|
||||
{
|
||||
LogMsg("NSEC3RecordIsDelegation: NSEC3HashName failed for ##s", name->c);
|
||||
LogMsg("NSEC3RecordIsDelegation: NSEC3HashName failed for %##s", name->c);
|
||||
return mDNSNULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2011-2012 Apple 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.
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -47,9 +47,8 @@ extern "C" {
|
|||
#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)
|
||||
#define UDNSBackOffMultiplier 2
|
||||
#define MinQuestionInterval (1 * 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
|
||||
|
@ -82,6 +81,11 @@ extern void LLQGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneInfo)
|
|||
extern void startLLQHandshake(mDNS *m, DNSQuestion *q);
|
||||
extern void sendLLQRefresh(mDNS *m, DNSQuestion *q);
|
||||
|
||||
extern void DNSPushNotificationGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneInfo);
|
||||
extern void DiscoverDNSPushNotificationServer(mDNS *m, DNSQuestion *q);
|
||||
extern void SubscribeToDNSPushNotificationServer(mDNS *m, DNSQuestion *q);
|
||||
extern void UnSubscribeToDNSPushNotificationServer(mDNS *m, DNSQuestion *q);
|
||||
|
||||
extern void SleepRecordRegistrations(mDNS *m);
|
||||
|
||||
// uDNS_UpdateRecord
|
||||
|
@ -124,7 +128,7 @@ extern mStatus uDNS_SetupDNSConfig(mDNS *const m);
|
|||
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);
|
||||
extern domainname *uDNS_GetNextSearchDomain(mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -144,6 +148,10 @@ extern void uDNS_ReceiveNATPacket(mDNS *m, const mDNSInterfaceID InterfaceID, mD
|
|||
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);
|
||||
|
||||
// DNS Push Notification
|
||||
extern void SubscribeToDNSPushNotification(mDNS *m, DNSQuestion *q);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -118,11 +118,11 @@ mDNSlocal void ParseCmdLinArgs(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
mDNSlocal void DumpStateLog(mDNS *const m)
|
||||
mDNSlocal void DumpStateLog()
|
||||
// Dump a little log of what we've been up to.
|
||||
{
|
||||
LogMsg("---- BEGIN STATE LOG ----");
|
||||
udsserver_info(m);
|
||||
LogMsg("---- BEGIN STATE LOG ----");
|
||||
udsserver_info();
|
||||
LogMsg("---- END STATE LOG ----");
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,7 @@ mDNSlocal mStatus MainLoop(mDNS *m) // Loop until we quit.
|
|||
(void) mDNSPosixRunEventLoopOnce(m, &timeout, &signals, &gotData);
|
||||
|
||||
if (sigismember(&signals, SIGHUP )) Reconfigure(m);
|
||||
if (sigismember(&signals, SIGUSR1)) DumpStateLog(m);
|
||||
if (sigismember(&signals, SIGUSR1)) DumpStateLog();
|
||||
// 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");
|
||||
if (sigismember(&signals, SIGINT) || sigismember(&signals, SIGTERM)) break;
|
||||
|
@ -235,9 +235,8 @@ mStatus udsSupportRemoveFDFromEventLoop(int fd, void *platform_data) // N
|
|||
return err;
|
||||
}
|
||||
|
||||
mDNSexport void RecordUpdatedNiceLabel(mDNS *const m, mDNSs32 delay)
|
||||
mDNSexport void RecordUpdatedNiceLabel(mDNSs32 delay)
|
||||
{
|
||||
(void)m;
|
||||
(void)delay;
|
||||
// No-op, for now
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2002-2015 Apple 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.
|
||||
|
@ -52,6 +52,7 @@
|
|||
|
||||
#include "mDNSUNP.h"
|
||||
#include "GenLinkedList.h"
|
||||
#include "dnsproxy.h"
|
||||
|
||||
// ***************************************************************************
|
||||
// Structures
|
||||
|
@ -138,7 +139,7 @@ mDNSlocal void SockAddrTomDNSAddr(const struct sockaddr *const sa, mDNSAddr *ipA
|
|||
|
||||
// mDNS core calls this routine when it needs to send a packet.
|
||||
mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const msg, const mDNSu8 *const end,
|
||||
mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst,
|
||||
mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst,
|
||||
mDNSIPPort dstPort, mDNSBool useBackgroundTrafficClass)
|
||||
{
|
||||
int err = 0;
|
||||
|
@ -311,16 +312,8 @@ mDNSlocal void SocketDataReady(mDNS *const m, PosixNetworkInterface *intf, int s
|
|||
&senderAddr, senderPort, &destAddr, MulticastDNSPort, InterfaceID);
|
||||
}
|
||||
|
||||
mDNSexport mDNSBool mDNSPlatformPeekUDP(mDNS *const m, UDPSocket *src)
|
||||
mDNSexport TCPSocket *mDNSPlatformTCPSocket(TCPSocketFlags flags, mDNSIPPort * port, mDNSBool useBackgroundTrafficClass)
|
||||
{
|
||||
(void)m; // unused
|
||||
(void)src; // unused
|
||||
return mDNSfalse;
|
||||
}
|
||||
|
||||
mDNSexport TCPSocket *mDNSPlatformTCPSocket(mDNS * const m, TCPSocketFlags flags, mDNSIPPort * port, mDNSBool useBackgroundTrafficClass)
|
||||
{
|
||||
(void)m; // Unused
|
||||
(void)flags; // Unused
|
||||
(void)port; // Unused
|
||||
(void)useBackgroundTrafficClass; // Unused
|
||||
|
@ -375,9 +368,8 @@ mDNSexport long mDNSPlatformWriteTCP(TCPSocket *sock, const char *msg, unsigned
|
|||
return 0;
|
||||
}
|
||||
|
||||
mDNSexport UDPSocket *mDNSPlatformUDPSocket(mDNS * const m, mDNSIPPort port)
|
||||
mDNSexport UDPSocket *mDNSPlatformUDPSocket(mDNSIPPort port)
|
||||
{
|
||||
(void)m; // Unused
|
||||
(void)port; // Unused
|
||||
return NULL;
|
||||
}
|
||||
|
@ -387,9 +379,8 @@ mDNSexport void mDNSPlatformUDPClose(UDPSocket *sock)
|
|||
(void)sock; // Unused
|
||||
}
|
||||
|
||||
mDNSexport void mDNSPlatformUpdateProxyList(mDNS *const m, const mDNSInterfaceID InterfaceID)
|
||||
mDNSexport void mDNSPlatformUpdateProxyList(const mDNSInterfaceID InterfaceID)
|
||||
{
|
||||
(void)m; // Unused
|
||||
(void)InterfaceID; // Unused
|
||||
}
|
||||
|
||||
|
@ -400,9 +391,8 @@ mDNSexport void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *c
|
|||
(void)InterfaceID; // Unused
|
||||
}
|
||||
|
||||
mDNSexport void mDNSPlatformSetLocalAddressCacheEntry(mDNS *const m, const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID)
|
||||
mDNSexport void mDNSPlatformSetLocalAddressCacheEntry(const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID)
|
||||
{
|
||||
(void)m; // Unused
|
||||
(void)tpa; // Unused
|
||||
(void)tha; // Unused
|
||||
(void)InterfaceID; // Unused
|
||||
|
@ -417,9 +407,8 @@ mDNSexport void mDNSPlatformTLSTearDownCerts(void)
|
|||
{
|
||||
}
|
||||
|
||||
mDNSexport void mDNSPlatformSetAllowSleep(mDNS *const m, mDNSBool allowSleep, const char *reason)
|
||||
mDNSexport void mDNSPlatformSetAllowSleep(mDNSBool allowSleep, const char *reason)
|
||||
{
|
||||
(void) m;
|
||||
(void) allowSleep;
|
||||
(void) reason;
|
||||
}
|
||||
|
@ -441,10 +430,9 @@ mDNSexport void FreeEtcHosts(mDNS *const m, AuthRecord *const rr, mStatus result
|
|||
#pragma mark ***** DDNS Config Platform Functions
|
||||
#endif
|
||||
|
||||
mDNSexport mDNSBool mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains,
|
||||
mDNSexport mDNSBool mDNSPlatformSetDNSConfig(mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains,
|
||||
DNameListElem **BrowseDomains, mDNSBool ackConfig)
|
||||
{
|
||||
(void) m;
|
||||
(void) setservers;
|
||||
(void) fqdn;
|
||||
(void) setsearch;
|
||||
|
@ -455,9 +443,8 @@ mDNSexport mDNSBool mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers,
|
|||
return mDNStrue;
|
||||
}
|
||||
|
||||
mDNSexport mStatus mDNSPlatformGetPrimaryInterface(mDNS * const m, mDNSAddr * v4, mDNSAddr * v6, mDNSAddr * router)
|
||||
mDNSexport mStatus mDNSPlatformGetPrimaryInterface(mDNSAddr * v4, mDNSAddr * v6, mDNSAddr * router)
|
||||
{
|
||||
(void) m;
|
||||
(void) v4;
|
||||
(void) v6;
|
||||
(void) router;
|
||||
|
@ -512,10 +499,11 @@ mDNSexport int ParseDNSServers(mDNS *m, const char *filePath)
|
|||
mDNSAddr DNSAddr;
|
||||
DNSAddr.type = mDNSAddrType_IPv4;
|
||||
DNSAddr.ip.v4.NotAnInteger = ina.s_addr;
|
||||
mDNS_AddDNSServer(m, NULL, mDNSInterface_Any, 0, &DNSAddr, UnicastDNSPort, kScopeNone, 0, mDNSfalse, 0, mDNStrue, mDNStrue, mDNSfalse);
|
||||
mDNS_AddDNSServer(m, NULL, mDNSInterface_Any, 0, &DNSAddr, UnicastDNSPort, kScopeNone, 0, mDNSfalse, mDNSfalse, 0, mDNStrue, mDNStrue, mDNSfalse);
|
||||
numOfServers++;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return (numOfServers > 0) ? 0 : -1;
|
||||
}
|
||||
|
||||
|
@ -581,11 +569,20 @@ mDNSexport mDNSu32 mDNSPlatformInterfaceIndexfromInterfaceID(mDNS *const m, mDNS
|
|||
// interface must have already been deregistered with the mDNS core.
|
||||
mDNSlocal void FreePosixNetworkInterface(PosixNetworkInterface *intf)
|
||||
{
|
||||
int rv;
|
||||
assert(intf != NULL);
|
||||
if (intf->intfName != NULL) free((void *)intf->intfName);
|
||||
if (intf->multicastSocket4 != -1) assert(close(intf->multicastSocket4) == 0);
|
||||
if (intf->multicastSocket4 != -1)
|
||||
{
|
||||
rv = close(intf->multicastSocket4);
|
||||
assert(rv == 0);
|
||||
}
|
||||
#if HAVE_IPV6
|
||||
if (intf->multicastSocket6 != -1) assert(close(intf->multicastSocket6) == 0);
|
||||
if (intf->multicastSocket6 != -1)
|
||||
{
|
||||
rv = close(intf->multicastSocket6);
|
||||
assert(rv == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Move interface to the RecentInterfaces list for a minute
|
||||
|
@ -602,7 +599,7 @@ mDNSlocal void ClearInterfaceList(mDNS *const m)
|
|||
while (m->HostInterfaces)
|
||||
{
|
||||
PosixNetworkInterface *intf = (PosixNetworkInterface*)(m->HostInterfaces);
|
||||
mDNS_DeregisterInterface(m, &intf->coreIntf, mDNSfalse);
|
||||
mDNS_DeregisterInterface(m, &intf->coreIntf, NormalActivation);
|
||||
if (gMDNSPlatformPosixVerboseLevel > 0) fprintf(stderr, "Deregistered interface %s\n", intf->intfName);
|
||||
FreePosixNetworkInterface(intf);
|
||||
}
|
||||
|
@ -639,10 +636,22 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
|
|||
// ... with a shared UDP port, if it's for multicast receiving
|
||||
if (err == 0 && port.NotAnInteger)
|
||||
{
|
||||
#if defined(SO_REUSEPORT)
|
||||
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEPORT, &kOn, sizeof(kOn));
|
||||
#elif defined(SO_REUSEADDR)
|
||||
// <rdar://problem/20946253>
|
||||
// We test for SO_REUSEADDR first, as suggested by Jonny Törnbom from Axis Communications
|
||||
// Linux kernel versions 3.9 introduces support for socket option
|
||||
// SO_REUSEPORT, however this is not implemented the same as on *BSD
|
||||
// systems. Linux version implements a "port hijacking" prevention
|
||||
// mechanism, limiting processes wanting to bind to an already existing
|
||||
// addr:port to have the same effective UID as the first who bound it. What
|
||||
// this meant for us was that the daemon ran as one user and when for
|
||||
// instance mDNSClientPosix was executed by another user, it wasn't allowed
|
||||
// to bind to the socket. Our suggestion was to switch the order in which
|
||||
// SO_REUSEPORT and SO_REUSEADDR was tested so that SO_REUSEADDR stays on
|
||||
// top and SO_REUSEPORT to be used only if SO_REUSEADDR doesn't exist.
|
||||
#if defined(SO_REUSEADDR) && !defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
|
||||
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
|
||||
#elif defined(SO_REUSEPORT)
|
||||
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEPORT, &kOn, sizeof(kOn));
|
||||
#else
|
||||
#error This platform has no way to avoid address busy errors on multicast.
|
||||
#endif
|
||||
|
@ -836,7 +845,13 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
|
|||
}
|
||||
|
||||
// Clean up
|
||||
if (err != 0 && *sktPtr != -1) { assert(close(*sktPtr) == 0); *sktPtr = -1; }
|
||||
if (err != 0 && *sktPtr != -1)
|
||||
{
|
||||
int rv;
|
||||
rv = close(*sktPtr);
|
||||
assert(rv == 0);
|
||||
*sktPtr = -1;
|
||||
}
|
||||
assert((err == 0) == (*sktPtr != -1));
|
||||
return err;
|
||||
}
|
||||
|
@ -855,7 +870,7 @@ mDNSlocal int SetupOneInterface(mDNS *const m, struct sockaddr *intfAddr, struct
|
|||
assert(intfMask != NULL);
|
||||
|
||||
// Allocate the interface structure itself.
|
||||
intf = (PosixNetworkInterface*)malloc(sizeof(*intf));
|
||||
intf = (PosixNetworkInterface*)calloc(1, sizeof(*intf));
|
||||
if (intf == NULL) { assert(0); err = ENOMEM; }
|
||||
|
||||
// And make a copy of the intfName.
|
||||
|
@ -907,13 +922,14 @@ mDNSlocal int SetupOneInterface(mDNS *const m, struct sockaddr *intfAddr, struct
|
|||
// and skip the probe phase of the probe/announce packet sequence.
|
||||
intf->coreIntf.DirectLink = mDNSfalse;
|
||||
#ifdef DIRECTLINK_INTERFACE_NAME
|
||||
if (strcmp(intfName, STRINGIFY(DIRECTLINK_INTERFACE_NAME)) == 0)
|
||||
intf->coreIntf.DirectLink = mDNStrue;
|
||||
if (strcmp(intfName, STRINGIFY(DIRECTLINK_INTERFACE_NAME)) == 0)
|
||||
intf->coreIntf.DirectLink = mDNStrue;
|
||||
#endif
|
||||
intf->coreIntf.SupportsUnicastMDNSResponse = mDNStrue;
|
||||
|
||||
// The interface is all ready to go, let's register it with the mDNS core.
|
||||
if (err == 0)
|
||||
err = mDNS_RegisterInterface(m, &intf->coreIntf, mDNSfalse);
|
||||
err = mDNS_RegisterInterface(m, &intf->coreIntf, NormalActivation);
|
||||
|
||||
// Clean up.
|
||||
if (err == 0)
|
||||
|
@ -1315,11 +1331,20 @@ mDNSexport mStatus mDNSPlatformInit(mDNS *const m)
|
|||
// In our case all we need to do is to tear down every network interface.
|
||||
mDNSexport void mDNSPlatformClose(mDNS *const m)
|
||||
{
|
||||
int rv;
|
||||
assert(m != NULL);
|
||||
ClearInterfaceList(m);
|
||||
if (m->p->unicastSocket4 != -1) assert(close(m->p->unicastSocket4) == 0);
|
||||
if (m->p->unicastSocket4 != -1)
|
||||
{
|
||||
rv = close(m->p->unicastSocket4);
|
||||
assert(rv == 0);
|
||||
}
|
||||
#if HAVE_IPV6
|
||||
if (m->p->unicastSocket6 != -1) assert(close(m->p->unicastSocket6) == 0);
|
||||
if (m->p->unicastSocket6 != -1)
|
||||
{
|
||||
rv = close(m->p->unicastSocket6);
|
||||
assert(rv == 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1366,14 +1391,36 @@ mDNSexport void mDNSPlatformUnlock (const mDNS *const m)
|
|||
// On the Posix platform this maps directly to the ANSI C strcpy.
|
||||
mDNSexport void mDNSPlatformStrCopy(void *dst, const void *src)
|
||||
{
|
||||
strcpy((char *)dst, (char *)src);
|
||||
strcpy((char *)dst, (const char *)src);
|
||||
}
|
||||
|
||||
mDNSexport mDNSu32 mDNSPlatformStrLCopy(void *dst, const void *src, mDNSu32 len)
|
||||
{
|
||||
#if HAVE_STRLCPY
|
||||
return ((mDNSu32)strlcpy((char *)dst, (const char *)src, len));
|
||||
#else
|
||||
size_t srcLen;
|
||||
|
||||
srcLen = strlen((const char *)src);
|
||||
if (srcLen < len)
|
||||
{
|
||||
memcpy(dst, src, srcLen + 1);
|
||||
}
|
||||
else if (len > 0)
|
||||
{
|
||||
memcpy(dst, src, len - 1);
|
||||
((char *)dst)[len - 1] = '\0';
|
||||
}
|
||||
|
||||
return ((mDNSu32)srcLen);
|
||||
#endif
|
||||
}
|
||||
|
||||
// mDNS core calls this routine to get the length of a C string.
|
||||
// On the Posix platform this maps directly to the ANSI C strlen.
|
||||
mDNSexport mDNSu32 mDNSPlatformStrLen (const void *src)
|
||||
{
|
||||
return strlen((char*)src);
|
||||
return strlen((const char*)src);
|
||||
}
|
||||
|
||||
// mDNS core calls this routine to copy memory.
|
||||
|
@ -1439,16 +1486,14 @@ mDNSexport mDNSu8 *DNSProxySetAttributes(DNSQuestion *q, DNSMessageHeader *h, DN
|
|||
return ptr;
|
||||
}
|
||||
|
||||
mDNSexport void DNSProxyInit(mDNS *const m, mDNSu32 IpIfArr[], mDNSu32 OpIf)
|
||||
mDNSexport void DNSProxyInit(mDNSu32 IpIfArr[], mDNSu32 OpIf)
|
||||
{
|
||||
(void) m;
|
||||
(void) IpIfArr;
|
||||
(void) OpIf;
|
||||
}
|
||||
|
||||
mDNSexport void DNSProxyTerminate(mDNS *const m)
|
||||
mDNSexport void DNSProxyTerminate(void)
|
||||
{
|
||||
(void) m;
|
||||
}
|
||||
|
||||
// mDNS core calls this routine to clear blocks of memory.
|
||||
|
@ -1461,12 +1506,19 @@ mDNSexport void mDNSPlatformMemZero(void *dst, mDNSu32 len)
|
|||
mDNSexport void * mDNSPlatformMemAllocate(mDNSu32 len) { return(malloc(len)); }
|
||||
mDNSexport void mDNSPlatformMemFree (void *mem) { free(mem); }
|
||||
|
||||
#if _PLATFORM_HAS_STRONG_PRNG_
|
||||
mDNSexport mDNSu32 mDNSPlatformRandomNumber(void)
|
||||
{
|
||||
return(arc4random());
|
||||
}
|
||||
#else
|
||||
mDNSexport mDNSu32 mDNSPlatformRandomSeed(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return(tv.tv_usec);
|
||||
}
|
||||
#endif
|
||||
|
||||
mDNSexport mDNSs32 mDNSPlatformOneSecond = 1024;
|
||||
|
||||
|
@ -1496,19 +1548,18 @@ mDNSexport mDNSs32 mDNSPlatformUTC(void)
|
|||
return time(NULL);
|
||||
}
|
||||
|
||||
mDNSexport void mDNSPlatformSendWakeupPacket(mDNS *const m, mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration)
|
||||
mDNSexport void mDNSPlatformSendWakeupPacket(mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration)
|
||||
{
|
||||
(void) m;
|
||||
(void) InterfaceID;
|
||||
(void) EthAddr;
|
||||
(void) IPAddr;
|
||||
(void) iteration;
|
||||
}
|
||||
|
||||
mDNSexport mDNSBool mDNSPlatformValidRecordForInterface(AuthRecord *rr, const NetworkInterfaceInfo *intf)
|
||||
mDNSexport mDNSBool mDNSPlatformValidRecordForInterface(const AuthRecord *rr, mDNSInterfaceID InterfaceID)
|
||||
{
|
||||
(void) rr;
|
||||
(void) intf;
|
||||
(void) InterfaceID;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1539,9 +1590,8 @@ mDNSexport void mDNSPlatformSendKeepalive(mDNSAddr *sadd, mDNSAddr *dadd, mDNSIP
|
|||
(void) win; // Unused
|
||||
}
|
||||
|
||||
mDNSexport mStatus mDNSPlatformRetrieveTCPInfo(mDNS *const m, mDNSAddr *laddr, mDNSIPPort *lport, mDNSAddr *raddr, mDNSIPPort *rport, mDNSTCPInfo *mti)
|
||||
mDNSexport mStatus mDNSPlatformRetrieveTCPInfo(mDNSAddr *laddr, mDNSIPPort *lport, mDNSAddr *raddr, mDNSIPPort *rport, mDNSTCPInfo *mti)
|
||||
{
|
||||
(void) m; // Unused
|
||||
(void) laddr; // Unused
|
||||
(void) raddr; // Unused
|
||||
(void) lport; // Unused
|
||||
|
@ -1551,10 +1601,9 @@ mDNSexport mStatus mDNSPlatformRetrieveTCPInfo(mDNS *const m, mDNSAddr *laddr, m
|
|||
return mStatus_NoError;
|
||||
}
|
||||
|
||||
mDNSexport mStatus mDNSPlatformGetRemoteMacAddr(mDNS *const m, mDNSAddr *raddr)
|
||||
mDNSexport mStatus mDNSPlatformGetRemoteMacAddr(mDNSAddr *raddr)
|
||||
{
|
||||
(void) raddr; // Unused
|
||||
(void) m; // Unused
|
||||
|
||||
return mStatus_NoError;
|
||||
}
|
||||
|
@ -1567,43 +1616,38 @@ mDNSexport mStatus mDNSPlatformStoreSPSMACAddr(mDNSAddr *spsaddr, char *ifnam
|
|||
return mStatus_NoError;
|
||||
}
|
||||
|
||||
mDNSexport mStatus mDNSPlatformClearSPSMACAddr(void)
|
||||
mDNSexport mStatus mDNSPlatformClearSPSData(void)
|
||||
{
|
||||
return mStatus_NoError;
|
||||
}
|
||||
|
||||
mDNSexport mStatus mDNSPlatformStoreOwnerOptRecord(char *ifname, DNSMessage *msg, int length)
|
||||
{
|
||||
(void) ifname; // Unused
|
||||
(void) msg; // Unused
|
||||
(void) length; // Unused
|
||||
return mStatus_UnsupportedErr;
|
||||
}
|
||||
|
||||
mDNSexport mDNSu16 mDNSPlatformGetUDPPort(UDPSocket *sock)
|
||||
{
|
||||
(void) sock; // unused
|
||||
|
||||
|
||||
return (mDNSu16)-1;
|
||||
}
|
||||
|
||||
mDNSexport mDNSBool mDNSPlatformInterfaceIsD2D(mDNSInterfaceID InterfaceID)
|
||||
{
|
||||
(void) InterfaceID; // unused
|
||||
|
||||
|
||||
return mDNSfalse;
|
||||
}
|
||||
|
||||
mDNSexport mDNSBool mDNSPlatformAllowPID(mDNS *const m, DNSQuestion *q)
|
||||
mDNSexport void mDNSPlatformSetSocktOpt(void *sock, mDNSTransport_Type transType, mDNSAddr_Type addrType, const DNSQuestion *q)
|
||||
{
|
||||
(void) m;
|
||||
(void) q;
|
||||
return mDNStrue;
|
||||
}
|
||||
|
||||
mDNSexport mDNSs32 mDNSPlatformGetServiceID(mDNS *const m, DNSQuestion *q)
|
||||
{
|
||||
(void) m;
|
||||
(void) q;
|
||||
return -1;
|
||||
}
|
||||
|
||||
mDNSexport void mDNSPlatformSetDelegatePID(UDPSocket *src, const mDNSAddr *dst, DNSQuestion *q)
|
||||
{
|
||||
(void) src;
|
||||
(void) dst;
|
||||
(void) sock;
|
||||
(void) transType;
|
||||
(void) addrType;
|
||||
(void) q;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ extern mStatus mDNSPlatformPosixRefreshInterfaceList(mDNS *const m);
|
|||
// Call mDNSPosixGetFDSet before calling select(), to update the parameters
|
||||
// as may be necessary to meet the needs of the mDNSCore code.
|
||||
// The timeout pointer MUST NOT be NULL.
|
||||
// Set timeout->tv_sec to 0x3FFFFFFF if you want to have effectively no timeout
|
||||
// Set timeout->tv_sec to FutureTime if you want to have effectively no timeout
|
||||
// After calling mDNSPosixGetFDSet(), call select(nfds, &readfds, NULL, NULL, &timeout); as usual
|
||||
// After select() returns, call mDNSPosixProcessFDSet() to let mDNSCore do its work
|
||||
extern void mDNSPosixGetFDSet(mDNS *m, int *nfds, fd_set *readfds, struct timeval *timeout);
|
||||
|
|
|
@ -83,14 +83,12 @@ void plen_to_mask(int plen, char *addr) {
|
|||
struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
|
||||
{
|
||||
struct ifi_info *ifi, *ifihead, **ifipnext, *ifipold, **ifiptr;
|
||||
FILE *fp;
|
||||
FILE *fp = NULL;
|
||||
char addr[8][5];
|
||||
int flags, myflags, index, plen, scope;
|
||||
char ifname[9], lastname[IFNAMSIZ];
|
||||
char addr6[32+7+1]; /* don't forget the seven ':' */
|
||||
struct addrinfo hints, *res0;
|
||||
struct sockaddr_in6 *sin6;
|
||||
struct in6_addr *addrptr;
|
||||
int err;
|
||||
int sockfd = -1;
|
||||
struct ifreq ifr;
|
||||
|
@ -150,18 +148,13 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
|
|||
char ipv6addr[INET6_ADDRSTRLEN];
|
||||
plen_to_mask(plen, ipv6addr);
|
||||
ifi->ifi_netmask = calloc(1, sizeof(struct sockaddr_in6));
|
||||
if (ifi->ifi_addr == NULL) {
|
||||
if (ifi->ifi_netmask == NULL) {
|
||||
goto gotError;
|
||||
}
|
||||
sin6=calloc(1, sizeof(struct sockaddr_in6));
|
||||
addrptr=calloc(1, sizeof(struct in6_addr));
|
||||
inet_pton(family, ipv6addr, addrptr);
|
||||
sin6->sin6_family=family;
|
||||
sin6->sin6_addr=*addrptr;
|
||||
sin6->sin6_scope_id=scope;
|
||||
memcpy(ifi->ifi_netmask, sin6, sizeof(struct sockaddr_in6));
|
||||
free(sin6);
|
||||
|
||||
((struct sockaddr_in6 *)ifi->ifi_netmask)->sin6_family=family;
|
||||
((struct sockaddr_in6 *)ifi->ifi_netmask)->sin6_scope_id=scope;
|
||||
inet_pton(family, ipv6addr, &((struct sockaddr_in6 *)ifi->ifi_netmask)->sin6_addr);
|
||||
|
||||
/* Add interface name */
|
||||
memcpy(ifi->ifi_name, ifname, IFI_NAME);
|
||||
|
@ -179,6 +172,7 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
|
|||
* EADDRNOTAVAIL for the main interface
|
||||
*/
|
||||
free(ifi->ifi_addr);
|
||||
free(ifi->ifi_netmask);
|
||||
free(ifi);
|
||||
ifipnext = ifiptr;
|
||||
*ifipnext = ifipold;
|
||||
|
@ -205,7 +199,12 @@ gotError:
|
|||
}
|
||||
done:
|
||||
if (sockfd != -1) {
|
||||
assert(close(sockfd) == 0);
|
||||
int rv;
|
||||
rv = close(sockfd);
|
||||
assert(rv == 0);
|
||||
}
|
||||
if (fp != NULL) {
|
||||
fclose(fp);
|
||||
}
|
||||
return(ifihead); /* pointer to first structure in linked list */
|
||||
}
|
||||
|
|
|
@ -834,6 +834,12 @@ typedef unsigned long int uintptr_t;
|
|||
#endif
|
||||
#endif
|
||||
|
||||
// Limits
|
||||
|
||||
#if( !defined( UINT32_MAX ) )
|
||||
#define UINT32_MAX UINT32_C( 4294967295 )
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#pragma mark == bool ==
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2003-2011 Apple 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.
|
||||
|
@ -13,13 +13,6 @@
|
|||
* 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.
|
||||
|
||||
File: GenLinkedList.c
|
||||
|
||||
Contains: implementation of generic linked lists.
|
||||
|
||||
Version: 1.0
|
||||
Tabs: 4 spaces
|
||||
*/
|
||||
|
||||
#include "GenLinkedList.h"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2004-2015 Apple 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.
|
||||
|
@ -23,6 +23,10 @@
|
|||
#include <netinet/in.h> // Needed for sockaddr_in
|
||||
#include <syslog.h>
|
||||
|
||||
#if APPLE_OSX_mDNSResponder
|
||||
#include <os/log.h>
|
||||
#endif
|
||||
|
||||
#include "mDNSEmbeddedAPI.h" // Defines the interface provided to the client layer above
|
||||
#include "DNSCommon.h"
|
||||
#include "PlatformCommon.h"
|
||||
|
@ -174,6 +178,14 @@ mDNSexport void mDNSPlatformWriteLogMsg(const char *ident, const char *buffer, m
|
|||
int syslog_level = LOG_ERR;
|
||||
switch (loglevel)
|
||||
{
|
||||
#if APPLE_OSX_mDNSResponder
|
||||
case MDNS_LOG_MSG: syslog_level = OS_LOG_TYPE_DEFAULT; break;
|
||||
case MDNS_LOG_OPERATION: syslog_level = OS_LOG_TYPE_INFO; break;
|
||||
case MDNS_LOG_SPS: syslog_level = OS_LOG_TYPE_INFO; break;
|
||||
case MDNS_LOG_INFO: syslog_level = OS_LOG_TYPE_INFO; break;
|
||||
case MDNS_LOG_DEBUG: syslog_level = OS_LOG_TYPE_DEBUG; break;
|
||||
default: syslog_level = OS_LOG_TYPE_DEFAULT; break;
|
||||
#else
|
||||
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;
|
||||
|
@ -182,6 +194,7 @@ mDNSexport void mDNSPlatformWriteLogMsg(const char *ident, const char *buffer, m
|
|||
default:
|
||||
fprintf(stderr, "Unknown loglevel %d, assuming LOG_ERR\n", loglevel);
|
||||
fflush(stderr);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!log_inited) { openlog(ident, LOG_CONS, LOG_DAEMON); log_inited++; }
|
||||
|
@ -190,10 +203,13 @@ mDNSexport void mDNSPlatformWriteLogMsg(const char *ident, const char *buffer, m
|
|||
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
|
||||
{
|
||||
#if APPLE_OSX_mDNSResponder
|
||||
mDNSPlatformLogToFile(syslog_level, buffer);
|
||||
#else
|
||||
syslog(syslog_level, "%s", buffer);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.\" -*- tab-width: 4 -*-
|
||||
.\"
|
||||
.\" Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
|
||||
.\" Copyright (c) 2004-2012 Apple 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.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2003-2013 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2003-2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
@ -10,7 +10,7 @@
|
|||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* 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 Inc. ("Apple") nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
|
@ -66,7 +66,7 @@
|
|||
*/
|
||||
|
||||
#ifndef _DNS_SD_H
|
||||
#define _DNS_SD_H 5763004
|
||||
#define _DNS_SD_H 8780101
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -88,6 +88,13 @@ extern "C" {
|
|||
#define DNSSD_API
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <winsock2.h>
|
||||
typedef SOCKET dnssd_sock_t;
|
||||
#else
|
||||
typedef int dnssd_sock_t;
|
||||
#endif
|
||||
|
||||
/* stdint.h does not exist on FreeBSD 4.x; its types are defined in sys/types.h instead */
|
||||
#if defined(__FreeBSD__) && (__FreeBSD__ < 5)
|
||||
#include <sys/types.h>
|
||||
|
@ -180,6 +187,15 @@ enum
|
|||
* in the future they will be delivered as usual.
|
||||
*/
|
||||
|
||||
kDNSServiceFlagsAutoTrigger = 0x1,
|
||||
/* Valid for browses using kDNSServiceInterfaceIndexAny.
|
||||
* Will auto trigger the browse over AWDL as well once the service is discoveryed
|
||||
* over BLE.
|
||||
* This flag is an input value to DNSServiceBrowse(), which is why we can
|
||||
* use the same value as kDNSServiceFlagsMoreComing, which is an output flag
|
||||
* for various client callbacks.
|
||||
*/
|
||||
|
||||
kDNSServiceFlagsAdd = 0x2,
|
||||
kDNSServiceFlagsDefault = 0x4,
|
||||
/* Flags for domain enumeration and browse/query reply callbacks.
|
||||
|
@ -330,10 +346,21 @@ enum
|
|||
*
|
||||
* 5. Thread Safety
|
||||
* The dns_sd.h API does not presuppose any particular threading model, and consequently
|
||||
* does no locking of its own (which would require linking some specific threading library).
|
||||
* If client code calls API routines on the same DNSServiceRef concurrently
|
||||
* from multiple threads, it is the client's responsibility to use a mutext
|
||||
* lock or take similar appropriate precautions to serialize those calls.
|
||||
* does no locking internally (which would require linking with a specific threading library).
|
||||
* If the client concurrently, from multiple threads (or contexts), calls API routines using
|
||||
* the same DNSServiceRef, it is the client's responsibility to provide mutual exclusion for
|
||||
* that DNSServiceRef.
|
||||
|
||||
* For example, use of DNSServiceRefDeallocate requires caution. A common mistake is as follows:
|
||||
* Thread B calls DNSServiceRefDeallocate to deallocate sdRef while Thread A is processing events
|
||||
* using sdRef. Doing this will lead to intermittent crashes on thread A if the sdRef is used after
|
||||
* it was deallocated.
|
||||
|
||||
* A telltale sign of this crash type is to see DNSServiceProcessResult on the stack preceding the
|
||||
* actual crash location.
|
||||
|
||||
* To state this more explicitly, mDNSResponder does not queue DNSServiceRefDeallocate so
|
||||
* that it occurs discretely before or after an event is handled.
|
||||
*/
|
||||
|
||||
kDNSServiceFlagsSuppressUnusable = 0x8000,
|
||||
|
@ -405,7 +432,7 @@ enum
|
|||
|
||||
kDNSServiceFlagsSecure = 0x200010,
|
||||
/*
|
||||
* The response has been validated by verifying all the signaures in the response and was able to
|
||||
* The response has been validated by verifying all the signatures in the response and was able to
|
||||
* build a successful authentication chain starting from a known trust anchor.
|
||||
*/
|
||||
|
||||
|
@ -484,23 +511,24 @@ enum
|
|||
* is only set in the callbacks and kDNSServiceFlagsThresholdOne is only set on
|
||||
* input to a DNSServiceBrowse call.
|
||||
*/
|
||||
kDNSServiceFlagsDenyCellular = 0x8000000,
|
||||
kDNSServiceFlagsPrivateOne = 0x8000000,
|
||||
/*
|
||||
* This flag is meaningful only for Unicast DNS queries. When set, the kernel will restrict
|
||||
* DNS resolutions on the cellular interface for that request.
|
||||
* This flag is private and should not be used.
|
||||
*/
|
||||
|
||||
kDNSServiceFlagsServiceIndex = 0x10000000,
|
||||
kDNSServiceFlagsPrivateTwo = 0x10000000,
|
||||
/*
|
||||
* This flag is meaningful only for DNSServiceGetAddrInfo() for Unicast DNS queries.
|
||||
* When set, DNSServiceGetAddrInfo() will interpret the "interfaceIndex" argument of the call
|
||||
* as the "serviceIndex".
|
||||
* This flag is private and should not be used.
|
||||
*/
|
||||
|
||||
kDNSServiceFlagsDenyExpensive = 0x20000000
|
||||
kDNSServiceFlagsPrivateThree = 0x20000000,
|
||||
/*
|
||||
* This flag is meaningful only for Unicast DNS queries. When set, the kernel will restrict
|
||||
* DNS resolutions on interfaces defined as expensive for that request.
|
||||
* This flag is private and should not be used.
|
||||
*/
|
||||
|
||||
kDNSServiceFlagsPrivateFour = 0x40000000
|
||||
/*
|
||||
* This flag is private and should not be used.
|
||||
*/
|
||||
|
||||
};
|
||||
|
@ -667,24 +695,49 @@ enum
|
|||
* -- or --
|
||||
* "Why is kDNSServiceMaxDomainName 1009, when the maximum legal domain name is 256 bytes?"
|
||||
*
|
||||
* All strings used in the DNS-SD APIs are UTF-8 strings. Apart from the exceptions noted below,
|
||||
* the APIs expect the strings to be properly escaped, using the conventional DNS escaping rules:
|
||||
* All strings used in the DNS-SD APIs are UTF-8 strings.
|
||||
* Apart from the exceptions noted below, the APIs expect the strings to be properly escaped, using the
|
||||
* conventional DNS escaping rules, as used by the traditional DNS res_query() API, as described below:
|
||||
*
|
||||
* '\\' represents a single literal '\' in the name
|
||||
* '\.' represents a single literal '.' in the name
|
||||
* Generally all UTF-8 characters (which includes all US ASCII characters) represent themselves,
|
||||
* with two exceptions, the dot ('.') character, which is the label separator,
|
||||
* and the backslash ('\') character, which is the escape character.
|
||||
* The escape character ('\') is interpreted as described below:
|
||||
*
|
||||
* '\ddd', where ddd is a three-digit decimal value from 000 to 255,
|
||||
* represents a single literal byte with that value.
|
||||
* A bare unescaped '.' is a label separator, marking a boundary between domain and subdomain.
|
||||
* represents a single literal byte with that value. Any byte value may be
|
||||
* represented in '\ddd' format, even characters that don't strictly need to be escaped.
|
||||
* For example, the ASCII code for 'w' is 119, and therefore '\119' is equivalent to 'w'.
|
||||
* Thus the command "ping '\119\119\119.apple.com'" is the equivalent to the command "ping 'www.apple.com'".
|
||||
* Nonprinting ASCII characters in the range 0-31 are often represented this way.
|
||||
* In particular, the ASCII NUL character (0) cannot appear in a C string because C uses it as the
|
||||
* string terminator character, so ASCII NUL in a domain name has to be represented in a C string as '\000'.
|
||||
* Other characters like space (ASCII code 32) are sometimes represented as '\032'
|
||||
* in contexts where having an actual space character in a C string would be inconvenient.
|
||||
*
|
||||
* Otherwise, for all cases where a '\' is followed by anything other than a three-digit decimal value
|
||||
* from 000 to 255, the character sequence '\x' represents a single literal occurrence of character 'x'.
|
||||
* This is legal for any character, so, for example, '\w' is equivalent to 'w'.
|
||||
* Thus the command "ping '\w\w\w.apple.com'" is the equivalent to the command "ping 'www.apple.com'".
|
||||
* However, this encoding is most useful when representing the characters '.' and '\',
|
||||
* which otherwise would have special meaning in DNS name strings.
|
||||
* This means that the following encodings are particularly common:
|
||||
* '\\' represents a single literal '\' in the name
|
||||
* '\.' represents a single literal '.' in the name
|
||||
*
|
||||
* A lone escape character ('\') appearing at the end of a string is not allowed, since it is
|
||||
* followed by neither a three-digit decimal value from 000 to 255 nor a single character.
|
||||
* If a lone escape character ('\') does appear as the last character of a string, it is silently ignored.
|
||||
*
|
||||
* The exceptions, that do not use escaping, are the routines where the full
|
||||
* DNS name of a resource is broken, for convenience, into servicename/regtype/domain.
|
||||
* In these routines, the "servicename" is NOT escaped. It does not need to be, since
|
||||
* it is, by definition, just a single literal string. Any characters in that string
|
||||
* represent exactly what they are. The "regtype" portion is, technically speaking,
|
||||
* escaped, but since legal regtypes are only allowed to contain letters, digits,
|
||||
* and hyphens, there is nothing to escape, so the issue is moot. The "domain"
|
||||
* portion is also escaped, though most domains in use on the public Internet
|
||||
* today, like regtypes, don't contain any characters that need to be escaped.
|
||||
* escaped, but since legal regtypes are only allowed to contain US ASCII letters,
|
||||
* digits, and hyphens, there is nothing to escape, so the issue is moot.
|
||||
* The "domain" portion is also escaped, though most domains in use on the public
|
||||
* Internet today, like regtypes, don't contain any characters that need to be escaped.
|
||||
* As DNS-SD becomes more popular, rich-text domains for service discovery will
|
||||
* become common, so software should be written to cope with domains with escaping.
|
||||
*
|
||||
|
@ -704,7 +757,7 @@ enum
|
|||
* full DNS name, the helper function DNSServiceConstructFullName() is provided.
|
||||
*
|
||||
* The following (highly contrived) example illustrates the escaping process.
|
||||
* Suppose you have an service called "Dr. Smith\Dr. Johnson", of type "_ftp._tcp"
|
||||
* Suppose you have a service called "Dr. Smith\Dr. Johnson", of type "_ftp._tcp"
|
||||
* in subdomain "4th. Floor" of subdomain "Building 2" of domain "apple.com."
|
||||
* The full (escaped) DNS name of this service's SRV record would be:
|
||||
* Dr\.\032Smith\\Dr\.\032Johnson._ftp._tcp.4th\.\032Floor.Building\0322.apple.com.
|
||||
|
@ -724,9 +777,8 @@ enum
|
|||
* DNS server." Normally, most clients will use 0 for interface index to
|
||||
* automatically get the default sensible behaviour.
|
||||
*
|
||||
* If the client passes a positive interface index, then for multicast names that
|
||||
* indicates to do the operation only on that one interface. For unicast names the
|
||||
* interface index is ignored unless kDNSServiceFlagsForceMulticast is also set.
|
||||
* If the client passes a positive interface index, then that indicates to do the
|
||||
* operation only on that one specified interface.
|
||||
*
|
||||
* If the client passes kDNSServiceInterfaceIndexLocalOnly when registering
|
||||
* a service, then that service will be found *only* by other local clients
|
||||
|
@ -737,12 +789,29 @@ enum
|
|||
* in a way such that it does not inadvertently appear in service lists on
|
||||
* all the other machines on the network.
|
||||
*
|
||||
* If the client passes kDNSServiceInterfaceIndexLocalOnly when browsing
|
||||
* then it will find *all* records registered on that same local machine.
|
||||
* Clients explicitly wishing to discover *only* LocalOnly services can
|
||||
* accomplish this by inspecting the interfaceIndex of each service reported
|
||||
* to their DNSServiceBrowseReply() callback function, and discarding those
|
||||
* where the interface index is not kDNSServiceInterfaceIndexLocalOnly.
|
||||
* If the client passes kDNSServiceInterfaceIndexLocalOnly when querying or
|
||||
* browsing, then the LocalOnly authoritative records and /etc/hosts caches
|
||||
* are searched and will find *all* records registered or configured on that
|
||||
* same local machine.
|
||||
*
|
||||
* If interested in getting negative answers to local questions while querying
|
||||
* or browsing, then set both the kDNSServiceInterfaceIndexLocalOnly and the
|
||||
* kDNSServiceFlagsReturnIntermediates flags. If no local answers exist at this
|
||||
* moment in time, then the reply will return an immediate negative answer. If
|
||||
* local records are subsequently created that answer the question, then those
|
||||
* answers will be delivered, for as long as the question is still active.
|
||||
*
|
||||
* If the kDNSServiceFlagsTimeout and kDNSServiceInterfaceIndexLocalOnly flags
|
||||
* are set simultaneously when either DNSServiceQueryRecord or DNSServiceGetAddrInfo
|
||||
* is called then both flags take effect. However, if DNSServiceQueryRecord is called
|
||||
* with both the kDNSServiceFlagsSuppressUnusable and kDNSServiceInterfaceIndexLocalOnly
|
||||
* flags set, then the kDNSServiceFlagsSuppressUnusable flag is ignored.
|
||||
*
|
||||
* Clients explicitly wishing to discover *only* LocalOnly services during a
|
||||
* browse may do this, without flags, by inspecting the interfaceIndex of each
|
||||
* service reported to a DNSServiceBrowseReply() callback function, and
|
||||
* discarding those answers where the interface index is not set to
|
||||
* kDNSServiceInterfaceIndexLocalOnly.
|
||||
*
|
||||
* kDNSServiceInterfaceIndexP2P is meaningful only in Browse, QueryRecord, Register,
|
||||
* and Resolve operations. It should not be used in other DNSService APIs.
|
||||
|
@ -771,6 +840,7 @@ enum
|
|||
#define kDNSServiceInterfaceIndexLocalOnly ((uint32_t)-1)
|
||||
#define kDNSServiceInterfaceIndexUnicast ((uint32_t)-2)
|
||||
#define kDNSServiceInterfaceIndexP2P ((uint32_t)-3)
|
||||
#define kDNSServiceInterfaceIndexBLE ((uint32_t)-4)
|
||||
|
||||
typedef uint32_t DNSServiceFlags;
|
||||
typedef uint32_t DNSServiceProtocol;
|
||||
|
@ -828,29 +898,6 @@ DNSServiceErrorType DNSSD_API DNSServiceGetProperty
|
|||
|
||||
#define kDNSServiceProperty_DaemonVersion "DaemonVersion"
|
||||
|
||||
|
||||
// Map the source port of the local UDP socket that was opened for sending the DNS query
|
||||
// to the process ID of the application that triggered the DNS resolution.
|
||||
//
|
||||
/* DNSServiceGetPID() Parameters:
|
||||
*
|
||||
* srcport: Source port (in network byte order) of the UDP socket that was created by
|
||||
* the daemon to send the DNS query on the wire.
|
||||
*
|
||||
* pid: Process ID of the application that started the name resolution which triggered
|
||||
* the daemon to send the query on the wire. The value can be -1 if the srcport
|
||||
* cannot be mapped.
|
||||
*
|
||||
* return value: Returns kDNSServiceErr_NoError on success, or kDNSServiceErr_ServiceNotRunning
|
||||
* if the daemon is not running. The value of the pid is undefined if the return
|
||||
* value has error.
|
||||
*/
|
||||
DNSServiceErrorType DNSSD_API DNSServiceGetPID
|
||||
(
|
||||
uint16_t srcport,
|
||||
int32_t *pid
|
||||
);
|
||||
|
||||
/*********************************************************************************************
|
||||
*
|
||||
* Unix Domain Socket access, DNSServiceRef deallocation, and data processing functions
|
||||
|
@ -871,8 +918,8 @@ DNSServiceErrorType DNSSD_API DNSServiceGetPID
|
|||
* a client can choose to fork a thread and have it loop calling "DNSServiceProcessResult(ref);"
|
||||
* If DNSServiceProcessResult() is called when no data is available for reading on the socket, it
|
||||
* will block until data does become available, and then process the data and return to the caller.
|
||||
* The application is reponsible for checking the return value of DNSServiceProcessResult() to determine
|
||||
* if the socket is valid and if it should continue to process data on the socket.
|
||||
* The application is responsible for checking the return value of DNSServiceProcessResult()
|
||||
* to determine if the socket is valid and if it should continue to process data on the socket.
|
||||
* When data arrives on the socket, the client is responsible for calling DNSServiceProcessResult(ref)
|
||||
* in a timely fashion -- if the client allows a large backlog of data to build up the daemon
|
||||
* may terminate the connection.
|
||||
|
@ -883,7 +930,7 @@ DNSServiceErrorType DNSSD_API DNSServiceGetPID
|
|||
* error.
|
||||
*/
|
||||
|
||||
int DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef);
|
||||
dnssd_sock_t DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef);
|
||||
|
||||
|
||||
/* DNSServiceProcessResult()
|
||||
|
@ -1085,14 +1132,14 @@ typedef void (DNSSD_API *DNSServiceRegisterReply)
|
|||
* and the registration will remain active indefinitely until the client
|
||||
* terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
|
||||
*
|
||||
* flags: Indicates the renaming behavior on name conflict (most applications
|
||||
* will pass 0). See flag definitions above for details.
|
||||
*
|
||||
* interfaceIndex: If non-zero, specifies the interface on which to register the service
|
||||
* (the index for a given interface is determined via the if_nametoindex()
|
||||
* family of calls.) Most applications will pass 0 to register on all
|
||||
* available interfaces. See "Constants for specifying an interface index" for more details.
|
||||
*
|
||||
* flags: Indicates the renaming behavior on name conflict (most applications
|
||||
* will pass 0). See flag definitions above for details.
|
||||
*
|
||||
* name: If non-NULL, specifies the service name to be registered.
|
||||
* Most applications will not specify a name, in which case the computer
|
||||
* name is used (this name is communicated to the client via the callback).
|
||||
|
@ -1232,7 +1279,7 @@ DNSServiceErrorType DNSSD_API DNSServiceRegister
|
|||
* Note that the DNSServiceAddRecord/UpdateRecord/RemoveRecord are *NOT* thread-safe
|
||||
* with respect to a single DNSServiceRef. If you plan to have multiple threads
|
||||
* in your program simultaneously add, update, or remove records from the same
|
||||
* DNSServiceRef, then it's the caller's responsibility to use a mutext lock
|
||||
* DNSServiceRef, then it's the caller's responsibility to use a mutex lock
|
||||
* or take similar appropriate precautions to serialize those calls.
|
||||
*
|
||||
* Parameters;
|
||||
|
@ -1315,7 +1362,7 @@ DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
|
|||
/* DNSServiceRemoveRecord
|
||||
*
|
||||
* Remove a record previously added to a service record set via DNSServiceAddRecord(), or deregister
|
||||
* an record registered individually via DNSServiceRegisterRecord().
|
||||
* a record registered individually via DNSServiceRegisterRecord().
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
|
@ -1623,7 +1670,9 @@ DNSServiceErrorType DNSSD_API DNSServiceResolve
|
|||
* only applies to clients that cancel the asynchronous operation when
|
||||
* they get a result. Clients that leave the asynchronous operation
|
||||
* running can safely assume that the data remains valid until they
|
||||
* get another callback telling them otherwise.
|
||||
* get another callback telling them otherwise. The ttl value is not
|
||||
* updated when the daemon answers from the cache, hence relying on
|
||||
* the accuracy of the ttl value is not recommended.
|
||||
*
|
||||
* context: The context pointer that was passed to the callout.
|
||||
*
|
||||
|
@ -1729,7 +1778,9 @@ DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
|
|||
* only applies to clients that cancel the asynchronous operation when
|
||||
* they get a result. Clients that leave the asynchronous operation
|
||||
* running can safely assume that the data remains valid until they
|
||||
* get another callback telling them otherwise.
|
||||
* get another callback telling them otherwise. The ttl value is not
|
||||
* updated when the daemon answers from the cache, hence relying on
|
||||
* the accuracy of the ttl value is not recommended.
|
||||
*
|
||||
* context: The context pointer that was passed to the callout.
|
||||
*
|
||||
|
@ -2242,8 +2293,8 @@ typedef union _TXTRecordRef_t { char PrivateData[16]; char *ForceNaturalAlignmen
|
|||
* For most applications, DNS-SD TXT records are generally
|
||||
* less than 100 bytes, so in most cases a simple fixed-sized
|
||||
* 256-byte buffer will be more than sufficient.
|
||||
* Recommended size limits for DNS-SD TXT Records are discussed in
|
||||
* <http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt>
|
||||
* Recommended size limits for DNS-SD TXT Records are discussed in RFC 6763
|
||||
* <https://tools.ietf.org/html/rfc6763#section-6.2>
|
||||
*
|
||||
* Note: When passing parameters to and from these TXT record APIs,
|
||||
* the key name does not include the '=' character. The '=' character
|
||||
|
@ -2293,8 +2344,8 @@ void DNSSD_API TXTRecordDeallocate
|
|||
* - Present with no value ("key" appears alone)
|
||||
* - Present with empty value ("key=" appears in TXT record)
|
||||
* - Present with non-empty value ("key=value" appears in TXT record)
|
||||
* For more details refer to "Data Syntax for DNS-SD TXT Records" in
|
||||
* <http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt>
|
||||
* For more details refer to "Data Syntax for DNS-SD TXT Records" in RFC 6763
|
||||
* <https://tools.ietf.org/html/rfc6763#section-6>
|
||||
*
|
||||
* txtRecord: A TXTRecordRef initialized by calling TXTRecordCreate().
|
||||
*
|
||||
|
@ -2606,41 +2657,6 @@ DNSServiceErrorType DNSSD_API DNSServiceSleepKeepalive
|
|||
);
|
||||
#endif
|
||||
|
||||
#ifdef APPLE_OSX_mDNSResponder
|
||||
/* DNSServiceCreateDelegateConnection()
|
||||
*
|
||||
* Create a delegate connection to the daemon allowing efficient registration of
|
||||
* multiple individual records.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* sdRef: A pointer to an uninitialized DNSServiceRef. Deallocating
|
||||
* the reference (via DNSServiceRefDeallocate()) severs the
|
||||
* connection and deregisters all records registered on this connection.
|
||||
*
|
||||
* pid : Process ID of the delegate
|
||||
*
|
||||
* uuid: UUID of the delegate
|
||||
*
|
||||
* Note that only one of the two arguments (pid or uuid) can be specified. If pid
|
||||
* is zero, uuid will be assumed to be a valid value; otherwise pid will be used.
|
||||
*
|
||||
* return value: Returns kDNSServiceErr_NoError on success, otherwise returns
|
||||
* an error code indicating the specific failure that occurred (in which
|
||||
* case the DNSServiceRef is not initialized). kDNSServiceErr_NotAuth is
|
||||
* returned to indicate that the calling process does not have entitlements
|
||||
* to use this API.
|
||||
*/
|
||||
DNSServiceErrorType DNSSD_API DNSServiceCreateDelegateConnection(DNSServiceRef *sdRef, int32_t pid, uuid_t uuid);
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE_API_PRIVATE
|
||||
|
||||
#define kDNSServiceCompPrivateDNS "PrivateDNS"
|
||||
#define kDNSServiceCompMulticastDNS "MulticastDNS"
|
||||
|
||||
#endif //__APPLE_API_PRIVATE
|
||||
|
||||
/* Some C compiler cleverness. We can make the compiler check certain things for us,
|
||||
* and report errors at compile-time if anything is wrong. The usual way to do this would
|
||||
* be to use a run-time "if" statement or the conventional run-time "assert" mechanism, but
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2016 Apple Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DNS_SD_INTERNAL_H
|
||||
#define _DNS_SD_INTERNAL_H
|
||||
|
||||
#if !APPLE_OSX_mDNSResponder
|
||||
#define DNSSD_NO_CREATE_DELEGATE_CONNECTION 1
|
||||
#endif
|
||||
|
||||
#include "dns_sd_private.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,89 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2015 Apple Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DNS_SD_PRIVATE_H
|
||||
#define _DNS_SD_PRIVATE_H
|
||||
|
||||
|
||||
// Private flags (kDNSServiceFlagsPrivateOne, kDNSServiceFlagsPrivateTwo, kDNSServiceFlagsPrivateThree, kDNSServiceFlagsPrivateFour) from dns_sd.h
|
||||
enum
|
||||
{
|
||||
kDNSServiceFlagsDenyCellular = 0x8000000,
|
||||
/*
|
||||
* This flag is meaningful only for Unicast DNS queries. When set, the daemon will restrict
|
||||
* DNS resolutions on the cellular interface for that request.
|
||||
*/
|
||||
kDNSServiceFlagsServiceIndex = 0x10000000,
|
||||
/*
|
||||
* This flag is meaningful only for DNSServiceGetAddrInfo() for Unicast DNS queries.
|
||||
* When set, DNSServiceGetAddrInfo() will interpret the "interfaceIndex" argument of the call
|
||||
* as the "serviceIndex".
|
||||
*/
|
||||
|
||||
kDNSServiceFlagsDenyExpensive = 0x20000000,
|
||||
/*
|
||||
* This flag is meaningful only for Unicast DNS queries. When set, the daemon will restrict
|
||||
* DNS resolutions on interfaces defined as expensive for that request.
|
||||
*/
|
||||
|
||||
kDNSServiceFlagsPathEvaluationDone = 0x40000000
|
||||
/*
|
||||
* This flag is meaningful for only Unicast DNS queries.
|
||||
* When set, it indicates that Network PathEvaluation has already been performed.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
#if !DNSSD_NO_CREATE_DELEGATE_CONNECTION
|
||||
/* DNSServiceCreateDelegateConnection()
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* sdRef: A pointer to an uninitialized DNSServiceRef. Deallocating
|
||||
* the reference (via DNSServiceRefDeallocate()) severs the
|
||||
* connection and deregisters all records registered on this connection.
|
||||
*
|
||||
* pid : Process ID of the delegate
|
||||
*
|
||||
* uuid: UUID of the delegate
|
||||
*
|
||||
* Note that only one of the two arguments (pid or uuid) can be specified. If pid
|
||||
* is zero, uuid will be assumed to be a valid value; otherwise pid will be used.
|
||||
*
|
||||
* return value: Returns kDNSServiceErr_NoError on success, otherwise returns
|
||||
* an error code indicating the specific failure that occurred (in which
|
||||
* case the DNSServiceRef is not initialized). kDNSServiceErr_NotAuth is
|
||||
* returned to indicate that the calling process does not have entitlements
|
||||
* to use this API.
|
||||
*/
|
||||
DNSServiceErrorType DNSSD_API DNSServiceCreateDelegateConnection(DNSServiceRef *sdRef, int32_t pid, uuid_t uuid);
|
||||
#endif
|
||||
|
||||
// Map the source port of the local UDP socket that was opened for sending the DNS query
|
||||
// to the process ID of the application that triggered the DNS resolution.
|
||||
//
|
||||
/* DNSServiceGetPID() Parameters:
|
||||
*
|
||||
* srcport: Source port (in network byte order) of the UDP socket that was created by
|
||||
* the daemon to send the DNS query on the wire.
|
||||
*
|
||||
* pid: Process ID of the application that started the name resolution which triggered
|
||||
* the daemon to send the query on the wire. The value can be -1 if the srcport
|
||||
* cannot be mapped.
|
||||
*
|
||||
* return value: Returns kDNSServiceErr_NoError on success, or kDNSServiceErr_ServiceNotRunning
|
||||
* if the daemon is not running. The value of the pid is undefined if the return
|
||||
* value has error.
|
||||
*/
|
||||
DNSServiceErrorType DNSSD_API DNSServiceGetPID
|
||||
(
|
||||
uint16_t srcport,
|
||||
int32_t *pid
|
||||
);
|
||||
|
||||
#define kDNSServiceCompPrivateDNS "PrivateDNS"
|
||||
#define kDNSServiceCompMulticastDNS "MulticastDNS"
|
||||
|
||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2006-2010 Apple 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.
|
||||
|
@ -76,6 +76,7 @@ typedef struct ZoneSpec
|
|||
|
||||
|
||||
static StringListElem * g_stringList = NULL;
|
||||
static StringListElem * g_addrList = NULL;
|
||||
static KeySpec * g_keys;
|
||||
static ZoneSpec * g_zones;
|
||||
static ZoneSpec g_zoneSpec;
|
||||
|
@ -173,6 +174,22 @@ optionsstatement:
|
|||
|
|
||||
LISTEN_ON PORT NUMBER addresscontent
|
||||
{
|
||||
mDNSIPPort listen_port = mDNSOpaque16fromIntVal( $3 );
|
||||
DaemonInfo* d = ( DaemonInfo* ) context;
|
||||
d->addr.sin_port = ( listen_port.NotAnInteger) ? listen_port.NotAnInteger : UnicastDNSPort.NotAnInteger;
|
||||
StringListElem* addr = g_addrList;
|
||||
while (addr != NULL)
|
||||
{
|
||||
StringListElem* next;
|
||||
// The first ipv4 address in {,} is used; the rest are ignored.
|
||||
if (inet_pton( AF_INET, addr->string, &d->addr.sin_addr ) == 0) {
|
||||
inet_pton( AF_INET, "127.0.0.1", &d->ns_addr.sin_addr );
|
||||
LogMsg("LISTEN_ON: An invalid ipv4 address, %s, detected.", addr->string);
|
||||
}
|
||||
next = addr->next;
|
||||
free(addr);
|
||||
addr = next;
|
||||
}
|
||||
}
|
||||
|
|
||||
NAMESERVER ADDRESS networkaddress
|
||||
|
@ -308,6 +325,20 @@ addressstatements:
|
|||
addressstatement:
|
||||
DOTTED_DECIMAL_ADDRESS
|
||||
{
|
||||
StringListElem * elem;
|
||||
|
||||
elem = ( StringListElem* ) malloc( sizeof( StringListElem ) );
|
||||
|
||||
if ( !elem )
|
||||
{
|
||||
LogMsg("ERROR: memory allocation failure");
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
elem->string = $1;
|
||||
|
||||
elem->next = g_addrList;
|
||||
g_addrList = elem;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2004, Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2004-2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
@ -10,7 +10,7 @@
|
|||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* 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 Inc. ("Apple") nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2003-2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
@ -10,7 +10,7 @@
|
|||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* 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 Inc. ("Apple") nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
|
@ -29,14 +29,15 @@
|
|||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "dnssd_ipc.h"
|
||||
|
||||
#if APPLE_OSX_mDNSResponder
|
||||
#include <mach-o/dyld.h>
|
||||
#include <uuid/uuid.h>
|
||||
#include <TargetConditionals.h>
|
||||
#include "dns_sd_internal.h"
|
||||
#endif
|
||||
|
||||
#include "dnssd_ipc.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#define _SSIZE_T
|
||||
|
@ -74,7 +75,7 @@ static void syslog( int priority, const char * message, ...)
|
|||
va_start( args, message );
|
||||
len = _vscprintf( message, args ) + 1;
|
||||
buffer = malloc( len * sizeof(char) );
|
||||
if ( buffer ) { vsprintf( buffer, message, args ); OutputDebugString( buffer ); free( buffer ); }
|
||||
if ( buffer ) { vsnprintf( buffer, len, message, args ); OutputDebugString( buffer ); free( buffer ); }
|
||||
WSASetLastError( err );
|
||||
}
|
||||
#else
|
||||
|
@ -171,6 +172,19 @@ struct _DNSRecordRef_t
|
|||
DNSServiceOp *sdr;
|
||||
};
|
||||
|
||||
#if !defined(USE_TCP_LOOPBACK)
|
||||
static void SetUDSPath(struct sockaddr_un *saddr, const char *path)
|
||||
{
|
||||
size_t pathLen;
|
||||
|
||||
pathLen = strlen(path);
|
||||
if (pathLen < sizeof(saddr->sun_path))
|
||||
memcpy(saddr->sun_path, path, pathLen + 1);
|
||||
else
|
||||
saddr->sun_path[0] = '\0';
|
||||
}
|
||||
#endif
|
||||
|
||||
// Write len bytes. Return 0 on success, -1 on error
|
||||
static int write_all(dnssd_sock_t sd, char *buf, size_t len)
|
||||
{
|
||||
|
@ -181,10 +195,11 @@ static int write_all(dnssd_sock_t sd, char *buf, size_t len)
|
|||
ssize_t num_written = send(sd, buf, (long)len, 0);
|
||||
if (num_written < 0 || (size_t)num_written > len)
|
||||
{
|
||||
// Should never happen. If it does, it indicates some OS bug,
|
||||
// Check whether socket has gone defunct,
|
||||
// otherwise, an error here indicates some OS bug
|
||||
// or that the mDNSResponder daemon crashed (which should never happen).
|
||||
#if !defined(__ppc__) && defined(SO_ISDEFUNCT)
|
||||
int defunct;
|
||||
#if !defined(__ppc__) && defined(SO_ISDEFUNCT)
|
||||
int defunct = 0;
|
||||
socklen_t dlen = sizeof (defunct);
|
||||
if (getsockopt(sd, SOL_SOCKET, SO_ISDEFUNCT, &defunct, &dlen) < 0)
|
||||
syslog(LOG_WARNING, "dnssd_clientstub write_all: SO_ISDEFUNCT failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
|
||||
|
@ -195,12 +210,12 @@ static int write_all(dnssd_sock_t sd, char *buf, size_t len)
|
|||
(num_written < 0) ? dnssd_strerror(dnssd_errno) : "");
|
||||
else
|
||||
syslog(LOG_INFO, "dnssd_clientstub write_all(%d) DEFUNCT", sd);
|
||||
#else
|
||||
#else
|
||||
syslog(LOG_WARNING, "dnssd_clientstub write_all(%d) failed %ld/%ld %d %s", sd,
|
||||
(long)num_written, (long)len,
|
||||
(num_written < 0) ? dnssd_errno : 0,
|
||||
(num_written < 0) ? dnssd_strerror(dnssd_errno) : "");
|
||||
#endif
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
buf += num_written;
|
||||
|
@ -231,7 +246,9 @@ static int read_all(dnssd_sock_t sd, char *buf, int len)
|
|||
{
|
||||
int printWarn = 0;
|
||||
int defunct = 0;
|
||||
// Should never happen. If it does, it indicates some OS bug,
|
||||
|
||||
// Check whether socket has gone defunct,
|
||||
// otherwise, an error here indicates some OS bug
|
||||
// or that the mDNSResponder daemon crashed (which should never happen).
|
||||
#if defined(WIN32)
|
||||
// <rdar://problem/7481776> Suppress logs for "A non-blocking socket operation
|
||||
|
@ -271,6 +288,12 @@ static int more_bytes(dnssd_sock_t sd)
|
|||
fd_set *fs;
|
||||
int ret;
|
||||
|
||||
#if defined(_WIN32)
|
||||
fs = &readfds;
|
||||
FD_ZERO(fs);
|
||||
FD_SET(sd, fs);
|
||||
ret = select((int)sd+1, fs, (fd_set*)NULL, (fd_set*)NULL, &tv);
|
||||
#else
|
||||
if (sd < FD_SETSIZE)
|
||||
{
|
||||
fs = &readfds;
|
||||
|
@ -284,7 +307,7 @@ static int more_bytes(dnssd_sock_t sd)
|
|||
// two ints and not just one.
|
||||
int nfdbits = sizeof (int) * 8;
|
||||
int nints = (sd/nfdbits) + 1;
|
||||
fs = (fd_set *)calloc(nints, sizeof(int));
|
||||
fs = (fd_set *)calloc(nints, (size_t)sizeof(int));
|
||||
if (fs == NULL)
|
||||
{
|
||||
syslog(LOG_WARNING, "dnssd_clientstub more_bytes: malloc failed");
|
||||
|
@ -295,6 +318,7 @@ static int more_bytes(dnssd_sock_t sd)
|
|||
ret = select((int)sd+1, fs, (fd_set*)NULL, (fd_set*)NULL, &tv);
|
||||
if (fs != &readfds)
|
||||
free(fs);
|
||||
#endif
|
||||
return (ret > 0);
|
||||
}
|
||||
|
||||
|
@ -355,7 +379,7 @@ static ipc_msg_hdr *create_hdr(uint32_t op, size_t *len, char **data_start, int
|
|||
struct timeval tv;
|
||||
if (gettimeofday(&tv, NULL) < 0)
|
||||
{ syslog(LOG_WARNING, "dnssd_clientstub create_hdr: gettimeofday failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno)); return NULL; }
|
||||
sprintf(ctrl_path, "%s%d-%.3lx-%.6lu", CTL_PATH_PREFIX, (int)getpid(),
|
||||
snprintf(ctrl_path, sizeof(ctrl_path), "%s%d-%.3lx-%.6lu", CTL_PATH_PREFIX, (int)getpid(),
|
||||
(unsigned long)(tv.tv_sec & 0xFFF), (unsigned long)(tv.tv_usec));
|
||||
*len += strlen(ctrl_path) + 1;
|
||||
#else
|
||||
|
@ -405,7 +429,11 @@ static void FreeDNSServiceOp(DNSServiceOp *x)
|
|||
// We don't use our DNSServiceRefValid macro here because if we're cleaning up after a socket() call failed
|
||||
// then sockfd could legitimately contain a failing value (e.g. dnssd_InvalidSocket)
|
||||
if ((x->sockfd ^ x->validator) != ValidatorBits)
|
||||
{
|
||||
static DNSServiceOp *op_were_not_going_to_free_but_we_need_to_fool_the_analyzer;
|
||||
syslog(LOG_WARNING, "dnssd_clientstub attempt to dispose invalid DNSServiceRef %p %08X %08X", x, x->sockfd, x->validator);
|
||||
op_were_not_going_to_free_but_we_need_to_fool_the_analyzer = x;
|
||||
}
|
||||
else
|
||||
{
|
||||
x->next = NULL;
|
||||
|
@ -425,8 +453,8 @@ static void FreeDNSServiceOp(DNSServiceOp *x)
|
|||
x->disp_queue = NULL;
|
||||
#endif
|
||||
// DNSRecords may have been added to subordinate sdRef e.g., DNSServiceRegister/DNSServiceAddRecord
|
||||
// or on the main sdRef e.g., DNSServiceCreateConnection/DNSServiveRegisterRecord. DNSRecords may have
|
||||
// been freed if the application called DNSRemoveRecord
|
||||
// or on the main sdRef e.g., DNSServiceCreateConnection/DNSServiceRegisterRecord.
|
||||
// DNSRecords may have been freed if the application called DNSRemoveRecord.
|
||||
FreeDNSRecords(x);
|
||||
if (x->kacontext)
|
||||
{
|
||||
|
@ -530,6 +558,11 @@ static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags f
|
|||
char* uds_serverpath = getenv(MDNS_UDS_SERVERPATH_ENVVAR);
|
||||
if (uds_serverpath == NULL)
|
||||
uds_serverpath = MDNS_UDS_SERVERPATH;
|
||||
else if (strlen(uds_serverpath) >= MAX_CTLPATH)
|
||||
{
|
||||
uds_serverpath = MDNS_UDS_SERVERPATH;
|
||||
syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: using default path since env len is invalid");
|
||||
}
|
||||
#endif
|
||||
*ref = NULL;
|
||||
sdr->sockfd = socket(AF_DNSSD, SOCK_STREAM, 0);
|
||||
|
@ -551,7 +584,7 @@ static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags f
|
|||
saddr.sin_port = htons(MDNS_TCP_SERVERPORT);
|
||||
#else
|
||||
saddr.sun_family = AF_LOCAL;
|
||||
strcpy(saddr.sun_path, uds_serverpath);
|
||||
SetUDSPath(&saddr, uds_serverpath);
|
||||
#if !defined(__ppc__) && defined(SO_DEFUNCTOK)
|
||||
{
|
||||
int defunct = 1;
|
||||
|
@ -578,8 +611,10 @@ static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags f
|
|||
}
|
||||
else
|
||||
{
|
||||
#if !defined(USE_TCP_LOOPBACK)
|
||||
syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: connect() failed path:%s Socket:%d Err:%d Errno:%d %s",
|
||||
uds_serverpath, sdr->sockfd, err, dnssd_errno, dnssd_strerror(dnssd_errno));
|
||||
#endif
|
||||
dnssd_close(sdr->sockfd);
|
||||
FreeDNSServiceOp(sdr);
|
||||
return kDNSServiceErr_ServiceNotRunning;
|
||||
|
@ -597,21 +632,31 @@ static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags f
|
|||
|
||||
static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
|
||||
{
|
||||
uint32_t datalen = hdr->datalen; // We take a copy here because we're going to convert hdr->datalen to network byte order
|
||||
#if defined(USE_TCP_LOOPBACK) || defined(USE_NAMED_ERROR_RETURN_SOCKET)
|
||||
char *const data = (char *)hdr + sizeof(ipc_msg_hdr);
|
||||
#endif
|
||||
uint32_t datalen;
|
||||
dnssd_sock_t listenfd = dnssd_InvalidSocket, errsd = dnssd_InvalidSocket;
|
||||
DNSServiceErrorType err = kDNSServiceErr_Unknown; // Default for the "goto cleanup" cases
|
||||
int MakeSeparateReturnSocket = 0;
|
||||
int MakeSeparateReturnSocket;
|
||||
#if defined(USE_TCP_LOOPBACK) || defined(USE_NAMED_ERROR_RETURN_SOCKET)
|
||||
char *data;
|
||||
#endif
|
||||
|
||||
if (!hdr)
|
||||
{
|
||||
syslog(LOG_WARNING, "dnssd_clientstub deliver_request: !hdr");
|
||||
return kDNSServiceErr_Unknown;
|
||||
}
|
||||
|
||||
datalen = hdr->datalen; // We take a copy here because we're going to convert hdr->datalen to network byte order
|
||||
#if defined(USE_TCP_LOOPBACK) || defined(USE_NAMED_ERROR_RETURN_SOCKET)
|
||||
data = (char *)hdr + sizeof(ipc_msg_hdr);
|
||||
#endif
|
||||
|
||||
// Note: need to check hdr->op, not sdr->op.
|
||||
// hdr->op contains the code for the specific operation we're currently doing, whereas sdr->op
|
||||
// contains the original parent DNSServiceOp (e.g. for an add_record_request, hdr->op will be
|
||||
// add_record_request but the parent sdr->op will be connection_request or reg_service_request)
|
||||
if (sdr->primary ||
|
||||
hdr->op == reg_record_request || hdr->op == add_record_request || hdr->op == update_record_request || hdr->op == remove_record_request)
|
||||
MakeSeparateReturnSocket = 1;
|
||||
MakeSeparateReturnSocket = (sdr->primary ||
|
||||
hdr->op == reg_record_request || hdr->op == add_record_request || hdr->op == update_record_request || hdr->op == remove_record_request);
|
||||
|
||||
if (!DNSServiceRefValid(sdr))
|
||||
{
|
||||
|
@ -621,12 +666,6 @@ static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
|
|||
return kDNSServiceErr_BadReference;
|
||||
}
|
||||
|
||||
if (!hdr)
|
||||
{
|
||||
syslog(LOG_WARNING, "dnssd_clientstub deliver_request: !hdr");
|
||||
return kDNSServiceErr_Unknown;
|
||||
}
|
||||
|
||||
if (MakeSeparateReturnSocket)
|
||||
{
|
||||
#if defined(USE_TCP_LOOPBACK)
|
||||
|
@ -661,7 +700,7 @@ static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
|
|||
#ifndef NOT_HAVE_SA_LEN
|
||||
caddr.sun_len = sizeof(struct sockaddr_un);
|
||||
#endif
|
||||
strcpy(caddr.sun_path, data);
|
||||
SetUDSPath(&caddr, data);
|
||||
mask = umask(0);
|
||||
bindresult = bind(listenfd, (struct sockaddr *)&caddr, sizeof(caddr));
|
||||
umask(mask);
|
||||
|
@ -842,7 +881,7 @@ cleanup:
|
|||
return err;
|
||||
}
|
||||
|
||||
int DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef)
|
||||
dnssd_sock_t DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef)
|
||||
{
|
||||
if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRefSockFD called with NULL DNSServiceRef"); return dnssd_InvalidSocket; }
|
||||
|
||||
|
@ -859,7 +898,7 @@ int DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef)
|
|||
return dnssd_InvalidSocket;
|
||||
}
|
||||
|
||||
return (int) sdRef->sockfd;
|
||||
return sdRef->sockfd;
|
||||
}
|
||||
|
||||
#if _DNS_SD_LIBDISPATCH
|
||||
|
@ -1144,13 +1183,18 @@ void DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdRef)
|
|||
|
||||
DNSServiceErrorType DNSSD_API DNSServiceGetProperty(const char *property, void *result, uint32_t *size)
|
||||
{
|
||||
DNSServiceErrorType err;
|
||||
char *ptr;
|
||||
size_t len = strlen(property) + 1;
|
||||
size_t len;
|
||||
ipc_msg_hdr *hdr;
|
||||
DNSServiceOp *tmp;
|
||||
uint32_t actualsize;
|
||||
|
||||
DNSServiceErrorType err = ConnectToServer(&tmp, 0, getproperty_request, NULL, NULL, NULL);
|
||||
if (!property || !result || !size)
|
||||
return kDNSServiceErr_BadParam;
|
||||
|
||||
len = strlen(property) + 1;
|
||||
err = ConnectToServer(&tmp, 0, getproperty_request, NULL, NULL, NULL);
|
||||
if (err) return err;
|
||||
|
||||
hdr = create_hdr(getproperty_request, &len, &ptr, 0, tmp);
|
||||
|
@ -1158,6 +1202,8 @@ DNSServiceErrorType DNSSD_API DNSServiceGetProperty(const char *property, void *
|
|||
|
||||
put_string(property, &ptr);
|
||||
err = deliver_request(hdr, tmp); // Will free hdr for us
|
||||
if (err) { DNSServiceRefDeallocate(tmp); return err; }
|
||||
|
||||
if (read_all(tmp->sockfd, (char*)&actualsize, (int)sizeof(actualsize)) < 0)
|
||||
{ DNSServiceRefDeallocate(tmp); return kDNSServiceErr_ServiceNotRunning; }
|
||||
|
||||
|
@ -1178,28 +1224,21 @@ DNSServiceErrorType DNSSD_API DNSServiceGetPID(const uint16_t srcport, int32_t *
|
|||
{
|
||||
char *ptr;
|
||||
ipc_msg_hdr *hdr;
|
||||
DNSServiceOp *tmp;
|
||||
DNSServiceOp *tmp = NULL;
|
||||
size_t len = sizeof(int32_t);
|
||||
|
||||
DNSServiceErrorType err = ConnectToServer(&tmp, 0, getpid_request, NULL, NULL, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
if (err) return err;
|
||||
|
||||
hdr = create_hdr(getpid_request, &len, &ptr, 0, tmp);
|
||||
if (!hdr)
|
||||
{
|
||||
DNSServiceRefDeallocate(tmp);
|
||||
return kDNSServiceErr_NoMemory;
|
||||
}
|
||||
if (!hdr) { DNSServiceRefDeallocate(tmp); return kDNSServiceErr_NoMemory; }
|
||||
|
||||
put_uint16(srcport, &ptr);
|
||||
err = deliver_request(hdr, tmp); // Will free hdr for us
|
||||
if (err) { DNSServiceRefDeallocate(tmp); return err; }
|
||||
|
||||
if (read_all(tmp->sockfd, (char*)pid, sizeof(int32_t)) < 0)
|
||||
{
|
||||
DNSServiceRefDeallocate(tmp);
|
||||
return kDNSServiceErr_ServiceNotRunning;
|
||||
}
|
||||
{ DNSServiceRefDeallocate(tmp); return kDNSServiceErr_ServiceNotRunning; }
|
||||
|
||||
DNSServiceRefDeallocate(tmp);
|
||||
return kDNSServiceErr_NoError;
|
||||
|
@ -1275,14 +1314,15 @@ DNSServiceErrorType DNSSD_API DNSServiceResolve
|
|||
ipc_msg_hdr *hdr;
|
||||
DNSServiceErrorType err;
|
||||
|
||||
if (!name || !regtype || !domain || !callBack) return kDNSServiceErr_BadParam;
|
||||
if (!sdRef || !name || !regtype || !domain || !callBack) return kDNSServiceErr_BadParam;
|
||||
|
||||
// Need a real InterfaceID for WakeOnResolve
|
||||
if ((flags & kDNSServiceFlagsWakeOnResolve) != 0 &&
|
||||
((interfaceIndex == kDNSServiceInterfaceIndexAny) ||
|
||||
(interfaceIndex == kDNSServiceInterfaceIndexLocalOnly) ||
|
||||
(interfaceIndex == kDNSServiceInterfaceIndexUnicast) ||
|
||||
(interfaceIndex == kDNSServiceInterfaceIndexP2P)))
|
||||
(interfaceIndex == kDNSServiceInterfaceIndexP2P) ||
|
||||
(interfaceIndex == kDNSServiceInterfaceIndexBLE)))
|
||||
{
|
||||
return kDNSServiceErr_BadParam;
|
||||
}
|
||||
|
@ -1350,6 +1390,9 @@ DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
|
|||
ipc_msg_hdr *hdr;
|
||||
DNSServiceErrorType err;
|
||||
|
||||
// NULL name handled below.
|
||||
if (!sdRef || !callBack) return kDNSServiceErr_BadParam;
|
||||
|
||||
if ((interfaceIndex == kDNSServiceInterfaceIndexAny) && includeP2PWithIndexAny())
|
||||
flags |= kDNSServiceFlagsIncludeP2P;
|
||||
|
||||
|
@ -1391,6 +1434,7 @@ static void handle_addrinfo_response(DNSServiceOp *const sdr, const CallbackHead
|
|||
rdlen = get_uint16(&data, end);
|
||||
rdata = get_rdata (&data, end, rdlen);
|
||||
ttl = get_uint32(&data, end);
|
||||
(void)rrclass; // Unused
|
||||
|
||||
// We only generate client callbacks for A and AAAA results (including NXDOMAIN results for
|
||||
// those types, if the client has requested those with the kDNSServiceFlagsReturnIntermediates).
|
||||
|
@ -1458,7 +1502,7 @@ DNSServiceErrorType DNSSD_API DNSServiceGetAddrInfo
|
|||
ipc_msg_hdr *hdr;
|
||||
DNSServiceErrorType err;
|
||||
|
||||
if (!hostname) return kDNSServiceErr_BadParam;
|
||||
if (!sdRef || !hostname || !callBack) return kDNSServiceErr_BadParam;
|
||||
|
||||
err = ConnectToServer(sdRef, flags, addrinfo_request, handle_addrinfo_response, callBack, context);
|
||||
if (err)
|
||||
|
@ -1512,6 +1556,9 @@ DNSServiceErrorType DNSSD_API DNSServiceBrowse
|
|||
ipc_msg_hdr *hdr;
|
||||
DNSServiceErrorType err;
|
||||
|
||||
// NULL domain handled below
|
||||
if (!sdRef || !regtype || !callBack) return kDNSServiceErr_BadParam;
|
||||
|
||||
if ((interfaceIndex == kDNSServiceInterfaceIndexAny) && includeP2PWithIndexAny())
|
||||
flags |= kDNSServiceFlagsIncludeP2P;
|
||||
|
||||
|
@ -1540,11 +1587,16 @@ DNSServiceErrorType DNSSD_API DNSServiceBrowse
|
|||
DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser(DNSServiceFlags flags, const char *domain);
|
||||
DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser(DNSServiceFlags flags, const char *domain)
|
||||
{
|
||||
DNSServiceErrorType err;
|
||||
DNSServiceOp *tmp;
|
||||
char *ptr;
|
||||
size_t len = sizeof(flags) + strlen(domain) + 1;
|
||||
size_t len;
|
||||
ipc_msg_hdr *hdr;
|
||||
DNSServiceErrorType err = ConnectToServer(&tmp, 0, setdomain_request, NULL, NULL, NULL);
|
||||
|
||||
if (!domain) return kDNSServiceErr_BadParam;
|
||||
len = sizeof(flags) + strlen(domain) + 1;
|
||||
|
||||
err = ConnectToServer(&tmp, 0, setdomain_request, NULL, NULL, NULL);
|
||||
if (err) return err;
|
||||
|
||||
hdr = create_hdr(setdomain_request, &len, &ptr, 0, tmp);
|
||||
|
@ -1590,8 +1642,8 @@ DNSServiceErrorType DNSSD_API DNSServiceRegister
|
|||
DNSServiceErrorType err;
|
||||
union { uint16_t s; u_char b[2]; } port = { PortInNetworkByteOrder };
|
||||
|
||||
if (!sdRef || !regtype) return kDNSServiceErr_BadParam;
|
||||
if (!name) name = "";
|
||||
if (!regtype) return kDNSServiceErr_BadParam;
|
||||
if (!domain) domain = "";
|
||||
if (!host) host = "";
|
||||
if (!txtRecord) txtRecord = (void*)"";
|
||||
|
@ -1613,13 +1665,7 @@ DNSServiceErrorType DNSSD_API DNSServiceRegister
|
|||
|
||||
hdr = create_hdr(reg_service_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
|
||||
if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
|
||||
|
||||
// If it is going over a shared connection, then don't set the IPC_FLAGS_NOREPLY
|
||||
// as it affects all the operations over the shared connection. This is not
|
||||
// a normal case and hence receiving the response back from the daemon and
|
||||
// discarding it in ConnectionResponse is okay.
|
||||
|
||||
if (!(flags & kDNSServiceFlagsShareConnection) && !callBack) hdr->ipc_flags |= IPC_FLAGS_NOREPLY;
|
||||
if (!callBack) hdr->ipc_flags |= IPC_FLAGS_NOREPLY;
|
||||
|
||||
put_flags(flags, &ptr);
|
||||
put_uint32(interfaceIndex, &ptr);
|
||||
|
@ -1659,9 +1705,13 @@ DNSServiceErrorType DNSSD_API DNSServiceEnumerateDomains
|
|||
size_t len;
|
||||
ipc_msg_hdr *hdr;
|
||||
DNSServiceErrorType err;
|
||||
int f1;
|
||||
int f2;
|
||||
|
||||
int f1 = (flags & kDNSServiceFlagsBrowseDomains) != 0;
|
||||
int f2 = (flags & kDNSServiceFlagsRegistrationDomains) != 0;
|
||||
if (!sdRef || !callBack) return kDNSServiceErr_BadParam;
|
||||
|
||||
f1 = (flags & kDNSServiceFlagsBrowseDomains) != 0;
|
||||
f2 = (flags & kDNSServiceFlagsRegistrationDomains) != 0;
|
||||
if (f1 + f2 != 1) return kDNSServiceErr_BadParam;
|
||||
|
||||
err = ConnectToServer(sdRef, flags, enumeration_request, handle_enumeration_response, callBack, context);
|
||||
|
@ -1736,10 +1786,13 @@ static void ConnectionResponse(DNSServiceOp *const sdr, const CallbackHeader *co
|
|||
|
||||
DNSServiceErrorType DNSSD_API DNSServiceCreateConnection(DNSServiceRef *sdRef)
|
||||
{
|
||||
DNSServiceErrorType err;
|
||||
char *ptr;
|
||||
size_t len = 0;
|
||||
ipc_msg_hdr *hdr;
|
||||
DNSServiceErrorType err = ConnectToServer(sdRef, 0, connection_request, ConnectionResponse, NULL, NULL);
|
||||
|
||||
if (!sdRef) return kDNSServiceErr_BadParam;
|
||||
err = ConnectToServer(sdRef, 0, connection_request, ConnectionResponse, NULL, NULL);
|
||||
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
|
||||
|
||||
hdr = create_hdr(connection_request, &len, &ptr, 0, *sdRef);
|
||||
|
@ -1757,6 +1810,7 @@ DNSServiceErrorType DNSSD_API DNSServiceCreateDelegateConnection(DNSServiceRef *
|
|||
size_t len = 0;
|
||||
ipc_msg_hdr *hdr;
|
||||
|
||||
if (!sdRef) return kDNSServiceErr_BadParam;
|
||||
DNSServiceErrorType err = ConnectToServer(sdRef, 0, connection_delegate_request, ConnectionResponse, NULL, NULL);
|
||||
if (err)
|
||||
{
|
||||
|
@ -1846,7 +1900,11 @@ DNSServiceErrorType DNSSD_API DNSServiceRegisterRecord
|
|||
if ((interfaceIndex == kDNSServiceInterfaceIndexAny) && includeP2PWithIndexAny())
|
||||
flags |= kDNSServiceFlagsIncludeP2P;
|
||||
|
||||
if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRegisterRecord called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
|
||||
if (!sdRef || !RecordRef || !fullname || (!rdata && rdlen) || !callBack)
|
||||
{
|
||||
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRegisterRecord called with NULL parameter");
|
||||
return kDNSServiceErr_BadParam;
|
||||
}
|
||||
|
||||
if (!DNSServiceRefValid(sdRef))
|
||||
{
|
||||
|
@ -1927,8 +1985,11 @@ DNSServiceErrorType DNSSD_API DNSServiceAddRecord
|
|||
DNSRecordRef rref;
|
||||
DNSRecord **p;
|
||||
|
||||
if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
|
||||
if (!RecordRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with NULL DNSRecordRef pointer"); return kDNSServiceErr_BadParam; }
|
||||
if (!sdRef || !RecordRef || (!rdata && rdlen))
|
||||
{
|
||||
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with NULL parameter");
|
||||
return kDNSServiceErr_BadParam;
|
||||
}
|
||||
if (sdRef->op != reg_service_request)
|
||||
{
|
||||
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with non-DNSServiceRegister DNSServiceRef %p %d", sdRef, sdRef->op);
|
||||
|
@ -1988,7 +2049,11 @@ DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
|
|||
size_t len = 0;
|
||||
char *ptr;
|
||||
|
||||
if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceUpdateRecord called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
|
||||
if (!sdRef || (!rdata && rdlen))
|
||||
{
|
||||
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceUpdateRecord called with NULL parameter");
|
||||
return kDNSServiceErr_BadParam;
|
||||
}
|
||||
|
||||
if (!DNSServiceRefValid(sdRef))
|
||||
{
|
||||
|
@ -2064,12 +2129,15 @@ DNSServiceErrorType DNSSD_API DNSServiceReconfirmRecord
|
|||
const void *rdata
|
||||
)
|
||||
{
|
||||
DNSServiceErrorType err;
|
||||
char *ptr;
|
||||
size_t len;
|
||||
ipc_msg_hdr *hdr;
|
||||
DNSServiceOp *tmp;
|
||||
DNSServiceOp *tmp = NULL;
|
||||
|
||||
DNSServiceErrorType err = ConnectToServer(&tmp, flags, reconfirm_record_request, NULL, NULL, NULL);
|
||||
if (!fullname || (!rdata && rdlen)) return kDNSServiceErr_BadParam;
|
||||
|
||||
err = ConnectToServer(&tmp, flags, reconfirm_record_request, NULL, NULL, NULL);
|
||||
if (err) return err;
|
||||
|
||||
len = sizeof(DNSServiceFlags);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2003-2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
@ -10,7 +10,7 @@
|
|||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* 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 Inc. ("Apple") nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2003-2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
@ -10,7 +10,7 @@
|
|||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* 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 Inc. ("Apple") nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
|
@ -41,7 +41,6 @@
|
|||
# define dnssd_EWOULDBLOCK WSAEWOULDBLOCK
|
||||
# define dnssd_EINTR WSAEINTR
|
||||
# define dnssd_ECONNRESET WSAECONNRESET
|
||||
# define dnssd_sock_t SOCKET
|
||||
# define dnssd_socklen_t int
|
||||
# define dnssd_close(sock) closesocket(sock)
|
||||
# define dnssd_errno WSAGetLastError()
|
||||
|
@ -67,7 +66,6 @@ extern char *win32_strerror(int inErrorCode);
|
|||
# define dnssd_EINTR EINTR
|
||||
# define dnssd_ECONNRESET ECONNRESET
|
||||
# define dnssd_EPIPE EPIPE
|
||||
# define dnssd_sock_t int
|
||||
# define dnssd_socklen_t unsigned int
|
||||
# define dnssd_close(sock) close(sock)
|
||||
# define dnssd_errno errno
|
||||
|
@ -88,7 +86,7 @@ extern char *win32_strerror(int inErrorCode);
|
|||
# define MDNS_UDS_SERVERPATH_ENVVAR "DNSSD_UDS_PATH"
|
||||
# define LISTENQ 100
|
||||
// longest legal control path length
|
||||
# define MAX_CTLPATH 256
|
||||
# define MAX_CTLPATH (sizeof(((struct sockaddr_un*)0)->sun_path))
|
||||
# define dnssd_sockaddr_t struct sockaddr_un
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2003-2015 Apple 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.
|
||||
|
@ -13,13 +13,6 @@
|
|||
* 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.
|
||||
|
||||
File: mDNSDebug.c
|
||||
|
||||
Contains: Implementation of debugging utilities. Requires a POSIX environment.
|
||||
|
||||
Version: 1.0
|
||||
|
||||
*/
|
||||
|
||||
#include "mDNSDebug.h"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.\" -*- tab-width: 4 -*-
|
||||
.\"
|
||||
.\" Copyright (c) 2003-2004 Apple Computer, Inc. All Rights Reserved.
|
||||
.\" Copyright (c) 2003-2012 Apple 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.
|
||||
|
@ -80,9 +80,28 @@ A SIGINFO signal will dump a snapshot summary of the internal state to
|
|||
.Pa /var/log/system.log Ns :
|
||||
.Pp
|
||||
.Dl % sudo killall -INFO mDNSResponder
|
||||
.Sh OPTIONAL ARGUMENTS
|
||||
.Nm
|
||||
accepts the following optional arguments:
|
||||
.Bl -tag -width "AlwaysAppendSearchDomains"
|
||||
.It Fl AlwaysAppendSearchDomains
|
||||
Append search domains for multi-labeled Partially Qualified Domain Name as well as single-labeled Partially Qualified Domain Name.
|
||||
This argument is not recommended because of the extra DNS traffic it generates and its adverse effect on battery life.
|
||||
.It Fl NoMulticastAdvertisements
|
||||
Prevent the system from advertising Bonjour services via Multicast DNS.
|
||||
.El
|
||||
.Pp
|
||||
To cause
|
||||
.Nm
|
||||
to run with these optional arguments when it launches on OS X 10.11 (El Capitan) and later, set the
|
||||
.Sy AlwaysAppendSearchDomains
|
||||
or
|
||||
.Sy NoMulticastAdvertisements
|
||||
boolean keys to true in /Library/Preferences/com.apple.mDNSResponder.plist and reboot.
|
||||
.Pp
|
||||
.Sh FILES
|
||||
.Pa /usr/sbin/mDNSResponder \" Pathname
|
||||
.\"
|
||||
.Pa /usr/sbin/mDNSResponder
|
||||
.Pa /Library/Preferences/com.apple.mDNSResponder.plist
|
||||
.Pp
|
||||
.Sh INFO
|
||||
.Pp
|
||||
|
@ -112,5 +131,5 @@ daemon first appeared in Mac OS X 10.2 (Jaguar).
|
|||
Also available from the Darwin open source repository
|
||||
(though not officially supported by Apple) are
|
||||
.Nm
|
||||
daemons for other platforms, including Mac OS 9, Microsoft Windows,
|
||||
daemons for other platforms, including Microsoft Windows,
|
||||
Linux, FreeBSD, NetBSD, Solaris, and other POSIX systems.
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2002-2013 Apple 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.
|
||||
|
@ -13,28 +13,214 @@
|
|||
* 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.
|
||||
|
||||
File: uds_daemon.h
|
||||
|
||||
Contains: Interfaces necessary to talk to uds_daemon.c.
|
||||
|
||||
Version: 1.0
|
||||
|
||||
*/
|
||||
|
||||
#ifndef UDS_DAEMON_H
|
||||
#define UDS_DAEMON_H
|
||||
|
||||
#include "mDNSEmbeddedAPI.h"
|
||||
#include "dnssd_ipc.h"
|
||||
|
||||
/* Client request: */
|
||||
|
||||
// ***************************************************************************
|
||||
#if COMPILER_LIKES_PRAGMA_MARK
|
||||
#pragma mark -
|
||||
#pragma mark - Types and Data Structures
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
t_uninitialized,
|
||||
t_morecoming,
|
||||
t_complete,
|
||||
t_error,
|
||||
t_terminated
|
||||
} transfer_state;
|
||||
|
||||
typedef struct request_state request_state;
|
||||
|
||||
typedef void (*req_termination_fn)(request_state *request);
|
||||
|
||||
typedef struct registered_record_entry
|
||||
{
|
||||
struct registered_record_entry *next;
|
||||
mDNSu32 key;
|
||||
client_context_t regrec_client_context;
|
||||
request_state *request;
|
||||
mDNSBool external_advertise;
|
||||
mDNSInterfaceID origInterfaceID;
|
||||
AuthRecord *rr; // Pointer to variable-sized AuthRecord (Why a pointer? Why not just embed it here?)
|
||||
} registered_record_entry;
|
||||
|
||||
// A single registered service: ServiceRecordSet + bookkeeping
|
||||
// Note that we duplicate some fields from parent service_info object
|
||||
// to facilitate cleanup, when instances and parent may be deallocated at different times.
|
||||
typedef struct service_instance
|
||||
{
|
||||
struct service_instance *next;
|
||||
request_state *request;
|
||||
AuthRecord *subtypes;
|
||||
mDNSBool renameonmemfree; // Set on config change when we deregister original name
|
||||
mDNSBool clientnotified; // Has client been notified of successful registration yet?
|
||||
mDNSBool default_local; // is this the "local." from an empty-string registration?
|
||||
mDNSBool external_advertise; // is this is being advertised externally?
|
||||
domainname domain;
|
||||
ServiceRecordSet srs; // note -- variable-sized object -- must be last field in struct
|
||||
} service_instance;
|
||||
|
||||
// for multi-domain default browsing
|
||||
typedef struct browser_t
|
||||
{
|
||||
struct browser_t *next;
|
||||
domainname domain;
|
||||
DNSQuestion q;
|
||||
} browser_t;
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef unsigned int pid_t;
|
||||
typedef unsigned int socklen_t;
|
||||
#endif
|
||||
|
||||
#if (!defined(MAXCOMLEN))
|
||||
#define MAXCOMLEN 16
|
||||
#endif
|
||||
|
||||
struct request_state
|
||||
{
|
||||
request_state *next;
|
||||
request_state *primary; // If this operation is on a shared socket, pointer to primary
|
||||
// request_state for the original DNSServiceCreateConnection() operation
|
||||
dnssd_sock_t sd;
|
||||
pid_t process_id; // Client's PID value
|
||||
char pid_name[MAXCOMLEN]; // Client's process name
|
||||
mDNSu8 uuid[UUID_SIZE];
|
||||
mDNSBool validUUID;
|
||||
dnssd_sock_t errsd;
|
||||
mDNSu32 uid;
|
||||
void * platform_data;
|
||||
|
||||
// Note: On a shared connection these fields in the primary structure, including hdr, are re-used
|
||||
// for each new request. This is because, until we've read the ipc_msg_hdr to find out what the
|
||||
// operation is, we don't know if we're going to need to allocate a new request_state or not.
|
||||
transfer_state ts;
|
||||
mDNSu32 hdr_bytes; // bytes of header already read
|
||||
ipc_msg_hdr hdr;
|
||||
mDNSu32 data_bytes; // bytes of message data already read
|
||||
char *msgbuf; // pointer to data storage to pass to free()
|
||||
const char *msgptr; // pointer to data to be read from (may be modified)
|
||||
char *msgend; // pointer to byte after last byte of message
|
||||
|
||||
// reply, termination, error, and client context info
|
||||
int no_reply; // don't send asynchronous replies to client
|
||||
mDNSs32 time_blocked; // record time of a blocked client
|
||||
int unresponsiveness_reports;
|
||||
struct reply_state *replies; // corresponding (active) reply list
|
||||
req_termination_fn terminate;
|
||||
DNSServiceFlags flags;
|
||||
mDNSu32 interfaceIndex;
|
||||
|
||||
union
|
||||
{
|
||||
registered_record_entry *reg_recs; // list of registrations for a connection-oriented request
|
||||
struct
|
||||
{
|
||||
mDNSInterfaceID interface_id;
|
||||
mDNSBool default_domain;
|
||||
mDNSBool ForceMCast;
|
||||
domainname regtype;
|
||||
browser_t *browsers;
|
||||
const mDNSu8 *AnonData;
|
||||
} browser;
|
||||
struct
|
||||
{
|
||||
mDNSInterfaceID InterfaceID;
|
||||
mDNSu16 txtlen;
|
||||
void *txtdata;
|
||||
mDNSIPPort port;
|
||||
domainlabel name;
|
||||
char type_as_string[MAX_ESCAPED_DOMAIN_NAME];
|
||||
domainname type;
|
||||
mDNSBool default_domain;
|
||||
domainname host;
|
||||
mDNSBool autoname; // Set if this name is tied to the Computer Name
|
||||
mDNSBool autorename; // Set if this client wants us to automatically rename on conflict
|
||||
mDNSBool allowremotequery; // Respond to unicast queries from outside the local link?
|
||||
int num_subtypes;
|
||||
mDNSBool AnonData;
|
||||
service_instance *instances;
|
||||
} servicereg;
|
||||
struct
|
||||
{
|
||||
mDNSInterfaceID interface_id;
|
||||
mDNSu32 flags;
|
||||
mDNSu32 protocol;
|
||||
DNSQuestion q4;
|
||||
DNSQuestion *q42;
|
||||
DNSQuestion q6;
|
||||
DNSQuestion *q62;
|
||||
mDNSu8 v4ans;
|
||||
mDNSu8 v6ans;
|
||||
} addrinfo;
|
||||
struct
|
||||
{
|
||||
mDNSIPPort ReqExt; // External port we originally requested, for logging purposes
|
||||
NATTraversalInfo NATinfo;
|
||||
} pm;
|
||||
struct
|
||||
{
|
||||
DNSServiceFlags flags;
|
||||
DNSQuestion q_all;
|
||||
DNSQuestion q_default;
|
||||
DNSQuestion q_autoall;
|
||||
} enumeration;
|
||||
struct
|
||||
{
|
||||
DNSQuestion q;
|
||||
DNSQuestion *q2;
|
||||
mDNSu8 ans;
|
||||
} queryrecord;
|
||||
struct
|
||||
{
|
||||
DNSQuestion qtxt;
|
||||
DNSQuestion qsrv;
|
||||
const ResourceRecord *txt;
|
||||
const ResourceRecord *srv;
|
||||
mDNSs32 ReportTime;
|
||||
mDNSBool external_advertise;
|
||||
} resolve;
|
||||
} u;
|
||||
};
|
||||
|
||||
// struct physically sits between ipc message header and call-specific fields in the message buffer
|
||||
typedef struct
|
||||
{
|
||||
DNSServiceFlags flags; // Note: This field is in NETWORK byte order
|
||||
mDNSu32 ifi; // Note: This field is in NETWORK byte order
|
||||
DNSServiceErrorType error; // Note: This field is in NETWORK byte order
|
||||
} reply_hdr;
|
||||
|
||||
typedef struct reply_state
|
||||
{
|
||||
struct reply_state *next; // If there are multiple unsent replies
|
||||
mDNSu32 totallen;
|
||||
mDNSu32 nwriten;
|
||||
ipc_msg_hdr mhdr[1];
|
||||
reply_hdr rhdr[1];
|
||||
} reply_state;
|
||||
|
||||
/* Client interface: */
|
||||
|
||||
#define SRS_PORT(S) mDNSVal16((S)->RR_SRV.resrec.rdata->u.srv.port)
|
||||
|
||||
#define LogTimer(MSG,T) LogMsgNoIdent( MSG " %08X %11d %08X %11d", (T), (T), (T)-now, (T)-now)
|
||||
|
||||
extern int udsserver_init(dnssd_sock_t skts[], mDNSu32 count);
|
||||
extern mDNSs32 udsserver_idle(mDNSs32 nextevent);
|
||||
extern void udsserver_info(mDNS *const m); // print out info about current state
|
||||
extern void udsserver_info(void); // 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 LogMcastStateInfo(mDNS *const m, mDNSBool mflag, mDNSBool start, mDNSBool mstatelog);
|
||||
extern void LogMcastStateInfo(mDNSBool mflag, mDNSBool start, mDNSBool mstatelog);
|
||||
#define LogMcastQ (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMcastQuestion
|
||||
#define LogMcastS (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMcastService
|
||||
#define LogMcast (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMsg
|
||||
|
@ -47,7 +233,7 @@ extern mStatus udsSupportAddFDToEventLoop(dnssd_sock_t fd, udsEventCallback call
|
|||
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 void RecordUpdatedNiceLabel(mDNS *const m, mDNSs32 delay);
|
||||
extern void RecordUpdatedNiceLabel(mDNSs32 delay);
|
||||
|
||||
// Globals and functions defined in uds_daemon.c and also shared with the old "daemon.c" on OS X
|
||||
|
||||
|
@ -58,13 +244,12 @@ 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 mDNSBool callExternalHelpers(mDNSInterfaceID InterfaceID, const domainname *const domain, DNSServiceFlags flags);
|
||||
extern void FreeExtraRR(mDNS *const m, AuthRecord *const rr, mStatus result);
|
||||
extern int CountPeerRegistrations(mDNS *const m, ServiceRecordSet *const srs);
|
||||
extern int CountPeerRegistrations(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);
|
||||
|
@ -79,7 +264,7 @@ extern void external_connection_release(const domainname *instance);
|
|||
#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_stop_advertising_service(A,B) do { (void)(A); (void)(B); } while (0)
|
||||
#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)
|
||||
|
@ -88,3 +273,10 @@ extern void external_connection_release(const domainname *instance);
|
|||
|
||||
extern const char mDNSResponderVersionString_SCCS[];
|
||||
#define mDNSResponderVersionString (mDNSResponderVersionString_SCCS+5)
|
||||
|
||||
#if DEBUG
|
||||
extern void SetDebugBoundPath(void);
|
||||
extern int IsDebugSocketInUse(void);
|
||||
#endif
|
||||
|
||||
#endif /* UDS_DAEMON_H */
|
||||
|
|
|
@ -0,0 +1,400 @@
|
|||
#include "CNameRecordTests.h"
|
||||
#include "unittest_common.h"
|
||||
|
||||
mDNSlocal int InitThisUnitTest(void);
|
||||
mDNSlocal int StartClientQueryRequest(void);
|
||||
mDNSlocal int PopulateCacheWithClientResponseRecords(void);
|
||||
mDNSlocal int SimulateNetworkChangeAndVerifyTest(void);
|
||||
mDNSlocal int FinalizeUnitTest(void);
|
||||
mDNSlocal mStatus AddDNSServer(void);
|
||||
|
||||
// This unit test's variables
|
||||
static UDPSocket* local_socket;
|
||||
static request_state* client_request_message;
|
||||
|
||||
struct UDPSocket_struct
|
||||
{
|
||||
mDNSIPPort port; // MUST BE FIRST FIELD -- mDNSCoreReceive expects every UDPSocket_struct to begin with mDNSIPPort port
|
||||
};
|
||||
typedef struct UDPSocket_struct UDPSocket;
|
||||
|
||||
// This client request was generated using the following command: "dns-sd -Q 123server.dotbennu.com. A".
|
||||
uint8_t query_client_msgbuf[35] = {
|
||||
0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x32, 0x33, 0x73, 0x65, 0x72, 0x76, 0x65,
|
||||
0x72, 0x2e, 0x64, 0x6f, 0x74, 0x62, 0x65, 0x6e, 0x6e, 0x75, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00,
|
||||
0x01, 0x00, 0x01
|
||||
};
|
||||
|
||||
// This uDNS message is a canned response that was originally captured by wireshark.
|
||||
uint8_t query_response_msgbuf[108] = {
|
||||
0x69, 0x41, // transaction id
|
||||
0x85, 0x80, // flags
|
||||
0x00, 0x01, // 1 question for 123server.dotbennu.com. Addr
|
||||
0x00, 0x02, // 2 anwsers: 123server.dotbennu.com. CNAME test212.dotbennu.com., test212.dotbennu.com. Addr 10.100.0.1,
|
||||
0x00, 0x01, // 1 authorities anwser: dotbennu.com. NS cardinal2.apple.com.
|
||||
0x00, 0x00, 0x09, 0x31, 0x32, 0x33,
|
||||
0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x08, 0x64, 0x6f, 0x74, 0x62, 0x65, 0x6e, 0x6e, 0x75, 0x03,
|
||||
0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00,
|
||||
0x02, 0x56, 0x00, 0x0a, 0x07, 0x74, 0x65, 0x73, 0x74, 0x32, 0x31, 0x32, 0xc0, 0x16, 0xc0, 0x34,
|
||||
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x04, 0x0a, 0x64, 0x00, 0x01, 0xc0, 0x16,
|
||||
0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x51, 0x80, 0x00, 0x12, 0x09, 0x63, 0x61, 0x72, 0x64, 0x69,
|
||||
0x6e, 0x61, 0x6c, 0x32, 0x05, 0x61, 0x70, 0x70, 0x6c, 0x65, 0xc0, 0x1f
|
||||
};
|
||||
|
||||
// Variables associated with contents of the above uDNS message
|
||||
#define uDNS_TargetQID 16745
|
||||
char udns_original_domainname_cstr[] = "123server.dotbennu.com.";
|
||||
char udns_cname_domainname_cstr[] = "test212.dotbennu.com.";
|
||||
static const mDNSv4Addr dns_response_ipv4 = {{ 10, 100, 0, 1 }};
|
||||
|
||||
UNITTEST_HEADER(CNameRecordTests)
|
||||
UNITTEST_TEST(InitThisUnitTest)
|
||||
UNITTEST_TEST(StartClientQueryRequest)
|
||||
UNITTEST_TEST(PopulateCacheWithClientResponseRecords)
|
||||
UNITTEST_TEST(SimulateNetworkChangeAndVerifyTest)
|
||||
UNITTEST_TEST(FinalizeUnitTest)
|
||||
UNITTEST_FOOTER
|
||||
|
||||
// The InitThisUnitTest() initializes the mDNSResponder environment as well as
|
||||
// a DNSServer. It also allocates memory for a local_socket and client request.
|
||||
// Note: This unit test does not send packets on the wire and it does not open sockets.
|
||||
UNITTEST_HEADER(InitThisUnitTest)
|
||||
// Init unit test environment and verify no error occurred.
|
||||
mStatus result = init_mdns_environment(mDNStrue);
|
||||
UNITTEST_ASSERT(result == mStatus_NoError);
|
||||
|
||||
// Add one DNS server and verify it was added.
|
||||
AddDNSServer();
|
||||
UNITTEST_ASSERT(NumUnicastDNSServers == 1);
|
||||
|
||||
// Create memory for a socket that is never used or opened.
|
||||
local_socket = mDNSPlatformMemAllocate(sizeof(UDPSocket));
|
||||
mDNSPlatformMemZero(local_socket, sizeof(UDPSocket));
|
||||
|
||||
// Create memory for a request that is used to make this unit test's client request.
|
||||
client_request_message = calloc(1, sizeof(request_state));
|
||||
UNITTEST_FOOTER
|
||||
|
||||
// This test simulates a uds client request by setting up a client request and then
|
||||
// calling mDNSResponder's handle_client_request. The handle_client_request function
|
||||
// processes the request and starts a query. This unit test verifies
|
||||
// the client request and query were setup as expected. This unit test also calls
|
||||
// mDNS_execute which determines the cache does not contain the new question's
|
||||
// answer.
|
||||
UNITTEST_HEADER(StartClientQueryRequest)
|
||||
mDNS *const m = &mDNSStorage;
|
||||
request_state* req = client_request_message;
|
||||
char *msgptr = (char *)query_client_msgbuf;
|
||||
size_t msgsz = sizeof(query_client_msgbuf);
|
||||
mDNSs32 min_size = sizeof(DNSServiceFlags) + sizeof(mDNSu32) + 4;
|
||||
DNSQuestion *q;
|
||||
mStatus err = mStatus_NoError;
|
||||
char qname_cstr[MAX_ESCAPED_DOMAIN_NAME];
|
||||
|
||||
// Process the unit test's client request
|
||||
start_client_request(req, msgptr, msgsz, query_request, local_socket);
|
||||
UNITTEST_ASSERT(err == mStatus_NoError);
|
||||
|
||||
// Verify the request fields were set as expected
|
||||
UNITTEST_ASSERT(req->next == mDNSNULL);
|
||||
UNITTEST_ASSERT(req->primary == mDNSNULL);
|
||||
UNITTEST_ASSERT(req->sd == client_req_sd);
|
||||
UNITTEST_ASSERT(req->process_id == client_req_process_id);
|
||||
UNITTEST_ASSERT(!strcmp(req->pid_name, client_req_pid_name));
|
||||
UNITTEST_ASSERT(req->validUUID == mDNSfalse);
|
||||
UNITTEST_ASSERT(req->errsd == 0);
|
||||
UNITTEST_ASSERT(req->uid == client_req_uid);
|
||||
UNITTEST_ASSERT(req->ts == t_complete);
|
||||
UNITTEST_ASSERT((mDNSs32)req->data_bytes > min_size);
|
||||
UNITTEST_ASSERT(req->msgend == msgptr+msgsz);
|
||||
UNITTEST_ASSERT(req->msgbuf == mDNSNULL);
|
||||
UNITTEST_ASSERT(req->hdr.version == VERSION);
|
||||
UNITTEST_ASSERT(req->replies == mDNSNULL);
|
||||
UNITTEST_ASSERT(req->terminate != mDNSNULL);
|
||||
UNITTEST_ASSERT(req->flags == kDNSServiceFlagsReturnIntermediates);
|
||||
UNITTEST_ASSERT(req->interfaceIndex == kDNSServiceInterfaceIndexAny);
|
||||
|
||||
// Verify the query fields were set as expected
|
||||
q = &req->u.queryrecord.q;
|
||||
UNITTEST_ASSERT(q != mDNSNULL);
|
||||
UNITTEST_ASSERT(q == m->Questions);
|
||||
UNITTEST_ASSERT(q == m->NewQuestions);
|
||||
UNITTEST_ASSERT(q->SuppressUnusable == mDNSfalse);
|
||||
UNITTEST_ASSERT(q->ReturnIntermed == mDNStrue);
|
||||
UNITTEST_ASSERT(q->SuppressQuery == mDNSfalse);
|
||||
|
||||
UNITTEST_ASSERT(q->qnameOrig == mDNSNULL);
|
||||
ConvertDomainNameToCString(&q->qname, qname_cstr);
|
||||
UNITTEST_ASSERT(!strcmp(qname_cstr, udns_original_domainname_cstr));
|
||||
UNITTEST_ASSERT(q->qnamehash == DomainNameHashValue(&q->qname));
|
||||
|
||||
UNITTEST_ASSERT(q->InterfaceID == mDNSInterface_Any);
|
||||
UNITTEST_ASSERT(q->flags == req->flags);
|
||||
UNITTEST_ASSERT(q->qtype == 1);
|
||||
UNITTEST_ASSERT(q->qclass == 1);
|
||||
UNITTEST_ASSERT(q->LongLived == 0);
|
||||
UNITTEST_ASSERT(q->ExpectUnique == mDNSfalse);
|
||||
UNITTEST_ASSERT(q->ForceMCast == 0);
|
||||
UNITTEST_ASSERT(q->TimeoutQuestion == 0);
|
||||
UNITTEST_ASSERT(q->WakeOnResolve == 0);
|
||||
UNITTEST_ASSERT(q->UseBackgroundTrafficClass == 0);
|
||||
UNITTEST_ASSERT(q->ValidationRequired == 0);
|
||||
UNITTEST_ASSERT(q->ValidatingResponse == 0);
|
||||
UNITTEST_ASSERT(q->ProxyQuestion == 0);
|
||||
UNITTEST_ASSERT(q->AnonInfo == mDNSNULL);
|
||||
UNITTEST_ASSERT(q->QuestionCallback != mDNSNULL);
|
||||
UNITTEST_ASSERT(q->QuestionContext == req);
|
||||
UNITTEST_ASSERT(q->SearchListIndex == 0);
|
||||
UNITTEST_ASSERT(q->DNSSECAuthInfo == mDNSNULL);
|
||||
UNITTEST_ASSERT(q->DAIFreeCallback == mDNSNULL);
|
||||
UNITTEST_ASSERT(q->RetryWithSearchDomains == 0);
|
||||
UNITTEST_ASSERT(q->AppendSearchDomains == 0);
|
||||
UNITTEST_ASSERT(q->AppendLocalSearchDomains == 0);
|
||||
UNITTEST_ASSERT(q->DuplicateOf == mDNSNULL);
|
||||
|
||||
// Call mDNS_Execute to see if the new question, q, has an answer in the cache.
|
||||
// It won't be yet because the cache is empty.
|
||||
m->NextScheduledEvent = mDNS_TimeNow_NoLock(m);
|
||||
mDNS_Execute(m);
|
||||
|
||||
// Verify mDNS_Execute processed the new question.
|
||||
UNITTEST_ASSERT(m->NewQuestions == mDNSNULL);
|
||||
|
||||
// Verify the cache is empty and the request got no reply.
|
||||
UNITTEST_ASSERT(m->rrcache_totalused == 0);
|
||||
UNITTEST_ASSERT(req->replies == mDNSNULL);
|
||||
|
||||
UNITTEST_FOOTER
|
||||
|
||||
// This unit test receives a canned uDNS response message by calling the mDNSCoreReceive() function.
|
||||
// It then verifies cache entries were added for the CNAME and A records that were contained in the
|
||||
// answers of the canned response, query_response_msgbuf. This unit test also verifies that
|
||||
// 2 add events were generated for the client.
|
||||
UNITTEST_HEADER(PopulateCacheWithClientResponseRecords)
|
||||
mDNS *const m = &mDNSStorage;
|
||||
DNSMessage *msgptr = (DNSMessage *)query_response_msgbuf;
|
||||
size_t msgsz = sizeof(query_response_msgbuf);
|
||||
struct reply_state *reply;
|
||||
request_state* req = client_request_message;
|
||||
DNSQuestion *q = &req->u.queryrecord.q;
|
||||
const char *data;
|
||||
const char *end;
|
||||
char name[kDNSServiceMaxDomainName];
|
||||
uint16_t rrtype, rrclass, rdlen;
|
||||
const char *rdata;
|
||||
size_t len;
|
||||
char domainname_cstr[MAX_ESCAPED_DOMAIN_NAME];
|
||||
|
||||
// Receive and populate the cache with canned response
|
||||
receive_response(req, msgptr, msgsz);
|
||||
|
||||
// Verify 2 cache entries for CName and A record are present
|
||||
mDNSu32 CacheUsed =0, notUsed =0;
|
||||
LogCacheRecords_ut(mDNS_TimeNow(m), &CacheUsed, ¬Used);
|
||||
UNITTEST_ASSERT(CacheUsed == m->rrcache_totalused);
|
||||
UNITTEST_ASSERT(CacheUsed == 4); // 2 for the CacheGroup object plus 2 for the A and CNAME records
|
||||
UNITTEST_ASSERT(m->PktNum == 1); // one packet was received
|
||||
|
||||
// Verify question's qname is now set with the A record's domainname
|
||||
UNITTEST_ASSERT(q->qnameOrig == mDNSNULL);
|
||||
ConvertDomainNameToCString(&q->qname, domainname_cstr);
|
||||
UNITTEST_ASSERT(q->qnamehash == DomainNameHashValue(&q->qname));
|
||||
UNITTEST_ASSERT(!strcmp(domainname_cstr, udns_cname_domainname_cstr));
|
||||
|
||||
// Verify client's add event for CNAME is properly formed
|
||||
reply = req->replies;
|
||||
UNITTEST_ASSERT(reply != mDNSNULL);
|
||||
UNITTEST_ASSERT(reply->next == mDNSNULL);
|
||||
|
||||
data = (char *)&reply->rhdr[1];
|
||||
end = data+reply->totallen;
|
||||
get_string(&data, data+reply->totallen, name, kDNSServiceMaxDomainName);
|
||||
rrtype = get_uint16(&data, end);
|
||||
rrclass = get_uint16(&data, end);
|
||||
rdlen = get_uint16(&data, end);
|
||||
rdata = get_rdata(&data, end, rdlen);
|
||||
len = get_reply_len(name, rdlen);
|
||||
|
||||
UNITTEST_ASSERT(reply->totallen == len + sizeof(ipc_msg_hdr));
|
||||
UNITTEST_ASSERT(reply->mhdr->version == VERSION);
|
||||
UNITTEST_ASSERT(reply->mhdr->datalen == len);
|
||||
UNITTEST_ASSERT(reply->mhdr->ipc_flags == 0);
|
||||
UNITTEST_ASSERT(reply->mhdr->op == query_reply_op);
|
||||
|
||||
UNITTEST_ASSERT(reply->rhdr->flags == htonl(kDNSServiceFlagsAdd));
|
||||
UNITTEST_ASSERT(reply->rhdr->ifi == kDNSServiceInterfaceIndexAny);
|
||||
UNITTEST_ASSERT(reply->rhdr->error == kDNSServiceErr_NoError);
|
||||
|
||||
UNITTEST_ASSERT(rrtype == kDNSType_CNAME);
|
||||
UNITTEST_ASSERT(rrclass == kDNSClass_IN);
|
||||
ConvertDomainNameToCString((const domainname *const)rdata, domainname_cstr);
|
||||
UNITTEST_ASSERT(!strcmp(domainname_cstr, "test212.dotbennu.com."));
|
||||
|
||||
// The mDNS_Execute call generates an add event for the A record
|
||||
m->NextScheduledEvent = mDNS_TimeNow_NoLock(m);
|
||||
mDNS_Execute(m);
|
||||
|
||||
// Verify the client's reply contains a properly formed add event for the A record.
|
||||
reply = req->replies;
|
||||
UNITTEST_ASSERT(reply != mDNSNULL);
|
||||
UNITTEST_ASSERT(reply->next != mDNSNULL);
|
||||
reply = reply->next;
|
||||
|
||||
data = (char *)&reply->rhdr[1];
|
||||
end = data+reply->totallen;
|
||||
get_string(&data, data+reply->totallen, name, kDNSServiceMaxDomainName);
|
||||
rrtype = get_uint16(&data, end);
|
||||
rrclass = get_uint16(&data, end);
|
||||
rdlen = get_uint16(&data, end);
|
||||
rdata = get_rdata(&data, end, rdlen);
|
||||
len = get_reply_len(name, rdlen);
|
||||
|
||||
UNITTEST_ASSERT(reply->totallen == len + sizeof(ipc_msg_hdr));
|
||||
UNITTEST_ASSERT(reply->mhdr->version == VERSION);
|
||||
UNITTEST_ASSERT(reply->mhdr->datalen == len);
|
||||
|
||||
UNITTEST_ASSERT(reply->mhdr->ipc_flags == 0);
|
||||
UNITTEST_ASSERT(reply->mhdr->op == query_reply_op);
|
||||
|
||||
UNITTEST_ASSERT(reply->rhdr->flags == htonl(kDNSServiceFlagsAdd));
|
||||
UNITTEST_ASSERT(reply->rhdr->ifi == kDNSServiceInterfaceIndexAny);
|
||||
UNITTEST_ASSERT(reply->rhdr->error == kDNSServiceErr_NoError);
|
||||
|
||||
UNITTEST_ASSERT(rrtype == kDNSType_A);
|
||||
UNITTEST_ASSERT(rrclass == kDNSClass_IN);
|
||||
UNITTEST_ASSERT(rdata[0] == dns_response_ipv4.b[0]);
|
||||
UNITTEST_ASSERT(rdata[1] == dns_response_ipv4.b[1]);
|
||||
UNITTEST_ASSERT(rdata[2] == dns_response_ipv4.b[2]);
|
||||
UNITTEST_ASSERT(rdata[3] == dns_response_ipv4.b[3]);
|
||||
|
||||
UNITTEST_FOOTER
|
||||
|
||||
// This function verifies the cache and event handling occurred as expected when a network change happened.
|
||||
// The uDNS_SetupDNSConfig is called to simulate a network change and two outcomes occur. First the A record
|
||||
// query is restarted and sent to a new DNS server. Second the cache records are purged. Then mDNS_Execute
|
||||
// is called and it removes the purged cache records and generates a remove event for the A record.
|
||||
// The following are verified:
|
||||
// 1.) The restart of query for A record.
|
||||
// 2.) The cache is empty after mDNS_Execute removes the cache entres.
|
||||
// 3.) The remove event is verified by examining the request's reply data.
|
||||
UNITTEST_HEADER(SimulateNetworkChangeAndVerifyTest)
|
||||
mDNS *const m = &mDNSStorage;
|
||||
request_state* req = client_request_message;
|
||||
DNSQuestion* q = &req->u.queryrecord.q;
|
||||
mDNSu32 CacheUsed =0, notUsed =0;
|
||||
const char *data; const char *end;
|
||||
char name[kDNSServiceMaxDomainName];
|
||||
uint16_t rrtype, rrclass, rdlen;
|
||||
const char *rdata;
|
||||
size_t len;
|
||||
|
||||
// The uDNS_SetupDNSConfig reconfigures the resolvers so the A record query is restarted and
|
||||
// both the CNAME and A record are purged.
|
||||
uDNS_SetupDNSConfig(m);
|
||||
|
||||
// Verify the A record query was restarted. This is done indirectly by noticing the transaction id and interval have changed.
|
||||
UNITTEST_ASSERT(q->ThisQInterval == InitialQuestionInterval);
|
||||
UNITTEST_ASSERT(q->TargetQID.NotAnInteger != uDNS_TargetQID);
|
||||
|
||||
// Then mDNS_Execute removes both records from the cache and calls the client back with a remove event for A record.
|
||||
m->NextScheduledEvent = mDNS_TimeNow_NoLock(m);
|
||||
mDNS_Execute(m);
|
||||
|
||||
// Verify the cache entries are removed
|
||||
LogCacheRecords_ut(mDNS_TimeNow(m), &CacheUsed, ¬Used);
|
||||
UNITTEST_ASSERT(CacheUsed == m->rrcache_totalused);
|
||||
UNITTEST_ASSERT(CacheUsed == 0);
|
||||
|
||||
// Verify the A record's remove event is setup as expected in the reply data
|
||||
struct reply_state *reply;
|
||||
reply = req->replies;
|
||||
UNITTEST_ASSERT(reply != mDNSNULL);
|
||||
|
||||
UNITTEST_ASSERT(reply != mDNSNULL);
|
||||
UNITTEST_ASSERT(reply->next != mDNSNULL);
|
||||
UNITTEST_ASSERT(reply->next->next != mDNSNULL);
|
||||
|
||||
reply = reply->next->next; // Get to last event to verify remove event
|
||||
data = (char *)&reply->rhdr[1];
|
||||
end = data+reply->totallen;
|
||||
get_string(&data, data+reply->totallen, name, kDNSServiceMaxDomainName);
|
||||
rrtype = get_uint16(&data, end);
|
||||
rrclass = get_uint16(&data, end);
|
||||
rdlen = get_uint16(&data, end);
|
||||
rdata = get_rdata(&data, end, rdlen);
|
||||
len = get_reply_len(name, rdlen);
|
||||
|
||||
UNITTEST_ASSERT(reply->totallen == reply->mhdr->datalen + sizeof(ipc_msg_hdr));
|
||||
UNITTEST_ASSERT(reply->mhdr->version == VERSION);
|
||||
UNITTEST_ASSERT(reply->mhdr->datalen == len);
|
||||
UNITTEST_ASSERT(reply->mhdr->ipc_flags == 0);
|
||||
UNITTEST_ASSERT(reply->mhdr->op == query_reply_op);
|
||||
|
||||
UNITTEST_ASSERT(reply->rhdr->flags != htonl(kDNSServiceFlagsAdd));
|
||||
UNITTEST_ASSERT(reply->rhdr->ifi == kDNSServiceInterfaceIndexAny);
|
||||
UNITTEST_ASSERT(reply->rhdr->error == kDNSServiceErr_NoError);
|
||||
|
||||
UNITTEST_ASSERT(rrtype == kDNSType_A);
|
||||
UNITTEST_ASSERT(rrclass == kDNSClass_IN);
|
||||
UNITTEST_ASSERT(rdata[0] == dns_response_ipv4.b[0]);
|
||||
UNITTEST_ASSERT(rdata[1] == dns_response_ipv4.b[1]);
|
||||
UNITTEST_ASSERT(rdata[2] == dns_response_ipv4.b[2]);
|
||||
UNITTEST_ASSERT(rdata[3] == dns_response_ipv4.b[3]);
|
||||
|
||||
UNITTEST_FOOTER
|
||||
|
||||
// This function does memory cleanup and no verification.
|
||||
UNITTEST_HEADER(FinalizeUnitTest)
|
||||
mDNS *m = &mDNSStorage;
|
||||
request_state* req = client_request_message;
|
||||
DNSServer *ptr, **p = &m->DNSServers;
|
||||
|
||||
while (req->replies)
|
||||
{
|
||||
reply_state *reply = req->replies;
|
||||
req->replies = req->replies->next;
|
||||
mDNSPlatformMemFree(reply);
|
||||
}
|
||||
mDNSPlatformMemFree(req);
|
||||
|
||||
mDNSPlatformMemFree(local_socket);
|
||||
|
||||
while (*p)
|
||||
{
|
||||
ptr = *p;
|
||||
*p = (*p)->next;
|
||||
LogInfo("FinalizeUnitTest: Deleting server %p %#a:%d (%##s)", ptr, &ptr->addr, mDNSVal16(ptr->port), ptr->domain.c);
|
||||
mDNSPlatformMemFree(ptr);
|
||||
}
|
||||
UNITTEST_FOOTER
|
||||
|
||||
// The mDNS_AddDNSServer function adds a dns server to mDNSResponder's list.
|
||||
mDNSlocal mStatus AddDNSServer(void)
|
||||
{
|
||||
mDNS *m = &mDNSStorage;
|
||||
m->timenow = 0;
|
||||
mDNS_Lock(m);
|
||||
domainname d;
|
||||
mDNSAddr addr;
|
||||
mDNSIPPort port;
|
||||
mDNSs32 serviceID = 0;
|
||||
mDNSu32 scoped = 0;
|
||||
mDNSu32 timeout = dns_server_timeout;
|
||||
mDNSBool cellIntf = 0;
|
||||
mDNSBool isExpensive = 0;
|
||||
mDNSu16 resGroupID = dns_server_resGroupID;
|
||||
mDNSBool reqA = mDNStrue;
|
||||
mDNSBool reqAAAA = mDNStrue;
|
||||
mDNSBool reqDO = mDNSfalse;
|
||||
d.c[0] = 0;
|
||||
addr.type = mDNSAddrType_IPv4;
|
||||
addr.ip.v4.NotAnInteger = dns_server_ipv4.NotAnInteger;
|
||||
port.NotAnInteger = client_resp_src_port;
|
||||
mDNS_AddDNSServer(m, &d, primary_interfaceID, serviceID, &addr, port, scoped, timeout,
|
||||
cellIntf, isExpensive, resGroupID,
|
||||
reqA, reqAAAA, reqDO);
|
||||
mDNS_Unlock(m);
|
||||
return mStatus_NoError;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
#ifndef ReconfirmRecordTests_h
|
||||
#define ReconfirmRecordTests_h
|
||||
|
||||
#include "unittest.h"
|
||||
|
||||
int CNameRecordTests(void);
|
||||
|
||||
#endif /* ReconfirmRecordTests_h */
|
|
@ -0,0 +1,50 @@
|
|||
#include "mDNSEmbeddedAPI.h"
|
||||
#include "DNSMessageTest.h"
|
||||
#include "../mDNSCore/DNSCommon.h"
|
||||
|
||||
int SizeTest(void);
|
||||
int InitializeTest(void);
|
||||
int PutDomainNameAsLabels(void);
|
||||
int PutRData(void);
|
||||
int Finalize(void);
|
||||
|
||||
|
||||
DNSMessage *msg;
|
||||
|
||||
|
||||
UNITTEST_HEADER(DNSMessageTest)
|
||||
UNITTEST_TEST(SizeTest)
|
||||
UNITTEST_TEST(InitializeTest)
|
||||
UNITTEST_TEST(Finalize)
|
||||
UNITTEST_FOOTER
|
||||
|
||||
|
||||
UNITTEST_HEADER(SizeTest)
|
||||
msg = (DNSMessage *)malloc (sizeof(DNSMessage));
|
||||
UNITTEST_ASSERT_RETURN(msg != NULL);
|
||||
|
||||
// message header should be 12 bytes
|
||||
UNITTEST_ASSERT(sizeof(msg->h) == 12);
|
||||
UNITTEST_FOOTER
|
||||
|
||||
|
||||
UNITTEST_HEADER(InitializeTest)
|
||||
// Initialize the message
|
||||
InitializeDNSMessage(&msg->h, onesID, QueryFlags);
|
||||
|
||||
// Check that the message is initialized properly
|
||||
UNITTEST_ASSERT(msg->h.numAdditionals == 0);
|
||||
UNITTEST_ASSERT(msg->h.numAnswers == 0);
|
||||
UNITTEST_ASSERT(msg->h.numQuestions == 0);
|
||||
UNITTEST_ASSERT(msg->h.numAuthorities == 0);
|
||||
UNITTEST_FOOTER
|
||||
|
||||
|
||||
UNITTEST_HEADER(PutDomainNameAsLabels)
|
||||
|
||||
UNITTEST_FOOTER
|
||||
|
||||
UNITTEST_HEADER(Finalize)
|
||||
UNITTEST_ASSERT_RETURN(msg != NULL)
|
||||
free(msg);
|
||||
UNITTEST_FOOTER
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef DNSMessageTest_h
|
||||
#define DNSMessageTest_h
|
||||
|
||||
#include "unittest.h"
|
||||
|
||||
int DNSMessageTest(void);
|
||||
|
||||
#endif /* DNSMessageTest_h */
|
|
@ -0,0 +1,28 @@
|
|||
#include "DomainNameTest.h"
|
||||
#include "mDNSEmbeddedAPI.h"
|
||||
#include "../mDNSCore/DNSCommon.h"
|
||||
|
||||
int SameDomainNameTest(void);
|
||||
int SameDomainLabelTest(void);
|
||||
int LocalDomainTest(void);
|
||||
|
||||
|
||||
UNITTEST_HEADER(DomainNameTest)
|
||||
UNITTEST_TEST(SameDomainLabelTest)
|
||||
UNITTEST_TEST(SameDomainNameTest)
|
||||
UNITTEST_TEST(LocalDomainTest)
|
||||
UNITTEST_FOOTER
|
||||
|
||||
|
||||
|
||||
|
||||
UNITTEST_HEADER(SameDomainLabelTest)
|
||||
UNITTEST_FOOTER
|
||||
|
||||
|
||||
UNITTEST_HEADER(SameDomainNameTest)
|
||||
UNITTEST_FOOTER
|
||||
|
||||
|
||||
UNITTEST_HEADER(LocalDomainTest)
|
||||
UNITTEST_FOOTER
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef DomainNameTest_h
|
||||
#define DomainNameTest_h
|
||||
|
||||
#include "unittest.h"
|
||||
int DomainNameTest(void);
|
||||
|
||||
#endif /* DomainNameTest_h */
|
|
@ -0,0 +1,19 @@
|
|||
#include "InterfaceTest.h"
|
||||
#include "mDNSEmbeddedAPI.h"
|
||||
|
||||
|
||||
NetworkInterfaceInfo *intf;
|
||||
mDNS *m;
|
||||
|
||||
int LocalSubnetTest(void);
|
||||
|
||||
UNITTEST_HEADER(InterfaceTest)
|
||||
UNITTEST_TEST(LocalSubnetTest)
|
||||
UNITTEST_FOOTER
|
||||
|
||||
UNITTEST_HEADER(LocalSubnetTest)
|
||||
// need a way to initialize m before we call into the class of APIs that use a ptr to mDNS
|
||||
// should that pointer be common to all tests?
|
||||
// mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr)
|
||||
// TEST_ASSERT_RETURN (for IPv4/IPv6 local subnet)
|
||||
UNITTEST_FOOTER
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
#ifndef InterfaceTest_h
|
||||
#define InterfaceTest_h
|
||||
|
||||
#include "unittest.h"
|
||||
|
||||
int InterfaceTest(void);
|
||||
|
||||
#endif /* InterfaceTest_h */
|
|
@ -0,0 +1,378 @@
|
|||
#include "LocalOnlyTimeoutTests.h"
|
||||
#include "unittest_common.h"
|
||||
|
||||
mDNSlocal int InitUnitTest(void);
|
||||
mDNSlocal int StartLocalOnlyClientQueryRequest(void);
|
||||
mDNSlocal int PopulateCacheWithClientLOResponseRecords(void);
|
||||
mDNSlocal int RestartLocalOnlyClientQueryRequest(void);
|
||||
mDNSlocal int FinalizeUnitTest(void);
|
||||
mDNSlocal mStatus InitEtcHostsRecords();
|
||||
|
||||
// This unit test's variables
|
||||
static request_state* client_request_message;
|
||||
static UDPSocket* local_socket;
|
||||
static char domainname_cstr[MAX_ESCAPED_DOMAIN_NAME];
|
||||
|
||||
// This query request message was generated from the following command: "dns-sd -lo -timeout -Q cardinal2.apple.com. A"
|
||||
char query_req_msgbuf[33]= {
|
||||
0x00, 0x01, 0x90, 0x00,
|
||||
// DNSServiceFlags.L = (kDNSServiceFlagsReturnIntermediates |kDNSServiceFlagsSuppressUnusable | kDNSServiceFlagsTimeout)
|
||||
0xff, 0xff, 0xff, 0xff,
|
||||
// interfaceIndex = mDNSInterface_LocalOnly
|
||||
0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c,
|
||||
0x32, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x00, 0x00, 0x01, 0x00,
|
||||
0x01
|
||||
};
|
||||
|
||||
UNITTEST_HEADER(LocalOnlyTimeoutTests)
|
||||
UNITTEST_TEST(InitUnitTest)
|
||||
UNITTEST_TEST(StartLocalOnlyClientQueryRequest)
|
||||
UNITTEST_TEST(PopulateCacheWithClientLOResponseRecords)
|
||||
UNITTEST_TEST(RestartLocalOnlyClientQueryRequest)
|
||||
UNITTEST_TEST(FinalizeUnitTest)
|
||||
UNITTEST_FOOTER
|
||||
|
||||
// The InitUnitTest() initializes a minimal mDNSResponder environment as
|
||||
// well as allocates memory for a local_socket and client request.
|
||||
// It also sets the domainname_cstr specified in the client's query request.
|
||||
// Note: This unit test does not send packets on the wire and it does not open sockets.
|
||||
UNITTEST_HEADER(InitUnitTest)
|
||||
|
||||
// Init mDNSStorage
|
||||
mStatus result = init_mdns_storage();
|
||||
if (result != mStatus_NoError)
|
||||
return result;
|
||||
|
||||
// Allocate a client request
|
||||
local_socket = calloc(1, sizeof(request_state));
|
||||
|
||||
// Allocate memory for a request that is used to make client requests.
|
||||
client_request_message = calloc(1, sizeof(request_state));
|
||||
|
||||
// Init domainname that is used by unit tests
|
||||
strlcpy(domainname_cstr, "cardinal2.apple.com.", sizeof(domainname_cstr));
|
||||
|
||||
UNITTEST_FOOTER
|
||||
|
||||
// This unit test starts a local only request for "cardinal2.apple.com.". It first
|
||||
// calls start_client_request to start a query, it then verifies the
|
||||
// req and query data structures are set as expected. Next, the cache is verified to
|
||||
// be empty by AnswerNewLocalOnlyQuestion() and so results in GenerateNegativeResponse()
|
||||
// getting called which sets up a reply with a negative answer in it for the client.
|
||||
// On return from mDNS_Execute, the client's reply structure is verified to be set as
|
||||
// expected. Lastly the timeout is simulated and mDNS_Execute is called. This results
|
||||
// in a call to TimeoutQuestions(). And again, the GenerateNegativeResponse() is called
|
||||
// which returns a negative response to the client. This time the client reply is verified
|
||||
// to be setup with a timeout result.
|
||||
UNITTEST_HEADER(StartLocalOnlyClientQueryRequest)
|
||||
|
||||
mDNS *const m = &mDNSStorage;
|
||||
request_state* req = client_request_message;
|
||||
char *msgptr = (char *)query_req_msgbuf;
|
||||
size_t msgsz = sizeof(query_req_msgbuf);
|
||||
DNSQuestion *q;
|
||||
mDNSs32 min_size = sizeof(DNSServiceFlags) + sizeof(mDNSu32) + 4;
|
||||
mStatus err = mStatus_NoError;
|
||||
char qname_cstr[MAX_ESCAPED_DOMAIN_NAME];
|
||||
struct reply_state *reply;
|
||||
size_t len;
|
||||
|
||||
// Process the unit test's client request
|
||||
start_client_request(req, msgptr, msgsz, query_request, local_socket);
|
||||
UNITTEST_ASSERT(err == mStatus_NoError);
|
||||
|
||||
// Verify the query initialized and request fields were set as expected
|
||||
UNITTEST_ASSERT(err == mStatus_NoError);
|
||||
UNITTEST_ASSERT(req->hdr.version == VERSION);
|
||||
UNITTEST_ASSERT((mDNSs32)req->data_bytes > min_size);
|
||||
UNITTEST_ASSERT(req->flags == (kDNSServiceFlagsSuppressUnusable | kDNSServiceFlagsReturnIntermediates | kDNSServiceFlagsTimeout));
|
||||
UNITTEST_ASSERT(req->interfaceIndex == kDNSServiceInterfaceIndexLocalOnly);
|
||||
UNITTEST_ASSERT(req->terminate != mDNSNULL);
|
||||
|
||||
q = &req->u.queryrecord.q;
|
||||
UNITTEST_ASSERT(q == m->NewLocalOnlyQuestions);
|
||||
UNITTEST_ASSERT(m->Questions == NULL);
|
||||
UNITTEST_ASSERT(m->NewQuestions == NULL);
|
||||
UNITTEST_ASSERT(q->SuppressUnusable == 1);
|
||||
UNITTEST_ASSERT(q->ReturnIntermed == 1);
|
||||
UNITTEST_ASSERT(q->SuppressQuery == 0); // Regress <rdar://problem/27571734>
|
||||
|
||||
UNITTEST_ASSERT(q->qnameOrig == mDNSNULL);
|
||||
ConvertDomainNameToCString(&q->qname, qname_cstr);
|
||||
UNITTEST_ASSERT(!strcmp(qname_cstr, domainname_cstr));
|
||||
UNITTEST_ASSERT(q->qnamehash == DomainNameHashValue(&q->qname));
|
||||
|
||||
UNITTEST_ASSERT(q->InterfaceID == mDNSInterface_LocalOnly);
|
||||
UNITTEST_ASSERT(q->flags == req->flags);
|
||||
UNITTEST_ASSERT(q->qtype == 1);
|
||||
UNITTEST_ASSERT(q->qclass == 1);
|
||||
UNITTEST_ASSERT(q->LongLived == 0);
|
||||
UNITTEST_ASSERT(q->ExpectUnique == mDNSfalse);
|
||||
UNITTEST_ASSERT(q->ForceMCast == 0);
|
||||
UNITTEST_ASSERT(q->TimeoutQuestion == 1);
|
||||
UNITTEST_ASSERT(q->WakeOnResolve == 0);
|
||||
UNITTEST_ASSERT(q->UseBackgroundTrafficClass == 0);
|
||||
UNITTEST_ASSERT(q->ValidationRequired == 0);
|
||||
UNITTEST_ASSERT(q->ValidatingResponse == 0);
|
||||
UNITTEST_ASSERT(q->ProxyQuestion == 0);
|
||||
UNITTEST_ASSERT(q->AnonInfo == mDNSNULL);
|
||||
UNITTEST_ASSERT(q->QuestionCallback != mDNSNULL);
|
||||
UNITTEST_ASSERT(q->QuestionContext == req);
|
||||
UNITTEST_ASSERT(q->SearchListIndex == 0);
|
||||
UNITTEST_ASSERT(q->DNSSECAuthInfo == mDNSNULL);
|
||||
UNITTEST_ASSERT(q->DAIFreeCallback == mDNSNULL);
|
||||
UNITTEST_ASSERT(q->RetryWithSearchDomains == 0);
|
||||
UNITTEST_ASSERT(q->StopTime != 0);
|
||||
UNITTEST_ASSERT(q->AppendSearchDomains == 0);
|
||||
UNITTEST_ASSERT(q->AppendLocalSearchDomains == 0);
|
||||
UNITTEST_ASSERT(q->DuplicateOf == mDNSNULL);
|
||||
|
||||
// At this point the the cache is empty. Calling mDNS_Execute will answer the local-only
|
||||
// question with a negative response.
|
||||
m->NextScheduledEvent = mDNS_TimeNow_NoLock(m);
|
||||
mDNS_Execute(m); // Regress <rdar://problem/28721294>
|
||||
|
||||
// Verify reply is a negative response and error code is set to kDNSServiceErr_NoSuchRecord error.
|
||||
reply = req->replies;
|
||||
UNITTEST_ASSERT(reply != mDNSNULL);
|
||||
|
||||
UNITTEST_ASSERT(m->NewLocalOnlyQuestions == NULL);
|
||||
UNITTEST_ASSERT(q->LOAddressAnswers == 0);
|
||||
|
||||
len = get_reply_len(qname_cstr, 0);
|
||||
|
||||
UNITTEST_ASSERT(reply->next == mDNSNULL);
|
||||
UNITTEST_ASSERT(reply->totallen == reply->mhdr->datalen + sizeof(ipc_msg_hdr));
|
||||
UNITTEST_ASSERT(reply->mhdr->version == VERSION);
|
||||
UNITTEST_ASSERT(reply->mhdr->datalen == len);
|
||||
UNITTEST_ASSERT(reply->mhdr->ipc_flags == 0);
|
||||
UNITTEST_ASSERT(reply->mhdr->op == query_reply_op);
|
||||
|
||||
UNITTEST_ASSERT(reply->rhdr->flags == htonl(kDNSServiceFlagsAdd));
|
||||
UNITTEST_ASSERT(reply->rhdr->ifi == kDNSServiceInterfaceIndexLocalOnly); // Regress <rdar://problem/27340874>
|
||||
UNITTEST_ASSERT(reply->rhdr->error ==
|
||||
(DNSServiceErrorType)htonl(kDNSServiceErr_NoSuchRecord)); // Regress <rdar://problem/24827555>
|
||||
|
||||
// Simulate what udsserver_idle normally does for clean up
|
||||
freeL("StartLocalOnlyClientQueryRequest:reply", reply);
|
||||
req->replies = NULL;
|
||||
|
||||
// Simulate the query time out of the local-only question.
|
||||
// The expected behavior is a negative answer with time out error
|
||||
m->NextScheduledEvent = mDNS_TimeNow_NoLock(m);
|
||||
q->StopTime = mDNS_TimeNow_NoLock(m);
|
||||
m->NextScheduledStopTime -= mDNSPlatformOneSecond*5;
|
||||
mDNS_Execute(m);
|
||||
|
||||
// Verify the reply is a negative response with timeout error.
|
||||
reply = req->replies;
|
||||
UNITTEST_ASSERT(reply != NULL);
|
||||
UNITTEST_ASSERT(m->NewLocalOnlyQuestions == NULL);
|
||||
UNITTEST_ASSERT(q->LOAddressAnswers == 0);
|
||||
|
||||
len = get_reply_len(qname_cstr, 0);
|
||||
|
||||
UNITTEST_ASSERT(reply->next == mDNSNULL);
|
||||
UNITTEST_ASSERT(reply->totallen == len + sizeof(ipc_msg_hdr));
|
||||
UNITTEST_ASSERT(reply->mhdr->version == VERSION);
|
||||
UNITTEST_ASSERT(reply->mhdr->datalen == len);
|
||||
UNITTEST_ASSERT(reply->mhdr->ipc_flags == 0);
|
||||
UNITTEST_ASSERT(reply->mhdr->op == query_reply_op);
|
||||
UNITTEST_ASSERT(reply->rhdr->flags == htonl(kDNSServiceFlagsAdd));
|
||||
UNITTEST_ASSERT(reply->rhdr->ifi == kDNSServiceInterfaceIndexLocalOnly); // Regress <rdar://problem/27340874>
|
||||
UNITTEST_ASSERT(reply->rhdr->error ==
|
||||
(DNSServiceErrorType)htonl(kDNSServiceErr_Timeout)); // Regress <rdar://problem/27562965>
|
||||
|
||||
// Free request and reallocate to use when query is restarted
|
||||
free_req(req);
|
||||
client_request_message = calloc(1, sizeof(request_state));
|
||||
|
||||
UNITTEST_FOOTER
|
||||
|
||||
// This unit test populates the cache with four /etc/hosts records and then
|
||||
// verifies there are four entries in the cache.
|
||||
UNITTEST_HEADER(PopulateCacheWithClientLOResponseRecords)
|
||||
|
||||
mDNS *const m = &mDNSStorage;
|
||||
|
||||
// Verify cache is empty
|
||||
int count = LogEtcHosts_ut(m);
|
||||
UNITTEST_ASSERT(count == 0);
|
||||
|
||||
// Populate /etc/hosts
|
||||
mStatus result = InitEtcHostsRecords();
|
||||
UNITTEST_ASSERT(result == mStatus_NoError);
|
||||
|
||||
// mDNS_Execute is called to populate the /etc/hosts cache.
|
||||
m->NextScheduledEvent = mDNS_TimeNow_NoLock(m);
|
||||
mDNS_Execute(m);
|
||||
|
||||
count = LogEtcHosts_ut(m);
|
||||
UNITTEST_ASSERT(count == 4);
|
||||
|
||||
UNITTEST_FOOTER
|
||||
|
||||
// This unit test starts a local only request for "cardinal2.apple.com.". It first
|
||||
// calls start_client_request to start a query, it then verifies the
|
||||
// req and query data structures are set as expected. Next, the cache is verified to
|
||||
// contain the answer by AnswerNewLocalOnlyQuestion() and so results in setting up an
|
||||
// answer reply to the client. On return from mDNS_Execute, the client's reply structure
|
||||
// is verified to be set as expected. Lastly the timeout is simulated and mDNS_Execute is
|
||||
// called. This results in a call to TimeoutQuestions(). And this time, the
|
||||
// GenerateNegativeResponse() is called which returns a negative response to the client
|
||||
// which specifies the timeout occurred. Again, the answer reply is verified to
|
||||
// to specify a timeout.
|
||||
UNITTEST_HEADER(RestartLocalOnlyClientQueryRequest)
|
||||
|
||||
mDNS *const m = &mDNSStorage;
|
||||
request_state* req = client_request_message;
|
||||
char *msgptr = (char *)query_req_msgbuf;
|
||||
size_t msgsz = sizeof(query_req_msgbuf); DNSQuestion *q;
|
||||
mDNSs32 min_size = sizeof(DNSServiceFlags) + sizeof(mDNSu32) + 4;
|
||||
mStatus err = mStatus_NoError;
|
||||
char qname_cstr[MAX_ESCAPED_DOMAIN_NAME];
|
||||
struct reply_state *reply;
|
||||
size_t len;
|
||||
|
||||
// Process the unit test's client request
|
||||
start_client_request(req, msgptr, msgsz, query_request, local_socket);
|
||||
UNITTEST_ASSERT(err == mStatus_NoError);
|
||||
|
||||
UNITTEST_ASSERT(err == mStatus_NoError);
|
||||
UNITTEST_ASSERT(req->hdr.version == VERSION);
|
||||
UNITTEST_ASSERT((mDNSs32)req->data_bytes > min_size);
|
||||
UNITTEST_ASSERT(req->flags == (kDNSServiceFlagsSuppressUnusable | kDNSServiceFlagsReturnIntermediates | kDNSServiceFlagsTimeout));
|
||||
UNITTEST_ASSERT(req->interfaceIndex == kDNSServiceInterfaceIndexLocalOnly);
|
||||
UNITTEST_ASSERT(req->terminate != mDNSNULL);
|
||||
UNITTEST_ASSERT(m->Questions == NULL);
|
||||
|
||||
q = &req->u.queryrecord.q;
|
||||
UNITTEST_ASSERT(q == m->NewLocalOnlyQuestions);
|
||||
UNITTEST_ASSERT(q->SuppressUnusable == 1);
|
||||
UNITTEST_ASSERT(q->ReturnIntermed == 1);
|
||||
UNITTEST_ASSERT(q->SuppressQuery == 0); // Regress <rdar://problem/27571734>
|
||||
UNITTEST_ASSERT(q->qnamehash == DomainNameHashValue(&q->qname));
|
||||
UNITTEST_ASSERT(q->InterfaceID == mDNSInterface_LocalOnly);
|
||||
UNITTEST_ASSERT(q->flags == req->flags);
|
||||
UNITTEST_ASSERT(q->qtype == 1);
|
||||
UNITTEST_ASSERT(q->qclass == 1);
|
||||
UNITTEST_ASSERT(q->LongLived == 0);
|
||||
UNITTEST_ASSERT(q->ExpectUnique == mDNSfalse);
|
||||
UNITTEST_ASSERT(q->ForceMCast == 0);
|
||||
UNITTEST_ASSERT(q->TimeoutQuestion == 1);
|
||||
UNITTEST_ASSERT(q->WakeOnResolve == 0);
|
||||
UNITTEST_ASSERT(q->UseBackgroundTrafficClass == 0);
|
||||
UNITTEST_ASSERT(q->ValidationRequired == 0);
|
||||
UNITTEST_ASSERT(q->ValidatingResponse == 0);
|
||||
UNITTEST_ASSERT(q->ProxyQuestion == 0);
|
||||
UNITTEST_ASSERT(q->AnonInfo == mDNSNULL);
|
||||
UNITTEST_ASSERT(q->QuestionCallback != mDNSNULL);
|
||||
UNITTEST_ASSERT(q->QuestionContext == req);
|
||||
UNITTEST_ASSERT(q->SearchListIndex == 0);
|
||||
UNITTEST_ASSERT(q->DNSSECAuthInfo == mDNSNULL);
|
||||
UNITTEST_ASSERT(q->DAIFreeCallback == mDNSNULL);
|
||||
UNITTEST_ASSERT(q->RetryWithSearchDomains == 0);
|
||||
UNITTEST_ASSERT(q->StopTime != 0);
|
||||
UNITTEST_ASSERT(q->AppendSearchDomains == 0);
|
||||
UNITTEST_ASSERT(q->AppendLocalSearchDomains == 0);
|
||||
UNITTEST_ASSERT(q->DuplicateOf == mDNSNULL);
|
||||
ConvertDomainNameToCString(&q->qname, qname_cstr);
|
||||
UNITTEST_ASSERT(!strcmp(qname_cstr, domainname_cstr));
|
||||
|
||||
// Answer local-only question with found cache entry
|
||||
m->NextScheduledEvent = mDNS_TimeNow_NoLock(m);
|
||||
mDNS_Execute(m); // Regress <rdar://problem/28721294>
|
||||
UNITTEST_ASSERT(m->NewLocalOnlyQuestions == NULL);
|
||||
UNITTEST_ASSERT(req->u.queryrecord.ans == 1);
|
||||
UNITTEST_ASSERT(q->LOAddressAnswers == 1);
|
||||
UNITTEST_ASSERT(q == m->LocalOnlyQuestions);
|
||||
|
||||
reply = req->replies;
|
||||
len = get_reply_len(qname_cstr, 4);
|
||||
|
||||
UNITTEST_ASSERT(reply->next == mDNSNULL);
|
||||
UNITTEST_ASSERT(reply->totallen == len + sizeof(ipc_msg_hdr));
|
||||
UNITTEST_ASSERT(reply->mhdr->version == VERSION);
|
||||
UNITTEST_ASSERT(reply->mhdr->datalen == len);
|
||||
UNITTEST_ASSERT(reply->mhdr->ipc_flags == 0);
|
||||
UNITTEST_ASSERT(reply->mhdr->op == query_reply_op);
|
||||
UNITTEST_ASSERT(reply->rhdr->flags == htonl(kDNSServiceFlagsAdd));
|
||||
UNITTEST_ASSERT(reply->rhdr->ifi == kDNSServiceInterfaceIndexLocalOnly); // Regress <rdar://problem/27340874>
|
||||
UNITTEST_ASSERT(reply->rhdr->error == kDNSServiceErr_NoError);
|
||||
|
||||
// Simulate the query time out of the local-only question.
|
||||
// The expected behavior is a negative answer with time out error
|
||||
m->NextScheduledEvent = mDNS_TimeNow_NoLock(m);
|
||||
q->StopTime = mDNS_TimeNow_NoLock(m);
|
||||
m->NextScheduledStopTime -= mDNSPlatformOneSecond*5;
|
||||
mDNS_Execute(m);
|
||||
|
||||
reply = req->replies->next;
|
||||
UNITTEST_ASSERT(reply != NULL);
|
||||
UNITTEST_ASSERT(reply->next == NULL);
|
||||
UNITTEST_ASSERT(m->NewLocalOnlyQuestions == NULL);
|
||||
UNITTEST_ASSERT(q->LOAddressAnswers == 0);
|
||||
len = get_reply_len(qname_cstr, 0);
|
||||
|
||||
UNITTEST_ASSERT(reply->next == mDNSNULL);
|
||||
UNITTEST_ASSERT(reply->totallen == len + + sizeof(ipc_msg_hdr));
|
||||
UNITTEST_ASSERT(reply->mhdr->version == VERSION);
|
||||
UNITTEST_ASSERT(reply->mhdr->datalen == len);
|
||||
UNITTEST_ASSERT(reply->mhdr->ipc_flags == 0);
|
||||
UNITTEST_ASSERT(reply->mhdr->op == query_reply_op);
|
||||
UNITTEST_ASSERT(reply->rhdr->flags == htonl(kDNSServiceFlagsAdd));
|
||||
UNITTEST_ASSERT(reply->rhdr->ifi == kDNSServiceInterfaceIndexLocalOnly); // Regress <rdar://problem/27340874>
|
||||
UNITTEST_ASSERT(reply->rhdr->error ==
|
||||
(DNSServiceErrorType)htonl(kDNSServiceErr_Timeout)); // Regress <rdar://problem/27562965>
|
||||
|
||||
free_req(req);
|
||||
UNITTEST_FOOTER
|
||||
|
||||
// This function does memory cleanup and no verification.
|
||||
UNITTEST_HEADER(FinalizeUnitTest)
|
||||
mDNSPlatformMemFree(local_socket);
|
||||
UNITTEST_FOOTER
|
||||
|
||||
mDNSlocal mStatus InitEtcHostsRecords(void)
|
||||
{
|
||||
mDNS *m = &mDNSStorage;
|
||||
struct sockaddr_storage hostaddr;
|
||||
|
||||
AuthHash newhosts;
|
||||
mDNSPlatformMemZero(&newhosts, sizeof(AuthHash));
|
||||
|
||||
memset(&hostaddr, 0, sizeof(hostaddr));
|
||||
get_ip("127.0.0.1", &hostaddr);
|
||||
|
||||
domainname domain;
|
||||
MakeDomainNameFromDNSNameString(&domain, "localhost");
|
||||
|
||||
mDNSMacOSXCreateEtcHostsEntry_ut(&domain, (struct sockaddr *) &hostaddr, mDNSNULL, mDNSNULL, &newhosts);
|
||||
|
||||
memset(&hostaddr, 0, sizeof(hostaddr));
|
||||
get_ip("0000:0000:0000:0000:0000:0000:0000:0001", &hostaddr);
|
||||
|
||||
MakeDomainNameFromDNSNameString(&domain, "localhost");
|
||||
|
||||
mDNSMacOSXCreateEtcHostsEntry_ut(&domain, (struct sockaddr *) &hostaddr, mDNSNULL, mDNSNULL, &newhosts);
|
||||
|
||||
memset(&hostaddr, 0, sizeof(hostaddr));
|
||||
get_ip("255.255.255.255", &hostaddr);
|
||||
|
||||
MakeDomainNameFromDNSNameString(&domain, "broadcasthost");
|
||||
|
||||
mDNSMacOSXCreateEtcHostsEntry_ut(&domain, (struct sockaddr *) &hostaddr, mDNSNULL, mDNSNULL, &newhosts);
|
||||
|
||||
memset(&hostaddr, 0, sizeof(hostaddr));
|
||||
get_ip("17.226.40.200", &hostaddr);
|
||||
|
||||
MakeDomainNameFromDNSNameString(&domain, "cardinal2.apple.com");
|
||||
|
||||
mDNSMacOSXCreateEtcHostsEntry_ut(&domain, (struct sockaddr *) &hostaddr, mDNSNULL, mDNSNULL, &newhosts);
|
||||
UpdateEtcHosts_ut(&newhosts);
|
||||
|
||||
m->NextScheduledEvent = mDNS_TimeNow_NoLock(m);
|
||||
mDNS_Execute(m);
|
||||
|
||||
return mStatus_NoError;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
#ifndef LocalOnlyTimeoutTests_h
|
||||
#define LocalOnlyTimeoutTests_h
|
||||
|
||||
#include "unittest.h"
|
||||
|
||||
int LocalOnlyTimeoutTests(void);
|
||||
|
||||
#endif /* LocalOnlyTimeoutTests_h */
|
|
@ -0,0 +1,61 @@
|
|||
#include "mDNSEmbeddedAPI.h"
|
||||
#include "../mDNSCore/DNSCommon.h"
|
||||
#include "ResourceRecordTest.h"
|
||||
|
||||
int TXTSetupTest(void);
|
||||
int ASetupTest(void);
|
||||
int OPTSetupTest(void);
|
||||
|
||||
|
||||
UNITTEST_HEADER(ResourceRecordTest)
|
||||
UNITTEST_TEST(TXTSetupTest)
|
||||
UNITTEST_TEST(ASetupTest)
|
||||
UNITTEST_TEST(OPTSetupTest)
|
||||
UNITTEST_FOOTER
|
||||
|
||||
|
||||
UNITTEST_HEADER(TXTSetupTest)
|
||||
|
||||
AuthRecord authRec;
|
||||
mDNS_SetupResourceRecord(&authRec, mDNSNULL, mDNSInterface_Any, kDNSType_TXT, kStandardTTL, kDNSRecordTypeShared, AuthRecordAny,mDNSNULL, mDNSNULL);
|
||||
// This fails >> UNITTEST_ASSERT_RETURN(authRec.resrec.RecordType == kDNSType_TXT);
|
||||
UNITTEST_ASSERT_RETURN(authRec.resrec.rdata->MaxRDLength == sizeof(RDataBody));
|
||||
|
||||
// Retest with a RDataStorage set to a a buffer
|
||||
UNITTEST_FOOTER
|
||||
|
||||
|
||||
UNITTEST_HEADER(ASetupTest)
|
||||
AuthRecord authRec;
|
||||
mDNS_SetupResourceRecord(&authRec, mDNSNULL, mDNSInterface_Any, kDNSType_A, kHostNameTTL, kDNSRecordTypeUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
|
||||
|
||||
// This fails >> UNITTEST_ASSERT_RETURN(authRec.resrec.RecordType == kDNSType_A);
|
||||
// Add more verifications
|
||||
|
||||
UNITTEST_FOOTER
|
||||
|
||||
|
||||
UNITTEST_HEADER(OPTSetupTest)
|
||||
AuthRecord opt;
|
||||
mDNSu32 updatelease = 7200;
|
||||
/* mDNSu8 data[AbsoluteMaxDNSMessageData];
|
||||
mDNSu8 *p = data;
|
||||
mDNSu16 numAdditionals;
|
||||
*/
|
||||
// Setup the OPT Record
|
||||
mDNS_SetupResourceRecord(&opt, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
|
||||
|
||||
// Verify the basic initialization is all ok
|
||||
|
||||
opt.resrec.rrclass = NormalMaxDNSMessageData;
|
||||
opt.resrec.rdlength = sizeof(rdataOPT); // One option in this OPT record
|
||||
opt.resrec.rdestimate = sizeof(rdataOPT);
|
||||
opt.resrec.rdata->u.opt[0].opt = kDNSOpt_Lease;
|
||||
opt.resrec.rdata->u.opt[0].u.updatelease = updatelease;
|
||||
|
||||
// Put the resource record in and verify everything is fine
|
||||
// p = PutResourceRecordTTLWithLimit(&data, p, &numAdditionals, &opt.resrec, opt.resrec.rroriginalttl, data + AbsoluteMaxDNSMessageData);
|
||||
|
||||
|
||||
// Repeat with bad data to make sure it bails out cleanly
|
||||
UNITTEST_FOOTER
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
|
||||
#ifndef ResourceRecordTest_h
|
||||
#define ResourceRecordTest_h
|
||||
|
||||
#include "unittest.h"
|
||||
|
||||
int ResourceRecordTest(void);
|
||||
|
||||
#endif /* ResourceRecordTest_h */
|
|
@ -0,0 +1,35 @@
|
|||
#include "DNSCommon.h"
|
||||
|
||||
mDNSexport void init_logging_ut(void)
|
||||
{
|
||||
#if APPLE_OSX_mDNSResponder
|
||||
init_logging();
|
||||
|
||||
/* When doing unit testing, it is likely that some local functions and
|
||||
* variables will not be needed to do unit testing validation. So to get
|
||||
* around compiler warnings about unused functions or variables, each
|
||||
* warning work-around is handled explicitly below.
|
||||
*/
|
||||
|
||||
/* The next three LogOperation() are used to trick the compiler into
|
||||
* suppressing unused function and variable warnings. This is done by
|
||||
* outputting the function or variable pointer to a log message.
|
||||
*/
|
||||
LogOperation("Quiet compiler warnings for KQueueLoop= %p, "
|
||||
"KQWokenFlushBytes= %p, SignalCallback= %p, "
|
||||
"mDNS_StatusCallback= %p, LaunchdCheckin= %p",
|
||||
KQueueLoop, KQWokenFlushBytes,
|
||||
SignalCallback, mDNS_StatusCallback,
|
||||
LaunchdCheckin);
|
||||
LogOperation("Quiet compiler warnings for SandboxProcess= %p, "
|
||||
"mDNSDaemonInitialize= %p, HandleSIG= %p, "
|
||||
"PreferencesGetValueInt= %p, PreferencesGetValueBool= %p",
|
||||
SandboxProcess, mDNSDaemonInitialize,
|
||||
HandleSIG, PreferencesGetValueInt,
|
||||
PreferencesGetValueBool);
|
||||
LogOperation("Quiet compiler warnings for rrcachestorage= %p, "
|
||||
"NoMulticastAdvertisements= %p",
|
||||
rrcachestorage, NoMulticastAdvertisements);
|
||||
|
||||
#endif // APPLE_OSX_mDNSResponder
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
#include "mDNSCoreReceiveTest.h"
|
||||
#include "unittest_common.h"
|
||||
|
||||
int InitmDNSCoreReceiveTest(void);
|
||||
int ValidQueryReqTest(void);
|
||||
int NullDstQueryReqTest(void);
|
||||
int ReceiveArpLogMsgTest(void);
|
||||
void InitmDNSStorage(mDNS *const m);
|
||||
|
||||
// This DNS message was gleaned from a uDNS query request packet that was captured with Wireshark.
|
||||
uint8_t udns_query_request_message[28] = { // contains 1 question for www.f5.com
|
||||
0x31, 0xca, // transaction id
|
||||
0x01, 0x00, // flags
|
||||
0x00, 0x01, // 1 question
|
||||
0x00, 0x00, // no anwsers
|
||||
0x00, 0x00, // no authoritative answers
|
||||
0x00, 0x00, // no additionals
|
||||
0x03, 0x77, 0x77, 0x77, 0x02, 0x66, 0x35, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01
|
||||
};
|
||||
|
||||
// This DNS message was gleaned from a uDNS query request packet that was captured with Wireshark.
|
||||
// Then the header id (more specifically, the msg->h.id) was deliberately cleared to force code
|
||||
// path to traverse regression case, <rdar://problem/28556513>.
|
||||
uint8_t udns_query_request_message_with_invalid_id[28] = { // contains 1 question for www.f5.com, msg->h.id = 0
|
||||
0x00, 0x00, // transaction id
|
||||
0x01, 0x00, // flags
|
||||
0x00, 0x01, // 1 question
|
||||
0x00, 0x00, // no anwsers
|
||||
0x00, 0x00, // no authoritative answers
|
||||
0x00, 0x00, // no additionals
|
||||
0x03, 0x77, 0x77, 0x77, 0x02, 0x66, 0x35, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01
|
||||
};
|
||||
|
||||
uint8_t arp_request_packet[28] = { // contains 1 question for www.f5.com, msg->h.id = 0
|
||||
0x00, 0x01, // hardware type: enet
|
||||
0x08, 0x00, // protocol type: IP
|
||||
0x06, // hardware size
|
||||
0x04, // Protcol size
|
||||
0x00, 0x01, // opcode request
|
||||
0x24, 0x01, 0xc7, 0x24, 0x35, 0x00, // Sender mac addr
|
||||
0x11, 0xe2, 0x14, 0x01, // Sender ip addr
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // target mac addr
|
||||
0x11, 0xe2, 0x17, 0xbe // target ip addr
|
||||
};
|
||||
UNITTEST_HEADER(mDNSCoreReceiveTest)
|
||||
UNITTEST_TEST(InitmDNSCoreReceiveTest)
|
||||
UNITTEST_TEST(ValidQueryReqTest)
|
||||
UNITTEST_TEST(NullDstQueryReqTest)
|
||||
UNITTEST_TEST(ReceiveArpLogMsgTest)
|
||||
UNITTEST_FOOTER
|
||||
|
||||
UNITTEST_HEADER(InitmDNSCoreReceiveTest)
|
||||
mDNSPlatformTimeInit();
|
||||
init_logging_ut();
|
||||
mDNS_LoggingEnabled = 0;
|
||||
mDNS_PacketLoggingEnabled = 0;
|
||||
UNITTEST_FOOTER
|
||||
|
||||
UNITTEST_HEADER(ReceiveArpLogMsgTest)
|
||||
// Init unit test environment and verify no error occurred.
|
||||
mStatus result = init_mdns_environment(mDNStrue);
|
||||
UNITTEST_ASSERT(result == mStatus_NoError);
|
||||
|
||||
UNITTEST_ASSERT(result == mStatus_NoError);
|
||||
ArpLogMsgTest(&mDNSStorage, (const ARP_EthIP *) arp_request_packet, primary_interfaceID);
|
||||
UNITTEST_ASSERT(result == mStatus_NoError);
|
||||
UNITTEST_FOOTER
|
||||
|
||||
UNITTEST_HEADER(ValidQueryReqTest)
|
||||
mDNS *const m = &mDNSStorage;
|
||||
mDNSAddr srcaddr, dstaddr;
|
||||
mDNSIPPort srcport, dstport;
|
||||
DNSMessage * msg;
|
||||
const mDNSu8 * end;
|
||||
|
||||
// This test case does not require setup of interfaces, the record's cache, or pending questions
|
||||
// so m is initialized to all zeros.
|
||||
InitmDNSStorage(m);
|
||||
|
||||
// Used random values for srcaddr and srcport
|
||||
srcaddr.type = mDNSAddrType_IPv4;
|
||||
srcaddr.ip.v4.b[0] = 192;
|
||||
srcaddr.ip.v4.b[1] = 168;
|
||||
srcaddr.ip.v4.b[2] = 1;
|
||||
srcaddr.ip.v4.b[3] = 10;
|
||||
srcport.NotAnInteger = swap16((mDNSu16)53);
|
||||
|
||||
// Used random values for dstaddr and dstport
|
||||
dstaddr.type = mDNSAddrType_IPv4;
|
||||
dstaddr.ip.v4.b[0] = 192;
|
||||
dstaddr.ip.v4.b[1] = 168;
|
||||
dstaddr.ip.v4.b[2] = 1;
|
||||
dstaddr.ip.v4.b[3] = 20;
|
||||
dstport.NotAnInteger = swap16((mDNSu16)49339);
|
||||
|
||||
// Set message to a DNS message (copied from a WireShark packet)
|
||||
msg = (DNSMessage *)udns_query_request_message;
|
||||
end = udns_query_request_message + sizeof(udns_query_request_message);
|
||||
|
||||
// Execute mDNSCoreReceive using a valid DNS message
|
||||
mDNSCoreReceive(m, msg, end, &srcaddr, srcport, &dstaddr, dstport, if_nametoindex("en0"));
|
||||
|
||||
// Verify that mDNSCoreReceiveQuery traversed the normal code path
|
||||
UNITTEST_ASSERT(m->mDNSStats.NormalQueries == 1);
|
||||
|
||||
UNITTEST_FOOTER
|
||||
|
||||
UNITTEST_HEADER(NullDstQueryReqTest)
|
||||
|
||||
mDNS *const m = &mDNSStorage;
|
||||
mDNSAddr srcaddr;
|
||||
mDNSIPPort srcport, dstport;
|
||||
DNSMessage * msg;
|
||||
const mDNSu8 * end;
|
||||
|
||||
// This test case does not require setup of interfaces, the record's cache, or pending questions
|
||||
// so m is initialized to all zeros.
|
||||
InitmDNSStorage(m);
|
||||
|
||||
// Used random values for srcaddr and srcport
|
||||
srcaddr.type = mDNSAddrType_IPv4;
|
||||
srcaddr.ip.v4.b[0] = 192;
|
||||
srcaddr.ip.v4.b[1] = 168;
|
||||
srcaddr.ip.v4.b[2] = 1;
|
||||
srcaddr.ip.v4.b[3] = 10;
|
||||
srcport.NotAnInteger = swap16((mDNSu16)53);
|
||||
|
||||
// Used random value for dstport
|
||||
dstport.NotAnInteger = swap16((mDNSu16)49339);
|
||||
|
||||
// Set message to a DNS message (copied from a WireShark packet)
|
||||
msg = (DNSMessage *)udns_query_request_message_with_invalid_id;
|
||||
end = udns_query_request_message_with_invalid_id + sizeof(udns_query_request_message_with_invalid_id);
|
||||
|
||||
// Execute mDNSCoreReceive to regress <rdar://problem/28556513>
|
||||
mDNSCoreReceive(m, msg, end, &srcaddr, srcport, NULL, dstport, if_nametoindex("en0"));
|
||||
|
||||
// Verify that mDNSCoreReceiveQuery was NOT traversed through the normal code path
|
||||
UNITTEST_ASSERT(m->mDNSStats.NormalQueries == 0);
|
||||
|
||||
// Verify code path that previously crashed, in <rdar://problem/28556513>, now traverses successfully
|
||||
// by checking a counter that was incremented on code path that crashed.
|
||||
UNITTEST_ASSERT(m->MPktNum == 1);
|
||||
|
||||
UNITTEST_FOOTER
|
||||
|
||||
void InitmDNSStorage(mDNS *const m)
|
||||
{
|
||||
memset(m, 0, sizeof(mDNS));
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
#ifndef mDNSCoreReceiveTest_h
|
||||
#define mDNSCoreReceiveTest_h
|
||||
|
||||
#include "unittest.h"
|
||||
|
||||
int mDNSCoreReceiveTest(void);
|
||||
|
||||
#endif /* mDNSCoreReceiveTest_h */
|
|
@ -0,0 +1,42 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2015 Apple 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 "unittest.h"
|
||||
#include "DNSMessageTest.h"
|
||||
#include "ResourceRecordTest.h"
|
||||
#include "mDNSCoreReceiveTest.h"
|
||||
#include "CNameRecordTests.h"
|
||||
#include "LocalOnlyTimeoutTests.h"
|
||||
|
||||
const char *HWVersionString = "unittestMac1,1";
|
||||
const char *OSVersionString = "unittest 1.1.1 (1A111)";
|
||||
const char *BinaryNameString = "unittest";
|
||||
const char *VersionString = "unittest mDNSResponer-00 (Jan 1 1970 00:00:00)";
|
||||
|
||||
|
||||
|
||||
UNITTEST_HEADER(run_tests)
|
||||
UNITTEST_GROUP(DNSMessageTest)
|
||||
UNITTEST_GROUP(ResourceRecordTest)
|
||||
UNITTEST_GROUP(mDNSCoreReceiveTest)
|
||||
//UNITTEST_GROUP(CNameRecordTests) // Commenting out until issue reported in <rdar://problem/30589360> is debugged.
|
||||
UNITTEST_GROUP(LocalOnlyTimeoutTests)
|
||||
UNITTEST_FOOTER
|
||||
|
||||
// UNITTEST_MAIN is run in daemon.c
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
#include "DNSCommon.h" // Defines general DNS utility routines
|
||||
|
||||
// To match *either* a v4 or v6 instance of this interface
|
||||
mDNSlocal mDNSInterfaceID SearchForInterfaceByAddr(mDNSAddr* addr)
|
||||
{
|
||||
NetworkInterfaceInfoOSX *i;
|
||||
for (i = mDNSStorage.p->InterfaceList; i; i = i->next)
|
||||
if (i->Exists)
|
||||
{
|
||||
if ((i->ifinfo.ip.type == mDNSAddrType_IPv4) &&
|
||||
i->ifinfo.ip.ip.v4.NotAnInteger == addr->ip.v4.NotAnInteger)
|
||||
return i->ifinfo.InterfaceID;
|
||||
else if ((i->ifinfo.ip.type == mDNSAddrType_IPv6) &&
|
||||
(i->ifinfo.ip.ip.v6.l[0] == addr->ip.v6.l[0] &&
|
||||
i->ifinfo.ip.ip.v6.l[1] == addr->ip.v6.l[1] &&
|
||||
i->ifinfo.ip.ip.v6.l[2] == addr->ip.v6.l[2] &&
|
||||
i->ifinfo.ip.ip.v6.l[3] == addr->ip.v6.l[3])
|
||||
)
|
||||
return i->ifinfo.InterfaceID;
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
mDNSexport void SetInterfaces_ut(mDNSInterfaceID* pri_id, mDNSAddr *pri_v4, mDNSAddr* pri_v6, mDNSAddr* pri_router)
|
||||
{
|
||||
mDNSs32 utc = mDNSPlatformUTC();
|
||||
|
||||
MarkAllInterfacesInactive(utc);
|
||||
UpdateInterfaceList(utc);
|
||||
ClearInactiveInterfaces(utc);
|
||||
SetupActiveInterfaces(utc);
|
||||
|
||||
// set primary interface info
|
||||
{
|
||||
mDNSAddr* addr;
|
||||
NetworkChangedKey_IPv4 = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4);
|
||||
NetworkChangedKey_IPv6 = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv6);
|
||||
NetworkChangedKey_Hostnames = SCDynamicStoreKeyCreateHostNames(NULL);
|
||||
NetworkChangedKey_Computername = SCDynamicStoreKeyCreateComputerName(NULL);
|
||||
NetworkChangedKey_DNS = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetDNS);
|
||||
NetworkChangedKey_StateInterfacePrefix = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, CFSTR(""), NULL);
|
||||
|
||||
mDNSPlatformGetPrimaryInterface(pri_v4, pri_v6, pri_router);
|
||||
addr = (pri_v4->type == mDNSAddrType_IPv4) ? pri_v4 : pri_v6;
|
||||
*pri_id = SearchForInterfaceByAddr(addr);
|
||||
|
||||
CFRelease(NetworkChangedKey_IPv4);
|
||||
CFRelease(NetworkChangedKey_IPv6);
|
||||
CFRelease(NetworkChangedKey_Hostnames);
|
||||
CFRelease(NetworkChangedKey_Computername);
|
||||
CFRelease(NetworkChangedKey_DNS);
|
||||
CFRelease(NetworkChangedKey_StateInterfacePrefix);
|
||||
}
|
||||
}
|
||||
|
||||
mDNSexport mDNSBool mDNSMacOSXCreateEtcHostsEntry_ut(const domainname *domain, const struct sockaddr *sa, const domainname *cname, char *ifname, AuthHash *auth)
|
||||
{
|
||||
return mDNSMacOSXCreateEtcHostsEntry(domain, sa, cname, ifname, auth);
|
||||
}
|
||||
|
||||
mDNSexport void UpdateEtcHosts_ut(void *context)
|
||||
{
|
||||
mDNS_Lock(&mDNSStorage);
|
||||
UpdateEtcHosts(&mDNSStorage, context);
|
||||
mDNS_Unlock(&mDNSStorage);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#include "DNSCommon.h" // Defines general DNS utility routines
|
||||
|
||||
mDNSexport mStatus mDNS_InitStorage_ut(mDNS *const m, mDNS_PlatformSupport *const p,
|
||||
CacheEntity *rrcachestorage, mDNSu32 rrcachesize,
|
||||
mDNSBool AdvertiseLocalAddresses, mDNSCallback *Callback, void *Context)
|
||||
{
|
||||
return mDNS_InitStorage(m, p, rrcachestorage, rrcachesize, AdvertiseLocalAddresses, Callback, Context);
|
||||
}
|
||||
|
||||
mDNSexport mStatus ArpLogMsgTest(mDNS *const m, const ARP_EthIP *const arp, const mDNSInterfaceID InterfaceID)
|
||||
{
|
||||
NetworkInterfaceInfo *intf = FirstInterfaceForID(m, InterfaceID);
|
||||
static const char msg[] = "ARP Req message";
|
||||
LogMsg("Arp %-7s %s %.6a %.4a for %.4a",
|
||||
intf->ifname, msg, arp->sha.b, arp->spa.b, arp->tpa.b);
|
||||
return mStatus_NoError;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#include "DNSCommon.h" // Defines general DNS utility routines
|
||||
|
||||
mDNSexport mStatus handle_client_request_ut(void *req)
|
||||
{
|
||||
return handle_client_request((request_state*)req);
|
||||
}
|
||||
|
||||
mDNSexport void LogCacheRecords_ut(mDNSs32 now, mDNSu32* retCacheUsed, mDNSu32* retCacheActive)
|
||||
{
|
||||
mDNSu32 CacheUsed =0, CacheActive =0, slot;
|
||||
const CacheGroup *cg;
|
||||
const CacheRecord *cr;
|
||||
|
||||
LogMsgNoIdent("------------ Cache -------------");
|
||||
LogMsgNoIdent("Slt Q TTL if U Type rdlen");
|
||||
for (slot = 0; slot < CACHE_HASH_SLOTS; slot++)
|
||||
{
|
||||
for (cg = mDNSStorage.rrcache_hash[slot]; cg; cg=cg->next)
|
||||
{
|
||||
CacheUsed++; // Count one cache entity for the CacheGroup object
|
||||
for (cr = cg->members; cr; cr=cr->next)
|
||||
{
|
||||
const mDNSs32 remain = cr->resrec.rroriginalttl - (now - cr->TimeRcvd) / mDNSPlatformOneSecond;
|
||||
const char *ifname;
|
||||
mDNSInterfaceID InterfaceID = cr->resrec.InterfaceID;
|
||||
if (!InterfaceID && cr->resrec.rDNSServer && cr->resrec.rDNSServer->scoped)
|
||||
InterfaceID = cr->resrec.rDNSServer->interface;
|
||||
ifname = InterfaceNameForID(&mDNSStorage, InterfaceID);
|
||||
if (cr->CRActiveQuestion) CacheActive++;
|
||||
PrintOneCacheRecord(cr, slot, remain, ifname, &CacheUsed);
|
||||
PrintCachedRecords(cr, slot, remain, ifname, &CacheUsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*retCacheUsed = CacheUsed;
|
||||
*retCacheActive = CacheActive;
|
||||
}
|
||||
|
||||
mDNSexport int LogEtcHosts_ut(mDNS *const m)
|
||||
{
|
||||
return LogEtcHosts(m);
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2015 Apple 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 <stdlib.h>
|
||||
#include "unittest.h"
|
||||
|
||||
int _unittest_assert_i(const int condition, const int i, const char * const conditionStr,
|
||||
const char * const filename, const unsigned int linenum,
|
||||
const char * const functionname, __test_item ** __i, int * const __success)
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
__test_item* tba = malloc(sizeof(__test_item));
|
||||
tba->next = *__i;
|
||||
tba->file = filename;
|
||||
tba->line = linenum;
|
||||
tba->func = functionname;
|
||||
tba->s = conditionStr;
|
||||
tba->iter_count = i;
|
||||
*__i = tba;
|
||||
*__success = 0;
|
||||
printf("F");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(".");
|
||||
}
|
||||
|
||||
fflush(NULL);
|
||||
return condition;
|
||||
}
|
||||
|
||||
void _unittest_print_list(__test_item* __i)
|
||||
{
|
||||
__test_item* __tmp = NULL;
|
||||
while (__i)
|
||||
{
|
||||
__test_item* __o = __i->next;
|
||||
__i->next = __tmp;
|
||||
__tmp = __i;
|
||||
__i = __o;
|
||||
}
|
||||
__i = __tmp;
|
||||
|
||||
while(__i)
|
||||
{
|
||||
printf("%s: In function `%s':\n%s:%d: error: failed UNITTEST_ASSERT", __i->file, __i->func, __i->file, __i->line);
|
||||
if (__i->iter_count != -1) printf(" at iteration %d", __i->iter_count);
|
||||
printf(": %s\n", __i->s);
|
||||
__test_item* tbd = __i;
|
||||
__i = __i->next;
|
||||
free(tbd);
|
||||
}
|
||||
}
|
||||
|
||||
// test by building like:
|
||||
// gcc -g -Wall -Werror -DTEST_UNITTEST_SCAFFOLD unittest.c
|
||||
// #define TEST_UNITTEST_SCAFFOLD 1
|
||||
#if TEST_UNITTEST_SCAFFOLD
|
||||
|
||||
// modify this test as necessary to test the scaffold
|
||||
UNITTEST_HEADER(test1)
|
||||
int i = 0;
|
||||
int j = 1;
|
||||
int k = 2;
|
||||
|
||||
UNITTEST_ASSERT(i==j);
|
||||
UNITTEST_ASSERTI(j==i, k);
|
||||
UNITTEST_ASSERT(i==i);
|
||||
UNITTEST_ASSERTI(j==j, k);
|
||||
UNITTEST_ASSERT_RETURN(j==j);
|
||||
UNITTEST_ASSERTI_RETURN(j==j, k);
|
||||
UNITTEST_FOOTER
|
||||
|
||||
UNITTEST_HEADER(test2)
|
||||
UNITTEST_ASSERT(1);
|
||||
UNITTEST_ASSERT(0);
|
||||
UNITTEST_ASSERT(1);
|
||||
UNITTEST_FOOTER
|
||||
|
||||
UNITTEST_HEADER(unittest_tests)
|
||||
UNITTEST_TEST(test1)
|
||||
UNITTEST_TEST(test2)
|
||||
UNITTEST_FOOTER
|
||||
|
||||
UNITTEST_HEADER(run_tests)
|
||||
UNITTEST_GROUP(unittest_tests)
|
||||
UNITTEST_FOOTER
|
||||
|
||||
UNITTEST_MAIN
|
||||
|
||||
#endif // TEST_UNITTEST_SCAFFOLD
|
|
@ -0,0 +1,124 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*-
|
||||
*
|
||||
* Copyright (c) 2015 Apple 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include "unittest_common.h"
|
||||
|
||||
#include <MacTypes.h>
|
||||
#ifndef _UNITTEST_H_
|
||||
#define _UNITTEST_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct __test_item_
|
||||
{
|
||||
struct __test_item_* next;
|
||||
const char* file;
|
||||
unsigned int line;
|
||||
const char* func;
|
||||
const char* s;
|
||||
int iter_count;
|
||||
} __test_item;
|
||||
|
||||
int run_tests(void);
|
||||
|
||||
#define UNITTEST_HEADER(X) int X() { int __success = 1; __test_item* __i = NULL;
|
||||
|
||||
#define UNITTEST_GROUP(X) { printf("== %s ==\n", #X); __success = X() && __success; }
|
||||
#define UNITTEST_TEST(X) { printf("%s: ", #X); fflush(NULL); __success = X() && __success; }
|
||||
|
||||
int _unittest_assert_i(const int condition, const int i, const char * const conditionStr,
|
||||
const char * const filename, const unsigned int linenum,
|
||||
const char * const functionname, __test_item ** __i, int * const __success);
|
||||
#define UNITTEST_ASSERTI(X,I) (_unittest_assert_i((X)!=0, (I), #X, __FILE__, __LINE__, __func__, &__i, &__success))
|
||||
#define UNITTEST_ASSERT(X) UNITTEST_ASSERTI(X, -1)
|
||||
#define UNITTEST_ASSERTI_RETURN(X,I) { if (!UNITTEST_ASSERTI(X,I)) goto __unittest_footer__; }
|
||||
#define UNITTEST_ASSERT_RETURN(X) UNITTEST_ASSERTI_RETURN(X, -1)
|
||||
|
||||
void _unittest_print_list(__test_item* __i);
|
||||
#define UNITTEST_FOOTER goto __unittest_footer__; __unittest_footer__: printf("\n"); fflush(NULL); _unittest_print_list(__i); return __success; }
|
||||
|
||||
#define UNITTEST_MAIN int main (int argc, char** argv) \
|
||||
{ \
|
||||
(void)(argv); \
|
||||
signal(SIGPIPE, SIG_IGN); \
|
||||
FILE* fp; \
|
||||
unlink("unittest_success"); \
|
||||
if (!run_tests()) \
|
||||
{ \
|
||||
printf("unit test FAILED\n"); \
|
||||
return -1; \
|
||||
} \
|
||||
fp = fopen("unittest_success", "w"); \
|
||||
if (!fp) return -2; \
|
||||
fprintf(fp, "unit test %s\n", "SUCCEEDED"); \
|
||||
fclose(fp); \
|
||||
printf("unit test SUCCESS\n"); \
|
||||
if (argc != 1) \
|
||||
{ \
|
||||
char c; \
|
||||
printf("run leaks now\n"); \
|
||||
read(STDIN_FILENO, &c, 1); \
|
||||
} \
|
||||
return 0; \
|
||||
}
|
||||
#define UNITTEST_SENDDNSMESSAGE mStatus mDNSSendDNSMessage(mDNS *const m, DNSMessage *const msg, mDNSu8 *end, \
|
||||
mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst, \
|
||||
mDNSIPPort dstport, TCPSocket *sock, DomainAuthInfo *authInfo, \
|
||||
mDNSBool useBackgroundTrafficClass) \
|
||||
{ \
|
||||
(void)(m); \
|
||||
(void)(msg); \
|
||||
(void)(end); \
|
||||
(void)(InterfaceID); \
|
||||
(void)(src); \
|
||||
(void)(dst); \
|
||||
(void)(dstport); \
|
||||
(void)(sock); \
|
||||
(void)(authInfo); \
|
||||
(void)(useBackgroundTrafficClass); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define UNITTEST_SETSOCKOPT void mDNSPlatformSetSocktOpt(void *sockCxt, mDNSTransport_Type transType, \
|
||||
mDNSAddr_Type addrType, const DNSQuestion *q) \
|
||||
{ \
|
||||
(void)(sockCxt); \
|
||||
(void)(transType); \
|
||||
(void)(addrType); \
|
||||
(void)(q); \
|
||||
return; \
|
||||
}
|
||||
|
||||
#define UNITTEST_UDPCLOSE void mDNSPlatformUDPClose(UDPSocket *sock) \
|
||||
{ \
|
||||
(void)(sock); \
|
||||
}
|
||||
|
||||
#define UNITTEST_FAIL_ASSERT { assert(((void*)__func__) == 0); }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ndef _UNITTEST_H_
|
|
@ -0,0 +1,157 @@
|
|||
#include "unittest_common.h"
|
||||
#include "dns_sd.h"
|
||||
#include "mDNSEmbeddedAPI.h"
|
||||
#include "mDNSMacOSX.h"
|
||||
|
||||
static mDNS_PlatformSupport PlatformStorage;
|
||||
#define RR_CACHE_SIZE ((32*1024) / sizeof(CacheRecord))
|
||||
static CacheEntity gRrcachestorage[RR_CACHE_SIZE];
|
||||
|
||||
// Primary interface info that is used when simulating the receive of the response packet
|
||||
mDNSInterfaceID primary_interfaceID;
|
||||
mDNSAddr primary_v4;
|
||||
mDNSAddr primary_v6;
|
||||
mDNSAddr primary_router;
|
||||
|
||||
// This function sets up the minimum environement to run a unit test. It
|
||||
// initializes logging, interfaces, and timenow.
|
||||
mDNSexport mStatus init_mdns_environment(mDNSBool enableLogging)
|
||||
{
|
||||
mDNS *m = &mDNSStorage;
|
||||
|
||||
init_logging_ut();
|
||||
mDNS_LoggingEnabled = enableLogging;
|
||||
mDNS_PacketLoggingEnabled = enableLogging;
|
||||
|
||||
mStatus result = mDNS_InitStorage_ut(m, &PlatformStorage, gRrcachestorage, RR_CACHE_SIZE, mDNSfalse, mDNSNULL, mDNSNULL);
|
||||
if (result != mStatus_NoError)
|
||||
return result;
|
||||
|
||||
primary_v4 = primary_v6 = primary_router = zeroAddr;
|
||||
SetInterfaces_ut(&primary_interfaceID, &primary_v4, &primary_v6, &primary_router);
|
||||
|
||||
m->timenow = mDNS_TimeNow_NoLock(m);
|
||||
return mStatus_NoError;
|
||||
}
|
||||
|
||||
// This function sets up the minimum environement to run a unit test. It
|
||||
// initializes logging and timenow. This is the call to use if your
|
||||
// unit test does not use interfaces.
|
||||
mDNSexport mStatus init_mdns_storage()
|
||||
{
|
||||
mDNS *m = &mDNSStorage;
|
||||
|
||||
init_logging_ut();
|
||||
mDNS_LoggingEnabled = 1;
|
||||
mDNS_PacketLoggingEnabled = 1;
|
||||
|
||||
mStatus result = mDNS_InitStorage_ut(m, &PlatformStorage, gRrcachestorage, RR_CACHE_SIZE, mDNSfalse, mDNSNULL, mDNSNULL);
|
||||
if (result != mStatus_NoError)
|
||||
return result;
|
||||
|
||||
return mStatus_NoError;
|
||||
}
|
||||
|
||||
mDNSlocal void init_client_request(request_state* req, char *msgbuf, size_t msgSize, uint32_t op)
|
||||
{
|
||||
// Simulate read_msg behavior since unit test does not open a socket
|
||||
memset(req, 0, sizeof(request_state));
|
||||
|
||||
req->ts = t_complete;
|
||||
req->msgbuf = mDNSNULL;
|
||||
req->msgptr = msgbuf;
|
||||
req->msgend = msgbuf + msgSize;
|
||||
|
||||
// The rest of the request values are set in order to simulate a request
|
||||
req->sd = client_req_sd;
|
||||
req->uid = client_req_uid;
|
||||
req->hdr_bytes = client_req_hdr_bytes;
|
||||
req->hdr.version = client_req_hdr_version;
|
||||
req->hdr.op = op; // query_request
|
||||
req->hdr.datalen = msgSize;
|
||||
req->data_bytes = msgSize;
|
||||
req->process_id = client_req_process_id;
|
||||
memcpy(req->pid_name, client_req_pid_name, strlen(client_req_pid_name));
|
||||
}
|
||||
|
||||
// This function calls the mDNSResponder handle_client_request() API. It initializes
|
||||
// the request and query data structures.
|
||||
mDNSexport mStatus start_client_request(request_state* req, char *msgbuf, size_t msgsz, uint32_t op, UDPSocket* socket)
|
||||
{
|
||||
// Process the unit test's client request
|
||||
init_client_request(req, msgbuf, msgsz, op);
|
||||
|
||||
mStatus result = handle_client_request_ut((void*)req);
|
||||
DNSQuestion* q = &req->u.queryrecord.q;
|
||||
q->LocalSocket = socket;
|
||||
return result;
|
||||
}
|
||||
|
||||
// This function calls the mDNSResponder mDNSCoreReceive() API.
|
||||
mDNSexport void receive_response(const request_state* req, DNSMessage *msg, size_t msgSize)
|
||||
{
|
||||
mDNS *m = &mDNSStorage;
|
||||
mDNSAddr srcaddr;
|
||||
mDNSIPPort srcport, dstport;
|
||||
const mDNSu8 * end;
|
||||
DNSQuestion *q = (DNSQuestion *)&req->u.queryrecord.q;
|
||||
UInt8* data = (UInt8*)msg;
|
||||
|
||||
// Used same values for DNS server as specified during init of unit test
|
||||
srcaddr.type = mDNSAddrType_IPv4;
|
||||
srcaddr.ip.v4.NotAnInteger = dns_server_ipv4.NotAnInteger;
|
||||
srcport.NotAnInteger = client_resp_src_port;
|
||||
|
||||
// Used random value for dstport
|
||||
dstport.NotAnInteger = swap16((mDNSu16)client_resp_dst_port);
|
||||
|
||||
// Set DNS message (that was copied from a WireShark packet)
|
||||
end = (const mDNSu8 *)msg + msgSize;
|
||||
|
||||
// Set socket info that mDNSCoreReceive uses to verify socket context
|
||||
q->LocalSocket->ss.port.NotAnInteger = swap16((mDNSu16)client_resp_dst_port);
|
||||
q->TargetQID.b[0] = data[0];
|
||||
q->TargetQID.b[1] = data[1];
|
||||
|
||||
// Execute mDNSCoreReceive which copies two DNS records into the cache
|
||||
mDNSCoreReceive(m, msg, end, &srcaddr, srcport, &primary_v4, dstport, primary_interfaceID);
|
||||
}
|
||||
|
||||
mDNSexport size_t get_reply_len(char* name, uint16_t rdlen)
|
||||
{
|
||||
size_t len = sizeof(DNSServiceFlags);
|
||||
len += sizeof(mDNSu32); // interface index
|
||||
len += sizeof(DNSServiceErrorType);
|
||||
len += strlen(name) + 1;
|
||||
len += 3 * sizeof(mDNSu16); // type, class, rdlen
|
||||
len += rdlen;
|
||||
len += sizeof(mDNSu32); // TTL
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
void free_req(request_state* req)
|
||||
{
|
||||
// Cleanup request's memory usage
|
||||
while (req->replies)
|
||||
{
|
||||
reply_state *reply = req->replies;
|
||||
req->replies = req->replies->next;
|
||||
mDNSPlatformMemFree(reply);
|
||||
}
|
||||
req->replies = NULL;
|
||||
mDNSPlatformMemFree(req);
|
||||
}
|
||||
|
||||
// Unit test support functions follow
|
||||
#define SA_LEN(addr) (((addr)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
|
||||
|
||||
mDNSexport void get_ip(const char *const name, struct sockaddr_storage *result)
|
||||
{
|
||||
struct addrinfo* aiList;
|
||||
int err = getaddrinfo(name, NULL, NULL, &aiList);
|
||||
if (err) fprintf(stderr, "getaddrinfo error %d for %s", err, name);
|
||||
else memcpy(result, aiList->ai_addr, SA_LEN(aiList->ai_addr));
|
||||
if (aiList) freeaddrinfo(aiList);
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef UNITTEST_COMMON_H
|
||||
#define UNITTEST_COMMON_H
|
||||
|
||||
#include "dns_sd.h"
|
||||
#include "uds_daemon.h"
|
||||
#include "uDNS.h"
|
||||
#include "dnssd_ipc.h"
|
||||
#include <netdb.h> // for getaddrinfo
|
||||
#include <net/if.h>
|
||||
#include <pthread.h>
|
||||
|
||||
// Primary interface info that is used when simulating the receive of the response packet
|
||||
extern mDNSInterfaceID primary_interfaceID;
|
||||
extern mDNSAddr primary_v4;
|
||||
extern mDNSAddr primary_v6;
|
||||
extern mDNSAddr primary_router;
|
||||
|
||||
// Arbitrary values to simulate a client_request request
|
||||
#define client_req_sd 12
|
||||
#define client_req_uid 502
|
||||
#define client_req_hdr_bytes 28
|
||||
#define client_req_hdr_version 1
|
||||
#define client_resp_src_port 13568
|
||||
#define client_resp_dst_port 49339
|
||||
#define uDNS_TargetQID 16745
|
||||
#define client_req_process_id 15418
|
||||
static char client_req_pid_name[MAXCOMLEN] = "mDNSUnitTest";
|
||||
|
||||
//Arbitrary values to simulate a DNS server
|
||||
#define dns_server_timeout 30
|
||||
#define dns_server_resGroupID 12
|
||||
static const mDNSv4Addr dns_server_ipv4 = {{ 192, 168, 1, 20 }};
|
||||
|
||||
extern mStatus init_mdns_environment(mDNSBool enableLogging);
|
||||
extern mStatus init_mdns_storage(void);
|
||||
extern size_t get_reply_len(char* name, uint16_t rdlen);
|
||||
extern mStatus start_client_request(request_state* req, char *msgbuf, size_t msgsz, uint32_t op, UDPSocket* socket);
|
||||
extern void receive_response(const request_state* req, DNSMessage *msg, size_t msgSize);
|
||||
extern void get_ip(const char *const name, struct sockaddr_storage *result);
|
||||
extern void free_req(request_state* req);
|
||||
|
||||
extern mStatus mDNS_InitStorage_ut(mDNS *const m, mDNS_PlatformSupport *const p,
|
||||
CacheEntity *rrcachestorage, mDNSu32 rrcachesize,
|
||||
mDNSBool AdvertiseLocalAddresses, mDNSCallback *Callback, void *Context);
|
||||
extern void init_logging_ut(void);
|
||||
extern void SetInterfaces_ut(mDNSInterfaceID* primary_interfaceID, mDNSAddr *primary_v4,
|
||||
mDNSAddr* primary_v6, mDNSAddr* primary_router);
|
||||
extern mStatus handle_client_request_ut(void *req);
|
||||
extern void LogCacheRecords_ut(mDNSs32 now, mDNSu32* retCacheUsed, mDNSu32* retCacheActive);
|
||||
extern int LogEtcHosts_ut(mDNS *const m);
|
||||
extern mDNSBool mDNSMacOSXCreateEtcHostsEntry_ut(const domainname *domain, const struct sockaddr *sa,
|
||||
const domainname *cname, char *ifname, AuthHash *auth);
|
||||
extern void UpdateEtcHosts_ut(void *context);
|
||||
extern mStatus ArpLogMsgTest(mDNS *const m, const ARP_EthIP *const arp, const mDNSInterfaceID InterfaceID);
|
||||
|
||||
|
||||
#endif /* UNITTEST_COMMON_H */
|
Loading…
Reference in New Issue