#include "TBonjourResolver.h"
#include "TBonjourRecord.h"
#include "TSysEvtHandler.h"
#include "TSystem.h"
#include "TError.h"
#include <arpa/inet.h>
ClassImp(TBonjourResolver)
TBonjourResolver::TBonjourResolver() : fDNSRef(0), fBonjourSocketHandler(0)
{
}
TBonjourResolver::~TBonjourResolver()
{
delete fBonjourSocketHandler;
if (fDNSRef) {
DNSServiceRefDeallocate(fDNSRef);
fDNSRef = 0;
}
}
Int_t TBonjourResolver::ResolveBonjourRecord(const TBonjourRecord &record)
{
if (fDNSRef) {
Warning("ResolveBonjourRecord", "resolve already in process");
return 0;
}
DNSServiceErrorType err = DNSServiceResolve(&fDNSRef, 0, 0,
record.GetServiceName(),
record.GetRegisteredType(),
record.GetReplyDomain(),
(DNSServiceResolveReply)BonjourResolveReply,
this);
if (err != kDNSServiceErr_NoError) {
Error("ResolveBonjourRecord", "error in DNSServiceResolve (%d)", err);
return -1;
}
Int_t sockfd = DNSServiceRefSockFD(fDNSRef);
if (sockfd == -1) {
Error("ResolveBonjourRecord", "invalide sockfd");
return -1;
}
fBonjourSocketHandler = new TFileHandler(sockfd, TFileHandler::kRead);
fBonjourSocketHandler->Connect("Notified()", "TBonjourResolver", this, "BonjourSocketReadyRead()");
fBonjourSocketHandler->Add();
return 0;
}
void TBonjourResolver::RecordResolved(const TInetAddress *hostInfo, Int_t port)
{
Long_t args[2];
args[0] = (Long_t) hostInfo;
args[1] = port;
Emit("RecordResolved(TInetAddress*,Int_t)", args);
}
void TBonjourResolver::BonjourSocketReadyRead()
{
if (!fDNSRef) return;
DNSServiceErrorType err = DNSServiceProcessResult(fDNSRef);
if (err != kDNSServiceErr_NoError)
Error("BonjourSocketReadyRead", "error in DNSServiceProcessResult");
}
void TBonjourResolver::BonjourResolveReply(DNSServiceRef,
DNSServiceFlags, UInt_t,
DNSServiceErrorType errorCode, const char *,
const char *hostTarget, UShort_t port,
UShort_t, const char *txtRecord,
void *context)
{
TBonjourResolver *resolver = static_cast<TBonjourResolver *>(context);
if (errorCode != kDNSServiceErr_NoError) {
::Error("TBonjourResolver::BonjourResolveReply", "error in BonjourResolveReply");
} else {
resolver->fPort = ntohs(port);
resolver->fHostAddress = gSystem->GetHostByName(hostTarget);
resolver->fTXTRecord = txtRecord;
resolver->RecordResolved(&resolver->fHostAddress, resolver->fPort);
}
}