mDNSlocal mStatus MakeTCPConnection(mDNS *const m, tcpLNTInfo *info, const mDNSAddr *const Addr, const mDNSIPPort Port, LNTOp_t op) { mStatus err = mStatus_NoError; mDNSIPPort srcport = zeroIPPort; if (mDNSIPv4AddressIsZero(Addr->ip.v4) || mDNSIPPortIsZero(Port)) { LogMsg("LNT MakeTCPConnection: bad address/port %#a:%d", Addr, mDNSVal16(Port)); return(mStatus_Invalid); } info->m = m; info->Address = *Addr; info->Port = Port; info->op = op; info->nread = 0; info->replyLen = LNT_MAXBUFSIZE; if (info->Reply != mDNSNULL) mDNSPlatformMemZero(info->Reply, LNT_MAXBUFSIZE); // reuse previously allocated buffer else if ((info->Reply = (mDNSs8 *) mDNSPlatformMemAllocate(LNT_MAXBUFSIZE)) == mDNSNULL) { LogInfo("can't allocate reply buffer"); return (mStatus_NoMemoryErr); } if (info->sock) { LogInfo("MakeTCPConnection: closing previous open connection"); mDNSPlatformTCPCloseConnection(info->sock); info->sock = mDNSNULL; } info->sock = mDNSPlatformTCPSocket(m, kTCPSocketFlags_Zero, &srcport); if (!info->sock) { LogMsg("LNT MakeTCPConnection: unable to create TCP socket"); mDNSPlatformMemFree(info->Reply); info->Reply = mDNSNULL; return(mStatus_NoMemoryErr); } LogInfo("MakeTCPConnection: connecting to %#a:%d", &info->Address, mDNSVal16(info->Port)); err = mDNSPlatformTCPConnect(info->sock, Addr, Port, 0, tcpConnectionCallback, info); if (err == mStatus_ConnPending) err = mStatus_NoError; else if (err == mStatus_ConnEstablished) { mDNS_DropLockBeforeCallback(); tcpConnectionCallback(info->sock, info, mDNStrue, mStatus_NoError); mDNS_ReclaimLockAfterCallback(); err = mStatus_NoError; } else { // Don't need to log this in customer builds -- it happens quite often during sleep, wake, configuration changes, etc. LogInfo("LNT MakeTCPConnection: connection failed"); mDNSPlatformTCPCloseConnection(info->sock); // Dispose the socket we created with mDNSPlatformTCPSocket() above info->sock = mDNSNULL; mDNSPlatformMemFree(info->Reply); info->Reply = mDNSNULL; } return(err); }
// Send a DNSSEC probe just for the sake of collecting DNSSEC statistics. mDNSexport void DNSSECProbe(mDNS *const m) { mDNSu32 rand; if (DNSSECProbeQuestion.ThisQInterval != -1) return; rand = mDNSRandom(0x3FFFFFFF) % 100; // Probe 5% of the time if (rand > 5) return; mDNS_DropLockBeforeCallback(); InitializeQuestion(m, &DNSSECProbeQuestion, mDNSInterface_Any, (const domainname *)"\003com", kDNSType_DS, DNSSECProbeCallback, mDNSNULL); DNSSECProbeQuestion.ValidatingResponse = 0; DNSSECProbeQuestion.ValidationRequired = DNSSEC_VALIDATION_SECURE; BumpDNSSECStats(m, kStatsActionIncrement, kStatsTypeProbe, 1); mDNS_StartQuery(m, &DNSSECProbeQuestion); mDNS_ReclaimLockAfterCallback(); }