2N/A/* -*- Mode: C; tab-width: 4 -*- 2N/A * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved. 2N/A * Redistribution and use in source and binary forms, with or without 2N/A * modification, are permitted provided that the following conditions are met: 2N/A * 1. Redistributions of source code must retain the above copyright notice, 2N/A * this list of conditions and the following disclaimer. 2N/A * 2. Redistributions in binary form must reproduce the above copyright notice, 2N/A * this list of conditions and the following disclaimer in the documentation 2N/A * and/or other materials provided with the distribution. 2N/A * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its 2N/A * contributors may be used to endorse or promote products derived from this 2N/A * software without specific prior written permission. 2N/A * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 2N/A * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 2N/A * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 2N/A * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 2N/A * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 2N/A * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 2N/A * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 2N/A * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2N/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 2N/A * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2N/A Change History (most recent first): 2N/ARevision 1.53 2006/09/07 04:43:12 herscher 2N/AFix compile error on Win32 platform by moving inclusion of syslog.h 2N/ARevision 1.52 2006/08/15 23:04:21 mkrochma 2N/A<rdar://problem/4090354> Client should be able to specify service name w/o callback 2N/ARevision 1.51 2006/07/24 23:45:55 cheshire 2N/A<rdar://problem/4605276> DNSServiceReconfirmRecord() should return error code 2N/ARevision 1.50 2006/06/28 08:22:27 cheshire 2N/ARevision 1.49 2006/06/28 07:58:59 cheshire 2N/AMinor textual tidying 2N/ARevision 1.48 2005/06/30 18:01:00 shersche 2N/A<rdar://problem/4096913> Clients shouldn't wait ten seconds to connect to mDNSResponder 2N/ARevision 1.47 2005/03/31 02:19:56 cheshire 2N/A<rdar://problem/4021486> Fix build warnings 2N/AReviewed by: Scott Herscher 2N/ARevision 1.46 2005/03/21 00:39:31 shersche 2N/A<rdar://problem/4021486> Fix build warnings on Win32 platform 2N/ARevision 1.45 2005/02/01 01:25:06 shersche 2N/ADefine sleep() to be Sleep() for Windows compatibility 2N/ARevision 1.44 2005/01/27 22:57:56 cheshire 2N/AFix compile errors on gcc4 2N/ARevision 1.43 2005/01/27 00:02:29 cheshire 2N/A<rdar://problem/3947461> Handle case where client runs before daemon has finished launching 2N/ARevision 1.42 2005/01/11 02:01:02 shersche 2N/AUse dnssd_close() rather than close() for Windows compatibility 2N/ARevision 1.41 2004/12/23 17:34:26 ksekar 2N/A<rdar://problem/3931319> Calls leak sockets if mDNSResponder is not running 2N/ARevision 1.40 2004/11/23 03:39:47 cheshire 2N/Ainstead of having to call through to the daemon via IPC to get this information. 2N/ARevision 1.39 2004/11/12 03:22:00 rpantos 2N/Ardar://problem/3809541 Add DNSSDMapIfIndexToName, DNSSDMapNameToIfIndex. 2N/ARevision 1.38 2004/11/02 02:51:23 cheshire 2N/A<rdar://problem/3526342> Remove overly-restrictive flag checks 2N/ARevision 1.37 2004/10/14 01:43:35 cheshire 2N/AFix opaque port passing problem 2N/ARevision 1.36 2004/10/06 02:22:19 cheshire 2N/AChanged MacRoman copyright symbol (should have been UTF-8 in any case :-) to ASCII-compatible "(c)" 2N/ARevision 1.35 2004/10/01 22:15:55 rpantos 2N/Ardar://problem/3824265: Replace APSL in client lib with BSD license. 2N/ARevision 1.34 2004/09/17 22:36:13 cheshire 2N/AAdd comment explaining that deliver_request frees the message it sends 2N/ARevision 1.33 2004/09/17 01:17:31 ksekar 2N/ARemove double-free of msg header, freed automatically by deliver_request() 2N/ARevision 1.32 2004/09/17 01:08:55 cheshire 2N/A The name "mDNSClientAPI.h" is misleading to new developers looking at this code. The interfaces 2N/A declared in that file are ONLY appropriate to single-address-space embedded applications. 2N/A For clients on general-purpose computers, the interfaces defined in dns_sd.h should be used. 2N/ARevision 1.31 2004/09/16 23:37:19 cheshire 2N/AFree hdr before returning 2N/ARevision 1.30 2004/09/16 23:14:24 cheshire 2N/AChanges for Windows compatibility 2N/ARevision 1.29 2004/09/16 21:46:38 ksekar 2N/A<rdar://problem/3665304> Need SPI for LoginWindow to associate a UID with a Wide Area domain 2N/ARevision 1.28 2004/08/11 17:10:04 cheshire 2N/ARevision 1.27 2004/08/11 00:54:16 cheshire 2N/AChange "hdr->op.request_op" to just "hdr->op" 2N/ARevision 1.26 2004/07/26 06:07:27 shersche 2N/Afix bugs when using an error socket to communicate with the daemon 2N/ARevision 1.25 2004/07/26 05:54:02 shersche 2N/ADNSServiceProcessResult() returns NoError if socket read returns EWOULDBLOCK 2N/ARevision 1.24 2004/07/20 06:46:21 shersche 2N/A<rdar://problem/3730123> fix endless loop in read_all() if recv returns 0 2N/ARevision 1.23 2004/06/29 00:48:38 cheshire 2N/ADon't use "MSG_WAITALL"; it returns "Invalid argument" on some Linux versions; 2N/Ause an explicit while() loop instead. 2N/ARevision 1.22 2004/06/26 03:16:34 shersche 2N/Aclean up warning messages on Win32 platform 2N/ASubmitted by: herscher 2N/ARevision 1.21 2004/06/18 04:53:56 rpantos 2N/AUse platform layer for socket types. Introduce USE_TCP_LOOPBACK. Remove dependency on mDNSEmbeddedAPI.h. 2N/ARevision 1.20 2004/06/12 00:50:22 cheshire 2N/AChanges for Windows compatibility 2N/ARevision 1.19 2004/05/25 18:29:33 cheshire 2N/ARevision 1.18 2004/05/18 23:51:27 cheshire 2N/ATidy up all checkin comments to use consistent "<rdar://problem/xxxxxxx>" format for bug numbers 2N/ARevision 1.17 2004/05/06 18:42:58 ksekar 2N/AGeneral dns_sd.h API cleanup, including the following radars: 2N/A<rdar://problem/3592068>: Remove flags with zero value 2N/A<rdar://problem/3479569>: Passing in NULL causes a crash. 2N/ARevision 1.16 2004/03/12 22:00:37 cheshire 2N/ARevision 1.15 2004/01/20 18:36:29 ksekar 2N/APropagated Libinfo fix for <rdar://problem/3483971>: SU: 2N/ADNSServiceUpdateRecord() doesn't allow you to update the TXT record 2N/Ainto TOT mDNSResponder. 2N/ARevision 1.14 2004/01/19 22:39:17 cheshire 2N/ADon't use "MSG_WAITALL"; it makes send() return "Invalid argument" on Linux; 2N/Ause an explicit while() loop instead. (In any case, this should only make a difference 2N/Awith non-blocking sockets, which we don't use on the client side right now.) 2N/ARevision 1.13 2004/01/19 21:46:52 cheshire 2N/ARevision 1.12 2003/12/23 20:46:47 ksekar 2N/A<rdar://problem/3497428>: sync dnssd files between libinfo & mDNSResponder 2N/ARevision 1.11 2003/12/08 21:11:42 rpantos 2N/AChanges necessary to support mDNSResponder on Linux. 2N/ARevision 1.10 2003/10/13 23:50:53 ksekar 2N/AUpdated dns_sd clientstub files to bring copies in synch with 2N/ARevision 1.9 2003/08/15 21:30:39 cheshire 2N/ABring up to date with LibInfo version 2N/ARevision 1.8 2003/08/13 23:54:52 ksekar 2N/ARevision 1.7 2003/08/12 19:56:25 cheshire 2N/A#
pragma ident "%Z%%M% %I% %E% SMI" 2N/A// disable warning: "'type cast' : from data pointer 'void *' to function pointer" 2N/A// disable warning: "nonstandard extension, function/data pointer conversion in expression" 2N/A// <rdar://problem/4096913> Specifies how many times we'll try and connect to the 2N/A// error socket (if needed) is named "dnssd_clipath.[pid].xxx:n" where xxx are the 2N/A// last 3 digits of the time (in seconds) and n is the 6-digit microsecond time 2N/A// general utility functions 2N/A// exported functions 2N/A// write len bytes. return 0 on success, -1 on error 2N/A // Don't use "MSG_WAITALL"; it returns "Invalid argument" on some Linux versions; use an explicit while() loop instead. 2N/A //if (send(sd, buf, len, MSG_WAITALL) != len) return -1; 2N/A// read len bytes. return 0 on success, -1 on error 2N/A // Don't use "MSG_WAITALL"; it returns "Invalid argument" on some Linux versions; use an explicit while() loop instead. 2N/A //if (recv(sd, buf, len, MSG_WAITALL) != len) return -1; 2N/A // Return error -2 when no data received and errno is not set 2N/A * allocate and initialize an ipc message header. value of len should initially be the 2N/A * length of the data, and is set to the value of the data plus the header. data_start 2N/A * is set to point to the beginning of the data section. reuse_socket should be non-zero 2N/A * for calls that can receive an immediate error return value on their primary socket. 2N/A * if zero, the path to a control socket is appended at the beginning of the message buffer. 2N/A * data_start is set past this string. 2N/A *
len +=
2;
// Allocate space for two-byte port number 2N/A // write message to buffer 2N/A // Put dummy data in for the port, since we don't know what 2N/A // it is yet. The data will get filled in before we 2N/A // send the message. This happens in deliver_request(). 2N/A // return a connected service ref (deallocate with DNSServiceRefDeallocate) 2N/A // <rdar://problem/4096913> If the system service is disabled, we only want to try 2N/A if (!
err)
break;
// If we succeeded, return sdr 2N/A // If we failed, then it may be because the daemon is still launching. 2N/A // This can happen for processes that launch early in the boot process, while the 2N/A // daemon is still coming up. Rather than fail here, we'll wait a bit and try again. 2N/A // If, after four seconds, we still can't connect to the daemon, 2N/A // then we give up and return a failure code. 2N/A sleep(
1);
// Sleep a bit, then try again 2N/A // setup temporary error socket 2N/A data[0] =
port.b[0];
// don't switch the byte order, as the 2N/A data[
1] =
port.b[
1];
// daemon expects it in network byte order 2N/A// According to Stevens (section 3.2), there is no portable way to 2N/A// determine whether sa_len is defined on a particular platform. 2N/A //syslog(LOG_WARNING, "deliver_request: creating UDS: %s\n", data); 2N/A //syslog(LOG_WARNING, "deliver_request writing %ld bytes\n", datalen + sizeof(ipc_msg_hdr)); 2N/A //syslog(LOG_WARNING, "deliver_request name is %s\n", (char *)msg + sizeof(ipc_msg_hdr)); 2N/A //syslog(LOG_WARNING, "deliver_request: accept\n"); 2N/A //syslog(LOG_WARNING, "deliver_request: accept returned %d\n", errsd); 2N/A //syslog(LOG_WARNING, "deliver_request: retrieved error code %d\n", err); 2N/A // syslog(LOG_WARNING, "deliver_request: removing UDS: %s\n", data); 2N/A // else syslog(LOG_WARNING, "deliver_request: removed UDS: %s\n", data); 2N/A// handle reply from server, calling application client callback. If there is no reply 2N/A// from the daemon on the socket contained in sdRef, the call will block. 2N/A // return NoError on EWOULDBLOCK. This will handle the case 2N/A // where a non-blocking socket is told there is data, but 2N/A // it was a false positive. Can check errno when error 2N/A // code returned is -1 2N/A // calculate total message length 2N/A // calculate total message length 2N/A // auto-name must also have auto-rename 2N/A // no callback must have auto-rename 2N/A//sdRef returned by DNSServiceRegister() 2N/A//DNSRecordRef returned by DNSServiceRegisterRecord or DNSServiceAddRecord