Index: source/ariba/utility/bootstrap/modules/multicastdns/MulticastDns.cpp
===================================================================
--- source/ariba/utility/bootstrap/modules/multicastdns/MulticastDns.cpp	(revision 4733)
+++ source/ariba/utility/bootstrap/modules/multicastdns/MulticastDns.cpp	(revision 4758)
@@ -42,11 +42,10 @@
 namespace utility {
 
+const string MulticastDns::serviceType = "_spovnet._tcp";
 use_logging_cpp(MulticastDns);
 
-MulticastDns::MulticastDns(string type, BootstrapInformationCallback* _callback)
-	: BootstrapModule(type, _callback), serviceType(type){
+MulticastDns::MulticastDns(BootstrapInformationCallback* _callback) : BootstrapModule(_callback) {
   #ifdef HAVE_LIBAVAHI_CLIENT
 	avahiclient = NULL;
-	avahigroup = NULL;
 	avahipoll = NULL;
 	avahibrowser = NULL;
@@ -80,15 +79,21 @@
 	// create a new avahi polling thread
 	avahipoll = avahi_threaded_poll_new();
-	assert( avahipoll != NULL );
+	if( avahipoll == NULL){
+		logging_error("creating avahi poll failed");
+		return;
+	}
 
 	// create a new avahi client
 	avahiclient = avahi_client_new( avahi_threaded_poll_get(avahipoll),
 			(AvahiClientFlags)0, MulticastDns::client_callback, this, &error );
-	assert( avahiclient != NULL );
+	if( avahiclient == NULL){
+		logging_error("creating avahi client failed");
+		return;
+	}
 
 	// block the event loop
 	avahi_threaded_poll_lock( avahipoll );
 
-	// create the service browser
+	// create the service browser for the specified type
 	avahibrowser = avahi_service_browser_new(
 			avahiclient, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
@@ -96,4 +101,9 @@
 			(AvahiLookupFlags)0, MulticastDns::browse_callback, this);
 
+	if( avahibrowser == NULL){
+		logging_error("creating avahi browser failed");
+		return;
+	}
+
 	//unblock the event loop and let it run
 	avahi_threaded_poll_unlock( avahipoll );
@@ -106,9 +116,31 @@
   #ifdef HAVE_LIBAVAHI_CLIENT
 
+	//
+	// stop poll and free browser
+	//
+
 	avahi_threaded_poll_stop( avahipoll );
 	avahi_service_browser_free( avahibrowser );
-	if( avahigroup != NULL ) avahi_entry_group_free( avahigroup );
+	avahibrowser = NULL;
+
+	//
+	// free all registered groups
+	//
+
+	AvahiGroupMap::iterator i = avahigroups.begin();
+	AvahiGroupMap::iterator iend = avahigroups.end();
+
+	for( ; i != iend; i++)
+		avahi_entry_group_free( i->second );
+
+	//
+	// free client and poll
+	//
+
 	avahi_client_free( avahiclient );
+	avahiclient = NULL;
+
 	avahi_threaded_poll_free( avahipoll );
+	avahipoll = NULL;
 
   #endif // HAVE_LIBAVAHI_CLIENT
@@ -117,40 +149,70 @@
 void MulticastDns::publishService(string name, string info){
   #ifdef HAVE_LIBAVAHI_CLIENT
+
+	if(name.length() > 63){
+		logging_error("service name length must not exceed 63 characters. "
+				<< name << " is " << name.length() << " characters");
+		return;
+	}
+
 
 	avahi_threaded_poll_lock(avahipoll);
 	assert( avahiclient != NULL );
 
-	char* n = NULL;
 	int ret = 0;
 
-	if( avahigroup == NULL){
-		avahigroup = avahi_entry_group_new(avahiclient, MulticastDns::entry_group_callback, this);
-
-		if(avahigroup == NULL) {
-			logging_warn("avahi_entry_group_new failed " << avahi_strerror(avahi_client_errno(avahiclient)));
-			avahi_threaded_poll_quit(avahipoll);
+	//
+	// if we have no group for this service, create one
+	//
+
+	AvahiGroupMap::iterator igroup = avahigroups.find(name);
+	AvahiEntryGroup* currentgroup = (igroup != avahigroups.end() ? igroup->second : NULL);
+
+	if( currentgroup == NULL ){
+
+		logging_debug("creating group for service " << name);
+		currentgroup = avahi_entry_group_new(avahiclient, MulticastDns::entry_group_callback, this);
+
+		if(currentgroup == NULL){
+			logging_error("failed creating avahi group for service "
+					<< name << ": " << avahi_strerror(avahi_client_errno(avahiclient)));
+			avahi_threaded_poll_unlock(avahipoll);
 			return;
 		}
-	}
-
-	logging_debug("avahi adding service " << name);
+
+		avahigroups.insert( make_pair(name, currentgroup) );
+	}
+
+	assert( currentgroup != NULL );
+
+	logging_debug("avahi adding service " << name << " to new group");
 
 	ret = avahi_entry_group_add_service(
-			avahigroup, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, (AvahiPublishFlags)0,
-			name.c_str(), serviceType.c_str(), NULL, NULL, 0, info.c_str(), NULL);
+			currentgroup, 			// group to add service to
+			AVAHI_IF_UNSPEC, 		// interface to announce, we use all interfaces
+			AVAHI_PROTO_UNSPEC, 	// protocol to announce, we use all protocols
+			(AvahiPublishFlags)0,	// no special flags
+			name.c_str(),			// name of the service, no more than 63 characters
+			serviceType.c_str(),	// type of the service: _spovnet._tcp (tcp does not mean anything here, just have to stick with this structure
+			NULL,					// publish in all domains
+			NULL,					// host name of our machine, let avahi find out
+			3333,					// port number the service is on, just dummy, everything is encoded in TXT
+			info.c_str(),			// arbitrary info
+			NULL);					// make that this is the last info field
 
 	if( ret < 0 ){
-
 		logging_warn("failed to add service " << name << ": " << avahi_strerror(ret));
-		avahi_threaded_poll_quit(avahipoll);
-		return;
-
+		avahigroups.erase(name);
+		avahi_threaded_poll_unlock(avahipoll);
+		return;
 	}
 
 	// tell the server to register the service
-	ret = avahi_entry_group_commit(avahigroup);
+	ret = avahi_entry_group_commit( currentgroup );
 	if(ret < 0) {
 		logging_warn("failed to commit entry group: " << avahi_strerror(ret));
-		avahi_threaded_poll_quit(avahipoll);
+		avahigroups.erase(name);
+		avahi_threaded_poll_unlock(avahipoll);
+		return;
 	}
 
@@ -163,6 +225,17 @@
   #ifdef HAVE_LIBAVAHI_CLIENT
 
-	if (avahigroup)
-		avahi_entry_group_reset(avahigroup);
+	avahi_threaded_poll_lock(avahipoll);
+
+	AvahiGroupMap::iterator i = avahigroups.find(name);
+	if( i != avahigroups.end() ){
+
+		logging_debug("revoking service " << name);
+		avahi_entry_group_reset( i->second );
+
+	} else {
+		logging_warn("service " << name << " is not registered, cannot revoke");
+	}
+
+	avahi_threaded_poll_unlock(avahipoll);
 
   #endif // HAVE_LIBAVAHI_CLIENT
@@ -187,5 +260,6 @@
         case AVAHI_CLIENT_FAILURE:
 
-        	logging_warn( "avahi client failure " << avahi_strerror(avahi_client_errno(client)) );
+        	logging_warn( "avahi client failure "
+        			<< avahi_strerror(avahi_client_errno(client)) << ". quitting" );
             avahi_threaded_poll_quit(obj->avahipoll);
 
@@ -199,17 +273,10 @@
         case AVAHI_CLIENT_S_REGISTERING:
 
-            //
-        	// the server records are now being established. This
-            // might be caused by a host name change. We need to wait
-            // for our own records to register until the host name is
-            // properly esatblished
-        	//
-
-            if( obj->avahigroup != NULL )
-                avahi_entry_group_reset(obj->avahigroup);
-
+            logging_debug("avahi client registering");
             break;
 
         case AVAHI_CLIENT_CONNECTING:
+
+        	logging_debug("avahi client conencting");
             break;
     }
@@ -223,5 +290,4 @@
 	MulticastDns* obj = (MulticastDns*)userdata;
 	assert(obj != NULL);
-	obj->avahigroup = group;
 
 	//
@@ -232,5 +298,4 @@
 		case AVAHI_ENTRY_GROUP_ESTABLISHED:
 
-			// entry group has been established successfully
 			logging_debug( "service entry group successfully established" );
 			break;
@@ -238,5 +303,4 @@
 		case AVAHI_ENTRY_GROUP_COLLISION:
 
-			// service name collision
 			logging_warn("service name collision for name");
 			break;
@@ -250,8 +314,13 @@
 
 		case AVAHI_ENTRY_GROUP_UNCOMMITED:
+
+			logging_debug("avahi entry group uncommited");
 			break;
 
 		case AVAHI_ENTRY_GROUP_REGISTERING:
-			break;
+
+			logging_debug("avahi entry group registering");
+			break;
+
 	} //switch(state)
 }
@@ -281,5 +350,6 @@
 					AVAHI_PROTO_UNSPEC, (AvahiLookupFlags)0,
 					MulticastDns::resolve_callback, obj))){
-				logging_warn( "failed to resolve service " << name << ", error " << avahi_strerror(avahi_client_errno(client)));
+				logging_warn( "failed to resolve service " << name
+						<< ", error " << avahi_strerror(avahi_client_errno(client)));
 			}
 
@@ -287,10 +357,16 @@
 
 		case AVAHI_BROWSER_REMOVE:
+
+			logging_debug("avahi browser remove");
 			break;
 
 		case AVAHI_BROWSER_ALL_FOR_NOW:
+
+			logging_debug("avahi all for now");
 			break;
 
 		case AVAHI_BROWSER_CACHE_EXHAUSTED:
+
+			logging_debug("avahi browser cache exhausted");
 			break;
 	}
@@ -312,23 +388,21 @@
 		case AVAHI_RESOLVER_FAILURE:
 
-			logging_warn("resolver failed to resolve service " << name << ", error " << avahi_strerror(avahi_client_errno(client)));
-			break;
-
-		case AVAHI_RESOLVER_FOUND: {
-
-			char a[AVAHI_ADDRESS_STR_MAX];
-			char* t = NULL;
-
-			avahi_address_snprint(a, sizeof(a), address);
-			t = avahi_string_list_to_string(txt);
-
-			if(obj != NULL && obj->callback != NULL){
-				obj->callback->onBootstrapServiceFound(name, t);
-				//foundNewService(name, type, domain, host_name, (int)port, a, t);
-			}
-
-			avahi_free( resolver );
-			break;
-		}
+			logging_warn("resolver failed to resolve service " << name
+					<< ", error " << avahi_strerror(avahi_client_errno(client)));
+			break;
+
+		case AVAHI_RESOLVER_FOUND:
+
+			char addr[AVAHI_ADDRESS_STR_MAX];
+			char* text = NULL;
+
+			avahi_address_snprint(addr, sizeof(addr), address);
+			text = avahi_string_list_to_string(txt);
+
+			if(obj != NULL && obj->callback != NULL)
+				obj->callback->onBootstrapServiceFound(name, text);
+
+			avahi_free( text );
+			break;
 	}
 
