From 6da0dda3255e2a49365aee6904fe00d4f2ca9d68 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 18 Jun 2020 14:22:10 +0200 Subject: mDNSResponder: Port to RTEMS 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 #include #include // platform support for UTC time +#ifdef __rtems__ +#include +#include +#endif /* __rtems__ */ #if USES_NETLINK #include @@ -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 #include +#ifdef __rtems__ +#include +#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 +#include 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); -- cgit v1.2.3