Skip to content

Commit

Permalink
dns_sd: Pass params pointer to DNS-SD functions
Browse files Browse the repository at this point in the history
This will be used later to carry context information to the DNS-SD
functions.

Signed-off-by: Paul Cercueil <[email protected]>
  • Loading branch information
pcercuei committed May 20, 2021
1 parent 763b803 commit 6d85454
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 58 deletions.
38 changes: 22 additions & 16 deletions dns_sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ static void dnssd_free_discovery_data(struct dns_sd_discovery_data *d)
}

/* Some functions for handling common linked list operations */
static void dnssd_remove_node(struct dns_sd_discovery_data **ddata, int n)
static void dnssd_remove_node(const struct iio_context_params *params,
struct dns_sd_discovery_data **ddata, int n)
{
struct dns_sd_discovery_data *d, *ndata, *ldata, *tdata;
int i;
Expand Down Expand Up @@ -81,10 +82,10 @@ struct iio_scan_backend_context {
struct addrinfo *res;
};

static int dnssd_fill_context_info(struct iio_context_info *info,
char *hostname, char *addr_str, int port)
static int dnssd_fill_context_info(const struct iio_context_params *params,
struct iio_context_info *info,
char *hostname, char *addr_str, int port)
{
const struct iio_context_params *params = &default_params;
struct iio_context *ctx;
char uri[sizeof("ip:") + MAXHOSTNAMELEN + sizeof (":65535") + 1];
char description[255], *p;
Expand Down Expand Up @@ -168,7 +169,8 @@ void dnssd_context_scan_free(struct iio_scan_backend_context *ctx)
* This is sort of silly, but we have seen non-iio devices advertised
* and discovered on the network. Oh well....
*/
void port_knock_discovery_data(struct dns_sd_discovery_data **ddata)
void port_knock_discovery_data(const struct iio_context_params *params,
struct dns_sd_discovery_data **ddata)
{
struct dns_sd_discovery_data *d, *ndata;
int i, ret;
Expand Down Expand Up @@ -216,7 +218,7 @@ void port_knock_discovery_data(struct dns_sd_discovery_data **ddata)
if (found) {
i++;
} else {
dnssd_remove_node(&d, i);
dnssd_remove_node(params, &d, i);
}
}
iio_mutex_unlock(d->lock);
Expand All @@ -225,7 +227,8 @@ void port_knock_discovery_data(struct dns_sd_discovery_data **ddata)
return;
}

void remove_dup_discovery_data(struct dns_sd_discovery_data **ddata)
void remove_dup_discovery_data(const struct iio_context_params *params,
struct dns_sd_discovery_data **ddata)
{
struct dns_sd_discovery_data *d, *ndata, *mdata;
int i, j;
Expand All @@ -245,7 +248,7 @@ void remove_dup_discovery_data(struct dns_sd_discovery_data **ddata)
!strcmp(mdata->addr_str, ndata->addr_str)){
IIO_DEBUG("Removing duplicate in list: '%s'\n",
ndata->hostname);
dnssd_remove_node(&d, j);
dnssd_remove_node(params, &d, j);
}
j++;
}
Expand All @@ -259,11 +262,12 @@ void remove_dup_discovery_data(struct dns_sd_discovery_data **ddata)
int dnssd_context_scan(struct iio_scan_backend_context *ctx,
struct iio_scan_result *scan_result)
{
const struct iio_context_params *params = get_default_params();
struct iio_context_info **info;
struct dns_sd_discovery_data *ddata, *ndata;
int ret = 0;

ret = dnssd_find_hosts(&ddata);
ret = dnssd_find_hosts(params, &ddata);

/* if we return an error when no devices are found, then other scans will fail */
if (ret == -ENXIO) {
Expand All @@ -282,7 +286,7 @@ int dnssd_context_scan(struct iio_scan_backend_context *ctx,
break;
}

ret = dnssd_fill_context_info(*info,
ret = dnssd_fill_context_info(params, *info,
ndata->hostname, ndata->addr_str,ndata->port);
if (ret < 0) {
IIO_DEBUG("Failed to add %s (%s) err: %d\n", ndata->hostname, ndata->addr_str, ret);
Expand All @@ -291,16 +295,17 @@ int dnssd_context_scan(struct iio_scan_backend_context *ctx,
}

fail:
dnssd_free_all_discovery_data(ddata);
dnssd_free_all_discovery_data(params, ddata);
return ret;
}

int dnssd_discover_host(char *addr_str, size_t addr_len, uint16_t *port)
int dnssd_discover_host(const struct iio_context_params *params, char *addr_str,
size_t addr_len, uint16_t *port)
{
struct dns_sd_discovery_data *ddata;
int ret = 0;

ret = dnssd_find_hosts(&ddata);
ret = dnssd_find_hosts(params, &ddata);

if (ret < 0)
goto host_fail;
Expand All @@ -311,14 +316,15 @@ int dnssd_discover_host(char *addr_str, size_t addr_len, uint16_t *port)
}

host_fail:
dnssd_free_all_discovery_data(ddata);
dnssd_free_all_discovery_data(params, ddata);

/* negative error codes, 0 for no data */
return ret;
}

void dnssd_free_all_discovery_data(struct dns_sd_discovery_data *d)
void dnssd_free_all_discovery_data(const struct iio_context_params *params,
struct dns_sd_discovery_data *d)
{
while (d)
dnssd_remove_node(&d, 0);
dnssd_remove_node(params, &d, 0);
}
23 changes: 17 additions & 6 deletions dns_sd.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
struct addrinfo;
struct AvahiSimplePoll;
struct AvahiAddress;
struct iio_context_params;

/* Common structure which all dns_sd_[*] files fill out
* Anything that is dynamically allocated (malloc) needs to be managed
Expand All @@ -50,6 +51,10 @@ struct dns_sd_discovery_data {
struct dns_sd_discovery_data *next;
};

struct dns_sd_cb_data {
struct dns_sd_discovery_data *d;
const struct iio_context_params *params;
};

/* This functions is implemented in network.c, but used in dns_sd.c
*/
Expand All @@ -60,25 +65,31 @@ int create_socket(const struct addrinfo *addrinfo);
*/

/* Resolves all IIO hosts on the available networks, and passes back a linked list */
int dnssd_find_hosts(struct dns_sd_discovery_data ** ddata);
int dnssd_find_hosts(const struct iio_context_params *params,
struct dns_sd_discovery_data **ddata);

/* Deallocates complete list of discovery data */
void dnssd_free_all_discovery_data(struct dns_sd_discovery_data *d);
void dnssd_free_all_discovery_data(const struct iio_context_params *params,
struct dns_sd_discovery_data *d);

/* These functions are common, and found in dns_sd.c, but are used in the
* dns_sd_[*].c implementations or network.c
*/

/* Passed back the first (random) IIOD service resolved by DNS DS. */
int dnssd_discover_host(char *addr_str, size_t addr_len, uint16_t *port);
int dnssd_discover_host(const struct iio_context_params *params,
char *addr_str, size_t addr_len, uint16_t *port);

/* remove duplicates from the list */
void remove_dup_discovery_data(struct dns_sd_discovery_data **ddata);
void remove_dup_discovery_data(const struct iio_context_params *params,
struct dns_sd_discovery_data **ddata);

/* port knocks */
void port_knock_discovery_data(struct dns_sd_discovery_data **ddata);
void port_knock_discovery_data(const struct iio_context_params *params,
struct dns_sd_discovery_data **ddata);

/* Use dnssd to resolve a given hostname */
int dnssd_resolve_host(const char *hostname, char *ip_addr, const int addr_len);
int dnssd_resolve_host(const struct iio_context_params *params,
const char *hostname, char *ip_addr, const int addr_len);

#endif /* __IIO_DNS_SD_H */
61 changes: 39 additions & 22 deletions dns_sd_avahi.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@ static struct dns_sd_discovery_data *new_discovery_data(void)
return d;
}

static void avahi_process_resolved(struct dns_sd_discovery_data *ddata,
static void avahi_process_resolved(struct dns_sd_cb_data *adata,
const AvahiAddress *addr,
const char *host_name,
const uint16_t port)
{
struct dns_sd_discovery_data *ddata = adata->d;

/* Avahi is multi-threaded, so lock the list */
iio_mutex_lock(ddata->lock);
ddata->resolved++;
Expand Down Expand Up @@ -106,7 +108,7 @@ static void __avahi_resolver_cb(AvahiServiceResolver *resolver,
AvahiLookupResultFlags flags,
void *d)
{
struct dns_sd_discovery_data *ddata = d;
struct dns_sd_cb_data *adata = d;
AvahiClient *client;
int err;

Expand All @@ -126,7 +128,7 @@ static void __avahi_resolver_cb(AvahiServiceResolver *resolver,
avahi_strerror(err));
break;
case AVAHI_RESOLVER_FOUND: {
avahi_process_resolved(ddata, address, host_name, port);
avahi_process_resolved(adata, address, host_name, port);
IIO_DEBUG("Avahi Resolver : service '%s' of type '%s' in domain '%s':\n",
name, type, domain);
break;
Expand All @@ -144,7 +146,8 @@ static void avahi_host_resolver(AvahiHostNameResolver *resolver,
AvahiLookupResultFlags flags,
void *d)
{
struct dns_sd_discovery_data *ddata = d;
struct dns_sd_cb_data *adata = d;
struct dns_sd_discovery_data *ddata = adata->d;
AvahiClient *client;
int err;

Expand All @@ -157,7 +160,7 @@ static void avahi_host_resolver(AvahiHostNameResolver *resolver,
host_name, avahi_strerror(err));
break;
case AVAHI_RESOLVER_FOUND:
avahi_process_resolved(ddata, address, host_name, IIOD_PORT);
avahi_process_resolved(adata, address, host_name, IIOD_PORT);
break;
}

Expand All @@ -175,7 +178,8 @@ static void __avahi_browser_cb(AvahiServiceBrowser *browser,
AvahiLookupResultFlags flags,
void *d)
{
struct dns_sd_discovery_data *ddata = (struct dns_sd_discovery_data *) d;
struct dns_sd_cb_data *adata = d;
struct dns_sd_discovery_data *ddata = adata->d;
struct AvahiClient *client = avahi_service_browser_get_client(browser);
unsigned int i;
struct timespec ts;
Expand All @@ -199,7 +203,7 @@ static void __avahi_browser_cb(AvahiServiceBrowser *browser,
if(!avahi_service_resolver_new(client, iface,
proto, name, type, domain,
AVAHI_PROTO_UNSPEC, 0,
__avahi_resolver_cb, d)) {
__avahi_resolver_cb, adata)) {
IIO_ERROR("Failed to resolve service '%s\n", name);
} else {
iio_mutex_lock(ddata->lock);
Expand Down Expand Up @@ -233,9 +237,11 @@ static void __avahi_browser_cb(AvahiServiceBrowser *browser,
* The returned value is zero on success, negative error code on failure.
*/

int dnssd_find_hosts(struct dns_sd_discovery_data **ddata)
int dnssd_find_hosts(const struct iio_context_params *params,
struct dns_sd_discovery_data **ddata)
{
struct dns_sd_discovery_data *d;
struct dns_sd_cb_data adata;
AvahiClient *client;
AvahiServiceBrowser *browser;
int ret = 0;
Expand All @@ -244,16 +250,19 @@ int dnssd_find_hosts(struct dns_sd_discovery_data **ddata)
if (!d)
return -ENOMEM;

adata.params = params;
adata.d = d;

d->lock = iio_mutex_create();
if (!d->lock) {
dnssd_free_all_discovery_data(d);
dnssd_free_all_discovery_data(params, d);
return -ENOMEM;
}

d->poll = avahi_simple_poll_new();
if (!d->poll) {
iio_mutex_destroy(d->lock);
dnssd_free_all_discovery_data(d);
dnssd_free_all_discovery_data(params, d);
return -ENOMEM;
}

Expand All @@ -268,7 +277,7 @@ int dnssd_find_hosts(struct dns_sd_discovery_data **ddata)
browser = avahi_service_browser_new(client,
AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
"_iio._tcp", NULL, 0,
__avahi_browser_cb, d);
__avahi_browser_cb, &adata);
if (!browser) {
ret = avahi_client_errno(client);
IIO_ERROR("Unable to create Avahi DNS-SD browser: %s\n",
Expand All @@ -280,8 +289,8 @@ int dnssd_find_hosts(struct dns_sd_discovery_data **ddata)
avahi_simple_poll_loop(d->poll);

if (d->resolved) {
port_knock_discovery_data(&d);
remove_dup_discovery_data(&d);
port_knock_discovery_data(params, &d);
remove_dup_discovery_data(params, &d);
} else
ret = -ENXIO;

Expand All @@ -296,10 +305,11 @@ int dnssd_find_hosts(struct dns_sd_discovery_data **ddata)
return ret;
}

static void avahi_resolve_host(struct dns_sd_discovery_data *d,
static void avahi_resolve_host(struct dns_sd_cb_data *adata,
const char *hostname,
const AvahiProtocol proto)
{
struct dns_sd_discovery_data *d = adata->d;
AvahiClient *client;
AvahiHostNameResolver *resolver;
int ret;
Expand All @@ -315,8 +325,9 @@ static void avahi_resolve_host(struct dns_sd_discovery_data *d,
goto err_free_poll;
}

resolver = avahi_host_name_resolver_new(client, AVAHI_IF_UNSPEC, proto, hostname, proto, 0,
avahi_host_resolver, d);
resolver = avahi_host_name_resolver_new(client, AVAHI_IF_UNSPEC, proto,
hostname, proto, 0,
avahi_host_resolver, adata);
if (!resolver) {
ret = avahi_client_errno(client);
IIO_ERROR("Unable to create Avahi DNS-SD browser: %s\n",
Expand All @@ -333,11 +344,13 @@ static void avahi_resolve_host(struct dns_sd_discovery_data *d,
avahi_simple_poll_free(d->poll);
}

int dnssd_resolve_host(const char *hostname,
int dnssd_resolve_host(const struct iio_context_params *params,
const char *hostname,
char *ip_addr,
const int addr_len)
{
struct dns_sd_discovery_data *d;
struct dns_sd_cb_data adata;
int ret = 0;

if (!hostname || hostname[0] == '\0')
Expand All @@ -352,21 +365,25 @@ int dnssd_resolve_host(const char *hostname,
ret = -ENOMEM;
goto err_free_data;
}

adata.params = params;
adata.d = d;

/*
* The reason not to use AVAHI_PROTO_UNSPEC is that avahi sometimes resolves the host
* to an ipv6 link local address which is not suitable to be used by connect. In fact,
* `port_knock_discovery_data()` would discard this entry. On the other hand, some users
* might really want to use ipv6 and have their environment correctly configured. Hence,
* we try to resolve both in ipv4 and ipv6...
*/
avahi_resolve_host(d, hostname, AVAHI_PROTO_INET);
avahi_resolve_host(&adata, hostname, AVAHI_PROTO_INET);
#ifdef HAVE_IPV6
avahi_resolve_host(d, hostname, AVAHI_PROTO_INET6);
avahi_resolve_host(&adata, hostname, AVAHI_PROTO_INET6);
#endif

if (d->resolved) {
port_knock_discovery_data(&d);
remove_dup_discovery_data(&d);
port_knock_discovery_data(params, &d);
remove_dup_discovery_data(params, &d);
} else {
ret = -ENXIO;
goto err_mutex_destroy;
Expand All @@ -383,6 +400,6 @@ int dnssd_resolve_host(const char *hostname,
err_mutex_destroy:
iio_mutex_destroy(d->lock);
err_free_data:
dnssd_free_all_discovery_data(d);
dnssd_free_all_discovery_data(params, d);
return ret;
}
Loading

0 comments on commit 6d85454

Please sign in to comment.