ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TBonjourResolver.cxx
Go to the documentation of this file.
1 // @(#)root/bonjour:$Id$
2 // Author: Fons Rademakers 29/05/2009
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 //////////////////////////////////////////////////////////////////////////
13 // //
14 // TBonjourResolver //
15 // //
16 // This class consists of one main member function, //
17 // ResolveBonjourRecord(), that resolves the service to an actual //
18 // IP address and port number. The rest of the class wraps the various //
19 // bits of Bonjour service resolver. The static callback function //
20 // is marked with the DNSSD_API macro to make sure that the callback //
21 // has the correct calling convention on Windows. //
22 // //
23 //////////////////////////////////////////////////////////////////////////
24 
25 #include "TBonjourResolver.h"
26 #include "TBonjourRecord.h"
27 #include "TSysEvtHandler.h"
28 #include "TSystem.h"
29 #include "TError.h"
30 
31 #include <arpa/inet.h>
32 
33 
35 
36 ////////////////////////////////////////////////////////////////////////////////
37 /// Default ctor.
38 
39 TBonjourResolver::TBonjourResolver() : fDNSRef(0), fBonjourSocketHandler(0), fPort(0)
40 {
41 }
42 
43 ////////////////////////////////////////////////////////////////////////////////
44 /// Cleanup.
45 
47 {
48  delete fBonjourSocketHandler;
49 
50  if (fDNSRef) {
51  DNSServiceRefDeallocate(fDNSRef);
52  fDNSRef = 0;
53  }
54 }
55 
56 ////////////////////////////////////////////////////////////////////////////////
57 /// Resolve Bonjour service to IP address and port.
58 /// Returns -1 in case of error, 0 otherwise.
59 
61 {
62  if (fDNSRef) {
63  Warning("ResolveBonjourRecord", "resolve already in process");
64  return 0;
65  }
66 
67  DNSServiceErrorType err = DNSServiceResolve(&fDNSRef, 0, 0,
68  record.GetServiceName(),
69  record.GetRegisteredType(),
70  record.GetReplyDomain(),
71  (DNSServiceResolveReply)BonjourResolveReply,
72  this);
73  if (err != kDNSServiceErr_NoError) {
74  Error("ResolveBonjourRecord", "error in DNSServiceResolve (%d)", err);
75  return -1;
76  }
77 
78  Int_t sockfd = DNSServiceRefSockFD(fDNSRef);
79  if (sockfd == -1) {
80  Error("ResolveBonjourRecord", "invalide sockfd");
81  return -1;
82  }
83 
85  fBonjourSocketHandler->Connect("Notified()", "TBonjourResolver", this, "BonjourSocketReadyRead()");
87 
88  return 0;
89 }
90 
91 ////////////////////////////////////////////////////////////////////////////////
92 /// Emit RecordResolved signal.
93 
95 {
96  Long_t args[2];
97  args[0] = (Long_t) hostInfo;
98  args[1] = port;
99 
100  Emit("RecordResolved(TInetAddress*,Int_t)", args);
101 }
102 
103 ////////////////////////////////////////////////////////////////////////////////
104 /// The Bonjour socket is ready for reading. Tell Bonjour to process the
105 /// information on the socket, this will invoke the BonjourResolveReply
106 /// callback. This is a private slot, used in ResolveBonjourRecord.
107 
109 {
110  // in case the resolver has already been deleted
111  if (!fDNSRef) return;
112 
113  DNSServiceErrorType err = DNSServiceProcessResult(fDNSRef);
114  if (err != kDNSServiceErr_NoError)
115  Error("BonjourSocketReadyRead", "error in DNSServiceProcessResult");
116 }
117 
118 ////////////////////////////////////////////////////////////////////////////////
119 /// Static Bonjour resolver callback function.
120 
122  DNSServiceFlags, UInt_t,
123  DNSServiceErrorType errorCode, const char *,
124  const char *hostTarget, UShort_t port,
125  UShort_t, const char *txtRecord,
126  void *context)
127 {
128  TBonjourResolver *resolver = static_cast<TBonjourResolver *>(context);
129  if (errorCode != kDNSServiceErr_NoError) {
130  ::Error("TBonjourResolver::BonjourResolveReply", "error in BonjourResolveReply");
131  //resolver->Error(errorCode);
132  } else {
133  resolver->fPort = ntohs(port);
134  resolver->fHostAddress = gSystem->GetHostByName(hostTarget);
135  resolver->fTXTRecord = txtRecord;
136  resolver->RecordResolved(&resolver->fHostAddress, resolver->fPort);
137  }
138 }
void BonjourSocketReadyRead()
The Bonjour socket is ready for reading.
Int_t ResolveBonjourRecord(const TBonjourRecord &record)
Resolve Bonjour service to IP address and port.
unsigned short UShort_t
Definition: RtypesCore.h:36
This class represents an Internet Protocol (IP) address.
Definition: TInetAddress.h:40
virtual void Add()
Add file event handler to system file handler list.
int Int_t
Definition: RtypesCore.h:41
void RecordResolved(const TInetAddress *hostInfo, Int_t port)
Emit RecordResolved signal.
const char * GetServiceName() const
ClassImp(TBonjourResolver) TBonjourResolver
Default ctor.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
virtual TInetAddress GetHostByName(const char *server)
Get Internet Protocol (IP) address of host.
Definition: TSystem.cxx:2193
void Emit(const char *signal)
Acitvate signal without args.
Definition: TQObject.cxx:559
virtual ~TBonjourResolver()
Cleanup.
DNSServiceRef fDNSRef
Bool_t Connect(const char *signal, const char *receiver_class, void *receiver, const char *slot)
Non-static method is used to connect from the signal of this object to the receiver slot...
Definition: TQObject.cxx:1135
R__EXTERN TSystem * gSystem
Definition: TSystem.h:545
const char * GetReplyDomain() const
unsigned int UInt_t
Definition: RtypesCore.h:42
long Long_t
Definition: RtypesCore.h:50
static void DNSSD_API BonjourResolveReply(DNSServiceRef, DNSServiceFlags, UInt_t, DNSServiceErrorType, const char *, const char *, UShort_t, UShort_t, const char *, void *)
Static Bonjour resolver callback function.
TFileHandler * fBonjourSocketHandler
const char * GetRegisteredType() const
TInetAddress fHostAddress
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904