Print this page
7120 mDNS resync was not wsdiff safe
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libdns_sd/java/common/JNISupport.c
+++ new/usr/src/lib/libdns_sd/java/common/JNISupport.c
1 1 /* -*- Mode: C; tab-width: 4 -*-
2 2 *
3 3 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
4 4 *
5 5 * Licensed under the Apache License, Version 2.0 (the "License");
6 6 * you may not use this file except in compliance with the License.
7 7 * You may obtain a copy of the License at
8 8 *
9 9 * http://www.apache.org/licenses/LICENSE-2.0
10 10 *
11 11 * Unless required by applicable law or agreed to in writing, software
12 12 * distributed under the License is distributed on an "AS IS" BASIS,
13 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 14 * See the License for the specific language governing permissions and
15 15 * limitations under the License.
16 16
17 17 This file contains the platform support for DNSSD and related Java classes.
18 18 It is used to shim through to the underlying <dns_sd.h> API.
19 19 */
20 20
21 21 // AUTO_CALLBACKS should be set to 1 if the underlying mDNS implementation fires response
22 22 // callbacks automatically (as in the early Windows prototypes).
23 23 // AUTO_CALLBACKS should be set to 0 if the client must call DNSServiceProcessResult() to
24 24 // invoke response callbacks (as is true on Mac OS X, Posix, Windows, etc.).
25 25 // (Invoking callbacks automatically on a different thread sounds attractive, but while
26 26 // the client gains by not needing to add an event source to its main event loop, it loses
27 27 // by being forced to deal with concurrency and locking, which can be a bigger burden.)
28 28 #ifndef AUTO_CALLBACKS
29 29 #define AUTO_CALLBACKS 0
30 30 #endif
31 31
32 32 #if !AUTO_CALLBACKS
33 33 #ifdef _WIN32
34 34 #include <winsock2.h>
35 35 #else //_WIN32
36 36 #include <sys/types.h>
37 37 #include <sys/select.h>
38 38 #endif // _WIN32
39 39 #endif // AUTO_CALLBACKS
40 40
41 41 #include <dns_sd.h>
42 42
43 43 #include <stdio.h>
44 44 #include <stdlib.h>
45 45 #include <string.h>
46 46 #ifdef _WIN32
47 47 #include <winsock2.h>
48 48 #include <iphlpapi.h>
49 49 static char * win32_if_indextoname( DWORD ifIndex, char * nameBuff);
50 50 static DWORD win32_if_nametoindex( const char * nameStr );
51 51 #define if_indextoname win32_if_indextoname
52 52 #define if_nametoindex win32_if_nametoindex
53 53 #define IF_NAMESIZE MAX_ADAPTER_NAME_LENGTH
54 54 #else // _WIN32
55 55 #include <sys/socket.h>
56 56 #include <net/if.h>
57 57 #endif // _WIN32
58 58
59 59 // When compiling with "-Wshadow" set, including jni.h produces the following error:
60 60 // /System/Library/Frameworks/JavaVM.framework/Versions/A/Headers/jni.h:609: warning: declaration of 'index' shadows a global declaration
61 61 // To work around this, we use the preprocessor to map the identifier 'index', which appears harmlessly in function prototype declarations,
62 62 // to something 'jni_index', which doesn't conflict
63 63 #define index jni_index
64 64 #include "DNSSD.java.h"
65 65 #undef index
66 66
67 67 //#include <syslog.h>
68 68
69 69 // convenience definition
70 70 #ifdef __GNUC__
71 71 #define _UNUSED __attribute__ ((unused))
72 72 #else
73 73 #define _UNUSED
74 74 #endif
75 75
76 76 enum {
77 77 kInterfaceVersionOne = 1,
78 78 kInterfaceVersionCurrent // Must match version in .jar file
79 79 };
80 80
81 81 typedef struct OpContext OpContext;
82 82
83 83 struct OpContext
84 84 {
85 85 DNSServiceRef ServiceRef;
86 86 JNIEnv *Env;
87 87 jobject JavaObj;
88 88 jobject ClientObj;
89 89 jmethodID Callback;
90 90 jmethodID Callback2;
91 91 };
92 92
93 93 // For AUTO_CALLBACKS, we must attach the callback thread to the Java VM prior to upcall.
94 94 #if AUTO_CALLBACKS
95 95 JavaVM *gJavaVM = NULL;
96 96 #endif
97 97
98 98
99 99 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_InitLibrary( JNIEnv *pEnv, jclass cls,
100 100 jint callerVersion)
101 101 {
102 102 /* Ensure that caller & interface versions match. */
103 103 if ( callerVersion != kInterfaceVersionCurrent)
104 104 return kDNSServiceErr_Incompatible;
105 105
106 106 #if AUTO_CALLBACKS
107 107 {
108 108 jsize numVMs;
109 109
110 110 if ( 0 != JNI_GetCreatedJavaVMs( &gJavaVM, 1, &numVMs))
111 111 return kDNSServiceErr_BadState;
112 112 }
113 113 #endif
114 114
115 115 // Set AppleDNSSD.hasAutoCallbacks
116 116 {
117 117 #if AUTO_CALLBACKS
118 118 jboolean hasAutoC = JNI_TRUE;
119 119 #else
120 120 jboolean hasAutoC = JNI_FALSE;
121 121 #endif
122 122 jfieldID hasAutoCField = (*pEnv)->GetStaticFieldID( pEnv, cls, "hasAutoCallbacks", "Z");
123 123 (*pEnv)->SetStaticBooleanField( pEnv, cls, hasAutoCField, hasAutoC);
124 124 }
125 125
126 126 return kDNSServiceErr_NoError;
127 127 }
128 128
129 129
130 130 static const char* SafeGetUTFChars( JNIEnv *pEnv, jstring str)
131 131 // Wrapper for JNI GetStringUTFChars() that returns NULL for null str.
132 132 {
133 133 return str != NULL ? (*pEnv)->GetStringUTFChars( pEnv, str, 0) : NULL;
134 134 }
135 135
136 136 static void SafeReleaseUTFChars( JNIEnv *pEnv, jstring str, const char *buff)
137 137 // Wrapper for JNI GetStringUTFChars() that handles null str.
138 138 {
139 139 if ( str != NULL)
140 140 (*pEnv)->ReleaseStringUTFChars( pEnv, str, buff);
141 141 }
142 142
143 143
144 144 #if AUTO_CALLBACKS
145 145 static void SetupCallbackState( JNIEnv **ppEnv)
146 146 {
147 147 (*gJavaVM)->AttachCurrentThread( gJavaVM, (void**) ppEnv, NULL);
148 148 }
149 149
150 150 static void TeardownCallbackState( void )
151 151 {
152 152 (*gJavaVM)->DetachCurrentThread( gJavaVM);
153 153 }
154 154
155 155 #else // AUTO_CALLBACKS
156 156
157 157 static void SetupCallbackState( JNIEnv **ppEnv _UNUSED)
158 158 {
159 159 // No setup necessary if ProcessResults() has been called
160 160 }
161 161
162 162 static void TeardownCallbackState( void )
163 163 {
164 164 // No teardown necessary if ProcessResults() has been called
165 165 }
166 166 #endif // AUTO_CALLBACKS
167 167
168 168
169 169 static OpContext *NewContext( JNIEnv *pEnv, jobject owner,
170 170 const char *callbackName, const char *callbackSig)
171 171 // Create and initialize a new OpContext.
172 172 {
173 173 OpContext *pContext = (OpContext*) malloc( sizeof *pContext);
174 174
175 175 if ( pContext != NULL)
176 176 {
177 177 jfieldID clientField = (*pEnv)->GetFieldID( pEnv, (*pEnv)->GetObjectClass( pEnv, owner),
178 178 "fListener", "Lcom/apple/dnssd/BaseListener;");
179 179
180 180 pContext->JavaObj = (*pEnv)->NewWeakGlobalRef( pEnv, owner); // must convert local ref to global to cache;
181 181 pContext->ClientObj = (*pEnv)->GetObjectField( pEnv, owner, clientField);
182 182 pContext->ClientObj = (*pEnv)->NewWeakGlobalRef( pEnv, pContext->ClientObj); // must convert local ref to global to cache
183 183 pContext->Callback = (*pEnv)->GetMethodID( pEnv,
184 184 (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj),
185 185 callbackName, callbackSig);
186 186 pContext->Callback2 = NULL; // not always used
187 187 }
188 188
189 189 return pContext;
190 190 }
191 191
192 192
193 193 static void ReportError( JNIEnv *pEnv, jobject target, jobject service, DNSServiceErrorType err)
194 194 // Invoke operationFailed() method on target with err.
195 195 {
196 196 jclass cls = (*pEnv)->GetObjectClass( pEnv, target);
197 197 jmethodID opFailed = (*pEnv)->GetMethodID( pEnv, cls, "operationFailed",
198 198 "(Lcom/apple/dnssd/DNSSDService;I)V");
199 199
200 200 (*pEnv)->CallVoidMethod( pEnv, target, opFailed, service, err);
201 201 }
202 202
203 203 JNIEXPORT void JNICALL Java_com_apple_dnssd_AppleService_HaltOperation( JNIEnv *pEnv, jobject pThis)
204 204 /* Deallocate the dns_sd service browser and set the Java object's fNativeContext field to 0. */
205 205 {
206 206 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
207 207 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
208 208
209 209 if ( contextField != 0)
210 210 {
211 211 OpContext *pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, pThis, contextField);
212 212 if ( pContext != NULL)
213 213 {
214 214 // MUST clear fNativeContext first, BEFORE calling DNSServiceRefDeallocate()
215 215 (*pEnv)->SetLongField(pEnv, pThis, contextField, 0);
216 216 if ( pContext->ServiceRef != NULL)
217 217 DNSServiceRefDeallocate( pContext->ServiceRef);
218 218
219 219 (*pEnv)->DeleteWeakGlobalRef( pEnv, pContext->JavaObj);
220 220 (*pEnv)->DeleteWeakGlobalRef( pEnv, pContext->ClientObj);
221 221 free( pContext);
222 222 }
223 223 }
224 224 }
225 225
226 226
227 227 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleService_BlockForData( JNIEnv *pEnv, jobject pThis)
228 228 /* Block until data arrives, or one second passes. Returns 1 if data present, 0 otherwise. */
229 229 {
230 230 // BlockForData() not supported with AUTO_CALLBACKS
231 231 #if !AUTO_CALLBACKS
232 232 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
233 233 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
234 234
235 235 if ( contextField != 0)
236 236 {
237 237 OpContext *pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, pThis, contextField);
238 238 if ( pContext != NULL)
239 239 {
240 240 fd_set readFDs;
241 241 int sd = DNSServiceRefSockFD( pContext->ServiceRef);
242 242 struct timeval timeout = { 1, 0 };
243 243 FD_ZERO( &readFDs);
244 244 FD_SET( sd, &readFDs);
245 245
246 246 // Q: Why do we poll here?
247 247 // A: Because there's no other thread-safe way to do it.
248 248 // Mac OS X terminates a select() call if you close one of the sockets it's listening on, but Linux does not,
249 249 // and arguably Linux is correct (See <http://www.ussg.iu.edu/hypermail/linux/kernel/0405.1/0418.html>)
250 250 // The problem is that the Mac OS X behaviour assumes that it's okay for one thread to close a socket while
251 251 // some other thread is monitoring that socket in select(), but the difficulty is that there's no general way
252 252 // to make that thread-safe, because there's no atomic way to enter select() and release a lock simultaneously.
253 253 // If we try to do this without holding any lock, then right as we jump to the select() routine,
254 254 // some other thread could stop our operation (thereby closing the socket),
255 255 // and then that thread (or even some third, unrelated thread)
256 256 // could do some other DNS-SD operation (or some other operation that opens a new file descriptor)
257 257 // and then we'd blindly resume our fall into the select() call, now blocking on a file descriptor
258 258 // that may coincidentally have the same numerical value, but is semantically unrelated
259 259 // to the true file descriptor we thought we were blocking on.
260 260 // We can't stop this race condition from happening, but at least if we wake up once a second we can detect
261 261 // when fNativeContext has gone to zero, and thereby discover that we were blocking on the wrong fd.
262 262
263 263 if (select( sd + 1, &readFDs, (fd_set*) NULL, (fd_set*) NULL, &timeout) == 1) return(1);
264 264 }
265 265 }
266 266 #endif // !AUTO_CALLBACKS
267 267 return(0);
268 268 }
269 269
270 270
271 271 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleService_ProcessResults( JNIEnv *pEnv, jobject pThis)
272 272 /* Call through to DNSServiceProcessResult() while data remains on socket. */
273 273 {
274 274 #if !AUTO_CALLBACKS // ProcessResults() not supported with AUTO_CALLBACKS
275 275
276 276 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
277 277 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
278 278 OpContext *pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, pThis, contextField);
279 279 DNSServiceErrorType err = kDNSServiceErr_BadState;
280 280
281 281 if ( pContext != NULL)
282 282 {
283 283 int sd = DNSServiceRefSockFD( pContext->ServiceRef);
284 284 fd_set readFDs;
285 285 struct timeval zeroTimeout = { 0, 0 };
286 286
287 287 pContext->Env = pEnv;
288 288
289 289 FD_ZERO( &readFDs);
290 290 FD_SET( sd, &readFDs);
291 291
292 292 err = kDNSServiceErr_NoError;
293 293 if (0 < select(sd + 1, &readFDs, (fd_set*) NULL, (fd_set*) NULL, &zeroTimeout))
294 294 {
295 295 err = DNSServiceProcessResult(pContext->ServiceRef);
296 296 // Use caution here!
297 297 // We cannot touch any data structures associated with this operation!
298 298 // The DNSServiceProcessResult() routine should have invoked our callback,
299 299 // and our callback could have terminated the operation with op.stop();
300 300 // and that means HaltOperation() will have been called, which frees pContext.
301 301 // Basically, from here we just have to get out without touching any stale
302 302 // data structures that could blow up on us! Particularly, any attempt
303 303 // to loop here reading more results from the file descriptor is unsafe.
304 304 }
305 305 }
306 306 return err;
307 307 #endif // AUTO_CALLBACKS
308 308 }
309 309
310 310
311 311 static void DNSSD_API ServiceBrowseReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
312 312 DNSServiceErrorType errorCode, const char *serviceName, const char *regtype,
313 313 const char *replyDomain, void *context)
314 314 {
315 315 OpContext *pContext = (OpContext*) context;
316 316
317 317 SetupCallbackState( &pContext->Env);
318 318
319 319 if ( pContext->ClientObj != NULL && pContext->Callback != NULL)
320 320 {
321 321 if ( errorCode == kDNSServiceErr_NoError)
322 322 {
323 323 (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj,
324 324 ( flags & kDNSServiceFlagsAdd) != 0 ? pContext->Callback : pContext->Callback2,
325 325 pContext->JavaObj, flags, interfaceIndex,
326 326 (*pContext->Env)->NewStringUTF( pContext->Env, serviceName),
327 327 (*pContext->Env)->NewStringUTF( pContext->Env, regtype),
328 328 (*pContext->Env)->NewStringUTF( pContext->Env, replyDomain));
329 329 }
330 330 else
331 331 ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
332 332 }
333 333
334 334 TeardownCallbackState();
335 335 }
336 336
337 337 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleBrowser_CreateBrowser( JNIEnv *pEnv, jobject pThis,
338 338 jint flags, jint ifIndex, jstring regType, jstring domain)
339 339 {
340 340 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
341 341 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
342 342 OpContext *pContext = NULL;
343 343 DNSServiceErrorType err = kDNSServiceErr_NoError;
344 344
345 345 if ( contextField != 0)
346 346 pContext = NewContext( pEnv, pThis, "serviceFound",
347 347 "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
348 348 else
349 349 err = kDNSServiceErr_BadParam;
350 350
351 351 if ( pContext != NULL)
352 352 {
353 353 const char *regStr = SafeGetUTFChars( pEnv, regType);
354 354 const char *domainStr = SafeGetUTFChars( pEnv, domain);
355 355
356 356 pContext->Callback2 = (*pEnv)->GetMethodID( pEnv,
357 357 (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj),
358 358 "serviceLost", "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
359 359
360 360 err = DNSServiceBrowse( &pContext->ServiceRef, flags, ifIndex, regStr, domainStr, ServiceBrowseReply, pContext);
361 361 if ( err == kDNSServiceErr_NoError)
362 362 {
363 363 (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
364 364 }
365 365
366 366 SafeReleaseUTFChars( pEnv, regType, regStr);
367 367 SafeReleaseUTFChars( pEnv, domain, domainStr);
368 368 }
369 369 else
370 370 err = kDNSServiceErr_NoMemory;
371 371
372 372 return err;
373 373 }
374 374
375 375
376 376 static void DNSSD_API ServiceResolveReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
377 377 DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget,
378 378 uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context)
379 379 {
380 380 OpContext *pContext = (OpContext*) context;
381 381 jclass txtCls;
382 382 jmethodID txtCtor;
383 383 jbyteArray txtBytes;
384 384 jobject txtObj;
385 385 jbyte *pBytes;
386 386
387 387 SetupCallbackState( &pContext->Env);
388 388
389 389 txtCls = (*pContext->Env)->FindClass( pContext->Env, "com/apple/dnssd/TXTRecord");
390 390 txtCtor = (*pContext->Env)->GetMethodID( pContext->Env, txtCls, "<init>", "([B)V");
391 391
392 392 if ( pContext->ClientObj != NULL && pContext->Callback != NULL && txtCtor != NULL &&
393 393 NULL != ( txtBytes = (*pContext->Env)->NewByteArray( pContext->Env, txtLen)))
394 394 {
395 395 if ( errorCode == kDNSServiceErr_NoError)
396 396 {
397 397 // Since Java ints are defined to be big-endian, we canonicalize 'port' from a 16-bit
398 398 // pattern into a number here.
399 399 port = ( ((unsigned char*) &port)[0] << 8) | ((unsigned char*) &port)[1];
400 400
401 401 // Initialize txtBytes with contents of txtRecord
402 402 pBytes = (*pContext->Env)->GetByteArrayElements( pContext->Env, txtBytes, NULL);
403 403 memcpy( pBytes, txtRecord, txtLen);
404 404 (*pContext->Env)->ReleaseByteArrayElements( pContext->Env, txtBytes, pBytes, JNI_COMMIT);
405 405
406 406 // Construct txtObj with txtBytes
407 407 txtObj = (*pContext->Env)->NewObject( pContext->Env, txtCls, txtCtor, txtBytes);
408 408 (*pContext->Env)->DeleteLocalRef( pContext->Env, txtBytes);
409 409
410 410 (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
411 411 pContext->JavaObj, flags, interfaceIndex,
412 412 (*pContext->Env)->NewStringUTF( pContext->Env, fullname),
413 413 (*pContext->Env)->NewStringUTF( pContext->Env, hosttarget),
414 414 port, txtObj);
415 415 }
416 416 else
417 417 ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
418 418 }
419 419
420 420 TeardownCallbackState();
421 421 }
422 422
423 423 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleResolver_CreateResolver( JNIEnv *pEnv, jobject pThis,
424 424 jint flags, jint ifIndex, jstring serviceName, jstring regType, jstring domain)
425 425 {
426 426 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
427 427 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
428 428 OpContext *pContext = NULL;
429 429 DNSServiceErrorType err = kDNSServiceErr_NoError;
430 430
431 431 if ( contextField != 0)
432 432 pContext = NewContext( pEnv, pThis, "serviceResolved",
433 433 "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;Ljava/lang/String;ILcom/apple/dnssd/TXTRecord;)V");
434 434 else
435 435 err = kDNSServiceErr_BadParam;
436 436
437 437 if ( pContext != NULL)
438 438 {
439 439 const char *servStr = SafeGetUTFChars( pEnv, serviceName);
440 440 const char *regStr = SafeGetUTFChars( pEnv, regType);
441 441 const char *domainStr = SafeGetUTFChars( pEnv, domain);
442 442
443 443 err = DNSServiceResolve( &pContext->ServiceRef, flags, ifIndex,
444 444 servStr, regStr, domainStr, ServiceResolveReply, pContext);
445 445 if ( err == kDNSServiceErr_NoError)
446 446 {
447 447 (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
448 448 }
449 449
450 450 SafeReleaseUTFChars( pEnv, serviceName, servStr);
451 451 SafeReleaseUTFChars( pEnv, regType, regStr);
452 452 SafeReleaseUTFChars( pEnv, domain, domainStr);
453 453 }
454 454 else
455 455 err = kDNSServiceErr_NoMemory;
456 456
457 457 return err;
458 458 }
459 459
460 460
461 461 static void DNSSD_API ServiceRegisterReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags,
462 462 DNSServiceErrorType errorCode, const char *serviceName,
463 463 const char *regType, const char *domain, void *context)
464 464 {
465 465 OpContext *pContext = (OpContext*) context;
466 466
467 467 SetupCallbackState( &pContext->Env);
468 468
469 469 if ( pContext->ClientObj != NULL && pContext->Callback != NULL)
470 470 {
471 471 if ( errorCode == kDNSServiceErr_NoError)
472 472 {
473 473 (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
474 474 pContext->JavaObj, flags,
475 475 (*pContext->Env)->NewStringUTF( pContext->Env, serviceName),
476 476 (*pContext->Env)->NewStringUTF( pContext->Env, regType),
477 477 (*pContext->Env)->NewStringUTF( pContext->Env, domain));
478 478 }
479 479 else
480 480 ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
481 481 }
482 482 TeardownCallbackState();
483 483 }
484 484
485 485 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRegistration_BeginRegister( JNIEnv *pEnv, jobject pThis,
486 486 jint ifIndex, jint flags, jstring serviceName, jstring regType,
487 487 jstring domain, jstring host, jint port, jbyteArray txtRecord)
488 488 {
489 489 //syslog(LOG_ERR, "BR");
490 490 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
491 491 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
492 492 OpContext *pContext = NULL;
493 493 DNSServiceErrorType err = kDNSServiceErr_NoError;
494 494 jbyte *pBytes;
495 495 jsize numBytes;
496 496
497 497 //syslog(LOG_ERR, "BR: contextField %d", contextField);
498 498
499 499 if ( contextField != 0)
500 500 pContext = NewContext( pEnv, pThis, "serviceRegistered",
501 501 "(Lcom/apple/dnssd/DNSSDRegistration;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
502 502 else
503 503 err = kDNSServiceErr_BadParam;
504 504
505 505 if ( pContext != NULL)
506 506 {
507 507 const char *servStr = SafeGetUTFChars( pEnv, serviceName);
508 508 const char *regStr = SafeGetUTFChars( pEnv, regType);
509 509 const char *domainStr = SafeGetUTFChars( pEnv, domain);
510 510 const char *hostStr = SafeGetUTFChars( pEnv, host);
511 511
512 512 //syslog(LOG_ERR, "BR: regStr %s", regStr);
513 513
514 514 // Since Java ints are defined to be big-endian, we de-canonicalize 'port' from a
515 515 // big-endian number into a 16-bit pattern here.
516 516 uint16_t portBits = port;
517 517 portBits = ( ((unsigned char*) &portBits)[0] << 8) | ((unsigned char*) &portBits)[1];
518 518
519 519 pBytes = txtRecord ? (*pEnv)->GetByteArrayElements( pEnv, txtRecord, NULL) : NULL;
520 520 numBytes = txtRecord ? (*pEnv)->GetArrayLength( pEnv, txtRecord) : 0;
521 521
522 522 err = DNSServiceRegister( &pContext->ServiceRef, flags, ifIndex, servStr, regStr,
523 523 domainStr, hostStr, portBits,
524 524 numBytes, pBytes, ServiceRegisterReply, pContext);
525 525 if ( err == kDNSServiceErr_NoError)
526 526 {
527 527 (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
528 528 }
529 529
530 530 if ( pBytes != NULL)
531 531 (*pEnv)->ReleaseByteArrayElements( pEnv, txtRecord, pBytes, 0);
532 532
533 533 SafeReleaseUTFChars( pEnv, serviceName, servStr);
534 534 SafeReleaseUTFChars( pEnv, regType, regStr);
535 535 SafeReleaseUTFChars( pEnv, domain, domainStr);
536 536 SafeReleaseUTFChars( pEnv, host, hostStr);
537 537 }
538 538 else
539 539 err = kDNSServiceErr_NoMemory;
540 540
541 541 return err;
542 542 }
543 543
544 544 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRegistration_AddRecord( JNIEnv *pEnv, jobject pThis,
545 545 jint flags, jint rrType, jbyteArray rData, jint ttl, jobject destObj)
546 546 {
547 547 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
548 548 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
549 549 jclass destCls = (*pEnv)->GetObjectClass( pEnv, destObj);
550 550 jfieldID recField = (*pEnv)->GetFieldID( pEnv, destCls, "fRecord", "J");
551 551 OpContext *pContext = NULL;
552 552 DNSServiceErrorType err = kDNSServiceErr_NoError;
553 553 jbyte *pBytes;
554 554 jsize numBytes;
555 555 DNSRecordRef recRef;
556 556
557 557 if ( contextField != 0)
558 558 pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, pThis, contextField);
559 559 if ( pContext == NULL || pContext->ServiceRef == NULL)
560 560 return kDNSServiceErr_BadParam;
561 561
562 562 pBytes = (*pEnv)->GetByteArrayElements( pEnv, rData, NULL);
563 563 numBytes = (*pEnv)->GetArrayLength( pEnv, rData);
564 564
565 565 err = DNSServiceAddRecord( pContext->ServiceRef, &recRef, flags, rrType, numBytes, pBytes, ttl);
566 566 if ( err == kDNSServiceErr_NoError)
567 567 {
568 568 (*pEnv)->SetLongField(pEnv, destObj, recField, (long) recRef);
569 569 }
570 570
571 571 if ( pBytes != NULL)
572 572 (*pEnv)->ReleaseByteArrayElements( pEnv, rData, pBytes, 0);
573 573
574 574 return err;
575 575 }
576 576
577 577 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSRecord_Update( JNIEnv *pEnv, jobject pThis,
578 578 jint flags, jbyteArray rData, jint ttl)
579 579 {
580 580 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
581 581 jfieldID ownerField = (*pEnv)->GetFieldID( pEnv, cls, "fOwner", "Lcom/apple/dnssd/AppleService;");
582 582 jfieldID recField = (*pEnv)->GetFieldID( pEnv, cls, "fRecord", "J");
583 583 OpContext *pContext = NULL;
584 584 DNSServiceErrorType err = kDNSServiceErr_NoError;
585 585 jbyte *pBytes;
586 586 jsize numBytes;
587 587 DNSRecordRef recRef = NULL;
588 588
589 589 if ( ownerField != 0)
590 590 {
591 591 jobject ownerObj = (*pEnv)->GetObjectField( pEnv, pThis, ownerField);
592 592 jclass ownerClass = (*pEnv)->GetObjectClass( pEnv, ownerObj);
593 593 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, ownerClass, "fNativeContext", "J");
594 594 if ( contextField != 0)
595 595 pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, ownerObj, contextField);
596 596 }
597 597 if ( recField != 0)
598 598 recRef = (DNSRecordRef) (long) (*pEnv)->GetLongField(pEnv, pThis, recField);
599 599 if ( pContext == NULL || pContext->ServiceRef == NULL)
600 600 return kDNSServiceErr_BadParam;
601 601
602 602 pBytes = (*pEnv)->GetByteArrayElements( pEnv, rData, NULL);
603 603 numBytes = (*pEnv)->GetArrayLength( pEnv, rData);
604 604
605 605 err = DNSServiceUpdateRecord( pContext->ServiceRef, recRef, flags, numBytes, pBytes, ttl);
606 606
607 607 if ( pBytes != NULL)
608 608 (*pEnv)->ReleaseByteArrayElements( pEnv, rData, pBytes, 0);
609 609
610 610 return err;
611 611 }
612 612
613 613 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSRecord_Remove( JNIEnv *pEnv, jobject pThis)
614 614 {
615 615 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
616 616 jfieldID ownerField = (*pEnv)->GetFieldID( pEnv, cls, "fOwner", "Lcom/apple/dnssd/AppleService;");
617 617 jfieldID recField = (*pEnv)->GetFieldID( pEnv, cls, "fRecord", "J");
618 618 OpContext *pContext = NULL;
619 619 DNSServiceErrorType err = kDNSServiceErr_NoError;
620 620 DNSRecordRef recRef = NULL;
621 621
622 622 if ( ownerField != 0)
623 623 {
624 624 jobject ownerObj = (*pEnv)->GetObjectField( pEnv, pThis, ownerField);
625 625 jclass ownerClass = (*pEnv)->GetObjectClass( pEnv, ownerObj);
626 626 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, ownerClass, "fNativeContext", "J");
627 627 if ( contextField != 0)
628 628 pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, ownerObj, contextField);
629 629 }
630 630 if ( recField != 0)
631 631 recRef = (DNSRecordRef) (long) (*pEnv)->GetLongField(pEnv, pThis, recField);
632 632 if ( pContext == NULL || pContext->ServiceRef == NULL)
633 633 return kDNSServiceErr_BadParam;
634 634
635 635 err = DNSServiceRemoveRecord( pContext->ServiceRef, recRef, 0);
636 636
637 637 return err;
638 638 }
639 639
640 640
641 641 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRecordRegistrar_CreateConnection( JNIEnv *pEnv, jobject pThis)
642 642 {
643 643 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
644 644 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
645 645 OpContext *pContext = NULL;
646 646 DNSServiceErrorType err = kDNSServiceErr_NoError;
647 647
648 648 if ( contextField != 0)
649 649 pContext = NewContext( pEnv, pThis, "recordRegistered", "(Lcom/apple/dnssd/DNSRecord;I)V");
650 650 else
651 651 err = kDNSServiceErr_BadParam;
652 652
653 653 if ( pContext != NULL)
654 654 {
655 655 err = DNSServiceCreateConnection( &pContext->ServiceRef);
656 656 if ( err == kDNSServiceErr_NoError)
657 657 {
658 658 (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
659 659 }
660 660 }
661 661 else
662 662 err = kDNSServiceErr_NoMemory;
663 663
664 664 return err;
665 665 }
666 666
667 667 struct RecordRegistrationRef
668 668 {
669 669 OpContext *Context;
670 670 jobject RecordObj;
671 671 };
672 672 typedef struct RecordRegistrationRef RecordRegistrationRef;
673 673
674 674 static void DNSSD_API RegisterRecordReply( DNSServiceRef sdRef _UNUSED,
675 675 DNSRecordRef recordRef _UNUSED, DNSServiceFlags flags,
676 676 DNSServiceErrorType errorCode, void *context)
677 677 {
678 678 RecordRegistrationRef *regEnvelope = (RecordRegistrationRef*) context;
679 679 OpContext *pContext = regEnvelope->Context;
680 680
681 681 SetupCallbackState( &pContext->Env);
682 682
683 683 if ( pContext->ClientObj != NULL && pContext->Callback != NULL)
684 684 {
685 685 if ( errorCode == kDNSServiceErr_NoError)
686 686 {
687 687 (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
688 688 regEnvelope->RecordObj, flags);
689 689 }
690 690 else
691 691 ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
692 692 }
693 693
694 694 (*pContext->Env)->DeleteWeakGlobalRef( pContext->Env, regEnvelope->RecordObj);
695 695 free( regEnvelope);
696 696
697 697 TeardownCallbackState();
698 698 }
699 699
700 700 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRecordRegistrar_RegisterRecord( JNIEnv *pEnv, jobject pThis,
701 701 jint flags, jint ifIndex, jstring fullname, jint rrType, jint rrClass,
702 702 jbyteArray rData, jint ttl, jobject destObj)
703 703 {
704 704 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
705 705 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
706 706 jclass destCls = (*pEnv)->GetObjectClass( pEnv, destObj);
707 707 jfieldID recField = (*pEnv)->GetFieldID( pEnv, destCls, "fRecord", "J");
708 708 const char *nameStr = SafeGetUTFChars( pEnv, fullname);
709 709 OpContext *pContext = NULL;
710 710 DNSServiceErrorType err = kDNSServiceErr_NoError;
711 711 jbyte *pBytes;
712 712 jsize numBytes;
713 713 DNSRecordRef recRef;
714 714 RecordRegistrationRef *regEnvelope;
715 715
716 716 if ( contextField != 0)
717 717 pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, pThis, contextField);
718 718 if ( pContext == NULL || pContext->ServiceRef == NULL || nameStr == NULL)
719 719 return kDNSServiceErr_BadParam;
720 720
721 721 regEnvelope = calloc( 1, sizeof *regEnvelope);
722 722 if ( regEnvelope == NULL)
723 723 return kDNSServiceErr_NoMemory;
724 724 regEnvelope->Context = pContext;
725 725 regEnvelope->RecordObj = (*pEnv)->NewWeakGlobalRef( pEnv, destObj); // must convert local ref to global to cache
726 726
727 727 pBytes = (*pEnv)->GetByteArrayElements( pEnv, rData, NULL);
728 728 numBytes = (*pEnv)->GetArrayLength( pEnv, rData);
729 729
730 730 err = DNSServiceRegisterRecord( pContext->ServiceRef, &recRef, flags, ifIndex,
731 731 nameStr, rrType, rrClass, numBytes, pBytes, ttl,
732 732 RegisterRecordReply, regEnvelope);
733 733
734 734 if ( err == kDNSServiceErr_NoError)
735 735 {
736 736 (*pEnv)->SetLongField(pEnv, destObj, recField, (long) recRef);
737 737 }
738 738 else
739 739 {
740 740 if ( regEnvelope->RecordObj != NULL)
741 741 (*pEnv)->DeleteWeakGlobalRef( pEnv, regEnvelope->RecordObj);
742 742 free( regEnvelope);
743 743 }
744 744
745 745 if ( pBytes != NULL)
746 746 (*pEnv)->ReleaseByteArrayElements( pEnv, rData, pBytes, 0);
747 747
748 748 SafeReleaseUTFChars( pEnv, fullname, nameStr);
749 749
750 750 return err;
751 751 }
752 752
753 753
754 754 static void DNSSD_API ServiceQueryReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
755 755 DNSServiceErrorType errorCode, const char *serviceName,
756 756 uint16_t rrtype, uint16_t rrclass, uint16_t rdlen,
757 757 const void *rdata, uint32_t ttl, void *context)
758 758 {
759 759 OpContext *pContext = (OpContext*) context;
760 760 jbyteArray rDataObj;
761 761 jbyte *pBytes;
762 762
763 763 SetupCallbackState( &pContext->Env);
764 764
765 765 if ( pContext->ClientObj != NULL && pContext->Callback != NULL &&
766 766 NULL != ( rDataObj = (*pContext->Env)->NewByteArray( pContext->Env, rdlen)))
767 767 {
768 768 if ( errorCode == kDNSServiceErr_NoError)
769 769 {
770 770 // Initialize rDataObj with contents of rdata
771 771 pBytes = (*pContext->Env)->GetByteArrayElements( pContext->Env, rDataObj, NULL);
772 772 memcpy( pBytes, rdata, rdlen);
773 773 (*pContext->Env)->ReleaseByteArrayElements( pContext->Env, rDataObj, pBytes, JNI_COMMIT);
774 774
775 775 (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
776 776 pContext->JavaObj, flags, interfaceIndex,
777 777 (*pContext->Env)->NewStringUTF( pContext->Env, serviceName),
778 778 rrtype, rrclass, rDataObj, ttl);
779 779 }
780 780 else
781 781 ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
782 782 }
783 783 TeardownCallbackState();
784 784 }
785 785
786 786 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleQuery_CreateQuery( JNIEnv *pEnv, jobject pThis,
787 787 jint flags, jint ifIndex, jstring serviceName, jint rrtype, jint rrclass)
788 788 {
789 789 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
790 790 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
791 791 OpContext *pContext = NULL;
792 792 DNSServiceErrorType err = kDNSServiceErr_NoError;
793 793
794 794 if ( contextField != 0)
795 795 pContext = NewContext( pEnv, pThis, "queryAnswered",
796 796 "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;II[BI)V");
797 797 else
798 798 err = kDNSServiceErr_BadParam;
799 799
800 800 if ( pContext != NULL)
801 801 {
802 802 const char *servStr = SafeGetUTFChars( pEnv, serviceName);
803 803
804 804 err = DNSServiceQueryRecord( &pContext->ServiceRef, flags, ifIndex, servStr,
805 805 rrtype, rrclass, ServiceQueryReply, pContext);
806 806 if ( err == kDNSServiceErr_NoError)
807 807 {
808 808 (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
809 809 }
810 810
811 811 SafeReleaseUTFChars( pEnv, serviceName, servStr);
812 812 }
813 813 else
814 814 err = kDNSServiceErr_NoMemory;
815 815
816 816 return err;
817 817 }
818 818
819 819
820 820 static void DNSSD_API DomainEnumReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
821 821 DNSServiceErrorType errorCode, const char *replyDomain, void *context)
822 822 {
823 823 OpContext *pContext = (OpContext*) context;
824 824
825 825 SetupCallbackState( &pContext->Env);
826 826
827 827 if ( pContext->ClientObj != NULL && pContext->Callback != NULL)
828 828 {
829 829 if ( errorCode == kDNSServiceErr_NoError)
830 830 {
831 831 (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj,
832 832 ( flags & kDNSServiceFlagsAdd) != 0 ? pContext->Callback : pContext->Callback2,
833 833 pContext->JavaObj, flags, interfaceIndex,
834 834 (*pContext->Env)->NewStringUTF( pContext->Env, replyDomain));
835 835 }
836 836 else
837 837 ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
838 838 }
839 839 TeardownCallbackState();
840 840 }
841 841
842 842 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDomainEnum_BeginEnum( JNIEnv *pEnv, jobject pThis,
843 843 jint flags, jint ifIndex)
844 844 {
845 845 jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
846 846 jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
847 847 OpContext *pContext = NULL;
848 848 DNSServiceErrorType err = kDNSServiceErr_NoError;
849 849
850 850 if ( contextField != 0)
851 851 pContext = NewContext( pEnv, pThis, "domainFound",
852 852 "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;)V");
853 853 else
854 854 err = kDNSServiceErr_BadParam;
855 855
856 856 if ( pContext != NULL)
857 857 {
858 858 pContext->Callback2 = (*pEnv)->GetMethodID( pEnv,
859 859 (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj),
860 860 "domainLost", "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;)V");
861 861
862 862 err = DNSServiceEnumerateDomains( &pContext->ServiceRef, flags, ifIndex,
863 863 DomainEnumReply, pContext);
864 864 if ( err == kDNSServiceErr_NoError)
865 865 {
866 866 (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
867 867 }
868 868 }
869 869 else
870 870 err = kDNSServiceErr_NoMemory;
871 871
872 872 return err;
873 873 }
874 874
875 875
876 876 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_ConstructName( JNIEnv *pEnv, jobject pThis _UNUSED,
877 877 jstring serviceName, jstring regtype, jstring domain, jobjectArray pOut)
878 878 {
879 879 DNSServiceErrorType err = kDNSServiceErr_NoError;
880 880 const char *nameStr = SafeGetUTFChars( pEnv, serviceName);
881 881 const char *regStr = SafeGetUTFChars( pEnv, regtype);
882 882 const char *domStr = SafeGetUTFChars( pEnv, domain);
883 883 char buff[ kDNSServiceMaxDomainName + 1];
884 884
885 885 err = DNSServiceConstructFullName( buff, nameStr, regStr, domStr);
886 886
887 887 if ( err == kDNSServiceErr_NoError)
888 888 {
889 889 // pOut is expected to be a String[1] array.
890 890 (*pEnv)->SetObjectArrayElement( pEnv, pOut, 0, (*pEnv)->NewStringUTF( pEnv, buff));
891 891 }
892 892
893 893 SafeReleaseUTFChars( pEnv, serviceName, nameStr);
894 894 SafeReleaseUTFChars( pEnv, regtype, regStr);
895 895 SafeReleaseUTFChars( pEnv, domain, domStr);
896 896
897 897 return err;
898 898 }
899 899
900 900 JNIEXPORT void JNICALL Java_com_apple_dnssd_AppleDNSSD_ReconfirmRecord( JNIEnv *pEnv, jobject pThis _UNUSED,
901 901 jint flags, jint ifIndex, jstring fullName,
902 902 jint rrtype, jint rrclass, jbyteArray rdata)
903 903 {
904 904 jbyte *pBytes;
905 905 jsize numBytes;
906 906 const char *nameStr = SafeGetUTFChars( pEnv, fullName);
907 907
908 908 pBytes = (*pEnv)->GetByteArrayElements( pEnv, rdata, NULL);
909 909 numBytes = (*pEnv)->GetArrayLength( pEnv, rdata);
910 910
911 911 DNSServiceReconfirmRecord( flags, ifIndex, nameStr, rrtype, rrclass, numBytes, pBytes);
912 912
913 913 if ( pBytes != NULL)
914 914 (*pEnv)->ReleaseByteArrayElements( pEnv, rdata, pBytes, 0);
915 915
916 916 SafeReleaseUTFChars( pEnv, fullName, nameStr);
917 917 }
918 918
919 919 #define LOCAL_ONLY_NAME "loo"
920 920 #define P2P_NAME "p2p"
921 921
922 922 JNIEXPORT jstring JNICALL Java_com_apple_dnssd_AppleDNSSD_GetNameForIfIndex( JNIEnv *pEnv, jobject pThis _UNUSED,
923 923 jint ifIndex)
924 924 {
925 925 char *p = LOCAL_ONLY_NAME, nameBuff[IF_NAMESIZE];
926 926
927 927 if (ifIndex == (jint) kDNSServiceInterfaceIndexP2P)
928 928 p = P2P_NAME;
929 929 else if (ifIndex != (jint) kDNSServiceInterfaceIndexLocalOnly)
930 930 p = if_indextoname( ifIndex, nameBuff );
931 931
932 932 return (*pEnv)->NewStringUTF( pEnv, p);
933 933 }
934 934
935 935
936 936 JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_GetIfIndexForName( JNIEnv *pEnv, jobject pThis _UNUSED,
937 937 jstring ifName)
938 938 {
939 939 uint32_t ifIndex = kDNSServiceInterfaceIndexLocalOnly;
940 940 const char *nameStr = SafeGetUTFChars( pEnv, ifName);
941 941
942 942 if (strcmp(nameStr, P2P_NAME) == 0)
943 943 ifIndex = kDNSServiceInterfaceIndexP2P;
944 944 else if (strcmp(nameStr, LOCAL_ONLY_NAME))
945 945 ifIndex = if_nametoindex( nameStr);
946 946
947 947 SafeReleaseUTFChars( pEnv, ifName, nameStr);
948 948
949 949 return ifIndex;
950 950 }
951 951
952 952
953 953 #if defined(_WIN32)
954 954 static char*
955 955 win32_if_indextoname( DWORD ifIndex, char * nameBuff)
956 956 {
957 957 PIP_ADAPTER_INFO pAdapterInfo = NULL;
958 958 PIP_ADAPTER_INFO pAdapter = NULL;
959 959 DWORD dwRetVal = 0;
960 960 char * ifName = NULL;
961 961 ULONG ulOutBufLen = 0;
962 962
963 963 if (GetAdaptersInfo( NULL, &ulOutBufLen) != ERROR_BUFFER_OVERFLOW)
964 964 {
965 965 goto exit;
966 966 }
967 967
968 968 pAdapterInfo = (IP_ADAPTER_INFO *) malloc(ulOutBufLen);
969 969
970 970 if (pAdapterInfo == NULL)
971 971 {
972 972 goto exit;
973 973 }
974 974
975 975 dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen );
976 976
977 977 if (dwRetVal != NO_ERROR)
978 978 {
979 979 goto exit;
980 980 }
981 981
982 982 pAdapter = pAdapterInfo;
983 983 while (pAdapter)
984 984 {
985 985 if (pAdapter->Index == ifIndex)
986 986 {
987 987 // It would be better if we passed in the length of nameBuff to this
988 988 // function, so we would have absolute certainty that no buffer
989 989 // overflows would occur. Buffer overflows *shouldn't* occur because
990 990 // nameBuff is of size MAX_ADAPTER_NAME_LENGTH.
991 991 strcpy( nameBuff, pAdapter->AdapterName );
992 992 ifName = nameBuff;
993 993 break;
994 994 }
995 995
996 996 pAdapter = pAdapter->Next;
997 997 }
998 998
999 999 exit:
1000 1000
1001 1001 if (pAdapterInfo != NULL)
1002 1002 {
1003 1003 free( pAdapterInfo );
1004 1004 pAdapterInfo = NULL;
1005 1005 }
1006 1006
1007 1007 return ifName;
1008 1008 }
1009 1009
1010 1010
1011 1011 static DWORD
1012 1012 win32_if_nametoindex( const char * nameStr )
1013 1013 {
1014 1014 PIP_ADAPTER_INFO pAdapterInfo = NULL;
1015 1015 PIP_ADAPTER_INFO pAdapter = NULL;
1016 1016 DWORD dwRetVal = 0;
1017 1017 DWORD ifIndex = 0;
1018 1018 ULONG ulOutBufLen = 0;
1019 1019
1020 1020 if (GetAdaptersInfo( NULL, &ulOutBufLen) != ERROR_BUFFER_OVERFLOW)
1021 1021 {
1022 1022 goto exit;
1023 1023 }
1024 1024
1025 1025 pAdapterInfo = (IP_ADAPTER_INFO *) malloc(ulOutBufLen);
1026 1026
1027 1027 if (pAdapterInfo == NULL)
1028 1028 {
1029 1029 goto exit;
1030 1030 }
1031 1031
1032 1032 dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen );
1033 1033
1034 1034 if (dwRetVal != NO_ERROR)
1035 1035 {
1036 1036 goto exit;
1037 1037 }
1038 1038
1039 1039 pAdapter = pAdapterInfo;
1040 1040 while (pAdapter)
1041 1041 {
1042 1042 if (strcmp(pAdapter->AdapterName, nameStr) == 0)
1043 1043 {
1044 1044 ifIndex = pAdapter->Index;
1045 1045 break;
1046 1046 }
1047 1047
1048 1048 pAdapter = pAdapter->Next;
1049 1049 }
1050 1050
1051 1051 exit:
1052 1052
1053 1053 if (pAdapterInfo != NULL)
1054 1054 {
1055 1055 free( pAdapterInfo );
1056 1056 pAdapterInfo = NULL;
1057 1057 }
1058 1058
1059 1059 return ifIndex;
1060 1060 }
1061 1061 #endif
↓ open down ↓ |
1061 lines elided |
↑ open up ↑ |
1062 1062
1063 1063
1064 1064 // Note: The C preprocessor stringify operator ('#') makes a string from its argument, without macro expansion
1065 1065 // e.g. If "version" is #define'd to be "4", then STRINGIFY_AWE(version) will return the string "version", not "4"
1066 1066 // To expand "version" to its value before making the string, use STRINGIFY(version) instead
1067 1067 #define STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) # s
1068 1068 #define STRINGIFY(s) STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s)
1069 1069
1070 1070 // NOT static -- otherwise the compiler may optimize it out
1071 1071 // The "@(#) " pattern is a special prefix the "what" command looks for
1072 +#ifndef MDNS_VERSIONSTR_NODTS
1072 1073 const char VersionString_SCCS[] = "@(#) libjdns_sd " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
1074 +#else
1075 +const char VersionString_SCCS[] = "@(#) libjdns_sd " STRINGIFY(mDNSResponderVersion);
1076 +#endif
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX