00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "TBonjourResolver.h"
00026 #include "TBonjourRecord.h"
00027 #include "TSysEvtHandler.h"
00028 #include "TSystem.h"
00029 #include "TError.h"
00030
00031 #include <arpa/inet.h>
00032
00033
00034 ClassImp(TBonjourResolver)
00035
00036
00037 TBonjourResolver::TBonjourResolver() : fDNSRef(0), fBonjourSocketHandler(0)
00038 {
00039
00040 }
00041
00042
00043 TBonjourResolver::~TBonjourResolver()
00044 {
00045
00046
00047 delete fBonjourSocketHandler;
00048
00049 if (fDNSRef) {
00050 DNSServiceRefDeallocate(fDNSRef);
00051 fDNSRef = 0;
00052 }
00053 }
00054
00055
00056 Int_t TBonjourResolver::ResolveBonjourRecord(const TBonjourRecord &record)
00057 {
00058
00059
00060
00061 if (fDNSRef) {
00062 Warning("ResolveBonjourRecord", "resolve already in process");
00063 return 0;
00064 }
00065
00066 DNSServiceErrorType err = DNSServiceResolve(&fDNSRef, 0, 0,
00067 record.GetServiceName(),
00068 record.GetRegisteredType(),
00069 record.GetReplyDomain(),
00070 (DNSServiceResolveReply)BonjourResolveReply,
00071 this);
00072 if (err != kDNSServiceErr_NoError) {
00073 Error("ResolveBonjourRecord", "error in DNSServiceResolve (%d)", err);
00074 return -1;
00075 }
00076
00077 Int_t sockfd = DNSServiceRefSockFD(fDNSRef);
00078 if (sockfd == -1) {
00079 Error("ResolveBonjourRecord", "invalide sockfd");
00080 return -1;
00081 }
00082
00083 fBonjourSocketHandler = new TFileHandler(sockfd, TFileHandler::kRead);
00084 fBonjourSocketHandler->Connect("Notified()", "TBonjourResolver", this, "BonjourSocketReadyRead()");
00085 fBonjourSocketHandler->Add();
00086
00087 return 0;
00088 }
00089
00090
00091 void TBonjourResolver::RecordResolved(const TInetAddress *hostInfo, Int_t port)
00092 {
00093
00094
00095 Long_t args[2];
00096 args[0] = (Long_t) hostInfo;
00097 args[1] = port;
00098
00099 Emit("RecordResolved(TInetAddress*,Int_t)", args);
00100 }
00101
00102
00103 void TBonjourResolver::BonjourSocketReadyRead()
00104 {
00105
00106
00107
00108
00109
00110 if (!fDNSRef) return;
00111
00112 DNSServiceErrorType err = DNSServiceProcessResult(fDNSRef);
00113 if (err != kDNSServiceErr_NoError)
00114 Error("BonjourSocketReadyRead", "error in DNSServiceProcessResult");
00115 }
00116
00117
00118 void TBonjourResolver::BonjourResolveReply(DNSServiceRef,
00119 DNSServiceFlags, UInt_t,
00120 DNSServiceErrorType errorCode, const char *,
00121 const char *hostTarget, UShort_t port,
00122 UShort_t, const char *txtRecord,
00123 void *context)
00124 {
00125
00126
00127 TBonjourResolver *resolver = static_cast<TBonjourResolver *>(context);
00128 if (errorCode != kDNSServiceErr_NoError) {
00129 ::Error("TBonjourResolver::BonjourResolveReply", "error in BonjourResolveReply");
00130
00131 } else {
00132 resolver->fPort = ntohs(port);
00133 resolver->fHostAddress = gSystem->GetHostByName(hostTarget);
00134 resolver->fTXTRecord = txtRecord;
00135 resolver->RecordResolved(&resolver->fHostAddress, resolver->fPort);
00136 }
00137 }