Skip to content

Commit cec79eb

Browse files
committed
[mdns] fix service loss on mDNSResponder daemon restart
1 parent eeda311 commit cec79eb

2 files changed

Lines changed: 165 additions & 65 deletions

File tree

src/mdns/mdns_mdnssd.cpp

Lines changed: 141 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,22 @@ PublisherMDnsSd::~PublisherMDnsSd(void)
267267
otbrError PublisherMDnsSd::Start(void)
268268
{
269269
mState = State::kReady;
270+
271+
for (const auto &kv : mServiceRegistrations)
272+
{
273+
static_cast<DnssdServiceRegistration &>(*kv.second).Register();
274+
}
275+
276+
for (const auto &kv : mHostRegistrations)
277+
{
278+
static_cast<DnssdHostRegistration &>(*kv.second).Register();
279+
}
280+
281+
for (const auto &kv : mKeyRegistrations)
282+
{
283+
static_cast<DnssdKeyRegistration &>(*kv.second).Register();
284+
}
285+
270286
mStateCallback(State::kReady);
271287
return OTBR_ERROR_NONE;
272288
}
@@ -289,18 +305,32 @@ void PublisherMDnsSd::Stop(StopMode aStopMode)
289305
switch (aStopMode)
290306
{
291307
case kNormalStop:
308+
mServiceRegistrations.clear();
309+
mHostRegistrations.clear();
310+
mKeyRegistrations.clear();
311+
DeallocateHostsRef();
292312
break;
293313

294314
case kStopOnServiceNotRunningError:
315+
for (const auto &kv : mServiceRegistrations)
316+
{
317+
static_cast<DnssdServiceRegistration &>(*kv.second).Unregister();
318+
}
319+
320+
for (const auto &kv : mHostRegistrations)
321+
{
322+
static_cast<DnssdHostRegistration &>(*kv.second).Unregister();
323+
}
324+
325+
for (const auto &kv : mKeyRegistrations)
326+
{
327+
static_cast<DnssdKeyRegistration &>(*kv.second).Unregister();
328+
}
329+
295330
DeallocateHostsRef();
296331
break;
297332
}
298333

299-
mServiceRegistrations.clear();
300-
mHostRegistrations.clear();
301-
mKeyRegistrations.clear();
302-
DeallocateHostsRef();
303-
304334
mSubscribedServices.clear();
305335
mSubscribedHosts.clear();
306336

@@ -340,31 +370,49 @@ void PublisherMDnsSd::Update(MainloopContext &aMainloop)
340370
{
341371
mTaskRunner.Update(aMainloop);
342372

343-
for (auto &kv : mServiceRegistrations)
373+
for (const auto &kv : mServiceRegistrations)
344374
{
345375
auto &serviceReg = static_cast<DnssdServiceRegistration &>(*kv.second);
346376

347-
serviceReg.Update(aMainloop);
377+
SuccessOrExit(serviceReg.Update(aMainloop), {
378+
Stop(kStopOnServiceNotRunningError);
379+
Start();
380+
});
348381
}
349382

350383
if (mHostsRef != nullptr)
351384
{
352385
int fd = DNSServiceRefSockFD(mHostsRef);
353386

354-
assert(fd != -1);
387+
if (fd == -1)
388+
{
389+
otbrLogWarning("mDNS connection socket is invalid, reconnecting...");
390+
Stop(kStopOnServiceNotRunningError);
391+
Start();
392+
ExitNow();
393+
}
355394

356395
aMainloop.AddFdToReadSet(fd);
357396
}
358397

359398
for (const auto &service : mSubscribedServices)
360399
{
361-
service->UpdateAll(aMainloop);
400+
SuccessOrExit(service->UpdateAll(aMainloop), {
401+
Stop(kStopOnServiceNotRunningError);
402+
Start();
403+
});
362404
}
363405

364406
for (const auto &host : mSubscribedHosts)
365407
{
366-
host->Update(aMainloop);
408+
SuccessOrExit(host->Update(aMainloop), {
409+
Stop(kStopOnServiceNotRunningError);
410+
Start();
411+
});
367412
}
413+
414+
exit:
415+
return;
368416
}
369417

370418
void PublisherMDnsSd::Process(const MainloopContext &aMainloop)
@@ -373,17 +421,28 @@ void PublisherMDnsSd::Process(const MainloopContext &aMainloop)
373421

374422
mTaskRunner.Process(aMainloop);
375423

376-
for (auto &kv : mServiceRegistrations)
424+
for (const auto &kv : mServiceRegistrations)
377425
{
378426
auto &serviceReg = static_cast<DnssdServiceRegistration &>(*kv.second);
379427

380-
serviceReg.Process(aMainloop, mServiceRefsToProcess);
428+
SuccessOrExit(serviceReg.Process(aMainloop, mServiceRefsToProcess), {
429+
Stop(kStopOnServiceNotRunningError);
430+
Start();
431+
});
381432
}
382433

383434
if (mHostsRef != nullptr)
384435
{
385436
int fd = DNSServiceRefSockFD(mHostsRef);
386437

438+
if (fd == -1)
439+
{
440+
otbrLogWarning("mDNS connection socket is invalid, reconnecting...");
441+
Stop(kStopOnServiceNotRunningError);
442+
Start();
443+
ExitNow();
444+
}
445+
387446
if (FD_ISSET(fd, &aMainloop.mReadFdSet))
388447
{
389448
mServiceRefsToProcess.push_back(mHostsRef);
@@ -392,12 +451,18 @@ void PublisherMDnsSd::Process(const MainloopContext &aMainloop)
392451

393452
for (const auto &service : mSubscribedServices)
394453
{
395-
service->ProcessAll(aMainloop, mServiceRefsToProcess);
454+
SuccessOrExit(service->ProcessAll(aMainloop, mServiceRefsToProcess), {
455+
Stop(kStopOnServiceNotRunningError);
456+
Start();
457+
});
396458
}
397459

398460
for (const auto &host : mSubscribedHosts)
399461
{
400-
host->Process(aMainloop, mServiceRefsToProcess);
462+
SuccessOrExit(host->Process(aMainloop, mServiceRefsToProcess), {
463+
Stop(kStopOnServiceNotRunningError);
464+
Start();
465+
});
401466
}
402467

403468
for (DNSServiceRef serviceRef : mServiceRefsToProcess)
@@ -428,14 +493,15 @@ void PublisherMDnsSd::Process(const MainloopContext &aMainloop)
428493
otbrLog(logLevel, OTBR_LOG_TAG, "DNSServiceProcessResult failed: %s (serviceRef = %p)",
429494
DNSErrorToString(error), serviceRef);
430495
}
431-
if (error == kDNSServiceErr_ServiceNotRunning)
496+
if (IsRetryableError(error))
432497
{
433-
otbrLogWarning("Need to reconnect to mdnsd");
498+
otbrLogWarning("mDNS error %d, need to reconnect to mdnsd", error);
434499
Stop(kStopOnServiceNotRunningError);
435500
Start();
436501
ExitNow();
437502
}
438503
}
504+
439505
exit:
440506
return;
441507
}
@@ -451,36 +517,48 @@ void PublisherMDnsSd::HandleServiceRefDeallocating(const DNSServiceRef &aService
451517
}
452518
}
453519

454-
void PublisherMDnsSd::DnssdServiceRegistration::Update(MainloopContext &aMainloop) const
520+
otbrError PublisherMDnsSd::DnssdServiceRegistration::Update(MainloopContext &aMainloop) const
455521
{
456-
int fd;
522+
otbrError error = OTBR_ERROR_NONE;
523+
int fd;
457524

458525
VerifyOrExit(mServiceRef != nullptr);
459526

460527
fd = DNSServiceRefSockFD(mServiceRef);
461-
VerifyOrExit(fd != -1);
528+
if (fd == -1)
529+
{
530+
otbrLogWarning("mDNS connection socket is invalid");
531+
error = OTBR_ERROR_INVALID_STATE;
532+
ExitNow();
533+
}
462534

463535
aMainloop.AddFdToReadSet(fd);
464536

465537
exit:
466-
return;
538+
return error;
467539
}
468540

469-
void PublisherMDnsSd::DnssdServiceRegistration::Process(const MainloopContext &aMainloop,
470-
std::vector<DNSServiceRef> &aReadyServices) const
541+
otbrError PublisherMDnsSd::DnssdServiceRegistration::Process(const MainloopContext &aMainloop,
542+
std::vector<DNSServiceRef> &aReadyServices) const
471543
{
472-
int fd;
544+
otbrError error = OTBR_ERROR_NONE;
545+
int fd;
473546

474547
VerifyOrExit(mServiceRef != nullptr);
475548

476549
fd = DNSServiceRefSockFD(mServiceRef);
477-
VerifyOrExit(fd != -1);
550+
if (fd == -1)
551+
{
552+
otbrLogWarning("mDNS connection socket is invalid");
553+
error = OTBR_ERROR_INVALID_STATE;
554+
ExitNow();
555+
}
478556

479557
VerifyOrExit(FD_ISSET(fd, &aMainloop.mReadFdSet));
480558
aReadyServices.push_back(mServiceRef);
481559

482560
exit:
483-
return;
561+
return error;
484562
}
485563

486564
otbrError PublisherMDnsSd::DnssdServiceRegistration::Register(void)
@@ -1113,34 +1191,46 @@ void PublisherMDnsSd::ServiceRef::DeallocateServiceRef(void)
11131191
}
11141192
}
11151193

1116-
void PublisherMDnsSd::ServiceRef::Update(MainloopContext &aMainloop) const
1194+
otbrError PublisherMDnsSd::ServiceRef::Update(MainloopContext &aMainloop) const
11171195
{
1118-
int fd;
1196+
otbrError error = OTBR_ERROR_NONE;
1197+
int fd;
11191198

11201199
VerifyOrExit(mServiceRef != nullptr);
11211200

11221201
fd = DNSServiceRefSockFD(mServiceRef);
1123-
assert(fd != -1);
1202+
if (fd == -1)
1203+
{
1204+
otbrLogWarning("mDNS connection socket is invalid");
1205+
error = OTBR_ERROR_INVALID_STATE;
1206+
ExitNow();
1207+
}
11241208
aMainloop.AddFdToReadSet(fd);
11251209
exit:
1126-
return;
1210+
return error;
11271211
}
11281212

1129-
void PublisherMDnsSd::ServiceRef::Process(const MainloopContext &aMainloop,
1130-
std::vector<DNSServiceRef> &aReadyServices) const
1213+
otbrError PublisherMDnsSd::ServiceRef::Process(const MainloopContext &aMainloop,
1214+
std::vector<DNSServiceRef> &aReadyServices) const
11311215
{
1132-
int fd;
1216+
otbrError error = OTBR_ERROR_NONE;
1217+
int fd;
11331218

11341219
VerifyOrExit(mServiceRef != nullptr);
11351220

11361221
fd = DNSServiceRefSockFD(mServiceRef);
1137-
assert(fd != -1);
1222+
if (fd == -1)
1223+
{
1224+
otbrLogWarning("mDNS connection socket is invalid");
1225+
error = OTBR_ERROR_INVALID_STATE;
1226+
ExitNow();
1227+
}
11381228
if (FD_ISSET(fd, &aMainloop.mReadFdSet))
11391229
{
11401230
aReadyServices.push_back(mServiceRef);
11411231
}
11421232
exit:
1143-
return;
1233+
return error;
11441234
}
11451235

11461236
void PublisherMDnsSd::ServiceSubscription::Release(void)
@@ -1247,25 +1337,35 @@ void PublisherMDnsSd::ServiceSubscription::Remove(uint32_t aInterfaceI
12471337
}
12481338
}
12491339

1250-
void PublisherMDnsSd::ServiceSubscription::UpdateAll(MainloopContext &aMainloop) const
1340+
otbrError PublisherMDnsSd::ServiceSubscription::UpdateAll(MainloopContext &aMainloop) const
12511341
{
1252-
Update(aMainloop);
1342+
otbrError error = OTBR_ERROR_NONE;
1343+
1344+
SuccessOrExit(error = Update(aMainloop));
12531345

12541346
for (const auto &instance : mResolvingInstances)
12551347
{
1256-
instance->Update(aMainloop);
1348+
SuccessOrExit(error = instance->Update(aMainloop));
12571349
}
1350+
1351+
exit:
1352+
return error;
12581353
}
12591354

1260-
void PublisherMDnsSd::ServiceSubscription::ProcessAll(const MainloopContext &aMainloop,
1261-
std::vector<DNSServiceRef> &aReadyServices) const
1355+
otbrError PublisherMDnsSd::ServiceSubscription::ProcessAll(const MainloopContext &aMainloop,
1356+
std::vector<DNSServiceRef> &aReadyServices) const
12621357
{
1263-
Process(aMainloop, aReadyServices);
1358+
otbrError error = OTBR_ERROR_NONE;
1359+
1360+
SuccessOrExit(error = Process(aMainloop, aReadyServices));
12641361

12651362
for (const auto &instance : mResolvingInstances)
12661363
{
1267-
instance->Process(aMainloop, aReadyServices);
1364+
SuccessOrExit(error = instance->Process(aMainloop, aReadyServices));
12681365
}
1366+
1367+
exit:
1368+
return error;
12691369
}
12701370

12711371
bool PublisherMDnsSd::ServiceInstanceResolution::Matches(uint32_t aInterfaceIndex,

0 commit comments

Comments
 (0)