summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2005-08-05 18:59:21 +0000
committerLennart Poettering <lennart@poettering.net>2005-08-05 18:59:21 +0000
commit0632e854728e8e64552ae08f90852d4a2658539e (patch)
tree0fab7d52e01da7ab9b81b8409dcf70cceb7d2852
parentd76069e946b4e89c828c96340677e40f583080c9 (diff)
* add proper error codes and patch everything to make use of it
* parameter validity checkin in all user visible functions of libavahi-core * two new python tools/examples avahi-resolve-host-name and avahi-resolve-address git-svn-id: file:///home/lennart/svn/public/avahi/trunk@238 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe
-rw-r--r--avahi-common/dbus.h26
-rw-r--r--avahi-common/rr.c46
-rw-r--r--avahi-common/rr.h8
-rw-r--r--avahi-common/util.c94
-rw-r--r--avahi-common/util.h5
-rw-r--r--avahi-core/avahi-reflector.c3
-rw-r--r--avahi-core/avahi-test.c3
-rw-r--r--avahi-core/browse-dns-server.c16
-rw-r--r--avahi-core/browse-domain.c17
-rw-r--r--avahi-core/browse-service-type.c13
-rw-r--r--avahi-core/browse-service.c21
-rw-r--r--avahi-core/browse.c10
-rw-r--r--avahi-core/conformance-test.c3
-rw-r--r--avahi-core/core.h42
-rw-r--r--avahi-core/resolve-address.c5
-rw-r--r--avahi-core/resolve-host-name.c21
-rw-r--r--avahi-core/resolve-service.c27
-rw-r--r--avahi-core/server.c190
-rw-r--r--avahi-core/server.h4
-rw-r--r--avahi-daemon/dbus-protocol.c176
-rw-r--r--avahi-daemon/main.c6
-rw-r--r--avahi-daemon/static-services.c7
-rw-r--r--avahi-discover-standalone/main.c5
-rw-r--r--avahi-utils/Makefile.am16
-rwxr-xr-xavahi-utils/avahi-resolve-address.in53
-rwxr-xr-xavahi-utils/avahi-resolve-host-name.in53
-rw-r--r--doxygen.cfg2
-rw-r--r--examples/browse-services.c16
-rw-r--r--examples/publish-service.c18
29 files changed, 755 insertions, 151 deletions
diff --git a/avahi-common/dbus.h b/avahi-common/dbus.h
index ddbd47a..64696d2 100644
--- a/avahi-common/dbus.h
+++ b/avahi-common/dbus.h
@@ -32,13 +32,25 @@ AVAHI_C_DECL_BEGIN
#define AVAHI_DBUS_INTERFACE_SERVICE_TYPE_BROWSER AVAHI_DBUS_NAME".ServiceTypeBrowser"
#define AVAHI_DBUS_INTERFACE_SERVICE_BROWSER AVAHI_DBUS_NAME".ServiceBrowser"
-#define AVAHI_DBUS_ERROR_INVALID_SERVICE "org.freedesktop.Avahi.InvalidServiceError"
-#define AVAHI_DBUS_ERROR_INVALID_ADDRESS "org.freedesktop.Avahi.InvalidAddressError"
-#define AVAHI_DBUS_ERROR_TIMEOUT "org.freedesktop.Avahi.TimeoutError"
-#define AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS "org.freedesktop.Avahi.TooManyClientsError"
-#define AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS "org.freedesktop.Avahi.TooManyObjectsError"
-#define AVAHI_DBUS_ERROR_TOO_MANY_ENTRIES "org.freedesktop.Avahi.TooManyEntriesError"
-#define AVAHI_DBUS_ERROR_OS "org.freedesktop.Avahi.OSError"
+#define AVAHI_DBUS_ERR_FAILURE "org.freedesktop.Avahi.Failure"
+#define AVAHI_DBUS_ERR_BAD_STATE "org.freedesktop.Avahi.BadStateError"
+#define AVAHI_DBUS_ERR_INVALID_HOST_NAME "org.freedesktop.Avahi.InvalidHostNameError"
+#define AVAHI_DBUS_ERR_INVALID_DOMAIN_NAME "org.freedesktop.Avahi.InvalidDomainNameError"
+#define AVAHI_DBUS_ERR_NO_NETWORK "org.freedesktop.Avahi.NoNetworkError"
+#define AVAHI_DBUS_ERR_INVALID_TTL "org.freedesktop.Avahi.InvalidTTLError"
+#define AVAHI_DBUS_ERR_IS_PATTERN "org.freedesktop.Avahi.IsPatternError"
+#define AVAHI_DBUS_ERR_LOCAL_COLLISION "org.freedesktop.Avahi.LocalCollisionError"
+#define AVAHI_DBUS_ERR_INVALID_RECORD "org.freedesktop.Avahi.InvalidRecordError"
+#define AVAHI_DBUS_ERR_INVALID_SERVICE_NAME "org.freedesktop.Avahi.InvalidServiceNameError"
+#define AVAHI_DBUS_ERR_INVALID_SERVICE_TYPE "org.freedesktop.Avahi.InvalidServiceTypeError"
+#define AVAHI_DBUS_ERR_INVALID_PORT "org.freedesktop.Avahi.InvalidPortError"
+#define AVAHI_DBUS_ERR_INVALID_KEY "org.freedesktop.Avahi.InvalidKeyError"
+#define AVAHI_DBUS_ERR_INVALID_ADDRESS "org.freedesktop.Avahi.InvalidAddressError"
+#define AVAHI_DBUS_ERR_TIMEOUT "org.freedesktop.Avahi.TimeoutError"
+#define AVAHI_DBUS_ERR_TOO_MANY_CLIENTS "org.freedesktop.Avahi.TooManyClientsError"
+#define AVAHI_DBUS_ERR_TOO_MANY_OBJECTS "org.freedesktop.Avahi.TooManyObjectsError"
+#define AVAHI_DBUS_ERR_TOO_MANY_ENTRIES "org.freedesktop.Avahi.TooManyEntriesError"
+#define AVAHI_DBUS_ERR_OS "org.freedesktop.Avahi.OSError"
AVAHI_C_DECL_END
diff --git a/avahi-common/rr.c b/avahi-common/rr.c
index c510e7f..1a30146 100644
--- a/avahi-common/rr.c
+++ b/avahi-common/rr.c
@@ -552,3 +552,49 @@ gboolean avahi_record_is_goodbye(AvahiRecord *r) {
return r->ttl == 0;
}
+
+gboolean avahi_key_valid(AvahiKey *k) {
+ g_assert(k);
+
+ if (!avahi_valid_domain_name(k->name))
+ return FALSE;
+
+ return TRUE;
+}
+
+gboolean avahi_record_valid(AvahiRecord *r) {
+ g_assert(r);
+
+ if (!avahi_key_valid(r->key))
+ return FALSE;
+
+ switch (r->key->type) {
+
+ case AVAHI_DNS_TYPE_PTR:
+ case AVAHI_DNS_TYPE_CNAME:
+ return avahi_valid_domain_name(r->data.ptr.name);
+
+ case AVAHI_DNS_TYPE_SRV:
+ return avahi_valid_domain_name(r->data.srv.name);
+
+ case AVAHI_DNS_TYPE_HINFO:
+ return
+ strlen(r->data.hinfo.os) <= 255 &&
+ strlen(r->data.hinfo.cpu) <= 255;
+
+
+ case AVAHI_DNS_TYPE_TXT: {
+
+ AvahiStringList *strlst;
+
+ for (strlst = r->data.txt.string_list; strlst; strlst = strlst->next)
+ if (strlst->size > 255)
+ return FALSE;
+
+ return TRUE;
+ }
+ }
+
+
+ return TRUE;
+}
diff --git a/avahi-common/rr.h b/avahi-common/rr.h
index 25d6eee..f5349e9 100644
--- a/avahi-common/rr.h
+++ b/avahi-common/rr.h
@@ -82,13 +82,11 @@ typedef struct {
guint32 ttl; /**< DNS TTL of this record */
union {
-
struct {
gpointer data;
guint16 size;
} generic; /**< Generic record data for unknown types */
-
struct {
guint16 priority;
@@ -200,6 +198,12 @@ gint avahi_record_lexicographical_compare(AvahiRecord *a, AvahiRecord *b);
/** Return TRUE if the specified record is an mDNS goodbye record. i.e. TTL is zero. */
gboolean avahi_record_is_goodbye(AvahiRecord *r);
+/** Check whether the specified key is valid */
+gboolean avahi_key_valid(AvahiKey *k);
+
+/** Check whether the specified record is valid */
+gboolean avahi_record_valid(AvahiRecord *r);
+
AVAHI_C_DECL_END
#endif
diff --git a/avahi-common/util.c b/avahi-common/util.c
index 8be7b88..a977bb2 100644
--- a/avahi-common/util.c
+++ b/avahi-common/util.c
@@ -414,3 +414,97 @@ gchar *avahi_format_mac_address(const guint8* mac, guint size) {
*(--t) = 0;
return r;
}
+
+gboolean avahi_valid_service_type(const gchar *t) {
+ const gchar *p;
+ g_assert(t);
+
+ if (strlen(t) < 5)
+ return FALSE;
+
+ if (*t != '_')
+ return FALSE;
+
+ if (!(p = strchr(t, '.')))
+ return FALSE;
+
+ if (p - t > 63 || p - t < 2)
+ return FALSE;
+
+ if (*(++p) != '_')
+ return FALSE;
+
+ if (strchr(p, '.'))
+ return FALSE;
+
+ if (strlen(p) > 63 || strlen(p) < 2)
+ return FALSE;
+
+ return TRUE;
+}
+
+gboolean avahi_valid_domain_name(const gchar *t) {
+ const gchar *p, *dp;
+ gboolean dot = FALSE;
+
+ g_assert(t);
+
+ if (*t == 0)
+ return FALSE;
+
+ /* Domains may not start with a dot */
+ if (*t == '.')
+ return FALSE;
+
+ dp = t;
+
+ for (p = t; *p; p++) {
+
+ if (*p == '.') {
+ if (dot) /* Two subsequent dots */
+ return FALSE;
+
+ if (p - dp > 63)
+ return FALSE;
+
+ dot = TRUE;
+ dp = p + 1;
+ } else
+ dot = FALSE;
+
+ }
+
+ if (p - dp > 63)
+ return FALSE;
+
+ /* A trailing dot IS allowed */
+
+ return TRUE;
+}
+
+gboolean avahi_valid_service_name(const gchar *t) {
+ g_assert(t);
+
+ if (*t == 0)
+ return FALSE;
+
+ if (strlen(t) > 63)
+ return FALSE;
+
+ return TRUE;
+}
+
+gboolean avahi_valid_host_name(const gchar *t) {
+ g_assert(t);
+
+ if (*t == 0)
+ return FALSE;
+
+ if (strlen(t) > 63)
+ return FALSE;
+
+ if (strchr(t, '.'))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/avahi-common/util.h b/avahi-common/util.h
index 731a5a1..0d4fb4b 100644
--- a/avahi-common/util.h
+++ b/avahi-common/util.h
@@ -60,6 +60,11 @@ guint avahi_domain_hash(const gchar *s);
gchar *avahi_format_mac_address(const guint8* mac, guint size);
+gboolean avahi_valid_service_type(const gchar *t);
+gboolean avahi_valid_domain_name(const gchar *t);
+gboolean avahi_valid_service_name(const gchar *t);
+gboolean avahi_valid_host_name(const gchar *t);
+
AVAHI_C_DECL_END
#endif
diff --git a/avahi-core/avahi-reflector.c b/avahi-core/avahi-reflector.c
index 7af0dd4..0a91b87 100644
--- a/avahi-core/avahi-reflector.c
+++ b/avahi-core/avahi-reflector.c
@@ -34,6 +34,7 @@ int main(int argc, char*argv[]) {
AvahiServer *server;
AvahiServerConfig config;
GMainLoop *loop;
+ gint error;
avahi_server_config_init(&config);
config.publish_hinfo = FALSE;
@@ -43,7 +44,7 @@ int main(int argc, char*argv[]) {
config.use_ipv6 = FALSE;
config.enable_reflector = TRUE;
- server = avahi_server_new(NULL, &config, NULL, NULL);
+ server = avahi_server_new(NULL, &config, NULL, NULL, &error);
avahi_server_config_free(&config);
loop = g_main_loop_new(NULL, FALSE);
diff --git a/avahi-core/avahi-test.c b/avahi-core/avahi-test.c
index cc950d4..5db2473 100644
--- a/avahi-core/avahi-test.c
+++ b/avahi-core/avahi-test.c
@@ -217,10 +217,11 @@ int main(int argc, char *argv[]) {
AvahiServiceBrowser *sb;
AvahiServiceResolver *sr;
AvahiDNSServerBrowser *dsb;
+ gint error;
avahi_server_config_init(&config);
/* config.host_name = g_strdup("test"); */
- server = avahi_server_new(NULL, &config, server_callback, NULL);
+ server = avahi_server_new(NULL, &config, server_callback, NULL, &error);
avahi_server_config_free(&config);
k = avahi_key_new("_http._tcp.local", AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR);
diff --git a/avahi-core/browse-dns-server.c b/avahi-core/browse-dns-server.c
index f8e8f30..057f3e3 100644
--- a/avahi-core/browse-dns-server.c
+++ b/avahi-core/browse-dns-server.c
@@ -157,15 +157,21 @@ AvahiDNSServerBrowser *avahi_dns_server_browser_new(AvahiServer *server, AvahiIf
g_assert(callback);
g_assert(type == AVAHI_DNS_SERVER_RESOLVE || type == AVAHI_DNS_SERVER_UPDATE);
+ if (domain && !avahi_valid_domain_name(domain)) {
+ avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME);
+ return NULL;
+ }
+
b = g_new(AvahiDNSServerBrowser, 1);
b->server = server;
- b->domain_name = avahi_normalize_name(domain ? domain : "local.");
+ b->domain_name = avahi_normalize_name(domain ? domain : "local");
b->callback = callback;
b->userdata = userdata;
b->aprotocol = aprotocol;
b->n_info = 0;
AVAHI_LLIST_HEAD_INIT(AvahiDNSServerInfo, b->info);
+ AVAHI_LLIST_PREPEND(AvahiDNSServerBrowser, browser, server->dns_server_browsers, b);
n = g_strdup_printf("%s.%s",type == AVAHI_DNS_SERVER_RESOLVE ? "_domain._udp" : "_dns-update._udp", b->domain_name);
k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_SRV);
@@ -174,7 +180,10 @@ AvahiDNSServerBrowser *avahi_dns_server_browser_new(AvahiServer *server, AvahiIf
b->record_browser = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, b);
avahi_key_unref(k);
- AVAHI_LLIST_PREPEND(AvahiDNSServerBrowser, browser, server->dns_server_browsers, b);
+ if (!b->record_browser) {
+ avahi_dns_server_browser_free(b);
+ return NULL;
+ }
return b;
}
@@ -187,7 +196,8 @@ void avahi_dns_server_browser_free(AvahiDNSServerBrowser *b) {
AVAHI_LLIST_REMOVE(AvahiDNSServerBrowser, browser, b->server->dns_server_browsers, b);
- avahi_record_browser_free(b->record_browser);
+ if (b->record_browser)
+ avahi_record_browser_free(b->record_browser);
g_free(b->domain_name);
g_free(b);
}
diff --git a/avahi-core/browse-domain.c b/avahi-core/browse-domain.c
index c6331b4..de3cb1b 100644
--- a/avahi-core/browse-domain.c
+++ b/avahi-core/browse-domain.c
@@ -60,6 +60,12 @@ AvahiDomainBrowser *avahi_domain_browser_new(AvahiServer *server, AvahiIfIndex i
g_assert(server);
g_assert(callback);
+ g_assert(type >= AVAHI_DOMAIN_BROWSER_BROWSE && type <= AVAHI_DOMAIN_BROWSER_BROWSE_LEGACY);
+
+ if (domain && !avahi_valid_domain_name(domain)) {
+ avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME);
+ return NULL;
+ }
b = g_new(AvahiDomainBrowser, 1);
b->server = server;
@@ -67,6 +73,8 @@ AvahiDomainBrowser *avahi_domain_browser_new(AvahiServer *server, AvahiIfIndex i
b->callback = callback;
b->userdata = userdata;
+ AVAHI_LLIST_PREPEND(AvahiDomainBrowser, browser, server->domain_browsers, b);
+
switch (type) {
case AVAHI_DOMAIN_BROWSER_BROWSE:
n = g_strdup_printf("b._dns-sd._udp.%s", b->domain_name);
@@ -97,7 +105,10 @@ AvahiDomainBrowser *avahi_domain_browser_new(AvahiServer *server, AvahiIfIndex i
b->record_browser = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, b);
avahi_key_unref(k);
- AVAHI_LLIST_PREPEND(AvahiDomainBrowser, browser, server->domain_browsers, b);
+ if (!b->record_browser) {
+ avahi_domain_browser_free(b);
+ return NULL;
+ }
return b;
}
@@ -107,7 +118,9 @@ void avahi_domain_browser_free(AvahiDomainBrowser *b) {
AVAHI_LLIST_REMOVE(AvahiDomainBrowser, browser, b->server->domain_browsers, b);
- avahi_record_browser_free(b->record_browser);
+ if (b->record_browser)
+ avahi_record_browser_free(b->record_browser);
+
g_free(b->domain_name);
g_free(b);
}
diff --git a/avahi-core/browse-service-type.c b/avahi-core/browse-service-type.c
index 7cd6cf7..3534b6f 100644
--- a/avahi-core/browse-service-type.c
+++ b/avahi-core/browse-service-type.c
@@ -90,12 +90,18 @@ AvahiServiceTypeBrowser *avahi_service_type_browser_new(AvahiServer *server, gin
g_assert(server);
g_assert(callback);
+ if (domain && !avahi_valid_domain_name(domain)) {
+ avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME);
+ return NULL;
+ }
+
b = g_new(AvahiServiceTypeBrowser, 1);
b->server = server;
b->domain_name = avahi_normalize_name(domain ? domain : "local");
b->callback = callback;
b->userdata = userdata;
+ AVAHI_LLIST_PREPEND(AvahiServiceTypeBrowser, browser, server->service_type_browsers, b);
n = g_strdup_printf("_services._dns-sd._udp.%s", b->domain_name);
k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR);
@@ -104,7 +110,8 @@ AvahiServiceTypeBrowser *avahi_service_type_browser_new(AvahiServer *server, gin
b->record_browser = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, b);
avahi_key_unref(k);
- AVAHI_LLIST_PREPEND(AvahiServiceTypeBrowser, browser, server->service_type_browsers, b);
+ if (!b->record_browser)
+ return NULL;
return b;
}
@@ -114,7 +121,9 @@ void avahi_service_type_browser_free(AvahiServiceTypeBrowser *b) {
AVAHI_LLIST_REMOVE(AvahiServiceTypeBrowser, browser, b->server->service_type_browsers, b);
- avahi_record_browser_free(b->record_browser);
+ if (b->record_browser)
+ avahi_record_browser_free(b->record_browser);
+
g_free(b->domain_name);
g_free(b);
}
diff --git a/avahi-core/browse-service.c b/avahi-core/browse-service.c
index f72ce6c..34a2536 100644
--- a/avahi-core/browse-service.c
+++ b/avahi-core/browse-service.c
@@ -93,21 +93,36 @@ AvahiServiceBrowser *avahi_service_browser_new(AvahiServer *server, AvahiIfIndex
g_assert(callback);
g_assert(service_type);
+ if (!avahi_valid_service_type(service_type)) {
+ avahi_server_set_errno(server, AVAHI_ERR_INVALID_SERVICE_TYPE);
+ return NULL;
+ }
+
+ if (domain && !avahi_valid_domain_name(domain)) {
+ avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME);
+ return NULL;
+ }
+
b = g_new(AvahiServiceBrowser, 1);
b->server = server;
b->domain_name = avahi_normalize_name(domain ? domain : "local");
b->service_type = avahi_normalize_name(service_type);
b->callback = callback;
b->userdata = userdata;
+ AVAHI_LLIST_PREPEND(AvahiServiceBrowser, browser, server->service_browsers, b);
n = g_strdup_printf("%s.%s", b->service_type, b->domain_name);
k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR);
g_free(n);
b->record_browser = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, b);
+
avahi_key_unref(k);
- AVAHI_LLIST_PREPEND(AvahiServiceBrowser, browser, server->service_browsers, b);
+ if (!b->record_browser) {
+ avahi_service_browser_free(b);
+ return NULL;
+ }
return b;
}
@@ -117,7 +132,9 @@ void avahi_service_browser_free(AvahiServiceBrowser *b) {
AVAHI_LLIST_REMOVE(AvahiServiceBrowser, browser, b->server->service_browsers, b);
- avahi_record_browser_free(b->record_browser);
+ if (b->record_browser)
+ avahi_record_browser_free(b->record_browser);
+
g_free(b->domain_name);
g_free(b->service_type);
g_free(b);
diff --git a/avahi-core/browse.c b/avahi-core/browse.c
index 5f4d216..5885cb4 100644
--- a/avahi-core/browse.c
+++ b/avahi-core/browse.c
@@ -124,7 +124,15 @@ AvahiRecordBrowser *avahi_record_browser_new(AvahiServer *server, AvahiIfIndex i
g_assert(key);
g_assert(callback);
- g_assert(!avahi_key_is_pattern(key));
+ if (avahi_key_is_pattern(key)) {
+ avahi_server_set_errno(server, AVAHI_ERR_IS_PATTERN);
+ return NULL;
+ }
+
+ if (!avahi_key_valid(key)) {
+ avahi_server_set_errno(server, AVAHI_ERR_INVALID_KEY);
+ return NULL;
+ }
b = g_new(AvahiRecordBrowser, 1);
b->dead = FALSE;
diff --git a/avahi-core/conformance-test.c b/avahi-core/conformance-test.c
index ccc9a12..13704c3 100644
--- a/avahi-core/conformance-test.c
+++ b/avahi-core/conformance-test.c
@@ -101,8 +101,9 @@ static void server_callback(AvahiServer *s, AvahiServerState state, gpointer use
int main(int argc, char *argv[]) {
GMainLoop *loop = NULL;
+ gint error;
- avahi = avahi_server_new(NULL, NULL, server_callback, NULL);
+ avahi = avahi_server_new(NULL, NULL, server_callback, NULL, &error);
loop = g_main_loop_new(NULL, FALSE);
g_timeout_add(1000*5, dump_timeout, avahi);
diff --git a/avahi-core/core.h b/avahi-core/core.h
index 25e9c0a..1adf244 100644
--- a/avahi-core/core.h
+++ b/avahi-core/core.h
@@ -35,7 +35,9 @@
#include <avahi-common/cdecl.h>
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
AVAHI_C_DECL_BEGIN
+#endif
/** An mDNS responder object */
typedef struct AvahiServer AvahiServer;
@@ -46,19 +48,42 @@ typedef struct AvahiEntry AvahiEntry;
/** A group of locally registered DNS RRs */
typedef struct AvahiEntryGroup AvahiEntryGroup;
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
AVAHI_C_DECL_END
+#endif
#include <avahi-common/address.h>
#include <avahi-common/rr.h>
#include <avahi-common/alternative.h>
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
AVAHI_C_DECL_BEGIN
+#endif
/** Error codes used by avahi */
enum {
- AVAHI_OK = 0, /**< OK */
- AVAHI_ERR_FAILURE = -1, /**< Generic error code */
- AVAHI_ERR_BAD_STATE = -2 /**< Object was in a bad state */
+ AVAHI_OK = 0, /**< OK */
+ AVAHI_ERR_FAILURE = -1, /**< Generic error code */
+ AVAHI_ERR_BAD_STATE = -2, /**< Object was in a bad state */
+ AVAHI_ERR_INVALID_HOST_NAME = -3, /**< Invalid host name */
+ AVAHI_ERR_INVALID_DOMAIN_NAME = -4, /**< Invalid domain name */
+ AVAHI_ERR_NO_NETWORK = -5, /**< No suitable network protocol available */
+ AVAHI_ERR_INVALID_TTL = -6, /**< Invalid DNS TTL */
+ AVAHI_ERR_IS_PATTERN = -7, /**< RR key is pattern */
+ AVAHI_ERR_LOCAL_COLLISION = -8, /**< Local name collision */
+ AVAHI_ERR_INVALID_RECORD = -9, /**< Invalid RR */
+ AVAHI_ERR_INVALID_SERVICE_NAME = -10, /**< Invalid service name */
+ AVAHI_ERR_INVALID_SERVICE_TYPE = -11, /**< Invalid service type */
+ AVAHI_ERR_INVALID_PORT = -12, /**< Invalid port number */
+ AVAHI_ERR_INVALID_KEY = -13, /**< Invalid key */
+ AVAHI_ERR_INVALID_ADDRESS = -14, /**< Invalid address */
+ AVAHI_ERR_TIMEOUT = -15, /**< Timeout reached */
+ AVAHI_ERR_TOO_MANY_CLIENTS = -16, /**< Too many clients */
+ AVAHI_ERR_TOO_MANY_OBJECTS = -17, /**< Too many objects */
+ AVAHI_ERR_TOO_MANY_ENTRIES = -18, /**< Too many entries */
+ AVAHI_ERR_OS = -19, /**< OS error */
+ AVAHI_ERR_ACCESS_DENIED = -20, /**< Access denied */
+ AVAHI_ERR_MAX = -21
};
/** States of a server object */
@@ -113,7 +138,8 @@ AvahiServer *avahi_server_new(
GMainContext *c, /**< The GLIB main loop context to attach to */
const AvahiServerConfig *sc, /**< If non-NULL a pointer to a configuration structure for the server. The server makes an internal deep copy of this structure, so you may free it using avahi_server_config_done() immediately after calling this function. */
AvahiServerCallback callback, /**< A callback which is called whenever the state of the server changes */
- gpointer userdata /**< An opaque pointer which is passed to the callback function */);
+ gpointer userdata, /**< An opaque pointer which is passed to the callback function */
+ gint *error);
/** Free an mDNS responder object */
void avahi_server_free(AvahiServer* s);
@@ -603,6 +629,14 @@ AvahiDNSServerBrowser *avahi_dns_server_browser_new(
/** Free an AvahiDNSServerBrowser object */
void avahi_dns_server_browser_free(AvahiDNSServerBrowser *b);
+/** Return a human readable error string for the specified error code */
+const gchar *avahi_strerror(gint error);
+
+/** Return the last error code */
+gint avahi_server_errno(AvahiServer *s);
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
AVAHI_C_DECL_END
+#endif
#endif
diff --git a/avahi-core/resolve-address.c b/avahi-core/resolve-address.c
index d315ac9..89f9bcf 100644
--- a/avahi-core/resolve-address.c
+++ b/avahi-core/resolve-address.c
@@ -111,6 +111,11 @@ AvahiAddressResolver *avahi_address_resolver_new(AvahiServer *server, AvahiIfInd
r->record_browser = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, r);
avahi_key_unref(k);
+
+ if (!r->record_browser) {
+ avahi_address_resolver_free(r);
+ return NULL;
+ }
return r;
}
diff --git a/avahi-core/resolve-host-name.c b/avahi-core/resolve-host-name.c
index 0ab2e73..c18722d 100644
--- a/avahi-core/resolve-host-name.c
+++ b/avahi-core/resolve-host-name.c
@@ -115,6 +115,11 @@ AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, AvahiIf
g_assert(aprotocol == AVAHI_PROTO_UNSPEC || aprotocol == AVAHI_PROTO_INET || aprotocol == AVAHI_PROTO_INET6);
+ if (!avahi_valid_domain_name(host_name)) {
+ avahi_server_set_errno(server, AVAHI_ERR_INVALID_HOST_NAME);
+ return NULL;
+ }
+
r = g_new(AvahiHostNameResolver, 1);
r->server = server;
r->host_name = avahi_normalize_name(host_name);
@@ -127,20 +132,34 @@ AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, AvahiIf
r->time_event = avahi_time_event_queue_add(server->time_event_queue, &tv, time_event_callback, r);
AVAHI_LLIST_PREPEND(AvahiHostNameResolver, resolver, server->host_name_resolvers, r);
+
+ r->record_browser_aaaa = r->record_browser_a = NULL;
if (aprotocol == AVAHI_PROTO_INET || aprotocol == AVAHI_PROTO_UNSPEC) {
k = avahi_key_new(host_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A);
r->record_browser_a = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, r);
avahi_key_unref(k);
+
+ if (!r->record_browser_a)
+ goto fail;
}
if (aprotocol == AVAHI_PROTO_INET6 || aprotocol == AVAHI_PROTO_UNSPEC) {
k = avahi_key_new(host_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_AAAA);
r->record_browser_aaaa = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, r);
avahi_key_unref(k);
+
+ if (!r->record_browser_aaaa)
+ goto fail;
}
-
+
+ g_assert(r->record_browser_aaaa || r->record_browser_a);
+
return r;
+
+fail:
+ avahi_host_name_resolver_free(r);
+ return NULL;
}
void avahi_host_name_resolver_free(AvahiHostNameResolver *r) {
diff --git a/avahi-core/resolve-service.c b/avahi-core/resolve-service.c
index b15af4f..2ad38f8 100644
--- a/avahi-core/resolve-service.c
+++ b/avahi-core/resolve-service.c
@@ -206,6 +206,21 @@ AvahiServiceResolver *avahi_service_resolver_new(AvahiServer *server, AvahiIfInd
g_assert(aprotocol == AVAHI_PROTO_UNSPEC || aprotocol == AVAHI_PROTO_INET || aprotocol == AVAHI_PROTO_INET6);
+ if (!avahi_valid_service_name(name)) {
+ avahi_server_set_errno(server, AVAHI_ERR_INVALID_SERVICE_NAME);
+ return NULL;
+ }
+
+ if (!avahi_valid_service_type(type)) {
+ avahi_server_set_errno(server, AVAHI_ERR_INVALID_SERVICE_TYPE);
+ return NULL;
+ }
+
+ if (!avahi_valid_domain_name(domain)) {
+ avahi_server_set_errno(server, AVAHI_ERR_INVALID_DOMAIN_NAME);
+ return NULL;
+ }
+
r = g_new(AvahiServiceResolver, 1);
r->server = server;
r->service_name = g_strdup(name);
@@ -234,10 +249,20 @@ AvahiServiceResolver *avahi_service_resolver_new(AvahiServer *server, AvahiIfInd
r->record_browser_srv = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, r);
avahi_key_unref(k);
+ if (!r->record_browser_srv) {
+ avahi_service_resolver_free(r);
+ return NULL;
+ }
+
k = avahi_key_new(t, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_TXT);
r->record_browser_txt = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, r);
avahi_key_unref(k);
-
+
+ if (!r->record_browser_txt) {
+ avahi_service_resolver_free(r);
+ return NULL;
+ }
+
return r;
}
diff --git a/avahi-core/server.c b/avahi-core/server.c
index 3c38507..c4acf35 100644
--- a/avahi-core/server.c
+++ b/avahi-core/server.c
@@ -259,6 +259,7 @@ static void incoming_probe(AvahiServer *s, AvahiRecord *record, AvahiInterface *
}
}
+
if (!ours) {
if (won)
@@ -1221,6 +1222,9 @@ gint avahi_server_set_host_name(AvahiServer *s, const gchar *host_name) {
g_assert(s);
g_assert(host_name);
+ if (host_name && !avahi_valid_host_name(host_name))
+ return avahi_server_set_errno(s, AVAHI_ERR_INVALID_HOST_NAME);
+
withdraw_host_rrs(s);
g_free(s->host_name);
@@ -1236,6 +1240,9 @@ gint avahi_server_set_domain_name(AvahiServer *s, const gchar *domain_name) {
g_assert(s);
g_assert(domain_name);
+ if (domain_name && !avahi_valid_domain_name(domain_name))
+ return avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME);
+
withdraw_host_rrs(s);
g_free(s->domain_name);
@@ -1257,8 +1264,20 @@ static void prepare_pollfd(AvahiServer *s, GPollFD *pollfd, gint fd) {
g_source_add_poll(s->source, pollfd);
}
-AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, AvahiServerCallback callback, gpointer userdata) {
+static gint valid_server_config(const AvahiServerConfig *sc) {
+
+ if (sc->host_name && !avahi_valid_host_name(sc->host_name))
+ return AVAHI_ERR_INVALID_HOST_NAME;
+
+ if (sc->domain_name && !avahi_valid_domain_name(sc->domain_name))
+ return AVAHI_ERR_INVALID_DOMAIN_NAME;
+
+ return AVAHI_OK;
+}
+
+AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, AvahiServerCallback callback, gpointer userdata, gint *error) {
AvahiServer *s;
+ gint e;
static GSourceFuncs source_funcs = {
prepare_func,
@@ -1269,6 +1288,12 @@ AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, Avah
NULL
};
+ if ((e = valid_server_config(sc)) < 0) {
+ if (error)
+ *error = e;
+ return NULL;
+ }
+
s = g_new(AvahiServer, 1);
s->n_host_rr_pending = 0;
s->need_entry_cleanup = s->need_group_cleanup = s->need_browser_cleanup = FALSE;
@@ -1282,9 +1307,12 @@ AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, Avah
s->fd_ipv6 = s->config.use_ipv6 ? avahi_open_socket_ipv6() : -1;
if (s->fd_ipv6 < 0 && s->fd_ipv4 < 0) {
- g_critical("Selected neither IPv6 nor IPv4 support, aborting.\n");
avahi_server_config_free(&s->config);
g_free(s);
+
+ if (error)
+ *error = AVAHI_ERR_NO_NETWORK;
+
return NULL;
}
@@ -1354,6 +1382,8 @@ AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, Avah
s->hinfo_entry_group = NULL;
s->browse_domain_entry_group = NULL;
register_stuff(s);
+
+ s->error = AVAHI_OK;
return s;
}
@@ -1461,13 +1491,16 @@ gint avahi_server_add(
g_assert(r);
if (r->ttl == 0)
- return -1;
+ return avahi_server_set_errno(s, AVAHI_ERR_INVALID_TTL);
if (avahi_key_is_pattern(r->key))
- return -1;
+ return avahi_server_set_errno(s, AVAHI_ERR_IS_PATTERN);
+
+ if (!avahi_record_valid(r))
+ return avahi_server_set_errno(s, AVAHI_ERR_INVALID_RECORD);
if (check_record_conflict(s, interface, protocol, r, flags) < 0)
- return -1;
+ return avahi_server_set_errno(s, AVAHI_ERR_LOCAL_COLLISION);
e = g_new(AvahiEntry, 1);
e->server = s;
@@ -1551,6 +1584,7 @@ gint avahi_server_add_ptr(
AvahiRecord *r;
gint ret;
+ g_assert(s);
g_assert(dest);
r = avahi_record_new_full(name ? name : s->host_name_fqdn, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR, ttl);
@@ -1570,11 +1604,16 @@ gint avahi_server_add_address(
AvahiAddress *a) {
gchar *n = NULL;
- gint ret = 0;
+ gint ret = AVAHI_OK;
g_assert(s);
g_assert(a);
name = name ? (n = avahi_normalize_name(name)) : s->host_name_fqdn;
+
+ if (!avahi_valid_domain_name(name)) {
+ avahi_server_set_errno(s, AVAHI_ERR_INVALID_HOST_NAME);
+ goto fail;
+ }
if (a->family == AVAHI_PROTO_INET) {
gchar *reverse;
@@ -1584,11 +1623,14 @@ gint avahi_server_add_address(
r->data.a.address = a->data.ipv4;
ret = avahi_server_add(s, g, interface, protocol, flags | AVAHI_ENTRY_UNIQUE | AVAHI_ENTRY_ALLOWMUTIPLE, r);
avahi_record_unref(r);
+
+ if (ret < 0)
+ goto fail;
reverse = avahi_reverse_lookup_name_ipv4(&a->data.ipv4);
- ret |= avahi_server_add_ptr(s, g, interface, protocol, flags | AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL_HOST_NAME, reverse, name);
+ ret = avahi_server_add_ptr(s, g, interface, protocol, flags | AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL_HOST_NAME, reverse, name);
g_free(reverse);
-
+
} else {
gchar *reverse;
AvahiRecord *r;
@@ -1598,14 +1640,22 @@ gint avahi_server_add_address(
ret = avahi_server_add(s, g, interface, protocol, flags | AVAHI_ENTRY_UNIQUE | AVAHI_ENTRY_ALLOWMUTIPLE, r);
avahi_record_unref(r);
+ if (ret < 0)
+ goto fail;
+
reverse = avahi_reverse_lookup_name_ipv6_arpa(&a->data.ipv6);
- ret |= avahi_server_add_ptr(s, g, interface, protocol, flags | AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL_HOST_NAME, reverse, name);
+ ret = avahi_server_add_ptr(s, g, interface, protocol, flags | AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL_HOST_NAME, reverse, name);
g_free(reverse);
+
+ if (ret < 0)
+ goto fail;
reverse = avahi_reverse_lookup_name_ipv6_int(&a->data.ipv6);
- ret |= avahi_server_add_ptr(s, g, interface, protocol, flags | AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL_HOST_NAME, reverse, name);
+ ret = avahi_server_add_ptr(s, g, interface, protocol, flags | AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL_HOST_NAME, reverse, name);
g_free(reverse);
}
+
+fail:
g_free(n);
@@ -1645,6 +1695,8 @@ gint avahi_server_add_txt_strlst(
const gchar *name,
AvahiStringList *strlst) {
+ g_assert(s);
+
return server_add_txt_strlst_nocopy(s, g, interface, protocol, flags, ttl, name, avahi_string_list_copy(strlst));
}
@@ -1721,19 +1773,31 @@ static gint server_add_service_strlst_nocopy(
gchar ptr_name[256], svc_name[256], ename[64], enum_ptr[256];
gchar *t, *d;
- AvahiRecord *r;
+ AvahiRecord *r = NULL;
gint ret = 0;
g_assert(s);
g_assert(type);
g_assert(name);
+ if (!avahi_valid_service_name(name))
+ return avahi_server_set_errno(s, AVAHI_ERR_INVALID_SERVICE_NAME);
+
+ if (!avahi_valid_service_type(type))
+ return avahi_server_set_errno(s, AVAHI_ERR_INVALID_SERVICE_TYPE);
+
+ if (domain && !avahi_valid_domain_name(domain))
+ return avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME);
+
+ if (host && !avahi_valid_domain_name(host))
+ return avahi_server_set_errno(s, AVAHI_ERR_INVALID_HOST_NAME);
+
+ if (port == 0)
+ return avahi_server_set_errno(s, AVAHI_ERR_INVALID_PORT);
+
escape_service_name(ename, sizeof(ename), name);
- if (domain) {
- while (domain[0] == '.')
- domain++;
- } else
+ if (!domain)
domain = s->domain_name;
if (!host)
@@ -1745,23 +1809,35 @@ static gint server_add_service_strlst_nocopy(
g_snprintf(ptr_name, sizeof(ptr_name), "%s.%s", t, d);
g_snprintf(svc_name, sizeof(svc_name), "%s.%s.%s", ename, t, d);
- ret = avahi_server_add_ptr(s, g, interface, protocol, AVAHI_ENTRY_NULL, AVAHI_DEFAULT_TTL, ptr_name, svc_name);
+ if ((ret = avahi_server_add_ptr(s, g, interface, protocol, AVAHI_ENTRY_NULL, AVAHI_DEFAULT_TTL, ptr_name, svc_name)) < 0)
+ goto fail;
r = avahi_record_new_full(svc_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_SRV, AVAHI_DEFAULT_TTL_HOST_NAME);
r->data.srv.priority = 0;
r->data.srv.weight = 0;
r->data.srv.port = port;
r->data.srv.name = avahi_normalize_name(host);
- ret |= avahi_server_add(s, g, interface, protocol, AVAHI_ENTRY_UNIQUE, r);
+ ret = avahi_server_add(s, g, interface, protocol, AVAHI_ENTRY_UNIQUE, r);
avahi_record_unref(r);
- ret |= server_add_txt_strlst_nocopy(s, g, interface, protocol, AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL, svc_name, strlst);
+ if (ret < 0)
+ goto fail;
+
+ ret = server_add_txt_strlst_nocopy(s, g, interface, protocol, AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL, svc_name, strlst);
+ strlst = NULL;
+
+ if (ret < 0)
+ goto fail;
g_snprintf(enum_ptr, sizeof(enum_ptr), "_services._dns-sd._udp.%s", d);
- ret |=avahi_server_add_ptr(s, g, interface, protocol, AVAHI_ENTRY_NULL, AVAHI_DEFAULT_TTL, enum_ptr, ptr_name);
+ ret = avahi_server_add_ptr(s, g, interface, protocol, AVAHI_ENTRY_NULL, AVAHI_DEFAULT_TTL, enum_ptr, ptr_name);
+fail:
+
g_free(d);
g_free(t);
+
+ avahi_string_list_free(strlst);
return ret;
}
@@ -1778,6 +1854,10 @@ gint avahi_server_add_service_strlst(
guint16 port,
AvahiStringList *strlst) {
+ g_assert(s);
+ g_assert(type);
+ g_assert(name);
+
return server_add_service_strlst_nocopy(s, g, interface, protocol, name, type, domain, host, port, avahi_string_list_copy(strlst));
}
@@ -1866,6 +1946,12 @@ gint avahi_server_add_dns_server_address(
g_assert(type == AVAHI_DNS_SERVER_UPDATE || type == AVAHI_DNS_SERVER_RESOLVE);
g_assert(address->family == AVAHI_PROTO_INET || address->family == AVAHI_PROTO_INET6);
+ if (domain && !avahi_valid_domain_name(domain))
+ return avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME);
+
+ if (port == 0)
+ return avahi_server_set_errno(s, AVAHI_ERR_INVALID_PORT);
+
if (address->family == AVAHI_PROTO_INET) {
hexstring(n+3, sizeof(n)-3, &address->data, 4);
r = avahi_record_new_full(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A, AVAHI_DEFAULT_TTL_HOST_NAME);
@@ -1878,10 +1964,11 @@ gint avahi_server_add_dns_server_address(
ret = avahi_server_add(s, g, interface, protocol, AVAHI_ENTRY_UNIQUE | AVAHI_ENTRY_ALLOWMUTIPLE, r);
avahi_record_unref(r);
-
- ret |= avahi_server_add_dns_server_name(s, g, interface, protocol, domain, type, n, port);
- return ret;
+ if (ret < 0)
+ return ret;
+
+ return avahi_server_add_dns_server_name(s, g, interface, protocol, domain, type, n, port);
}
gint avahi_server_add_dns_server_name(
@@ -1902,10 +1989,13 @@ gint avahi_server_add_dns_server_name(
g_assert(name);
g_assert(type == AVAHI_DNS_SERVER_UPDATE || type == AVAHI_DNS_SERVER_RESOLVE);
- if (domain) {
- while (domain[0] == '.')
- domain++;
- } else
+ if (domain && !avahi_valid_domain_name(domain))
+ return avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME);
+
+ if (port == 0)
+ return avahi_server_set_errno(s, AVAHI_ERR_INVALID_PORT);
+
+ if (!domain)
domain = s->domain_name;
d = avahi_normalize_name(domain);
@@ -1946,6 +2036,8 @@ void avahi_entry_group_change_state(AvahiEntryGroup *g, AvahiEntryGroupState sta
if (g->state == state)
return;
+ g_assert(state >= AVAHI_ENTRY_GROUP_UNCOMMITED && state <= AVAHI_ENTRY_GROUP_COLLISION);
+
g->state = state;
if (g->callback)
@@ -2031,7 +2123,7 @@ gint avahi_entry_group_commit(AvahiEntryGroup *g) {
g_assert(!g->dead);
if (g->state != AVAHI_ENTRY_GROUP_UNCOMMITED && g->state != AVAHI_ENTRY_GROUP_COLLISION)
- return AVAHI_ERR_BAD_STATE;
+ return avahi_server_set_errno(g->server, AVAHI_ERR_BAD_STATE);
g->n_register_try++;
@@ -2201,3 +2293,47 @@ AvahiServerConfig* avahi_server_config_copy(AvahiServerConfig *ret, const AvahiS
return ret;
}
+
+const gchar *avahi_strerror(gint error) {
+ g_assert(-error >= 0 && -error < -AVAHI_ERR_MAX);
+
+ const gchar * const msg[- AVAHI_ERR_MAX] = {
+ "OK",
+ "Operation failed",
+ "Bad state",
+ "Invalid host name",
+ "Invalid domain name",
+ "No suitable network protocol available",
+ "Invalid DNS TTL",
+ "Resource record key is pattern",
+ "Local name collision",
+ "Invalid record",
+ "Invalid service name",
+ "Invalid service type",
+ "Invalid port number",
+ "Invalid record key",
+ "Invalid address",
+ "Timeout reached",
+ "Too many clients",
+ "Too many objects",
+ "Too many entries",
+ "OS Error",
+ "Access denied"
+ };
+
+ return msg[-error];
+}
+
+gint avahi_server_errno(AvahiServer *s) {
+ g_assert(s);
+
+ return s->error;
+}
+
+/* Just for internal use */
+gint avahi_server_set_errno(AvahiServer *s, gint error) {
+ g_assert(s);
+
+ return s->error = error;
+}
+
diff --git a/avahi-core/server.h b/avahi-core/server.h
index 7049f58..6572fbb 100644
--- a/avahi-core/server.h
+++ b/avahi-core/server.h
@@ -131,6 +131,8 @@ struct AvahiServer {
/* Used for reflection of legacy unicast packets */
AvahiLegacyUnicastReflectSlot **legacy_unicast_reflect_slots;
guint16 legacy_unicast_reflect_id;
+
+ gint error;
};
gboolean avahi_server_entry_match_interface(AvahiEntry *e, AvahiInterface *i);
@@ -152,4 +154,6 @@ void avahi_host_rr_entry_group_callback(AvahiServer *s, AvahiEntryGroup *g, Avah
void avahi_server_decrease_host_rr_pending(AvahiServer *s);
void avahi_server_increase_host_rr_pending(AvahiServer *s);
+gint avahi_server_set_errno(AvahiServer *s, gint error);
+
#endif
diff --git a/avahi-daemon/dbus-protocol.c b/avahi-daemon/dbus-protocol.c
index 311d664..a87712d 100644
--- a/avahi-daemon/dbus-protocol.c
+++ b/avahi-daemon/dbus-protocol.c
@@ -319,10 +319,37 @@ static Client *client_get(const gchar *name, gboolean create) {
return client;
}
-static DBusHandlerResult respond_error(DBusConnection *c, DBusMessage *m, const gchar *error, const gchar *text) {
+static DBusHandlerResult respond_error(DBusConnection *c, DBusMessage *m, gint error, const gchar *text) {
DBusMessage *reply;
- reply = dbus_message_new_error(m, error, text);
+ const gchar * const table[- AVAHI_ERR_MAX] = {
+ NULL, /* OK */
+ AVAHI_DBUS_ERR_FAILURE,
+ AVAHI_DBUS_ERR_BAD_STATE,
+ AVAHI_DBUS_ERR_INVALID_HOST_NAME,
+ AVAHI_DBUS_ERR_INVALID_DOMAIN_NAME,
+ AVAHI_DBUS_ERR_NO_NETWORK,
+ AVAHI_DBUS_ERR_INVALID_TTL,
+ AVAHI_DBUS_ERR_IS_PATTERN,
+ AVAHI_DBUS_ERR_LOCAL_COLLISION,
+ AVAHI_DBUS_ERR_INVALID_RECORD,
+ AVAHI_DBUS_ERR_INVALID_SERVICE_NAME,
+ AVAHI_DBUS_ERR_INVALID_SERVICE_TYPE,
+ AVAHI_DBUS_ERR_INVALID_PORT,
+ AVAHI_DBUS_ERR_INVALID_KEY,
+ AVAHI_DBUS_ERR_INVALID_ADDRESS,
+ AVAHI_DBUS_ERR_TIMEOUT,
+ AVAHI_DBUS_ERR_TOO_MANY_CLIENTS,
+ AVAHI_DBUS_ERR_TOO_MANY_OBJECTS,
+ AVAHI_DBUS_ERR_TOO_MANY_ENTRIES,
+ AVAHI_DBUS_ERR_OS,
+ DBUS_ERROR_ACCESS_DENIED
+ };
+
+ g_assert(-error > -AVAHI_OK);
+ g_assert(-error < -AVAHI_ERR_MAX);
+
+ reply = dbus_message_new_error(m, table[-error], text ? text : avahi_strerror(error));
dbus_connection_send(c, reply, NULL);
dbus_message_unref(reply);
@@ -467,7 +494,6 @@ fail:
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
-
static void entry_group_callback(AvahiServer *s, AvahiEntryGroup *g, AvahiEntryGroupState state, gpointer userdata) {
EntryGroupInfo *i = userdata;
DBusMessage *m;
@@ -506,7 +532,7 @@ static DBusHandlerResult msg_entry_group_impl(DBusConnection *c, DBusMessage *m,
/* Access control */
if (strcmp(dbus_message_get_sender(m), i->client->name))
- return respond_error(c, m, DBUS_ERROR_ACCESS_DENIED, NULL);
+ return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL);
if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "Free")) {
@@ -548,10 +574,10 @@ static DBusHandlerResult msg_entry_group_impl(DBusConnection *c, DBusMessage *m,
goto fail;
}
- b = avahi_entry_group_is_empty(i->entry_group);
-
+ b = !!avahi_entry_group_is_empty(i->entry_group);
+
reply = dbus_message_new_method_return(m);
- dbus_message_append_args(m, DBUS_TYPE_BOOLEAN, &b, DBUS_TYPE_INVALID);
+ dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &b, DBUS_TYPE_INVALID);
dbus_connection_send(c, reply, NULL);
dbus_message_unref(reply);
@@ -584,7 +610,7 @@ static DBusHandlerResult msg_entry_group_impl(DBusConnection *c, DBusMessage *m,
DBUS_TYPE_STRING, &host,
DBUS_TYPE_UINT16, &port,
DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &txt, &txt_len,
- DBUS_TYPE_INVALID) || !type || !*type || !name || !*name || !port) {
+ DBUS_TYPE_INVALID) || !type || !name) {
avahi_log_warn("Error parsing EntryGroup::AddService message");
goto fail;
}
@@ -592,7 +618,7 @@ static DBusHandlerResult msg_entry_group_impl(DBusConnection *c, DBusMessage *m,
if (i->n_entries >= MAX_ENTRIES_PER_ENTRY_GROUP) {
avahi_log_warn("Too many entries per entry group, client request failed.");
dbus_free_string_array(txt);
- return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_ENTRIES, NULL);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_ENTRIES, NULL);
}
strlst = avahi_string_list_new_from_array((const gchar**) txt, txt_len);
@@ -605,9 +631,8 @@ static DBusHandlerResult msg_entry_group_impl(DBusConnection *c, DBusMessage *m,
host = NULL;
if (avahi_server_add_service_strlst(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, host, port, strlst) < 0) {
- avahi_log_warn("Failed to add service: %s", name);
avahi_string_list_free(strlst);
- return respond_error(c, m, AVAHI_DBUS_ERROR_INVALID_SERVICE, NULL);
+ return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
} else
i->n_entries ++;
@@ -626,25 +651,23 @@ static DBusHandlerResult msg_entry_group_impl(DBusConnection *c, DBusMessage *m,
DBUS_TYPE_INT32, &protocol,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_STRING, &address,
- DBUS_TYPE_INVALID) || !name || !*name || !address || !*address) {
+ DBUS_TYPE_INVALID) || !name || !address) {
avahi_log_warn("Error parsing EntryGroup::AddAddress message");
goto fail;
}
if (i->n_entries >= MAX_ENTRIES_PER_ENTRY_GROUP) {
avahi_log_warn("Too many entries per entry group, client request failed.");
- return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_ENTRIES, NULL);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_ENTRIES, NULL);
}
if (!(avahi_address_parse(address, AVAHI_PROTO_UNSPEC, &a))) {
- avahi_log_warn("Error parsing address data");
- return respond_error(c, m, AVAHI_DBUS_ERROR_INVALID_ADDRESS, NULL);
+ return respond_error(c, m, AVAHI_ERR_INVALID_ADDRESS, NULL);
}
- if (avahi_server_add_address(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, 0, name, &a) < 0) {
- avahi_log_warn("Failed to add service: %s", name);
- return respond_error(c, m, AVAHI_DBUS_ERROR_INVALID_ADDRESS, NULL);
- } else
+ if (avahi_server_add_address(avahi_server, i->entry_group, (AvahiIfIndex) interface, (AvahiProtocol) protocol, 0, name, &a) < 0)
+ return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
+ else
i->n_entries ++;
return respond_ok(c, m);
@@ -661,7 +684,6 @@ fail:
static void host_name_resolver_callback(AvahiHostNameResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const gchar *host_name, const AvahiAddress *a, gpointer userdata) {
HostNameResolverInfo *i = userdata;
- DBusMessage *reply;
g_assert(r);
g_assert(host_name);
@@ -670,6 +692,7 @@ static void host_name_resolver_callback(AvahiHostNameResolver *r, AvahiIfIndex i
if (event == AVAHI_RESOLVER_FOUND) {
char t[256], *pt = t;
gint32 i_interface, i_protocol, i_aprotocol;
+ DBusMessage *reply;
g_assert(a);
avahi_address_snprint(t, sizeof(t), a);
@@ -688,20 +711,19 @@ static void host_name_resolver_callback(AvahiHostNameResolver *r, AvahiIfIndex i
DBUS_TYPE_STRING, &pt,
DBUS_TYPE_INVALID);
+ dbus_connection_send(server->bus, reply, NULL);
+ dbus_message_unref(reply);
} else {
g_assert(event == AVAHI_RESOLVER_TIMEOUT);
- reply = dbus_message_new_error(i->message, AVAHI_DBUS_ERROR_TIMEOUT, NULL);
- }
- dbus_connection_send(server->bus, reply, NULL);
- dbus_message_unref(reply);
+ respond_error(server->bus, i->message, AVAHI_ERR_TIMEOUT, NULL);
+ }
host_name_resolver_free(i);
}
static void address_resolver_callback(AvahiAddressResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const AvahiAddress *address, const gchar *host_name, gpointer userdata) {
AddressResolverInfo *i = userdata;
- DBusMessage *reply;
g_assert(r);
g_assert(address);
@@ -710,6 +732,7 @@ static void address_resolver_callback(AvahiAddressResolver *r, AvahiIfIndex inte
if (event == AVAHI_RESOLVER_FOUND) {
char t[256], *pt = t;
gint32 i_interface, i_protocol, i_aprotocol;
+ DBusMessage *reply;
g_assert(host_name);
avahi_address_snprint(t, sizeof(t), address);
@@ -728,14 +751,13 @@ static void address_resolver_callback(AvahiAddressResolver *r, AvahiIfIndex inte
DBUS_TYPE_STRING, &host_name,
DBUS_TYPE_INVALID);
+ dbus_connection_send(server->bus, reply, NULL);
+ dbus_message_unref(reply);
} else {
g_assert(event == AVAHI_RESOLVER_TIMEOUT);
- reply = dbus_message_new_error(i->message, AVAHI_DBUS_ERROR_TIMEOUT, NULL);
+ respond_error(server->bus, i->message, AVAHI_ERR_TIMEOUT, NULL);
}
- dbus_connection_send(server->bus, reply, NULL);
- dbus_message_unref(reply);
-
address_resolver_free(i);
}
@@ -760,7 +782,7 @@ static DBusHandlerResult msg_domain_browser_impl(DBusConnection *c, DBusMessage
/* Access control */
if (strcmp(dbus_message_get_sender(m), i->client->name))
- return respond_error(c, m, DBUS_ERROR_ACCESS_DENIED, NULL);
+ return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL);
if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_DOMAIN_BROWSER, "Free")) {
@@ -828,7 +850,7 @@ static DBusHandlerResult msg_service_type_browser_impl(DBusConnection *c, DBusMe
/* Access control */
if (strcmp(dbus_message_get_sender(m), i->client->name))
- return respond_error(c, m, DBUS_ERROR_ACCESS_DENIED, NULL);
+ return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL);
if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVICE_TYPE_BROWSER, "Free")) {
@@ -894,11 +916,11 @@ static DBusHandlerResult msg_service_browser_impl(DBusConnection *c, DBusMessage
/* Introspection */
if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
- return handle_introspect(c, m, "ServiceBrowser.introspect");
+ return handle_introspect(c, m, "ServiceBrowser.Introspect");
/* Access control */
if (strcmp(dbus_message_get_sender(m), i->client->name))
- return respond_error(c, m, DBUS_ERROR_ACCESS_DENIED, NULL);
+ return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL);
if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVICE_BROWSER, "Free")) {
@@ -964,7 +986,6 @@ static void service_resolver_callback(
gpointer userdata) {
ServiceResolverInfo *i = userdata;
- DBusMessage *reply;
g_assert(r);
g_assert(i);
@@ -975,6 +996,7 @@ static void service_resolver_callback(
gchar **array;
guint n, j;
AvahiStringList *p;
+ DBusMessage *reply;
g_assert(host_name);
@@ -1009,18 +1031,17 @@ static void service_resolver_callback(
for (j = 0; j < n; j++)
g_free(array[j]);
+ dbus_connection_send(server->bus, reply, NULL);
+ dbus_message_unref(reply);
} else {
g_assert(event == AVAHI_RESOLVER_TIMEOUT);
- reply = dbus_message_new_error(i->message, AVAHI_DBUS_ERROR_TIMEOUT, NULL);
- }
- dbus_connection_send(server->bus, reply, NULL);
- dbus_message_unref(reply);
+ respond_error(server->bus, i->message, AVAHI_ERR_TIMEOUT, NULL);
+ }
service_resolver_free(i);
}
-
static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
DBusError error;
@@ -1092,7 +1113,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
gchar txt[256];
g_snprintf(txt, sizeof(txt), "OS Error: %s", strerror(errno));
- return respond_error(c, m, AVAHI_DBUS_ERROR_OS, txt);
+ return respond_error(c, m, AVAHI_ERR_OS, txt);
}
memset(&ifr, 0, sizeof(ifr));
@@ -1102,7 +1123,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
gchar txt[256];
g_snprintf(txt, sizeof(txt), "OS Error: %s", strerror(errno));
close(fd);
- return respond_error(c, m, AVAHI_DBUS_ERROR_OS, txt);
+ return respond_error(c, m, AVAHI_ERR_OS, txt);
}
close(fd);
@@ -1114,7 +1135,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
int fd;
struct ifreq ifr;
- if (!(dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID)) || !n || !*n) {
+ if (!(dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID)) || !n) {
avahi_log_warn("Error parsing Server::GetNetworkInterfaceIndexByName message");
goto fail;
}
@@ -1122,7 +1143,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
gchar txt[256];
g_snprintf(txt, sizeof(txt), "OS Error: %s", strerror(errno));
- return respond_error(c, m, AVAHI_DBUS_ERROR_OS, txt);
+ return respond_error(c, m, AVAHI_ERR_OS, txt);
}
memset(&ifr, 0, sizeof(ifr));
@@ -1132,7 +1153,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
gchar txt[256];
g_snprintf(txt, sizeof(txt), "OS Error: %s", strerror(errno));
close(fd);
- return respond_error(c, m, AVAHI_DBUS_ERROR_OS, txt);
+ return respond_error(c, m, AVAHI_ERR_OS, txt);
}
close(fd);
@@ -1142,7 +1163,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
} else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetAlternativeHostName")) {
gchar *n, * t;
- if (!(dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID)) || !n || !*n) {
+ if (!(dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID)) || !n) {
avahi_log_warn("Error parsing Server::GetAlternativeHostName message");
goto fail;
}
@@ -1156,7 +1177,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
} else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetAlternativeServiceName")) {
gchar *n, *t;
- if (!(dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID)) || !n || !*n) {
+ if (!(dbus_message_get_args(m, &error, DBUS_TYPE_STRING, &n, DBUS_TYPE_INVALID)) || !n) {
avahi_log_warn("Error parsing Server::GetAlternativeServiceName message");
goto fail;
}
@@ -1186,12 +1207,12 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
avahi_log_warn("Too many clients, client request failed.");
- return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
}
if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
- return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
}
i = g_new(EntryGroupInfo, 1);
@@ -1203,9 +1224,8 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
client->n_objects++;
if (!(i->entry_group = avahi_entry_group_new(avahi_server, entry_group_callback, i))) {
- avahi_log_warn("Failed to create entry group");
entry_group_free(i);
- goto fail;
+ return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
}
dbus_connection_register_object_path(c, i->path, &vtable, i);
@@ -1223,19 +1243,19 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
DBUS_TYPE_INT32, &protocol,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_INT32, &aprotocol,
- DBUS_TYPE_INVALID) || !name || !*name) {
+ DBUS_TYPE_INVALID) || !name) {
avahi_log_warn("Error parsing Server::ResolveHostName message");
goto fail;
}
if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
avahi_log_warn("Too many clients, client request failed.");
- return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
}
if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
- return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
}
i = g_new(HostNameResolverInfo, 1);
@@ -1246,8 +1266,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
if (!(i->host_name_resolver = avahi_host_name_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, (AvahiProtocol) aprotocol, host_name_resolver_callback, i))) {
host_name_resolver_free(i);
- avahi_log_warn("Failed to create host name resolver");
- goto fail;
+ return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
}
return DBUS_HANDLER_RESULT_HANDLED;
@@ -1264,24 +1283,22 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
DBUS_TYPE_INT32, &interface,
DBUS_TYPE_INT32, &protocol,
DBUS_TYPE_STRING, &address,
- DBUS_TYPE_INVALID) || !address || !*address) {
+ DBUS_TYPE_INVALID) || !address) {
avahi_log_warn("Error parsing Server::ResolveAddress message");
goto fail;
}
- if (!avahi_address_parse(address, AVAHI_PROTO_UNSPEC, &a)) {
- avahi_log_warn("Error parsing address data");
- return respond_error(c, m, AVAHI_DBUS_ERROR_INVALID_ADDRESS, NULL);
- }
+ if (!avahi_address_parse(address, AVAHI_PROTO_UNSPEC, &a))
+ return respond_error(c, m, AVAHI_ERR_INVALID_ADDRESS, NULL);
if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
avahi_log_warn("Too many clients, client request failed.");
- return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
}
if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
- return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
}
i = g_new(AddressResolverInfo, 1);
@@ -1292,8 +1309,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
if (!(i->address_resolver = avahi_address_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, &a, address_resolver_callback, i))) {
address_resolver_free(i);
- avahi_log_warn("Failed to create address resolver");
- goto fail;
+ return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
}
return DBUS_HANDLER_RESULT_HANDLED;
@@ -1326,12 +1342,12 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
avahi_log_warn("Too many clients, client request failed.");
- return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
}
if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
- return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
}
if (!*domain)
@@ -1345,9 +1361,8 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
client->n_objects++;
if (!(i->domain_browser = avahi_domain_browser_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, domain, (AvahiDomainBrowserType) type, domain_browser_callback, i))) {
- avahi_log_warn("Failed to create domain browser");
domain_browser_free(i);
- goto fail;
+ return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
}
dbus_connection_register_object_path(c, i->path, &vtable, i);
@@ -1379,13 +1394,13 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
avahi_log_warn("Too many clients, client request failed.");
- return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
}
if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
- return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
}
if (!*domain)
@@ -1399,9 +1414,8 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
client->n_objects++;
if (!(i->service_type_browser = avahi_service_type_browser_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, domain, service_type_browser_callback, i))) {
- avahi_log_warn("Failed to create service type browser");
service_type_browser_free(i);
- goto fail;
+ return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
}
dbus_connection_register_object_path(c, i->path, &vtable, i);
@@ -1427,20 +1441,20 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
DBUS_TYPE_INT32, &protocol,
DBUS_TYPE_STRING, &type,
DBUS_TYPE_STRING, &domain,
- DBUS_TYPE_INVALID) || !type || !*type) {
+ DBUS_TYPE_INVALID) || !type) {
avahi_log_warn("Error parsing Server::ServiceBrowserNew message");
goto fail;
}
if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
avahi_log_warn("Too many clients, client request failed.");
- return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
}
if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
- return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
}
if (!*domain)
@@ -1454,9 +1468,8 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
client->n_objects++;
if (!(i->service_browser = avahi_service_browser_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, type, domain, service_browser_callback, i))) {
- avahi_log_warn("Failed to create service browser");
service_browser_free(i);
- goto fail;
+ return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
}
dbus_connection_register_object_path(c, i->path, &vtable, i);
@@ -1476,19 +1489,19 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
DBUS_TYPE_STRING, &type,
DBUS_TYPE_STRING, &domain,
DBUS_TYPE_INT32, &aprotocol,
- DBUS_TYPE_INVALID) || !name || !*name || !type || !*type) {
+ DBUS_TYPE_INVALID) || !name || !type) {
avahi_log_warn("Error parsing Server::ResolveService message");
goto fail;
}
if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
avahi_log_warn("Too many clients, client request failed.");
- return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_CLIENTS, NULL);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
}
if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
avahi_log_warn("Too many objects for client '%s', client request failed.", client->name);
- return respond_error(c, m, AVAHI_DBUS_ERROR_TOO_MANY_OBJECTS, NULL);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
}
if (!*domain)
@@ -1502,8 +1515,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
if (!(i->service_resolver = avahi_service_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, (AvahiProtocol) aprotocol, service_resolver_callback, i))) {
service_resolver_free(i);
- avahi_log_warn("Failed to create service resolver");
- goto fail;
+ return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
}
return DBUS_HANDLER_RESULT_HANDLED;
diff --git a/avahi-daemon/main.c b/avahi-daemon/main.c
index 1083416..99bf860 100644
--- a/avahi-daemon/main.c
+++ b/avahi-daemon/main.c
@@ -150,6 +150,7 @@ static AvahiEntryGroup* add_dns_servers(AvahiServer *s, AvahiEntryGroup* g, gcha
else
if (avahi_server_add_dns_server_address(s, g, -1, AF_UNSPEC, NULL, AVAHI_DNS_SERVER_RESOLVE, &a, 53) < 0) {
avahi_entry_group_free(g);
+ avahi_log_error("Failed to add DNS server address: %s", avahi_strerror(avahi_server_errno(s)));
return NULL;
}
}
@@ -500,6 +501,7 @@ static gint run_server(DaemonConfig *c) {
gint r = -1;
GIOChannel *io = NULL;
guint watch_id = (guint) -1;
+ gint error;
g_assert(c);
@@ -527,8 +529,10 @@ static gint run_server(DaemonConfig *c) {
goto finish;
#endif
- if (!(avahi_server = avahi_server_new(NULL, &c->server_config, server_callback, c)))
+ if (!(avahi_server = avahi_server_new(NULL, &c->server_config, server_callback, c, &error))) {
+ avahi_log_error("Failed to create server: %s", avahi_strerror(error));
goto finish;
+ }
load_resolv_conf(c);
diff --git a/avahi-daemon/static-services.c b/avahi-daemon/static-services.c
index 8c54eab..0fdff14 100644
--- a/avahi-daemon/static-services.c
+++ b/avahi-daemon/static-services.c
@@ -193,9 +193,6 @@ static void add_static_service_group_to_server(StaticServiceGroup *g) {
g_assert(g);
- if (g->entry_group)
- return;
-
if (g->chosen_name)
g_free(g->chosen_name);
@@ -218,7 +215,9 @@ static void add_static_service_group_to_server(StaticServiceGroup *g) {
g->chosen_name, s->type,
s->domain_name, s->host_name, s->port,
s->txt_records) < 0) {
- avahi_log_error("Failed to add service '%s' of type '%s', ignoring service group (%s)", g->chosen_name, s->type, g->filename);
+ avahi_log_error("Failed to add service '%s' of type '%s', ignoring service group (%s): %s",
+ g->chosen_name, s->type, g->filename,
+ avahi_strerror(avahi_server_errno(avahi_server)));
remove_static_service_group_from_server(g);
return;
}
diff --git a/avahi-discover-standalone/main.c b/avahi-discover-standalone/main.c
index daecdaa..00984ec 100644
--- a/avahi-discover-standalone/main.c
+++ b/avahi-discover-standalone/main.c
@@ -267,6 +267,7 @@ int main(int argc, char *argv[]) {
GladeXML *xml;
AvahiServerConfig config;
GtkTreeViewColumn *c;
+ gint error;
gtk_init(&argc, &argv);
glade_init();
@@ -293,9 +294,11 @@ int main(int argc, char *argv[]) {
avahi_server_config_init(&config);
config.publish_hinfo = config.publish_addresses = config.publish_domain = config.publish_workstation = FALSE;
- server = avahi_server_new(NULL, &config, NULL, NULL);
+ server = avahi_server_new(NULL, &config, NULL, NULL, &error);
avahi_server_config_free(&config);
+ g_assert(server);
+
service_type_browser = avahi_service_type_browser_new(server, -1, AF_UNSPEC, argc >= 2 ? argv[1] : NULL, service_type_browser_callback, NULL);
gtk_main();
diff --git a/avahi-utils/Makefile.am b/avahi-utils/Makefile.am
index 90b908c..144ee12 100644
--- a/avahi-utils/Makefile.am
+++ b/avahi-utils/Makefile.am
@@ -24,14 +24,18 @@ pythonscripts = \
avahi-publish-service \
avahi-dump-all \
avahi-discover \
- avahi-bookmarks
+ avahi-bookmarks \
+ avahi-resolve-host-name \
+ avahi-resolve-address
EXTRA_DIST = \
avahi-publish-address.in \
avahi-publish-service.in \
avahi-dump-all.in \
avahi-discover.in \
- avahi-bookmarks.in
+ avahi-bookmarks.in \
+ avahi-resolve-host-name.in \
+ avahi-resolve-address.in
if HAVE_PYTHON
bin_SCRIPTS = $(pythonscripts)
@@ -58,4 +62,12 @@ avahi-bookmarks: avahi-bookmarks.in
sed -e 's,@PYTHON\@,$(PYTHON),g' $< > $@
chmod +x $@
+avahi-resolve-host-name: avahi-resolve-host-name.in
+ sed -e 's,@PYTHON\@,$(PYTHON),g' $< > $@
+ chmod +x $@
+
+avahi-resolve-address: avahi-resolve-address.in
+ sed -e 's,@PYTHON\@,$(PYTHON),g' $< > $@
+ chmod +x $@
+
CLEANFILES = $(pythonscripts)
diff --git a/avahi-utils/avahi-resolve-address.in b/avahi-utils/avahi-resolve-address.in
new file mode 100755
index 0000000..b72a95b
--- /dev/null
+++ b/avahi-utils/avahi-resolve-address.in
@@ -0,0 +1,53 @@
+#!@PYTHON@
+# -*-python-*-
+# $Id$
+
+# This file is part of avahi.
+#
+# avahi is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# avahi is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with avahi; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+
+import sys, getopt
+
+try:
+ import avahi, gobject, dbus
+except ImportError:
+ print "Sorry, to use this tool you need to install Avahi, pygtk and python-dbus."
+ sys.exit(1)
+
+try:
+ import dbus.glib
+except ImportError, e:
+ pass
+
+
+if len(sys.argv) <= 1:
+ print "Please specify host name(s) to resolve."
+ sys.exit(1)
+
+bus = dbus.SystemBus()
+server = dbus.Interface(bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER)
+
+ret = 0
+
+for a in sys.argv[1:]:
+ try:
+ r = server.ResolveAddress(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, a)
+ print r[3], r[4]
+ except dbus.DBusException, e:
+ print "Resolving '%s' failed: %s" % (a, str(e))
+ ret = 1
+
+sys.exit(ret)
diff --git a/avahi-utils/avahi-resolve-host-name.in b/avahi-utils/avahi-resolve-host-name.in
new file mode 100755
index 0000000..cc24526
--- /dev/null
+++ b/avahi-utils/avahi-resolve-host-name.in
@@ -0,0 +1,53 @@
+#!@PYTHON@
+# -*-python-*-
+# $Id$
+
+# This file is part of avahi.
+#
+# avahi is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# avahi is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with avahi; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA.
+
+import sys, getopt
+
+try:
+ import avahi, gobject, dbus
+except ImportError:
+ print "Sorry, to use this tool you need to install Avahi, pygtk and python-dbus."
+ sys.exit(1)
+
+try:
+ import dbus.glib
+except ImportError, e:
+ pass
+
+
+if len(sys.argv) <= 1:
+ print "Please specify host name(s) to resolve."
+ sys.exit(1)
+
+bus = dbus.SystemBus()
+server = dbus.Interface(bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER)
+
+ret = 0
+
+for name in sys.argv[1:]:
+ try:
+ r = server.ResolveHostName(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, name, avahi.PROTO_UNSPEC)
+ print r[2], r[4]
+ except dbus.DBusException, e:
+ print "Resolving '%s' failed: %s" % (name, str(e))
+ ret = 1
+
+sys.exit(ret)
diff --git a/doxygen.cfg b/doxygen.cfg
index f081d41..315fbd1 100644
--- a/doxygen.cfg
+++ b/doxygen.cfg
@@ -173,7 +173,7 @@ EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
-PREDEFINED =
+PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
diff --git a/examples/browse-services.c b/examples/browse-services.c
index bb8eed8..c58d230 100644
--- a/examples/browse-services.c
+++ b/examples/browse-services.c
@@ -77,6 +77,8 @@ int main(int argc, char*argv[]) {
AvahiServerConfig config;
AvahiServer *server = NULL;
AvahiServiceBrowser *sb;
+ gint error;
+ int ret = 1;
/* Do not publish any local records */
avahi_server_config_init(&config);
@@ -86,11 +88,17 @@ int main(int argc, char*argv[]) {
config.publish_domain = FALSE;
/* Allocate a new server */
- server = avahi_server_new(NULL, &config, NULL, NULL);
+ server = avahi_server_new(NULL, &config, NULL, NULL, &error);
/* Free the configuration data */
avahi_server_config_free(&config);
+ /* Check wether creating the server object succeeded */
+ if (!server) {
+ g_message("Failed to create server: %s", avahi_strerror(error));
+ goto fail;
+ }
+
/* Create the service browser */
sb = avahi_service_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_http._tcp", NULL, browse_callback, server);
@@ -98,6 +106,10 @@ int main(int argc, char*argv[]) {
main_loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(main_loop);
+ ret = 0;
+
+fail:
+
/* Cleanup things */
if (sb)
avahi_service_browser_free(sb);
@@ -108,5 +120,5 @@ int main(int argc, char*argv[]) {
if (main_loop)
g_main_loop_unref(main_loop);
- return 0;
+ return ret;
}
diff --git a/examples/publish-service.c b/examples/publish-service.c
index 7c9879c..a936147 100644
--- a/examples/publish-service.c
+++ b/examples/publish-service.c
@@ -121,7 +121,9 @@ static void server_callback(AvahiServer *s, AvahiServerState state, gpointer use
int main(int argc, char*argv[]) {
AvahiServerConfig config;
AvahiServer *server = NULL;
-
+ gint error;
+ int ret = 1;
+
srand(time(NULL));
name = g_strdup("MegaPrinter");
@@ -132,15 +134,25 @@ int main(int argc, char*argv[]) {
config.publish_workstation = FALSE;
/* Allocate a new server */
- server = avahi_server_new(NULL, &config, server_callback, NULL);
+ server = avahi_server_new(NULL, &config, server_callback, NULL, &error);
/* Free the configuration data */
avahi_server_config_free(&config);
+
+ /* Check wether creating the server object succeeded */
+ if (!server) {
+ g_message("Failed to create server: %s", avahi_strerror(error));
+ goto fail;
+ }
/* Run the main loop */
main_loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(main_loop);
+ ret = 0;
+
+fail:
+
/* Cleanup things */
if (group)
avahi_entry_group_free(group);
@@ -153,5 +165,5 @@ int main(int argc, char*argv[]) {
g_free(name);
- return 0;
+ return ret;
}