Exemplo n.º 1
0
int dns_service_publisher_start( dns_service_desc_t *service_desc )
{
	int ret = 0;
	int error;

	if( ! service_desc ) return 1;

	if( ! (threaded_poll = avahi_threaded_poll_new() ) ) {
		logging_printf(LOGGING_ERROR, "Unable to create publisher thread\n");
		return 1;
	}

	sd_name_copy = avahi_strdup( service_desc->name );
	sd_service_copy = avahi_strdup( service_desc->service );
	sd_port = service_desc->port;

	use_ipv4 = service_desc->publish_ipv4;
	use_ipv6 = service_desc->publish_ipv6;

	client = avahi_client_new(avahi_threaded_poll_get(threaded_poll), 0, client_callback, NULL, &error);

	if (! client) {
		logging_printf(LOGGING_ERROR, "Failed to create client: %s\n", avahi_strerror(error));
		return 1;
	}

	avahi_threaded_poll_start( threaded_poll );

	return ret;
}
Exemplo n.º 2
0
void Publisher::doStart() {
	int error;
	// create poll object
	poller = avahi_threaded_poll_new();
	if (poller == NULL) {
		std::cerr << "Could not create avahi threaded poll object." << std::endl;
		return;
	}
    // create client
    client = avahi_client_new(
    		avahi_threaded_poll_get(poller), AVAHI_CLIENT_NO_FAIL, &Publisher::clientCallback, this, &error);

    if (client == NULL) {
    	std::cerr << "Failed to create avahi client ("
    			<< avahi_strerror(error) << ")" << std::endl;
      return;
    }

    error = avahi_threaded_poll_start(poller);
    if (error < 0) {
      std::cerr << "Error starting avahi threaded poll ("
    		  << avahi_strerror(error) << ")" << std::endl;
    } else {
      running = true;
    }
  }
Exemplo n.º 3
0
static int avahi_register(char *srvname, int srvport) {
  debug(1, "avahi: avahi_register.");
  name = strdup(srvname);
  port = srvport;

  int err;
  if (!(tpoll = avahi_threaded_poll_new())) {
    warn("couldn't create avahi threaded tpoll!");
    return -1;
  }
  if (!(client =
            avahi_client_new(avahi_threaded_poll_get(tpoll), 0, client_callback, NULL, &err))) {
    warn("couldn't create avahi client: %s!", avahi_strerror(err));
    return -1;
  }
  
 // we need this to detect the IPv6 number we're advertising...
 // if (!(sb = avahi_service_browser_new(client, AVAHI_IF_UNSPEC,  AVAHI_PROTO_UNSPEC, config.regtype, NULL, 0, browse_callback, client))) {
 //     warn("Failed to create service browser: %s\n", avahi_strerror(avahi_client_errno(client)));
 //     return -1;
 // }


  if (avahi_threaded_poll_start(tpoll) < 0) {
    warn("couldn't start avahi tpoll thread");
    return -1;
  }

  return 0;
}
Exemplo n.º 4
0
void
serverDNSSDInit(void)
{
#ifdef HAVE_DNSSD
  if (DNSServiceCreateConnection(&DNSSDMaster) != kDNSServiceErr_NoError)
  {
    fputs("Error: Unable to initialize Bonjour.\n", stderr);
    exit(1);
  }

#elif defined(HAVE_AVAHI)
  int error;			/* Error code, if any */

  if ((DNSSDMaster = avahi_threaded_poll_new()) == NULL)
  {
    fputs("Error: Unable to initialize Bonjour.\n", stderr);
    exit(1);
  }

  if ((DNSSDClient = avahi_client_new(avahi_threaded_poll_get(DNSSDMaster), AVAHI_CLIENT_NO_FAIL, dnssd_client_cb, NULL, &error)) == NULL)
  {
    fputs("Error: Unable to initialize Bonjour.\n", stderr);
    exit(1);
  }

  avahi_threaded_poll_start(DNSSDMaster);
#endif /* HAVE_DNSSD */
}
Exemplo n.º 5
0
/*
 * Tries to setup the Zeroconf thread and any
 * neccessary config setting.
 */
void tivo_bonjour_register(void)
{
	int error;

	/* first of all we need to initialize our threading env */
	ctx.threaded_poll = avahi_threaded_poll_new();
	if (!ctx.threaded_poll)
		return;

	/* now we need to acquire a client */
	ctx.client = avahi_client_new(avahi_threaded_poll_get(ctx.threaded_poll),
			AVAHI_CLIENT_NO_FAIL, client_callback, NULL, &error);
	if (!ctx.client)
	{
		DPRINTF(E_ERROR, L_SSDP, "Failed to create client object: %s\n",
					avahi_strerror(error));
		tivo_bonjour_unregister();
		return;
	}

	if (avahi_threaded_poll_start(ctx.threaded_poll) < 0)
	{
		DPRINTF(E_ERROR, L_SSDP, "Failed to create thread: %s\n",
					avahi_strerror(avahi_client_errno(ctx.client)));
		tivo_bonjour_unregister();
	}
	else
		DPRINTF(E_INFO, L_SSDP, "Successfully started avahi loop\n");
}
Exemplo n.º 6
0
AvahiSession::AvahiSession()
	: mPoll(0),
	  mClient(0),
	  mGroup(0),
	  mEntries(0),
	  mServiceName(0)
{
	int err;

	mServiceName = avahi_strdup(kSCRendezvousServiceName);

	mPoll = avahi_threaded_poll_new();
	if (!mPoll) {
		scprintf("Zeroconf: failed to create poll API\n");
		return;
	}

	mClient = avahi_client_new(
		avahi_threaded_poll_get(mPoll),
		(AvahiClientFlags)0, client_cb, this, &err);
	if (!mClient) {
		scprintf("Zeroconf: failed to create client: %s\n", avahi_strerror(err));
		avahi_threaded_poll_free(mPoll);
		mPoll = 0;
		return;
	}

	avahi_threaded_poll_start(mPoll);
}
Exemplo n.º 7
0
/*****************************************************************************
 * Open: initialize and create stuff
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    services_discovery_t *p_sd = ( services_discovery_t* )p_this;
    services_discovery_sys_t *p_sys;
    int err;

    p_sd->p_sys = p_sys = calloc( 1, sizeof( services_discovery_sys_t ) );
    if( !p_sys )
        return VLC_ENOMEM;

    p_sd->description = _("Zeroconf network services");

    vlc_dictionary_init( &p_sys->services_name_to_input_item, 1 );

    p_sys->poll = avahi_threaded_poll_new();
    if( p_sys->poll == NULL )
    {
        msg_Err( p_sd, "failed to create Avahi threaded poll" );
        goto error;
    }

    p_sys->client = avahi_client_new( avahi_threaded_poll_get(p_sys->poll),
                                      0, client_callback, p_sd, &err );
    if( p_sys->client == NULL )
    {
        msg_Err( p_sd, "failed to create avahi client: %s",
                 avahi_strerror( err ) );
        goto error;
    }

    for( unsigned i = 0; i < NB_PROTOCOLS; i++ )
    {
        AvahiServiceBrowser *sb;
        sb = avahi_service_browser_new( p_sys->client, AVAHI_IF_UNSPEC,
                AVAHI_PROTO_UNSPEC,
                protocols[i].psz_service_name, NULL,
                0, browse_callback, p_sd );
        if( sb == NULL )
        {
            msg_Err( p_sd, "failed to create avahi service browser %s", avahi_strerror( avahi_client_errno(p_sys->client) ) );
            goto error;
        }
    }

    avahi_threaded_poll_start( p_sys->poll );

    return VLC_SUCCESS;

error:
    if( p_sys->client != NULL )
        avahi_client_free( p_sys->client );
    if( p_sys->poll != NULL )
        avahi_threaded_poll_free( p_sys->poll );

    vlc_dictionary_clear( &p_sys->services_name_to_input_item, NULL, NULL );
    free( p_sys );

    return VLC_EGENERIC;
}
Exemplo n.º 8
0
void avahi_initialise(void) {
	int ret;
	static int first = 1;

	if (getenv("AVAHI_DEBUG")) {
		db = 1;
	}
	if (first) {
		int i;
		for (i=0; i<NREG; i++) {
			registered[i].name = NULL;
			registered[i].host = NULL;
		}
		first = 0;
	}

if (db) fprintf(stderr, "in  avahi_initialise\n");
	if (_poll) {
if (db) fprintf(stderr, "    avahi_initialise: poll not null\n");
		return;
	}

	if (! (_poll = avahi_threaded_poll_new()) ) {
		rfbLog("warning: unable to open Avahi poll.\n");
		return;
	}

	_client = avahi_client_new(avahi_threaded_poll_get(_poll),
	    0, NULL, NULL, &ret);
	if (! _client) {
		rfbLog("warning: unable to open Avahi client: %s\n",
		    avahi_strerror(ret));

		avahi_threaded_poll_free(_poll);
		_poll = NULL;
		return;
	}

	if (avahi_threaded_poll_start(_poll) < 0) {
		rfbLog("warning: unable to start Avahi poll.\n");
		avahi_client_free(_client);
		_client = NULL;
		avahi_threaded_poll_free(_poll);
		_poll = NULL;
		return;
	}
if (db) fprintf(stderr, "out avahi_initialise\n");
}
Exemplo n.º 9
0
void AvahiQuerier::start() {
    std::cout << "Starrting querier" << std::endl;
    assert(!threadedPoll);
    threadedPoll = avahi_threaded_poll_new();
    int error;
    assert(!client);
    client = avahi_client_new(
            avahi_threaded_poll_get(threadedPoll),
            static_cast<AvahiClientFlags>(0), NULL, this, &error); // TODO
    if (!client) {
        // TODO
        std::cerr << "Avahi Error: " << avahi_strerror(error) << std::endl;
        return;
    }
    std::cout << "Starrting event loop" << std::endl;
    avahi_threaded_poll_start(threadedPoll);
}
Exemplo n.º 10
0
/*
 * Tries to setup the Zeroconf thread and any
 * neccessary config setting.
 */
void av_zeroconf_register(const AFPObj *obj) {
    int error;

    /* initialize the struct that holds our config settings. */
    if (ctx) {
        LOG(log_debug, logtype_afpd, "Resetting zeroconf records");
        avahi_entry_group_reset(ctx->group);
    } else {
        ctx = calloc(1, sizeof(struct context));
        ctx->obj = obj;
        assert(ctx);
    }

    /* first of all we need to initialize our threading env */
    if (!(ctx->threaded_poll = avahi_threaded_poll_new())) {
        goto fail;
    }

    /* now we need to acquire a client */
    if (!(ctx->client = avahi_client_new(avahi_threaded_poll_get(ctx->threaded_poll),
                                         AVAHI_CLIENT_NO_FAIL,
                                         client_callback,
                                         NULL,
                                         &error))) {
        LOG(log_error, logtype_afpd, "Failed to create client object: %s",
            avahi_strerror(error));
        goto fail;
    }

    if (avahi_threaded_poll_start(ctx->threaded_poll) < 0) {
        LOG(log_error, logtype_afpd, "Failed to create thread: %s",
            avahi_strerror(avahi_client_errno(ctx->client)));
        goto fail;
    } else {
        LOG(log_info, logtype_afpd, "Successfully started avahi loop.");
    }

    ctx->thread_running = 1;
    return;

fail:
    av_zeroconf_unregister();

    return;
}
Exemplo n.º 11
0
CZeroconfAvahi::CZeroconfAvahi(): mp_client(0), mp_poll (0), m_shutdown(false),m_thread_id(0)
{
    if (! (mp_poll = avahi_threaded_poll_new()))
    {
      CLog::Log(LOGERROR, "CZeroconfAvahi::CZeroconfAvahi(): Could not create threaded poll object");
      //TODO: throw exception?
      return;
    }

    if (!createClient())
    {
      CLog::Log(LOGERROR, "CZeroconfAvahi::CZeroconfAvahi(): Could not create client");
      //yeah, what if not? but should always succeed
    }

    //start event loop thread
    if (avahi_threaded_poll_start(mp_poll) < 0)
    {
      CLog::Log(LOGERROR, "CZeroconfAvahi::CZeroconfAvahi(): Failed to start avahi client thread");
    }
}
Exemplo n.º 12
0
// startAvahiClient initializes a poll object, and a client.
const char *startAvahiClient(AvahiThreadedPoll **threaded_poll, AvahiClient **client) {
  *threaded_poll = avahi_threaded_poll_new();
  if (!*threaded_poll) {
    return avahi_strerror(avahi_client_errno(*client));
  }

  int error;
  *client = avahi_client_new(avahi_threaded_poll_get(*threaded_poll),
      AVAHI_CLIENT_NO_FAIL, handleClientStateChange, NULL, &error);
  if (!*client) {
    avahi_threaded_poll_free(*threaded_poll);
    return avahi_strerror(error);
  }

  error = avahi_threaded_poll_start(*threaded_poll);
  if (AVAHI_OK != error) {
    avahi_client_free(*client);
    avahi_threaded_poll_free(*threaded_poll);
    return avahi_strerror(error);
  }
  return NULL;
}
Exemplo n.º 13
0
int
dnssd_init()
{
  int error;			/* Error code, if any */

  g_options.dnssd_data = calloc(1, sizeof(dnssd_t));
  if (g_options.dnssd_data == NULL) {
    ERR("Unable to allocate memory for DNS-SD broadcast data.");
    goto fail;
  }
  g_options.dnssd_data->DNSSDMaster = NULL;
  g_options.dnssd_data->DNSSDClient = NULL;
  g_options.dnssd_data->ipp_ref = NULL;

  if ((g_options.dnssd_data->DNSSDMaster = avahi_threaded_poll_new()) == NULL) {
    ERR("Error: Unable to initialize DNS-SD.");
    goto fail;
  }

  if ((g_options.dnssd_data->DNSSDClient =
       avahi_client_new(avahi_threaded_poll_get(g_options.dnssd_data->DNSSDMaster),
			AVAHI_CLIENT_NO_FAIL,
			dnssd_client_cb, NULL, &error)) == NULL) {
    ERR("Error: Unable to initialize DNS-SD client.");
    goto fail;
  }

  avahi_threaded_poll_start(g_options.dnssd_data->DNSSDMaster);

  NOTE("DNS-SD initialized.");

  return 0;

 fail:
  dnssd_shutdown();

  return -1;
}
Exemplo n.º 14
0
static int avahi_register(char *srvname, int srvport) {
  debug(1, "avahi: avahi_register.");
  service_name = strdup(srvname);
  port = srvport;

  int err;
  if (!(tpoll = avahi_threaded_poll_new())) {
    warn("couldn't create avahi threaded tpoll!");
    return -1;
  }
  if (!(client = avahi_client_new(avahi_threaded_poll_get(tpoll), AVAHI_CLIENT_NO_FAIL,
                                  client_callback, NULL, &err))) {
    warn("couldn't create avahi client: %s!", avahi_strerror(err));
    return -1;
  }

  if (avahi_threaded_poll_start(tpoll) < 0) {
    warn("couldn't start avahi tpoll thread");
    return -1;
  }

  return 0;
}
Exemplo n.º 15
0
void Client::start(bool runningDaemonRequired) {
        msPoll = avahi_threaded_poll_new();
	int error;

	//the creation of avahi client will fail if the avahi daemon is not available, 
	//this can be changed using the AVAHI_CLIENT_NO_FAIL flag
        AvahiClientFlags flags = (AvahiClientFlags) 0;
        if(!runningDaemonRequired)
        {
            flags = (AvahiClientFlags) AVAHI_CLIENT_NO_FAIL;
        } 
	msAvahiClient = avahi_client_new( avahi_threaded_poll_get(msPoll), flags, &Client::stateUpdateCallback, this, &error);

	// If creation of msAvahiClient is not immediately successful throw error 
	if (!msAvahiClient) {
            char buffer[512];
            snprintf(buffer,512, "Failed to create client: %s" , avahi_strerror(error));
            LOG_FATAL("%s", buffer);
            throw std::runtime_error(buffer);
	} else {
            LOG_DEBUG("Created client");
        }
        avahi_threaded_poll_start(msPoll);
}
Exemplo n.º 16
0
void
cupsdStartBrowsing(void)
{
  if (!Browsing || !BrowseLocalProtocols)
    return;

#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
  if (BrowseLocalProtocols & BROWSE_DNSSD)
  {
#  ifdef HAVE_DNSSD
    DNSServiceErrorType error;		/* Error from service creation */

   /*
    * First create a "master" connection for all registrations...
    */

    if ((error = DNSServiceCreateConnection(&DNSSDMaster))
	    != kDNSServiceErr_NoError)
    {
      cupsdLogMessage(CUPSD_LOG_ERROR,
		      "Unable to create master DNS-SD reference: %d", error);

      if (FatalErrors & CUPSD_FATAL_BROWSE)
	cupsdEndProcess(getpid(), 0);
    }
    else
    {
     /*
      * Add the master connection to the select list...
      */

      int fd = DNSServiceRefSockFD(DNSSDMaster);

      fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);

      cupsdAddSelect(fd, (cupsd_selfunc_t)dnssdUpdate, NULL, NULL);
    }

   /*
    * Set the computer name and register the web interface...
    */

    DNSSDPort = 0;
    cupsdUpdateDNSSDName();

#  else /* HAVE_AVAHI */
    if ((DNSSDMaster = avahi_threaded_poll_new()) == NULL)
    {
      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create DNS-SD thread.");

      if (FatalErrors & CUPSD_FATAL_BROWSE)
	cupsdEndProcess(getpid(), 0);
    }
    else
    {
      int error;			/* Error code, if any */

      DNSSDClient = avahi_client_new(avahi_threaded_poll_get(DNSSDMaster), AVAHI_CLIENT_NO_FAIL, dnssdClientCallback, NULL, &error);

      if (DNSSDClient == NULL)
      {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Unable to communicate with avahi-daemon: %s",
                        dnssdErrorString(error));

        if (FatalErrors & CUPSD_FATAL_BROWSE)
	  cupsdEndProcess(getpid(), 0);

        avahi_threaded_poll_free(DNSSDMaster);
        DNSSDMaster = NULL;
      }
      else
	avahi_threaded_poll_start(DNSSDMaster);
    }
#  endif /* HAVE_DNSSD */
  }
#endif /* HAVE_DNSSD || HAVE_AVAHI */

 /*
  * Enable LPD and SMB printer sharing as needed through external programs...
  */

  if (BrowseLocalProtocols & BROWSE_LPD)
    update_lpd(1);

  if (BrowseLocalProtocols & BROWSE_SMB)
    update_smb(1);

#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
 /*
  * Register the individual printers
  */

  dnssdRegisterAllPrinters(0);
#endif /* HAVE_DNSSD || HAVE_AVAHI */
}
Exemplo n.º 17
0
int wxAvahiThreadPool::Start(){
    return avahi_threaded_poll_start(m_pool);
}
Exemplo n.º 18
0
int main( AVAHI_GCC_UNUSED int argc, char *argv[] )
{
    AvahiClient *client = NULL;
    AvahiServiceBrowser *serviceBrowser = NULL;
    char       *myName;
    int         error;
    int         result = 1;
    TiVoUnit   *tivo;

    myName = strrchr(argv[0], '/') + 1;
    if (myName == (NULL+1))
        myName = argv[0];

    openlog( myName, LOG_PID, LOG_DAEMON );
    loginfo("started");

    /* must be done before any threads start */
    curl_global_init( CURL_GLOBAL_ALL );

    /* Allocate main loop object */
    bonjourThread = avahi_threaded_poll_new();
    if ( !bonjourThread )
    {
        logerror( "Failed to create threaded poll object." );
    }
    else
    {
        /* Allocate a new client */
        client = avahi_client_new( avahi_threaded_poll_get( bonjourThread ), 0, client_callback, NULL, &error );

        /* Check wether creating the client object succeeded */
        if ( !client )
        {
            logerror( "Unable to create client: %s", avahi_strerror( error ) );
        }
        else
        {
            /* Create the service browser */
            serviceBrowser = avahi_service_browser_new( client,
                                                        AVAHI_IF_UNSPEC,
                                                        AVAHI_PROTO_UNSPEC,
                                                        "_tivo-device._tcp",
                                                        NULL, 0,
                                                        browseCallback, client );
            if ( !serviceBrowser )
            {
                logerror( "Unable to create service browser: %s", avahi_strerror( avahi_client_errno( client ) ) );
            }
            else
            {
                /* start the background network scan for TiVos */
                avahi_threaded_poll_start( bonjourThread );

                /* hack: wait for some results to arrive */
                sleep(5);
                /* what did we find? */
                result = dumpTiVos();

                avahi_threaded_poll_stop( bonjourThread );
                avahi_service_browser_free( serviceBrowser );
            }
            avahi_client_free( client );
        }
        avahi_threaded_poll_free( bonjourThread );
    }

    /* docs say no other threads may be running */
    curl_global_cleanup();

    loginfo( "stopped" );
    closelog();

    return result;
}
Exemplo n.º 19
0
/* Register a distcc service in DNS-SD/mDNS.  If advertise_capabilities is
 * true, the registration will contain information about the distcc server's
 * capabilities.  If service_type is NULL, the default service type will be
 * used.  advertise_capabilities should be true when using the default
 * service type. */
void* dcc_zeroconf_register_extended(int advertise_capabilities,
                                     const char *service_type,
                                     uint16_t port,
                                     int n_cpus) {
    struct context *ctx = NULL;
    char hostname[_POSIX_HOST_NAME_MAX + 1];
    const AvahiPoll *threaded_poll;
    int len, error;

    ctx = calloc(1, sizeof(struct context));
    if (!ctx) {
        rs_log_crit("calloc() failed for ctx: %s", strerror(errno));
        goto fail;
    }

    ctx->advertise_capabilities = advertise_capabilities;
    ctx->port = port;
    ctx->n_cpus = n_cpus;

    /* Prepare service type.  Use the supplied value, or the default if
     * NULL was supplied. */
    if (service_type)
        ctx->service_type = strdup(service_type);
    else
        ctx->service_type = strdup(DCC_DNS_SERVICE_TYPE);
    if (!ctx->service_type) {
        rs_log_crit("strdup() failed for ctx->service_type: %s",
                    strerror(errno));
        goto fail;
    }

    /* Prepare service name.  This is just the chosen service type with
     * '@' and the hostname appended.  If this collides with anything else,
     * avahi_alternative_service_name will choose a replacement name. */
    if (gethostname(hostname, sizeof(hostname))) {
        rs_log_crit("gethostname() failed: %s", strerror(errno));
        goto fail;
    }

    /* Leave room for the '@' and trailing NUL. */
    len = strlen(ctx->service_type) + strlen(hostname) + 2;
    if (!(ctx->name = avahi_malloc(len))) {
        rs_log_crit("avahi_malloc() failed for ctx->name");
        goto fail;
    }

    snprintf(ctx->name, len, "%s@%s", ctx->service_type, hostname);

    /* Create the Avahi client. */
    if (!(ctx->threaded_poll = avahi_threaded_poll_new())) {
        rs_log_crit("Failed to create event loop object.");
        goto fail;
    }

    threaded_poll = avahi_threaded_poll_get(ctx->threaded_poll);

    if (!(ctx->client = avahi_client_new(threaded_poll, AVAHI_CLIENT_NO_FAIL,
                                         client_callback, ctx, &error))) {
        rs_log_crit("Failed to create client object: %s",
                    avahi_strerror(error));
        goto fail;
    }

    /* Create the mDNS event handler */
    if (avahi_threaded_poll_start(ctx->threaded_poll) < 0) {
        rs_log_crit("Failed to create thread.");
        goto fail;
    }

    return ctx;

fail:

    if (ctx)
        dcc_zeroconf_unregister(ctx);

    return NULL;
}
Exemplo n.º 20
0
int avahi_dacp_monitor(rtsp_conn_info *conn) {

  dacp_browser_struct *dbs = (dacp_browser_struct *)malloc(sizeof(dacp_browser_struct));
  

  if (dbs == NULL)
    die("can not allocate a dacp_browser_struct.");
    
  conn->mdns_private_pointer = (void *)dbs;

  // create the threaded poll code
  int err;
  if (!(dbs->service_poll = avahi_threaded_poll_new())) {
    warn("couldn't create avahi threaded service_poll!");
    if (dbs) {
      free((char *)dbs);
    }
    conn->mdns_private_pointer = NULL;
    return -1;
  }

  // create the service client
  if (!(dbs->service_client =
            avahi_client_new(avahi_threaded_poll_get(dbs->service_poll), AVAHI_CLIENT_NO_FAIL,
                             service_client_callback, (void *)conn, &err))) {
    warn("couldn't create avahi service client: %s!", avahi_strerror(err));
    if (dbs) { // should free the threaded poll code
      avahi_threaded_poll_free(dbs->service_poll);
      free((char *)dbs);
    }
    conn->mdns_private_pointer = NULL;
    return -1;
  }

  /* Create the service browser */
  if (!(dbs->service_browser =
            avahi_service_browser_new(dbs->service_client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
                                      "_dacp._tcp", NULL, 0, browse_callback, (void *)conn))) {
    warn("Failed to create service browser: %s\n",
         avahi_strerror(avahi_client_errno(dbs->service_client)));
    if (dbs) { // should free the threaded poll code and the service client
      avahi_client_free(dbs->service_client);
      avahi_threaded_poll_free(dbs->service_poll);
      free((char *)dbs);
    }
    conn->mdns_private_pointer = NULL;
    return -1;
  }
  // start the polling thread
  if (avahi_threaded_poll_start(dbs->service_poll) < 0) {
    warn("couldn't start avahi service_poll thread");
    if (dbs) { // should free the threaded poll code and the service client and the service browser
      avahi_service_browser_free(dbs->service_browser);
      avahi_client_free(dbs->service_client);
      avahi_threaded_poll_free(dbs->service_poll);
      free((char *)dbs);
    }
    conn->mdns_private_pointer = NULL;
    return -1;
  }
  return 0;
}