xrootd
|
00001 #ifndef __XRDOUCAvahiBONJOUR_HH__ 00002 #define __XRDOUCAvahiBONJOUR_HH__ 00003 00004 #include <avahi-client/client.h> 00005 #include <avahi-client/lookup.h> 00006 #include <avahi-client/publish.h> 00007 #include <avahi-common/alternative.h> 00008 #include <avahi-common/simple-watch.h> 00009 #include <avahi-common/malloc.h> 00010 #include <avahi-common/error.h> 00011 #include <avahi-common/timeval.h> 00012 00013 #include <list> 00014 #include "XrdOuc/XrdOucBonjour.hh" 00015 #include "XrdOuc/XrdOucString.hh" 00016 #include "XrdSys/XrdSysPthread.hh" 00017 00018 /******************************************************************************/ 00019 /* B o n j o u r s e r v i c e s */ 00020 /******************************************************************************/ 00021 00022 class XrdOucAvahiBonjour : public XrdOucBonjour { 00023 private: 00024 // Singleton instance. 00025 static XrdOucAvahiBonjour *_Instance; 00026 00027 // Mutex to protect the construction of the instance. 00028 static XrdSysMutex SingletonMutex; 00029 00030 // All the constructors are private in order to disable object creation, 00031 // copy or assignment. 00032 XrdOucAvahiBonjour(); 00033 virtual ~XrdOucAvahiBonjour(); 00034 XrdOucAvahiBonjour(const XrdOucAvahiBonjour &) { } 00035 XrdOucAvahiBonjour &operator=(const XrdOucAvahiBonjour &) { 00036 return *this; 00037 } 00038 00039 // This a trick to ensure that the singleton object will be deleted when 00040 // the class is unloaded at program shutdown. 00041 friend class XrdOucAvahiBonjourSingletonCleanup; 00042 class XrdOucAvahiBonjourSingletonCleanup { 00043 public: 00044 ~XrdOucAvahiBonjourSingletonCleanup(); 00045 }; 00046 00047 class XrdOucAvahiBonjourSearchNode { 00048 private: 00049 const char * ServiceName; 00050 00051 public: 00052 XrdOucAvahiBonjourSearchNode(const char * name) { 00053 ServiceName = name; 00054 } 00055 bool operator()(XrdOucBonjourNode * value); 00056 }; 00057 00058 // List of registered services we have. We mantain this since the service 00059 // ref is needed to keep alive in order to matain the registration. In 00060 // this moment a function to release registrations is not needed since 00061 // protocols live as much as the whole process. 00062 std::list<XrdOucBonjourRegisteredEntry *> ListOfRegistrations; 00063 00064 // Internal thread that updates the node list as updates come from the 00065 // dns responder. 00066 pthread_t BrowseEventLoopThreadInfo; 00067 static void * BrowseEventLoopThread(void * context); 00068 00069 // Avahi poller that implements the event loop. 00070 AvahiSimplePoll * poller; 00071 00072 // Callback functions for the Avahi services (similar to the ones in the 00073 // Apple Bonjour version). 00074 static void RegisterReply(AvahiClient *c, 00075 AvahiClientState state, 00076 void * userdata); 00077 00078 static void RegisterEntries(XrdOucBonjourRegisteredEntry * entry); 00079 00080 static void EntryGroupReply(AvahiEntryGroup *g, 00081 AvahiEntryGroupState state, 00082 void *userdata); 00083 00084 static void ClientReply(AvahiClient *c, 00085 AvahiClientState state, 00086 void * userdata); 00087 00088 static void BrowseReply(AvahiServiceBrowser *b, 00089 AvahiIfIndex interface, 00090 AvahiProtocol protocol, 00091 AvahiBrowserEvent event, 00092 const char *name, 00093 const char *type, 00094 const char *domain, 00095 AvahiLookupResultFlags flags, 00096 void* userdata); 00097 00098 static void ResolveReply(AvahiServiceResolver *r, 00099 AvahiIfIndex interface, 00100 AvahiProtocol protocol, 00101 AvahiResolverEvent event, 00102 const char *name, 00103 const char *type, 00104 const char *domain, 00105 const char *host_name, 00106 const AvahiAddress *address, 00107 uint16_t port, 00108 AvahiStringList *txt, 00109 AvahiLookupResultFlags flags, 00110 void* userdata); 00111 00112 public: 00113 // Register a service on the mDNS local service. This funcion also 00114 // subscribes the sender for updates on the discoverage service. 00115 int RegisterService(XrdOucBonjourRecord &record, 00116 unsigned short port = 0); 00117 00118 // Subscribes a new client to receive updates about service discoveries. 00119 // This will detatch a new thread to process the updates, running (when 00120 // a new update arrives) the callback function in its own thread. This 00121 // function mush be thread-safe, and its responsability of the client 00122 // to ensure that. 00123 int SubscribeForUpdates(const char * servicetype, 00124 XrdOucBonjourUpdateCallback callback, 00125 void * context); 00126 00127 // Resolves the name of a node. If you provides a pointer to a node 00128 // object, this function completes the current information about hostname 00129 // and port. It is important to use the resolution by-demand since the list 00130 // may not contain updated information due to the use of highly dynamical 00131 // DHCP and APIPA addresses. 00132 int ResolveNodeInformation(XrdOucBonjourResolutionEntry * nodeAndCallback); 00133 00134 // Accessor to get the singleton instance. 00135 static XrdOucAvahiBonjour &getInstance(); 00136 }; 00137 00138 /******************************************************************************/ 00139 /* A b s t r a c t f a c t o r y */ 00140 /******************************************************************************/ 00141 00142 class XrdOucAvahiBonjourFactory : public XrdOucBonjourFactory { 00143 XrdOucBonjour &GetBonjourManager() { 00144 return XrdOucAvahiBonjour::getInstance(); 00145 } 00146 }; 00147 00148 #endif