blob: 7c30207aab9078a6f3b47023eb148f56c3ad0331 [file] [log] [blame]
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __mDNSOSX_h
#define __mDNSOSX_h
#ifdef __cplusplus
extern "C" {
#endif
#include <SystemConfiguration/SystemConfiguration.h>
#include <IOKit/pwr_mgt/IOPM.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <IOKit/pwr_mgt/IOPMLibPrivate.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "mDNSEmbeddedAPI.h" // for domain name structure
//#define MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
#include <dispatch/dispatch.h>
#endif
typedef struct NetworkInterfaceInfoOSX_struct NetworkInterfaceInfoOSX;
typedef void (*KQueueEventCallback)(int fd, short filter, void *context);
typedef struct
{
KQueueEventCallback KQcallback;
void *KQcontext;
const char const *KQtask; // For debugging messages
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
dispatch_source_t readSource;
dispatch_source_t writeSource;
mDNSBool fdClosed;
#endif
} KQueueEntry;
typedef struct
{
mDNSIPPort port; // MUST BE FIRST FIELD -- UDPSocket_struct begins with a KQSocketSet,
// and mDNSCore requires every UDPSocket_struct to begin with a mDNSIPPort port
mDNS *m;
int sktv4;
KQueueEntry kqsv4;
#ifndef NO_IPV6
int sktv6;
KQueueEntry kqsv6;
#endif
int *closeFlag;
} KQSocketSet;
struct UDPSocket_struct
{
KQSocketSet ss; // First field of KQSocketSet has to be mDNSIPPort -- mDNSCore requires every UDPSocket_struct to begin with mDNSIPPort port
};
struct NetworkInterfaceInfoOSX_struct
{
NetworkInterfaceInfo ifinfo; // MUST be the first element in this structure
NetworkInterfaceInfoOSX *next;
mDNS *m;
mDNSu8 Exists; // 1 = currently exists in getifaddrs list; 0 = doesn't
// 2 = exists, but McastTxRx state changed
mDNSu8 Flashing; // Set if interface appeared for less than 60 seconds and then vanished
mDNSu8 Occulting; // Set if interface vanished for less than 60 seconds and then came back
mDNSu8 D2DInterface; // IFEF_LOCALNET_PRIVATE flag indicates we should call
// D2D plugin for operations over this interface
mDNSs32 AppearanceTime; // Time this interface appeared most recently in getifaddrs list
// i.e. the first time an interface is seen, AppearanceTime is set.
// If an interface goes away temporarily and then comes back then
// AppearanceTime is updated to the time of the most recent appearance.
mDNSs32 LastSeen; // If Exists==0, last time this interface appeared in getifaddrs list
unsigned int ifa_flags;
struct in_addr ifa_v4addr;
mDNSu32 scope_id; // interface index / IPv6 scope ID
mDNSEthAddr BSSID; // BSSID of 802.11 base station, if applicable
u_short sa_family;
int BPF_fd; // -1 uninitialized; -2 requested BPF; -3 failed
int BPF_mcfd; // Socket for our IPv6 ND group membership
u_int BPF_len;
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
dispatch_source_t BPF_source;
#else
CFSocketRef BPF_cfs;
CFRunLoopSourceRef BPF_rls;
#endif
NetworkInterfaceInfoOSX *Registered; // non-NULL means registered with mDNS Core
};
struct mDNS_PlatformSupport_struct
{
NetworkInterfaceInfoOSX *InterfaceList;
KQSocketSet permanentsockets;
domainlabel userhostlabel; // The hostlabel as it was set in System Preferences the last time we looked
domainlabel usernicelabel; // The nicelabel as it was set in System Preferences the last time we looked
// Following four variables are used for optimization where the helper is not
// invoked when not needed. It records the state of what we told helper the
// last time we invoked mDNSPreferencesSetName
domainlabel prevoldhostlabel; // Previous m->p->userhostlabel
domainlabel prevnewhostlabel; // Previous m->hostlabel
domainlabel prevoldnicelabel; // Previous m->p->usernicelabel
domainlabel prevnewnicelabel; // Previous m->nicelabel
mDNSs32 NotifyUser;
mDNSs32 HostNameConflict; // Time we experienced conflict on our link-local host name
mDNSs32 NetworkChanged;
mDNSs32 KeyChainTimer;
CFRunLoopRef CFRunLoop;
SCDynamicStoreRef Store;
CFRunLoopSourceRef StoreRLS;
CFRunLoopSourceRef PMRLS;
int SysEventNotifier;
KQueueEntry SysEventKQueue;
IONotificationPortRef PowerPortRef;
io_connect_t PowerConnection;
io_object_t PowerNotifier;
#ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
IOPMConnection IOPMConnection;
#endif
IOPMAssertionID IOPMAssertion;
long SleepCookie; // Cookie we need to pass to IOAllowPowerChange()
long WakeAtUTC;
mDNSs32 RequestReSleep;
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
dispatch_source_t timer;
dispatch_source_t custom;
#else
pthread_mutex_t BigMutex;
#endif
mDNSs32 BigMutexStartTime;
int WakeKQueueLoopFD;
};
extern int OfferSleepProxyService;
extern int DisableSleepProxyClient;
extern int UseInternalSleepProxy;
extern int OSXVers, iOSVers;
#define OSXVers_Base 4
#define OSXVers_10_0_Cheetah 4
#define OSXVers_10_1_Puma 5
#define OSXVers_10_2_Jaguar 6
#define OSXVers_10_3_Panther 7
#define OSXVers_10_4_Tiger 8
#define OSXVers_10_5_Leopard 9
#define OSXVers_10_6_SnowLeopard 10
extern int KQueueFD;
extern void NotifyOfElusiveBug(const char *title, const char *msg); // Both strings are UTF-8 text
extern void SetDomainSecrets(mDNS *m);
extern void mDNSMacOSXNetworkChanged(mDNS *const m);
extern void mDNSMacOSXSystemBuildNumber(char *HINFO_SWstring);
extern NetworkInterfaceInfoOSX *IfindexToInterfaceInfoOSX(const mDNS *const m, mDNSInterfaceID ifindex);
extern void mDNSUpdatePacketFilter(const ResourceRecord *const excludeRecord);
#ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
extern int KQueueSet(int fd, u_short flags, short filter, KQueueEntry *const entryRef);
mDNSexport void TriggerEventCompletion(void);
#else
extern int KQueueSet(int fd, u_short flags, short filter, const KQueueEntry *const entryRef);
#endif
// When events are processed on the non-kqueue thread (i.e. CFRunLoop notifications like Sleep/Wake,
// Interface changes, Keychain changes, etc.) they must use KQueueLock/KQueueUnlock to lock out the kqueue thread
extern void KQueueLock(mDNS *const m);
extern void KQueueUnlock(mDNS *const m, const char const *task);
extern void mDNSPlatformCloseFD(KQueueEntry *kq, int fd);
extern mDNSBool DictionaryIsEnabled(CFDictionaryRef dict);
extern void mDNSPlatformToggleInterfaceAdvt(mDNS *const m, mDNSBool stopAdvt);
// If any event takes more than WatchDogReportingThreshold milliseconds to be processed, we log a warning message
// General event categories are:
// o Mach client request initiated / terminated
// o UDS client request
// o Handling UDP packets received from the network
// o Environmental change events:
// - network interface changes
// - sleep/wake
// - keychain changes
// o Name conflict dialog dismissal
// o Reception of Unix signal (e.g. SIGINFO)
// o Idle task processing
// If we find that we're getting warnings for any of these categories, and it's not evident
// what's causing the problem, we may need to subdivide some categories into finer-grained
// sub-categories (e.g. "Idle task processing" covers a pretty broad range of sub-tasks).
extern int WatchDogReportingThreshold;
struct CompileTimeAssertionChecks_mDNSMacOSX
{
// 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
// cause structure sizes (and therefore memory usage) to balloon unreasonably.
char sizecheck_NetworkInterfaceInfoOSX[(sizeof(NetworkInterfaceInfoOSX) <= 7000) ? 1 : -1];
char sizecheck_mDNS_PlatformSupport [(sizeof(mDNS_PlatformSupport) <= 768) ? 1 : -1];
};
#ifdef __cplusplus
}
#endif
#endif