| @@ -1,339 +1,358 @@ | | | @@ -1,339 +1,358 @@ |
1 | /* -*- Mode: C; tab-width: 4 -*- | | 1 | /* -*- Mode: C; tab-width: 4 -*- |
2 | * | | 2 | * |
3 | * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved. | | 3 | * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved. |
4 | * | | 4 | * |
5 | * Licensed under the Apache License, Version 2.0 (the "License"); | | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
6 | * you may not use this file except in compliance with the License. | | 6 | * you may not use this file except in compliance with the License. |
7 | * You may obtain a copy of the License at | | 7 | * You may obtain a copy of the License at |
8 | * | | 8 | * |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | * | | 10 | * |
11 | * Unless required by applicable law or agreed to in writing, software | | 11 | * Unless required by applicable law or agreed to in writing, software |
12 | * distributed under the License is distributed on an "AS IS" BASIS, | | 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | * See the License for the specific language governing permissions and | | 14 | * See the License for the specific language governing permissions and |
15 | * limitations under the License. | | 15 | * limitations under the License. |
16 | | | 16 | |
17 | File: daemon.c | | 17 | File: daemon.c |
18 | | | 18 | |
19 | Contains: main & associated Application layer for mDNSResponder on Linux. | | 19 | Contains: main & associated Application layer for mDNSResponder on Linux. |
20 | | | 20 | |
21 | Change History (most recent first): | | 21 | Change History (most recent first): |
22 | | | 22 | |
23 | Log: PosixDaemon.c,v $ | | 23 | Log: PosixDaemon.c,v $ |
24 | Revision 1.49 2009/04/30 20:07:51 mcguire | | 24 | Revision 1.49 2009/04/30 20:07:51 mcguire |
25 | <rdar://problem/6822674> Support multiple UDSs from launchd | | 25 | <rdar://problem/6822674> Support multiple UDSs from launchd |
26 | | | 26 | |
27 | Revision 1.48 2009/04/11 01:43:28 jessic2 | | 27 | Revision 1.48 2009/04/11 01:43:28 jessic2 |
28 | <rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically | | 28 | <rdar://problem/4426780> Daemon: Should be able to turn on LogOperation dynamically |
29 | | | 29 | |
30 | Revision 1.47 2009/01/11 03:20:06 mkrochma | | 30 | Revision 1.47 2009/01/11 03:20:06 mkrochma |
31 | <rdar://problem/5797526> Fixes from Igor Seleznev to get mdnsd working on Solaris | | 31 | <rdar://problem/5797526> Fixes from Igor Seleznev to get mdnsd working on Solaris |
32 | | | 32 | |
33 | Revision 1.46 2008/11/03 23:09:15 cheshire | | 33 | Revision 1.46 2008/11/03 23:09:15 cheshire |
34 | Don't need to include mDNSDebug.h as well as mDNSEmbeddedAPI.h | | 34 | Don't need to include mDNSDebug.h as well as mDNSEmbeddedAPI.h |
35 | | | 35 | |
36 | Revision 1.45 2008/10/03 18:25:17 cheshire | | 36 | Revision 1.45 2008/10/03 18:25:17 cheshire |
37 | Instead of calling "m->MainCallback" function pointer directly, call mDNSCore routine "mDNS_ConfigChanged(m);" | | 37 | Instead of calling "m->MainCallback" function pointer directly, call mDNSCore routine "mDNS_ConfigChanged(m);" |
38 | | | 38 | |
39 | Revision 1.44 2008/09/15 23:52:30 cheshire | | 39 | Revision 1.44 2008/09/15 23:52:30 cheshire |
40 | <rdar://problem/6218902> mDNSResponder-177 fails to compile on Linux with .desc pseudo-op | | 40 | <rdar://problem/6218902> mDNSResponder-177 fails to compile on Linux with .desc pseudo-op |
41 | Made __crashreporter_info__ symbol conditional, so we only use it for OS X build | | 41 | Made __crashreporter_info__ symbol conditional, so we only use it for OS X build |
42 | | | 42 | |
43 | Revision 1.43 2007/10/22 20:05:34 cheshire | | 43 | Revision 1.43 2007/10/22 20:05:34 cheshire |
44 | Use mDNSPlatformSourceAddrForDest instead of FindSourceAddrForIP | | 44 | Use mDNSPlatformSourceAddrForDest instead of FindSourceAddrForIP |
45 | | | 45 | |
46 | Revision 1.42 2007/09/18 19:09:02 cheshire | | 46 | Revision 1.42 2007/09/18 19:09:02 cheshire |
47 | <rdar://problem/5489549> mDNSResponderHelper (and other binaries) missing SCCS version strings | | 47 | <rdar://problem/5489549> mDNSResponderHelper (and other binaries) missing SCCS version strings |
48 | | | 48 | |
49 | Revision 1.41 2007/09/04 17:02:25 cheshire | | 49 | Revision 1.41 2007/09/04 17:02:25 cheshire |
50 | <rdar://problem/5458929> False positives in changed files list in nightly builds | | 50 | <rdar://problem/5458929> False positives in changed files list in nightly builds |
51 | Added MDNS_VERSIONSTR_NODTS option at the reqest of Rishi Srivatsavai (Sun) | | 51 | Added MDNS_VERSIONSTR_NODTS option at the reqest of Rishi Srivatsavai (Sun) |
52 | | | 52 | |
53 | Revision 1.40 2007/07/31 23:08:34 mcguire | | 53 | Revision 1.40 2007/07/31 23:08:34 mcguire |
54 | <rdar://problem/5329542> BTMM: Make AutoTunnel mode work with multihoming | | 54 | <rdar://problem/5329542> BTMM: Make AutoTunnel mode work with multihoming |
55 | | | 55 | |
56 | Revision 1.39 2007/03/21 00:30:44 cheshire | | 56 | Revision 1.39 2007/03/21 00:30:44 cheshire |
57 | Remove obsolete mDNS_DeleteDNSServers() call | | 57 | Remove obsolete mDNS_DeleteDNSServers() call |
58 | | | 58 | |
59 | Revision 1.38 2007/02/14 01:58:19 cheshire | | 59 | Revision 1.38 2007/02/14 01:58:19 cheshire |
60 | <rdar://problem/4995831> Don't delete Unix Domain Socket on exit if we didn't create it on startup | | 60 | <rdar://problem/4995831> Don't delete Unix Domain Socket on exit if we didn't create it on startup |
61 | | | 61 | |
62 | Revision 1.37 2007/02/07 19:32:00 cheshire | | 62 | Revision 1.37 2007/02/07 19:32:00 cheshire |
63 | <rdar://problem/4980353> All mDNSResponder components should contain version strings in SCCS-compatible format | | 63 | <rdar://problem/4980353> All mDNSResponder components should contain version strings in SCCS-compatible format |
64 | | | 64 | |
65 | Revision 1.36 2007/02/06 19:06:48 cheshire | | 65 | Revision 1.36 2007/02/06 19:06:48 cheshire |
66 | <rdar://problem/3956518> Need to go native with launchd | | 66 | <rdar://problem/3956518> Need to go native with launchd |
67 | | | 67 | |
68 | Revision 1.35 2007/01/05 08:30:52 cheshire | | 68 | Revision 1.35 2007/01/05 08:30:52 cheshire |
69 | Trim excessive "Log" checkin history from before 2006 | | 69 | Trim excessive "Log" checkin history from before 2006 |
70 | (checkin history still available via "cvs log ..." of course) | | 70 | (checkin history still available via "cvs log ..." of course) |
71 | | | 71 | |
72 | Revision 1.34 2007/01/05 05:46:08 cheshire | | 72 | Revision 1.34 2007/01/05 05:46:08 cheshire |
73 | Add mDNS *const m parameter to udsserver_handle_configchange() | | 73 | Add mDNS *const m parameter to udsserver_handle_configchange() |
74 | | | 74 | |
75 | Revision 1.33 2006/12/21 00:10:53 cheshire | | 75 | Revision 1.33 2006/12/21 00:10:53 cheshire |
76 | Make mDNS_PlatformSupport PlatformStorage a static global instead of a stack variable | | 76 | Make mDNS_PlatformSupport PlatformStorage a static global instead of a stack variable |
77 | | | 77 | |
78 | Revision 1.32 2006/11/03 22:28:50 cheshire | | 78 | Revision 1.32 2006/11/03 22:28:50 cheshire |
79 | PosixDaemon needs to handle mStatus_ConfigChanged and mStatus_GrowCache messages | | 79 | PosixDaemon needs to handle mStatus_ConfigChanged and mStatus_GrowCache messages |
80 | | | 80 | |
81 | Revision 1.31 2006/08/14 23:24:46 cheshire | | 81 | Revision 1.31 2006/08/14 23:24:46 cheshire |
82 | Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0 | | 82 | Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0 |
83 | | | 83 | |
84 | Revision 1.30 2006/07/07 01:09:12 cheshire | | 84 | Revision 1.30 2006/07/07 01:09:12 cheshire |
85 | <rdar://problem/4472013> Add Private DNS server functionality to dnsextd | | 85 | <rdar://problem/4472013> Add Private DNS server functionality to dnsextd |
86 | Only use mallocL/freeL debugging routines when building mDNSResponder, not dnsextd | | 86 | Only use mallocL/freeL debugging routines when building mDNSResponder, not dnsextd |
87 | | | 87 | |
88 | */ | | 88 | */ |
89 | | | 89 | |
90 | #include <stdio.h> | | 90 | #include <stdio.h> |
91 | #include <string.h> | | 91 | #include <string.h> |
92 | #include <unistd.h> | | 92 | #include <unistd.h> |
93 | #include <stdlib.h> | | 93 | #include <stdlib.h> |
94 | #include <signal.h> | | 94 | #include <signal.h> |
95 | #include <errno.h> | | 95 | #include <errno.h> |
96 | #include <fcntl.h> | | 96 | #include <fcntl.h> |
97 | #include <pwd.h> | | 97 | #include <pwd.h> |
98 | #include <sys/types.h> | | 98 | #include <sys/types.h> |
99 | | | 99 | |
100 | #include "mDNSEmbeddedAPI.h" | | 100 | #include "mDNSEmbeddedAPI.h" |
101 | #include "mDNSPosix.h" | | 101 | #include "mDNSPosix.h" |
102 | #include "mDNSUNP.h" // For daemon() | | 102 | #include "mDNSUNP.h" // For daemon() |
103 | #include "uds_daemon.h" | | 103 | #include "uds_daemon.h" |
104 | #include "DNSCommon.h" | | 104 | #include "DNSCommon.h" |
105 | #include "PlatformCommon.h" | | 105 | #include "PlatformCommon.h" |
106 | | | 106 | |
107 | #ifndef MDNSD_USER | | 107 | #ifndef MDNSD_USER |
108 | #define MDNSD_USER "nobody" | | 108 | #define MDNSD_USER "nobody" |
109 | #endif | | 109 | #endif |
110 | | | 110 | |
111 | #define CONFIG_FILE "/etc/mdnsd.conf" | | 111 | #define CONFIG_FILE "/etc/mdnsd.conf" |
112 | static domainname DynDNSZone; // Default wide-area zone for service registration | | 112 | static domainname DynDNSZone; // Default wide-area zone for service registration |
113 | static domainname DynDNSHostname; | | 113 | static domainname DynDNSHostname; |
114 | | | 114 | |
115 | #define RR_CACHE_SIZE 500 | | 115 | #define RR_CACHE_SIZE 500 |
116 | static CacheEntity gRRCache[RR_CACHE_SIZE]; | | 116 | static CacheEntity gRRCache[RR_CACHE_SIZE]; |
117 | static mDNS_PlatformSupport PlatformStorage; | | 117 | static mDNS_PlatformSupport PlatformStorage; |
118 | | | 118 | |
119 | mDNSlocal void mDNS_StatusCallback(mDNS *const m, mStatus result) | | 119 | mDNSlocal void mDNS_StatusCallback(mDNS *const m, mStatus result) |
120 | { | | 120 | { |
121 | (void)m; // Unused | | 121 | (void)m; // Unused |
122 | if (result == mStatus_NoError) | | 122 | if (result == mStatus_NoError) |
123 | { | | 123 | { |
124 | // On successful registration of dot-local mDNS host name, daemon may want to check if | | 124 | // On successful registration of dot-local mDNS host name, daemon may want to check if |
125 | // any name conflict and automatic renaming took place, and if so, record the newly negotiated | | 125 | // any name conflict and automatic renaming took place, and if so, record the newly negotiated |
126 | // name in persistent storage for next time. It should also inform the user of the name change. | | 126 | // name in persistent storage for next time. It should also inform the user of the name change. |
127 | // On Mac OS X we store the current dot-local mDNS host name in the SCPreferences store, | | 127 | // On Mac OS X we store the current dot-local mDNS host name in the SCPreferences store, |
128 | // and notify the user with a CFUserNotification. | | 128 | // and notify the user with a CFUserNotification. |
129 | } | | 129 | } |
130 | else if (result == mStatus_ConfigChanged) | | 130 | else if (result == mStatus_ConfigChanged) |
131 | { | | 131 | { |
132 | udsserver_handle_configchange(m); | | 132 | udsserver_handle_configchange(m); |
133 | } | | 133 | } |
134 | else if (result == mStatus_GrowCache) | | 134 | else if (result == mStatus_GrowCache) |
135 | { | | 135 | { |
136 | // Allocate another chunk of cache storage | | 136 | // Allocate another chunk of cache storage |
137 | CacheEntity *storage = malloc(sizeof(CacheEntity) * RR_CACHE_SIZE); | | 137 | CacheEntity *storage = malloc(sizeof(CacheEntity) * RR_CACHE_SIZE); |
138 | if (storage) mDNS_GrowCache(m, storage, RR_CACHE_SIZE); | | 138 | if (storage) mDNS_GrowCache(m, storage, RR_CACHE_SIZE); |
139 | } | | 139 | } |
140 | } | | 140 | } |
141 | | | 141 | |
142 | // %%% Reconfigure() probably belongs in the platform support layer (mDNSPosix.c), not the daemon cde | | 142 | // %%% Reconfigure() probably belongs in the platform support layer (mDNSPosix.c), not the daemon cde |
143 | // -- all client layers running on top of mDNSPosix.c need to handle network configuration changes, | | 143 | // -- all client layers running on top of mDNSPosix.c need to handle network configuration changes, |
144 | // not only the Unix Domain Socket Daemon | | 144 | // not only the Unix Domain Socket Daemon |
145 | | | 145 | |
146 | static void Reconfigure(mDNS *m) | | 146 | static void Reconfigure(mDNS *m) |
147 | { | | 147 | { |
148 | mDNSAddr DynDNSIP; | | 148 | mDNSAddr DynDNSIP; |
149 | const mDNSAddr dummy = { mDNSAddrType_IPv4, { { { 1, 1, 1, 1 } } } };; | | 149 | const mDNSAddr dummy = { mDNSAddrType_IPv4, { { { 1, 1, 1, 1 } } } };; |
150 | mDNS_SetPrimaryInterfaceInfo(m, NULL, NULL, NULL); | | 150 | mDNS_SetPrimaryInterfaceInfo(m, NULL, NULL, NULL); |
151 | mDNS_Lock(m); | | 151 | mDNS_Lock(m); |
152 | if (ParseDNSServers(m, uDNS_SERVERS_FILE) < 0) | | 152 | if (ParseDNSServers(m, uDNS_SERVERS_FILE) < 0) |
153 | LogMsg("Unable to parse DNS server list. Unicast DNS-SD unavailable"); | | 153 | LogMsg("Unable to parse DNS server list. Unicast DNS-SD unavailable"); |
154 | mDNS_Unlock(m); | | 154 | mDNS_Unlock(m); |
155 | ReadDDNSSettingsFromConfFile(m, CONFIG_FILE, &DynDNSHostname, &DynDNSZone, NULL); | | 155 | ReadDDNSSettingsFromConfFile(m, CONFIG_FILE, &DynDNSHostname, &DynDNSZone, NULL); |
156 | mDNSPlatformSourceAddrForDest(&DynDNSIP, &dummy); | | 156 | mDNSPlatformSourceAddrForDest(&DynDNSIP, &dummy); |
157 | if (DynDNSHostname.c[0]) mDNS_AddDynDNSHostName(m, &DynDNSHostname, NULL, NULL); | | 157 | if (DynDNSHostname.c[0]) mDNS_AddDynDNSHostName(m, &DynDNSHostname, NULL, NULL); |
158 | if (DynDNSIP.type) mDNS_SetPrimaryInterfaceInfo(m, &DynDNSIP, NULL, NULL); | | 158 | if (DynDNSIP.type) mDNS_SetPrimaryInterfaceInfo(m, &DynDNSIP, NULL, NULL); |
159 | mDNS_ConfigChanged(m); | | 159 | mDNS_ConfigChanged(m); |
160 | } | | 160 | } |
161 | | | 161 | |
162 | // Do appropriate things at startup with command line arguments. Calls exit() if unhappy. | | 162 | // Do appropriate things at startup with command line arguments. Calls exit() if unhappy. |
163 | mDNSlocal void ParseCmdLinArgs(int argc, char **argv) | | 163 | mDNSlocal void ParseCmdLinArgs(int argc, char **argv) |
164 | { | | 164 | { |
165 | if (argc > 1) | | 165 | if (argc > 1) |
166 | { | | 166 | { |
167 | if (0 == strcmp(argv[1], "-debug")) mDNS_DebugMode = mDNStrue; | | 167 | if (0 == strcmp(argv[1], "-debug")) mDNS_DebugMode = mDNStrue; |
168 | else printf("Usage: %s [-debug]\n", argv[0]); | | 168 | else printf("Usage: %s [-debug]\n", argv[0]); |
169 | } | | 169 | } |
170 | | | 170 | |
171 | if (!mDNS_DebugMode) | | 171 | if (!mDNS_DebugMode) |
172 | { | | 172 | { |
173 | int result = daemon(0, 0); | | 173 | int result = daemon(0, 0); |
174 | if (result != 0) { LogMsg("Could not run as daemon - exiting"); exit(result); } | | 174 | if (result != 0) { LogMsg("Could not run as daemon - exiting"); exit(result); } |
175 | #if __APPLE__ | | 175 | #if __APPLE__ |
176 | LogMsg("The POSIX mdnsd should only be used on OS X for testing - exiting"); | | 176 | LogMsg("The POSIX mdnsd should only be used on OS X for testing - exiting"); |
177 | exit(-1); | | 177 | exit(-1); |
178 | #endif | | 178 | #endif |
179 | } | | 179 | } |
180 | } | | 180 | } |
181 | | | 181 | |
182 | mDNSlocal void DumpStateLog(mDNS *const m) | | 182 | mDNSlocal void DumpStateLog(mDNS *const m) |
183 | // Dump a little log of what we've been up to. | | 183 | // Dump a little log of what we've been up to. |
184 | { | | 184 | { |
185 | DNSServer *s; | | 185 | DNSServer *s; |
186 | | | 186 | |
187 | LogMsg("---- BEGIN STATE LOG ----"); | | 187 | LogMsg("---- BEGIN STATE LOG ----"); |
188 | udsserver_info(m); | | 188 | udsserver_info(m); |
189 | | | 189 | |
190 | LogMsgNoIdent("--------- DNS Servers ----------"); | | 190 | LogMsgNoIdent("--------- DNS Servers ----------"); |
191 | if (!mDNSStorage.DNSServers) LogMsgNoIdent("<None>"); | | 191 | if (!mDNSStorage.DNSServers) LogMsgNoIdent("<None>"); |
192 | else | | 192 | else |
193 | { | | 193 | { |
194 | for (s = m->DNSServers; s; s = s->next) | | 194 | for (s = m->DNSServers; s; s = s->next) |
195 | { | | 195 | { |
196 | LogMsgNoIdent("DNS Server %##s %#a:%d %s", | | 196 | LogMsgNoIdent("DNS Server %##s %#a:%d %s", |
197 | s->domain.c, &s->addr, mDNSVal16(s->port), | | 197 | s->domain.c, &s->addr, mDNSVal16(s->port), |
198 | s->teststate == DNSServer_Untested ? "(Untested)" : | | 198 | s->teststate == DNSServer_Untested ? "(Untested)" : |
199 | s->teststate == DNSServer_Passed ? "" : | | 199 | s->teststate == DNSServer_Passed ? "" : |
200 | s->teststate == DNSServer_Failed ? "(Failed)" : | | 200 | s->teststate == DNSServer_Failed ? "(Failed)" : |
201 | s->teststate == DNSServer_Disabled ? "(Disabled)" : "(Unknown state)"); | | 201 | s->teststate == DNSServer_Disabled ? "(Disabled)" : "(Unknown state)"); |
202 | } | | 202 | } |
203 | } | | 203 | } |
204 | | | 204 | |
205 | LogMsg("---- END STATE LOG ----"); | | 205 | LogMsg("---- END STATE LOG ----"); |
206 | } | | 206 | } |
207 | | | 207 | |
208 | mDNSlocal mStatus MainLoop(mDNS *m) // Loop until we quit. | | 208 | mDNSlocal mStatus MainLoop(mDNS *m) // Loop until we quit. |
209 | { | | 209 | { |
210 | sigset_t signals; | | 210 | sigset_t signals; |
211 | mDNSBool gotData = mDNSfalse; | | 211 | mDNSBool gotData = mDNSfalse; |
212 | | | 212 | |
213 | mDNSPosixListenForSignalInEventLoop(SIGINT); | | 213 | mDNSPosixListenForSignalInEventLoop(SIGINT); |
214 | mDNSPosixListenForSignalInEventLoop(SIGTERM); | | 214 | mDNSPosixListenForSignalInEventLoop(SIGTERM); |
215 | mDNSPosixListenForSignalInEventLoop(SIGUSR1); | | 215 | mDNSPosixListenForSignalInEventLoop(SIGUSR1); |
| | | 216 | #ifdef HAVE_SIGINFO |
| | | 217 | mDNSPosixListenForSignalInEventLoop(SIGUSR2); |
| | | 218 | mDNSPosixListenForSignalInEventLoop(SIGINFO); |
| | | 219 | #endif |
216 | mDNSPosixListenForSignalInEventLoop(SIGPIPE); | | 220 | mDNSPosixListenForSignalInEventLoop(SIGPIPE); |
217 | mDNSPosixListenForSignalInEventLoop(SIGHUP) ; | | 221 | mDNSPosixListenForSignalInEventLoop(SIGHUP) ; |
218 | | | 222 | |
219 | for (; ;) | | 223 | for (; ;) |
220 | { | | 224 | { |
221 | // Work out how long we expect to sleep before the next scheduled task | | 225 | // Work out how long we expect to sleep before the next scheduled task |
222 | struct timeval timeout; | | 226 | struct timeval timeout; |
223 | mDNSs32 ticks; | | 227 | mDNSs32 ticks; |
224 | | | 228 | |
225 | // Only idle if we didn't find any data the last time around | | 229 | // Only idle if we didn't find any data the last time around |
226 | if (!gotData) | | 230 | if (!gotData) |
227 | { | | 231 | { |
228 | mDNSs32 nextTimerEvent = mDNS_Execute(m); | | 232 | mDNSs32 nextTimerEvent = mDNS_Execute(m); |
229 | nextTimerEvent = udsserver_idle(nextTimerEvent); | | 233 | nextTimerEvent = udsserver_idle(nextTimerEvent); |
230 | ticks = nextTimerEvent - mDNS_TimeNow(m); | | 234 | ticks = nextTimerEvent - mDNS_TimeNow(m); |
231 | if (ticks < 1) ticks = 1; | | 235 | if (ticks < 1) ticks = 1; |
232 | } | | 236 | } |
233 | else // otherwise call EventLoop again with 0 timemout | | 237 | else // otherwise call EventLoop again with 0 timemout |
234 | ticks = 0; | | 238 | ticks = 0; |
235 | | | 239 | |
236 | timeout.tv_sec = ticks / mDNSPlatformOneSecond; | | 240 | timeout.tv_sec = ticks / mDNSPlatformOneSecond; |
237 | timeout.tv_usec = (ticks % mDNSPlatformOneSecond) * 1000000 / mDNSPlatformOneSecond; | | 241 | timeout.tv_usec = (ticks % mDNSPlatformOneSecond) * 1000000 / mDNSPlatformOneSecond; |
238 | | | 242 | |
239 | (void) mDNSPosixRunEventLoopOnce(m, &timeout, &signals, &gotData); | | 243 | (void) mDNSPosixRunEventLoopOnce(m, &timeout, &signals, &gotData); |
240 | | | 244 | |
241 | if (sigismember(&signals, SIGHUP )) Reconfigure(m); | | 245 | if (sigismember(&signals, SIGHUP )) Reconfigure(m); |
| | | 246 | #ifdef HAVE_SIGINFO |
| | | 247 | /* use OSX-compatible signals since we can, and gain enhanced debugging */ |
| | | 248 | if (sigismember(&signals, SIGINFO)) DumpStateLog(m); |
| | | 249 | if (sigismember(&signals, SIGUSR1)) |
| | | 250 | { |
| | | 251 | mDNS_LoggingEnabled = mDNS_LoggingEnabled ? 0 : 1; |
| | | 252 | LogMsg("SIGUSR1: Logging %s", mDNS_LoggingEnabled ? "Enabled" : "Disabled"); |
| | | 253 | } |
| | | 254 | if (sigismember(&signals, SIGUSR2)) |
| | | 255 | { |
| | | 256 | mDNS_PacketLoggingEnabled = mDNS_PacketLoggingEnabled ? 0 : 1; |
| | | 257 | LogMsg("SIGUSR2: Packet Logging %s", mDNS_PacketLoggingEnabled ? "Enabled" : "Disabled"); |
| | | 258 | } |
| | | 259 | #else |
242 | if (sigismember(&signals, SIGUSR1)) DumpStateLog(m); | | 260 | if (sigismember(&signals, SIGUSR1)) DumpStateLog(m); |
| | | 261 | #endif |
243 | // SIGPIPE happens when we try to write to a dead client; death should be detected soon in request_callback() and cleaned up. | | 262 | // SIGPIPE happens when we try to write to a dead client; death should be detected soon in request_callback() and cleaned up. |
244 | if (sigismember(&signals, SIGPIPE)) LogMsg("Received SIGPIPE - ignoring"); | | 263 | if (sigismember(&signals, SIGPIPE)) LogMsg("Received SIGPIPE - ignoring"); |
245 | if (sigismember(&signals, SIGINT) || sigismember(&signals, SIGTERM)) break; | | 264 | if (sigismember(&signals, SIGINT) || sigismember(&signals, SIGTERM)) break; |
246 | } | | 265 | } |
247 | return EINTR; | | 266 | return EINTR; |
248 | } | | 267 | } |
249 | | | 268 | |
250 | int main(int argc, char **argv) | | 269 | int main(int argc, char **argv) |
251 | { | | 270 | { |
252 | mStatus err; | | 271 | mStatus err; |
253 | | | 272 | |
254 | ParseCmdLinArgs(argc, argv); | | 273 | ParseCmdLinArgs(argc, argv); |
255 | | | 274 | |
256 | LogMsg("%s starting", mDNSResponderVersionString); | | 275 | LogMsg("%s starting", mDNSResponderVersionString); |
257 | | | 276 | |
258 | err = mDNS_Init(&mDNSStorage, &PlatformStorage, gRRCache, RR_CACHE_SIZE, mDNS_Init_AdvertiseLocalAddresses, | | 277 | err = mDNS_Init(&mDNSStorage, &PlatformStorage, gRRCache, RR_CACHE_SIZE, mDNS_Init_AdvertiseLocalAddresses, |
259 | mDNS_StatusCallback, mDNS_Init_NoInitCallbackContext); | | 278 | mDNS_StatusCallback, mDNS_Init_NoInitCallbackContext); |
260 | | | 279 | |
261 | if (mStatus_NoError == err) | | 280 | if (mStatus_NoError == err) |
262 | err = udsserver_init(mDNSNULL, 0); | | 281 | err = udsserver_init(mDNSNULL, 0); |
263 | | | 282 | |
264 | Reconfigure(&mDNSStorage); | | 283 | Reconfigure(&mDNSStorage); |
265 | | | 284 | |
266 | // Now that we're finished with anything privileged, switch over to running as "nobody" | | 285 | // Now that we're finished with anything privileged, switch over to running as "nobody" |
267 | if (mStatus_NoError == err) | | 286 | if (mStatus_NoError == err) |
268 | { | | 287 | { |
269 | const struct passwd *pw = getpwnam(MDNSD_USER); | | 288 | const struct passwd *pw = getpwnam(MDNSD_USER); |
270 | if (pw != NULL) | | 289 | if (pw != NULL) |
271 | { | | 290 | { |
272 | setgid(pw->pw_gid); | | 291 | setgid(pw->pw_gid); |
273 | setuid(pw->pw_uid); | | 292 | setuid(pw->pw_uid); |
274 | } | | 293 | } |
275 | else | | 294 | else |
276 | #ifdef MDNSD_NOROOT | | 295 | #ifdef MDNSD_NOROOT |
277 | { | | 296 | { |
278 | LogMsg("WARNING: mdnsd exiting because user \""MDNSD_USER"\" does not exist"); | | 297 | LogMsg("WARNING: mdnsd exiting because user \""MDNSD_USER"\" does not exist"); |
279 | err = mStatus_Invalid; | | 298 | err = mStatus_Invalid; |
280 | } | | 299 | } |
281 | #else | | 300 | #else |
282 | LogMsg("WARNING: mdnsd continuing as root because user \""MDNSD_USER"\" does not exist"); | | 301 | LogMsg("WARNING: mdnsd continuing as root because user \""MDNSD_USER"\" does not exist"); |
283 | #endif | | 302 | #endif |
284 | } | | 303 | } |
285 | | | 304 | |
286 | if (mStatus_NoError == err) | | 305 | if (mStatus_NoError == err) |
287 | err = MainLoop(&mDNSStorage); | | 306 | err = MainLoop(&mDNSStorage); |
288 | | | 307 | |
289 | LogMsg("%s stopping", mDNSResponderVersionString); | | 308 | LogMsg("%s stopping", mDNSResponderVersionString); |
290 | | | 309 | |
291 | mDNS_Close(&mDNSStorage); | | 310 | mDNS_Close(&mDNSStorage); |
292 | | | 311 | |
293 | if (udsserver_exit() < 0) | | 312 | if (udsserver_exit() < 0) |
294 | LogMsg("ExitCallback: udsserver_exit failed"); | | 313 | LogMsg("ExitCallback: udsserver_exit failed"); |
295 | | | 314 | |
296 | #if MDNS_DEBUGMSGS > 0 | | 315 | #if MDNS_DEBUGMSGS > 0 |
297 | printf("mDNSResponder exiting normally with %ld\n", err); | | 316 | printf("mDNSResponder exiting normally with %ld\n", err); |
298 | #endif | | 317 | #endif |
299 | | | 318 | |
300 | return err; | | 319 | return err; |
301 | } | | 320 | } |
302 | | | 321 | |
303 | // uds_daemon support //////////////////////////////////////////////////////////// | | 322 | // uds_daemon support //////////////////////////////////////////////////////////// |
304 | | | 323 | |
305 | mStatus udsSupportAddFDToEventLoop(int fd, udsEventCallback callback, void *context) | | 324 | mStatus udsSupportAddFDToEventLoop(int fd, udsEventCallback callback, void *context) |
306 | /* Support routine for uds_daemon.c */ | | 325 | /* Support routine for uds_daemon.c */ |
307 | { | | 326 | { |
308 | // Depends on the fact that udsEventCallback == mDNSPosixEventCallback | | 327 | // Depends on the fact that udsEventCallback == mDNSPosixEventCallback |
309 | return mDNSPosixAddFDToEventLoop(fd, callback, context); | | 328 | return mDNSPosixAddFDToEventLoop(fd, callback, context); |
310 | } | | 329 | } |
311 | | | 330 | |
312 | mStatus udsSupportRemoveFDFromEventLoop(int fd) // Note: This also CLOSES the file descriptor | | 331 | mStatus udsSupportRemoveFDFromEventLoop(int fd) // Note: This also CLOSES the file descriptor |
313 | { | | 332 | { |
314 | mStatus err = mDNSPosixRemoveFDFromEventLoop(fd); | | 333 | mStatus err = mDNSPosixRemoveFDFromEventLoop(fd); |
315 | close(fd); | | 334 | close(fd); |
316 | return err; | | 335 | return err; |
317 | } | | 336 | } |
318 | | | 337 | |
319 | mDNSexport void RecordUpdatedNiceLabel(mDNS *const m, mDNSs32 delay) | | 338 | mDNSexport void RecordUpdatedNiceLabel(mDNS *const m, mDNSs32 delay) |
320 | { | | 339 | { |
321 | (void)m; | | 340 | (void)m; |
322 | (void)delay; | | 341 | (void)delay; |
323 | // No-op, for now | | 342 | // No-op, for now |
324 | } | | 343 | } |
325 | | | 344 | |
326 | #if _BUILDING_XCODE_PROJECT_ | | 345 | #if _BUILDING_XCODE_PROJECT_ |
327 | // If the process crashes, then this string will be magically included in the automatically-generated crash log | | 346 | // If the process crashes, then this string will be magically included in the automatically-generated crash log |
328 | const char *__crashreporter_info__ = mDNSResponderVersionString_SCCS + 5; | | 347 | const char *__crashreporter_info__ = mDNSResponderVersionString_SCCS + 5; |
329 | asm(".desc ___crashreporter_info__, 0x10"); | | 348 | asm(".desc ___crashreporter_info__, 0x10"); |
330 | #endif | | 349 | #endif |
331 | | | 350 | |
332 | // For convenience when using the "strings" command, this is the last thing in the file | | 351 | // For convenience when using the "strings" command, this is the last thing in the file |
333 | #if mDNSResponderVersion > 1 | | 352 | #if mDNSResponderVersion > 1 |
334 | mDNSexport const char mDNSResponderVersionString_SCCS[] = "@(#) mDNSResponder-" STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")"; | | 353 | mDNSexport const char mDNSResponderVersionString_SCCS[] = "@(#) mDNSResponder-" STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")"; |
335 | #elif MDNS_VERSIONSTR_NODTS | | 354 | #elif MDNS_VERSIONSTR_NODTS |
336 | mDNSexport const char mDNSResponderVersionString_SCCS[] = "@(#) mDNSResponder (Engineering Build)"; | | 355 | mDNSexport const char mDNSResponderVersionString_SCCS[] = "@(#) mDNSResponder (Engineering Build)"; |
337 | #else | | 356 | #else |
338 | mDNSexport const char mDNSResponderVersionString_SCCS[] = "@(#) mDNSResponder (Engineering Build) (" __DATE__ " " __TIME__ ")"; | | 357 | mDNSexport const char mDNSResponderVersionString_SCCS[] = "@(#) mDNSResponder (Engineering Build) (" __DATE__ " " __TIME__ ")"; |
339 | #endif | | 358 | #endif |