[PATCH 10/10] mDNSResponder: Port to RTEMS

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Jun 19 11:02:24 UTC 2020


Update #4010.
---
 mDNSResponder/mDNSCore/anonymous.c          | 15 ++++--
 mDNSResponder/mDNSCore/mDNS.c               |  4 ++
 mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h    | 40 ++++++++++++++
 mDNSResponder/mDNSPosix/mDNSPosix.c         | 58 +++++++++++++++++++++
 mDNSResponder/mDNSPosix/mDNSPosix.h         |  6 +++
 mDNSResponder/mDNSPosix/mDNSUNP.c           |  2 +-
 mDNSResponder/mDNSShared/dnssd_clientshim.c | 13 ++++-
 mDNSResponder/mDNSShared/mDNSDebug.c        |  4 ++
 testsuite/foobarserver/test_main.c          |  2 +-
 9 files changed, 136 insertions(+), 8 deletions(-)

diff --git a/mDNSResponder/mDNSCore/anonymous.c b/mDNSResponder/mDNSCore/anonymous.c
index 5c138d23..fde3ed80 100644
--- a/mDNSResponder/mDNSCore/anonymous.c
+++ b/mDNSResponder/mDNSCore/anonymous.c
@@ -274,12 +274,17 @@ mDNSexport void SetAnonData(DNSQuestion *q, ResourceRecord *rr, mDNSBool ForQues
     }
 }
 
+mDNSlocal char *RRDisplayStringBuf(const ResourceRecord *const rr, char *const buffer)
+{
+    return GetRRDisplayString_rdb(rr, &rr->rdata->u, buffer);
+}
+
 // returns -1 if the caller should ignore the result
 // returns 1 if the record answers the question
 // returns 0 if the record does not answer the question
 mDNSexport int AnonInfoAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q)
 {
-    mDNSexport mDNS mDNSStorage;
+    char MsgBuffer[MaxMsg];             // Temp storage used while building error log messages
     ResourceRecord *nsec3RR;
     int i;
     AnonymousInfo *qai, *rai;
@@ -363,7 +368,7 @@ mDNSexport int AnonInfoAnswersQuestion(const ResourceRecord *const rr, const DNS
             mDNSPlatformMemCmp(qai->AnonData, rai->AnonData, qai->AnonDataLen) != 0)
         {
             debugf("AnonInfoAnswersQuestion: AnonData mis-match for record  %s question %##s ",
-                RRDisplayString(&mDNSStorage, rr), q->qname.c);
+                RRDisplayStringBuf(rr, MsgBuffer), q->qname.c);
             return 0;
         }
         // AnonData matches i.e they belong to the same group and the same service.
@@ -401,10 +406,10 @@ mDNSexport int AnonInfoAnswersQuestion(const ResourceRecord *const rr, const DNS
         // AnonData can be NULL for the cache entry and if we are hearing our own question back, AnonData is NULL for
         // that too and we can end up here for that case.
         debugf("AnonInfoAnswersQuestion: AnonData %p or nsec3RR %p, NULL for question %##s, record %s", AnonData, nsec3RR,
-            q->qname.c, RRDisplayString(&mDNSStorage, rr));
+            q->qname.c, RRDisplayStringBuf(rr, MsgBuffer));
         return 0;
     }
-    debugf("AnonInfoAnswersQuestion: Validating question %##s, ResourceRecord %s", q->qname.c, RRDisplayString(&mDNSStorage, nsec3RR));
+    debugf("AnonInfoAnswersQuestion: Validating question %##s, ResourceRecord %s", q->qname.c, RRDisplayStringBuf(nsec3RR, MsgBuffer));
 
 
     nsec3 = (rdataNSEC3 *)nsec3RR->rdata->u.data;
@@ -436,7 +441,7 @@ mDNSexport int AnonInfoAnswersQuestion(const ResourceRecord *const rr, const DNS
             return 0;
         }
     }
-    LogInfo("AnonInfoAnswersQuestion: ResourceRecord %s matched question %##s (%s)", RRDisplayString(&mDNSStorage, nsec3RR), q->qname.c, DNSTypeName(q->qtype));
+    LogInfo("AnonInfoAnswersQuestion: ResourceRecord %s matched question %##s (%s)", RRDisplayStringBuf(nsec3RR, MsgBuffer), q->qname.c, DNSTypeName(q->qtype));
     return 1;
 }
 
diff --git a/mDNSResponder/mDNSCore/mDNS.c b/mDNSResponder/mDNSCore/mDNS.c
index 4e70ef83..4473e82a 100755
--- a/mDNSResponder/mDNSCore/mDNS.c
+++ b/mDNSResponder/mDNSCore/mDNS.c
@@ -14586,7 +14586,11 @@ mDNSlocal mStatus mDNS_InitStorage(mDNS *const m, mDNS_PlatformSupport *const p,
     m->WABBrowseQueriesCount    = 0;
     m->WABLBrowseQueriesCount   = 0;
     m->WABRegQueriesCount       = 0;
+#ifndef __rtems__
     m->AutoTargetServices       = 0;
+#else /* __rtems__ */
+    m->AutoTargetServices       = 1;
+#endif /* __rtems__ */
 
 #if BONJOUR_ON_DEMAND
     m->NumAllInterfaceRecords   = 0;
diff --git a/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h b/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h
index d714de49..ba5dfb3f 100755
--- a/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h
+++ b/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h
@@ -3665,6 +3665,46 @@ extern void D2D_stop_advertising_record(AuthRecord *ar);
 
 // ***************************************************************************
 
+#ifdef __rtems__
+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;
+};
+
+extern mStatus mDNS_StartResolveService(mDNS *const m, ServiceInfoQuery *query, ServiceInfo *info, mDNSServiceInfoQueryCallback *Callback, void *Context);
+extern void    mDNS_StopResolveService (mDNS *const m, ServiceInfoQuery *query);
+#endif /* __rtems__ */
 #ifdef __cplusplus
 }
 #endif
diff --git a/mDNSResponder/mDNSPosix/mDNSPosix.c b/mDNSResponder/mDNSPosix/mDNSPosix.c
index 308252fb..9b4dbed8 100755
--- a/mDNSResponder/mDNSPosix/mDNSPosix.c
+++ b/mDNSResponder/mDNSPosix/mDNSPosix.c
@@ -40,6 +40,10 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <time.h>                   // platform support for UTC time
+#ifdef __rtems__
+#include <sys/param.h>
+#include <rtems/libio_.h>
+#endif /* __rtems__ */
 
 #if USES_NETLINK
 #include <asm/types.h>
@@ -76,7 +80,12 @@ struct IfChangeRec
 typedef struct IfChangeRec IfChangeRec;
 
 // Note that static data is initialized to zero in (modern) C.
+#ifndef __rtems__
 static fd_set gEventFDs;
+#else /* __rtems__ */
+static fd_set *gAllocatedEventFDs;
+#define gEventFDs (*gAllocatedEventFDs)
+#endif /* __rtems__ */
 static int gMaxFD;                              // largest fd in gEventFDs
 static GenLinkedList gEventSources;             // linked list of PosixEventSource's
 static sigset_t gEventSignalSet;                // Signals which event loop listens for
@@ -439,6 +448,15 @@ mDNSexport mDNSBool mDNSPlatformSetDNSConfig(mDNSBool setservers, mDNSBool setse
     (void) RegDomains;
     (void) BrowseDomains;
     (void) ackConfig;
+#ifdef __rtems__
+    /*
+     * Copied from mDNSMacOSX/mDNSMacOSX.c to prevent use of uninitialized
+     * stack variables.
+     */
+    if (fqdn         ) fqdn->c[0]      = 0;
+    if (RegDomains   ) *RegDomains     = NULL;
+    if (BrowseDomains) *BrowseDomains  = NULL;
+#endif /* __rtems__ */
 
     return mDNStrue;
 }
@@ -657,6 +675,7 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
         #endif
         if (err < 0) { err = errno; perror("setsockopt - SO_REUSExxxx"); }
 
+#ifndef __rtems__
         // Enable inbound packets on IFEF_AWDL interface.
         // Only done for multicast sockets, since we don't expect unicast socket operations
         // on the IFEF_AWDL interface. Operation is a no-op for other interface types.
@@ -664,6 +683,7 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
         #define SO_RECV_ANYIF   0x1104      /* unrestricted inbound processing */
         #endif
         if (setsockopt(*sktPtr, SOL_SOCKET, SO_RECV_ANYIF, &kOn, sizeof(kOn)) < 0) perror("setsockopt - SO_RECV_ANYIF");
+#endif /* __rtems__ */
     }
 
     // We want to receive destination addresses and interface identifiers.
@@ -1208,14 +1228,23 @@ mDNSlocal mDNSu32       ProcessRoutingNotification(int sd)
 mDNSlocal void InterfaceChangeCallback(int fd, short filter, void *context)
 {
     IfChangeRec     *pChgRec = (IfChangeRec*) context;
+#ifndef __rtems__
     fd_set readFDs;
+#else /* __rtems__ */
+    fd_set bigEnoughReadFDs[howmany(rtems_libio_number_iops, sizeof(fd_set) * 8)];
+#define readFDs (*(&bigEnoughReadFDs[0]))
+#endif /* __rtems__ */
     mDNSu32 changedInterfaces = 0;
     struct timeval zeroTimeout = { 0, 0 };
 
     (void)fd; // Unused
     (void)filter; // Unused
 
+#ifndef __rtems__
     FD_ZERO(&readFDs);
+#else /* __rtems__ */
+    memset(bigEnoughReadFDs, 0, sizeof(bigEnoughReadFDs));
+#endif /* __rtems__ */
     FD_SET(pChgRec->NotifySD, &readFDs);
 
     do
@@ -1272,6 +1301,9 @@ mDNSexport mStatus mDNSPlatformInit(mDNS *const m)
 {
     int err = 0;
     struct sockaddr sa;
+#ifdef __rtems__
+    pthread_mutexattr_t attr;
+#endif /* __rtems__ */
     assert(m != NULL);
 
     if (mDNSPlatformInit_CanReceiveUnicast()) m->CanReceiveUnicastOn5353 = mDNStrue;
@@ -1289,6 +1321,16 @@ mDNSexport mStatus mDNSPlatformInit(mDNS *const m)
     if (m->hostlabel.c[0] == 0) MakeDomainLabelFromLiteralString(&m->hostlabel, "Computer");
 
     mDNS_SetFQDN(m);
+#ifdef __rtems__
+    if (err == mStatus_NoError) {
+        gAllocatedEventFDs = calloc(howmany(rtems_libio_number_iops, sizeof(fd_set) * 8), sizeof(fd_set));
+        if (gAllocatedEventFDs == NULL) err = mStatus_NoMemoryErr;
+    }
+    if (err == mStatus_NoError) err = pthread_mutexattr_init(&attr);
+    if (err == mStatus_NoError) err = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
+    if (err == mStatus_NoError) err = pthread_mutex_init(&m->p->mutex, &attr);
+    if (err == mStatus_NoError) err = pthread_mutexattr_destroy(&attr);
+#endif /* __rtems__ */
 
     sa.sa_family = AF_INET;
     m->p->unicastSocket4 = -1;
@@ -1373,14 +1415,22 @@ mDNSexport mStatus mDNSPlatformPosixRefreshInterfaceList(mDNS *const m)
 // the platform from reentering mDNS core code.
 mDNSexport void    mDNSPlatformLock   (const mDNS *const m)
 {
+#ifndef __rtems__
     (void) m;   // Unused
+#else /* __rtems__ */
+    pthread_mutex_lock(&m->p->mutex);
+#endif /* __rtems__ */
 }
 
 // mDNS core calls this routine when it release the lock taken by
 // mDNSPlatformLock and allow the platform to reenter mDNS core code.
 mDNSexport void    mDNSPlatformUnlock (const mDNS *const m)
 {
+#ifndef __rtems__
     (void) m;   // Unused
+#else /* __rtems__ */
+    pthread_mutex_unlock(&m->p->mutex);
+#endif /* __rtems__ */
 }
 
 #if COMPILER_LIKES_PRAGMA_MARK
@@ -1755,8 +1805,10 @@ mStatus mDNSPosixAddFDToEventLoop(int fd, mDNSPosixEventCallback callback, void
     if (gEventSources.LinkOffset == 0)
         InitLinkedList(&gEventSources, offsetof(PosixEventSource, Next));
 
+#ifndef __rtems__
     if (fd >= (int) FD_SETSIZE || fd < 0)
         return mStatus_UnsupportedErr;
+#endif /* __rtems__ */
     if (callback == NULL)
         return mStatus_BadParamErr;
 
@@ -1836,7 +1888,13 @@ mStatus mDNSPosixIgnoreSignalInEventLoop(int signum)
 mStatus mDNSPosixRunEventLoopOnce(mDNS *m, const struct timeval *pTimeout,
                                   sigset_t *pSignalsReceived, mDNSBool *pDataDispatched)
 {
+#ifndef __rtems__
     fd_set listenFDs = gEventFDs;
+#else /* __rtems__ */
+    fd_set bigEnoughListenFDs[howmany(rtems_libio_number_iops, sizeof(fd_set) * 8)];
+#define listenFDs (*(&bigEnoughListenFDs[0]))
+    memcpy(bigEnoughListenFDs, gAllocatedEventFDs, sizeof(bigEnoughListenFDs));
+#endif /* __rtems__ */
     int fdMax = 0, numReady;
     struct timeval timeout = *pTimeout;
 
diff --git a/mDNSResponder/mDNSPosix/mDNSPosix.h b/mDNSResponder/mDNSPosix/mDNSPosix.h
index ca60d806..acff9c33 100755
--- a/mDNSResponder/mDNSPosix/mDNSPosix.h
+++ b/mDNSResponder/mDNSPosix/mDNSPosix.h
@@ -20,6 +20,9 @@
 
 #include <signal.h>
 #include <sys/time.h>
+#ifdef __rtems__
+#include <pthread.h>
+#endif /* __rtems__ */
 
 #ifdef  __cplusplus
 extern "C" {
@@ -55,6 +58,9 @@ struct mDNS_PlatformSupport_struct
 #if HAVE_IPV6
     int unicastSocket6;
 #endif
+#ifdef __rtems__
+    pthread_mutex_t mutex;
+#endif /* __rtems__ */
 };
 
 #define uDNS_SERVERS_FILE "/etc/resolv.conf"
diff --git a/mDNSResponder/mDNSPosix/mDNSUNP.c b/mDNSResponder/mDNSPosix/mDNSUNP.c
index e00ddd62..148a3594 100755
--- a/mDNSResponder/mDNSPosix/mDNSUNP.c
+++ b/mDNSResponder/mDNSPosix/mDNSUNP.c
@@ -256,7 +256,7 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
     lastlen = 0;
     len = 100 * sizeof(struct ifreq);   /* initial buffer size guess */
     for ( ; ; ) {
-        buf = (char*)malloc(len);
+        buf = (char*)calloc(1, len);
         if (buf == NULL) {
             goto gotError;
         }
diff --git a/mDNSResponder/mDNSShared/dnssd_clientshim.c b/mDNSResponder/mDNSShared/dnssd_clientshim.c
index c0a309d5..04806f8a 100644
--- a/mDNSResponder/mDNSShared/dnssd_clientshim.c
+++ b/mDNSResponder/mDNSShared/dnssd_clientshim.c
@@ -25,6 +25,8 @@
 
 #include "dns_sd.h"             // Defines the interface to the client layer above
 #include "mDNSEmbeddedAPI.h"        // The interface we're building on top of
+#include <sys/socket.h>
+#include <netinet/in.h>
 extern mDNS mDNSStorage;        // We need to pass the address of this storage to the lower-layer functions
 
 #if MDNS_BUILDINGSHAREDLIBRARY || MDNS_BUILDINGSTUBLIBRARY
@@ -68,6 +70,14 @@ typedef struct
     DNSQuestion q;
 } mDNS_DirectOP_Browse;
 
+typedef struct
+{
+    mDNS_DirectOP_Dispose  *disposefn;
+    DNSServiceRef aQuery;
+    DNSServiceGetAddrInfoReply callback;
+    void *context;
+} mDNS_DirectOP_GetAddrInfo;
+
 typedef struct
 {
     mDNS_DirectOP_Dispose  *disposefn;
@@ -261,6 +271,7 @@ DNSServiceErrorType DNSServiceRegister
     err = mDNS_RegisterService(&mDNSStorage, &x->s,
                                &x->name, &t, &d, // Name, type, domain
                                &x->host, port, // Host and port
+                               mDNSNULL,
                                txtRecord, txtLen, // TXT data, length
                                SubTypes, NumSubTypes, // Subtypes
                                mDNSInterface_Any, // Interface ID
@@ -674,7 +685,7 @@ DNSServiceErrorType DNSServiceQueryRecord
     x->q.ExpectUnique        = mDNSfalse;
     x->q.ForceMCast          = (flags & kDNSServiceFlagsForceMulticast) != 0;
     x->q.ReturnIntermed      = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
-    x->q.SuppressUnsable     = (flags & kDNSServiceFlagsSuppressUnusable) != 0;
+    x->q.SuppressUnusable    = (flags & kDNSServiceFlagsSuppressUnusable) != 0;
     x->q.SearchListIndex     = 0;
     x->q.AppendSearchDomains = 0;
     x->q.RetryWithSearchDomains = mDNSfalse;
diff --git a/mDNSResponder/mDNSShared/mDNSDebug.c b/mDNSResponder/mDNSShared/mDNSDebug.c
index dfe77a1d..aa6e662a 100644
--- a/mDNSResponder/mDNSShared/mDNSDebug.c
+++ b/mDNSResponder/mDNSShared/mDNSDebug.c
@@ -60,7 +60,11 @@ mDNSlocal void LogMsgWithLevelv(mDNSLogLevel_t logLevel, const char *format, va_
 {
     char buffer[512];
     buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
+#ifndef __rtems__
     mDNSPlatformWriteLogMsg(ProgramName, buffer, logLevel);
+#else /* __rtems__ */
+    mDNSPlatformWriteLogMsg(NULL, buffer, logLevel);
+#endif /* __rtems__ */
 }
 
 #define LOG_HELPER_BODY(L) \
diff --git a/testsuite/foobarserver/test_main.c b/testsuite/foobarserver/test_main.c
index 84c40c4d..be841bd4 100644
--- a/testsuite/foobarserver/test_main.c
+++ b/testsuite/foobarserver/test_main.c
@@ -110,7 +110,7 @@ foobar_register(mDNSu16 port)
 	MakeDomainNameFromDNSNameString(&domain, "local.");
 
 	status = mDNS_RegisterService(&mDNSStorage, srs, &name, &type, &domain,
-	    NULL, mDNSOpaque16fromIntVal(port), NULL, 0, NULL, 0,
+	    NULL, mDNSOpaque16fromIntVal(port), NULL, NULL, 0, NULL, 0,
 	    mDNSInterface_Any, foobar_callback, srs, 0);
 	assert(status == mStatus_NoError);
 
-- 
2.26.2



More information about the devel mailing list