From c1d9b9cffd6f756339c1d98a2d2914d49195cb41 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Oct 2005 00:18:57 +0000 Subject: [PATCH] add support for service subtypes: avahi_server_add_service_subtype() git-svn-id: file:///home/lennart/svn/public/avahi/trunk@714 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-common/dbus.c | 3 +- avahi-common/dbus.h | 1 + avahi-common/error.c | 3 +- avahi-common/error.h | 69 +++++++++++------------ avahi-compat-libdns_sd/compat.c | 1 + avahi-core/publish.h | 12 ++++ avahi-core/server.c | 98 +++++++++++++++++++++------------ avahi-core/server.h | 7 +++ examples/core-publish-service.c | 6 ++ 9 files changed, 129 insertions(+), 71 deletions(-) diff --git a/avahi-common/dbus.c b/avahi-common/dbus.c index 14d1b2b..d658868 100644 --- a/avahi-common/dbus.c +++ b/avahi-common/dbus.c @@ -63,7 +63,8 @@ static const char * const table[- AVAHI_ERR_MAX] = { AVAHI_DBUS_ERR_INVALID_FLAGS, AVAHI_DBUS_ERR_NOT_FOUND, AVAHI_DBUS_ERR_INVALID_CONFIG, - AVAHI_DBUS_ERR_VERSION_MISMATCH + AVAHI_DBUS_ERR_VERSION_MISMATCH, + AVAHI_DBUS_ERR_INVALID_SERVICE_SUBTYPE }; int avahi_error_dbus_to_number(const char *s) { diff --git a/avahi-common/dbus.h b/avahi-common/dbus.h index 5f2acff..cb7ba19 100644 --- a/avahi-common/dbus.h +++ b/avahi-common/dbus.h @@ -74,6 +74,7 @@ AVAHI_C_DECL_BEGIN #define AVAHI_DBUS_ERR_NOT_FOUND "org.freedesktop.Avahi.NotFoundError" #define AVAHI_DBUS_ERR_INVALID_CONFIG "org.freedesktop.Avahi.InvalidConfigurationError" #define AVAHI_DBUS_ERR_VERSION_MISMATCH "org.freedesktop.Avahi.VersionMismatchError" +#define AVAHI_DBUS_ERR_INVALID_SERVICE_SUBTYPE "org.freedesktop.Avahi.InvalidServiceSubtypeError" /** Convert a DBus error string into an Avahi error number */ int avahi_error_dbus_to_number(const char *s); diff --git a/avahi-common/error.c b/avahi-common/error.c index 4242361..76a05fd 100644 --- a/avahi-common/error.c +++ b/avahi-common/error.c @@ -60,7 +60,8 @@ const char *avahi_strerror(int error) { "Invalid flags", "Not found", "Invalid configuration", - "Version mismatch" + "Version mismatch", + "Invalid service subtype" }; if (-error < 0 || -error >= -AVAHI_ERR_MAX) diff --git a/avahi-common/error.h b/avahi-common/error.h index 851c600..623620a 100644 --- a/avahi-common/error.h +++ b/avahi-common/error.h @@ -32,39 +32,40 @@ AVAHI_C_DECL_BEGIN /** 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_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_INVALID_OPERATION = -21, /**< Invalid operation */ - AVAHI_ERR_DBUS_ERROR = -22, /**< An unexpected DBUS error occured */ - AVAHI_ERR_NOT_CONNECTED = -23, /**< Could not get a connection to the daemon */ - AVAHI_ERR_NO_MEMORY = -24, /**< Memory exhausted */ - AVAHI_ERR_INVALID_OBJECT = -25, /**< The object passed to this function was invalid */ - AVAHI_ERR_NO_DAEMON = -26, /**< Daemon not running */ - AVAHI_ERR_INVALID_INTERFACE = -27, /**< Invalid interface */ - AVAHI_ERR_INVALID_PROTOCOL = -28, /**< Invalid protocol */ - AVAHI_ERR_INVALID_FLAGS = -29, /**< Invalid flags */ - AVAHI_ERR_NOT_FOUND = -30, /**< Not found */ - AVAHI_ERR_INVALID_CONFIG = -31, /**< Configuration error */ - AVAHI_ERR_VERSION_MISMATCH = -32, /**< Verson mismatch */ + 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_INVALID_OPERATION = -21, /**< Invalid operation */ + AVAHI_ERR_DBUS_ERROR = -22, /**< An unexpected DBUS error occured */ + AVAHI_ERR_NOT_CONNECTED = -23, /**< Could not get a connection to the daemon */ + AVAHI_ERR_NO_MEMORY = -24, /**< Memory exhausted */ + AVAHI_ERR_INVALID_OBJECT = -25, /**< The object passed to this function was invalid */ + AVAHI_ERR_NO_DAEMON = -26, /**< Daemon not running */ + AVAHI_ERR_INVALID_INTERFACE = -27, /**< Invalid interface */ + AVAHI_ERR_INVALID_PROTOCOL = -28, /**< Invalid protocol */ + AVAHI_ERR_INVALID_FLAGS = -29, /**< Invalid flags */ + AVAHI_ERR_NOT_FOUND = -30, /**< Not found */ + AVAHI_ERR_INVALID_CONFIG = -31, /**< Configuration error */ + AVAHI_ERR_VERSION_MISMATCH = -32, /**< Verson mismatch */ + AVAHI_ERR_INVALID_SERVICE_SUBTYPE = -33, /**< Invalid service subtype */ /**** **** IF YOU ADD A NEW ERROR CODE HERE, PLEASE DON'T FORGET TO ADD @@ -74,7 +75,7 @@ enum { **** Also remember to update the MAX value below. ****/ - AVAHI_ERR_MAX = -33 + AVAHI_ERR_MAX = -34 }; /** Return a human readable error string for the specified error code */ diff --git a/avahi-compat-libdns_sd/compat.c b/avahi-compat-libdns_sd/compat.c index 9bb2ce8..e09099d 100644 --- a/avahi-compat-libdns_sd/compat.c +++ b/avahi-compat-libdns_sd/compat.c @@ -99,6 +99,7 @@ static DNSServiceErrorType map_error(int error) { case AVAHI_ERR_INVALID_PORT: case AVAHI_ERR_INVALID_KEY: case AVAHI_ERR_INVALID_ADDRESS: + case AVAHI_ERR_INVALID_SERVICE_SUBTYPE: return kDNSServiceErr_BadParam; diff --git a/avahi-core/publish.h b/avahi-core/publish.h index 4143bb3..aa9eae0 100644 --- a/avahi-core/publish.h +++ b/avahi-core/publish.h @@ -208,6 +208,18 @@ int avahi_server_add_service_strlst( uint16_t port, AvahiStringList *strlst); +/** Add a subtype for an already existing service */ +int avahi_server_add_service_subtype( + AvahiServer *s, + AvahiSEntryGroup *g, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiPublishFlags flags, + const char *name, /**< Specify the name of main service you already added here */ + const char *type, /**< Specify the main type of the service you already added here */ + const char *domain, /**< Specify the main type of the service you already added here */ + const char *subtype /**< The new subtype for the specified service */ ); + /** The type of DNS server */ typedef enum { AVAHI_DNS_SERVER_RESOLVE, /**< Unicast DNS servers for normal resolves (_domain._udp)*/ diff --git a/avahi-core/server.c b/avahi-core/server.c index 8082ea3..fdc53d5 100644 --- a/avahi-core/server.c +++ b/avahi-core/server.c @@ -1935,40 +1935,13 @@ static int server_add_service_strlst_nocopy( assert(type); assert(name); - if (!AVAHI_IF_VALID(interface)) { - ret = avahi_server_set_errno(s, AVAHI_ERR_INVALID_INTERFACE); - goto fail; - } - - if (!AVAHI_PROTO_VALID(protocol)) { - ret = avahi_server_set_errno(s, AVAHI_ERR_INVALID_PROTOCOL); - goto fail; - } - - if (!AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_NO_COOKIE|AVAHI_PUBLISH_IS_PROXY)) { - ret = avahi_server_set_errno(s, AVAHI_ERR_INVALID_FLAGS); - goto fail; - } - - if (!avahi_is_valid_service_name(name)) { - ret = avahi_server_set_errno(s, AVAHI_ERR_INVALID_SERVICE_NAME); - goto fail; - } - - if (!avahi_is_valid_service_type(type)) { - ret = avahi_server_set_errno(s, AVAHI_ERR_INVALID_SERVICE_TYPE); - goto fail; - } - - if (domain && !avahi_is_valid_domain_name(domain)) { - ret = avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME); - goto fail; - } - - if (host && !avahi_is_valid_domain_name(host)) { - ret = avahi_server_set_errno(s, AVAHI_ERR_INVALID_HOST_NAME); - goto fail; - } + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_PROTO_VALID(interface), AVAHI_ERR_INVALID_PROTOCOL); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_NO_COOKIE|AVAHI_PUBLISH_IS_PROXY), AVAHI_ERR_INVALID_FLAGS); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_name(name), AVAHI_ERR_INVALID_SERVICE_NAME); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_type(type), AVAHI_ERR_INVALID_SERVICE_TYPE); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !host || avahi_is_valid_domain_name(host), AVAHI_ERR_INVALID_HOST_NAME); if (!domain) domain = s->domain_name; @@ -1983,12 +1956,18 @@ static int server_add_service_strlst_nocopy( if ((ret = avahi_service_name_join(svc_name, sizeof(svc_name), name, type, domain)) < 0 || (ret = avahi_service_name_join(ptr_name, sizeof(ptr_name), NULL, type, domain)) < 0 || - (ret = avahi_service_name_join(enum_ptr, sizeof(enum_ptr), NULL, "_services._dns-sd._udp", domain)) < 0) + (ret = avahi_service_name_join(enum_ptr, sizeof(enum_ptr), NULL, "_services._dns-sd._udp", domain)) < 0) { + avahi_server_set_errno(s, ret); goto fail; + } + /* Add service enumeration PTR record */ + if ((ret = avahi_server_add_ptr(s, g, interface, protocol, flags & AVAHI_PUBLISH_IS_PROXY, AVAHI_DEFAULT_TTL, ptr_name, svc_name)) < 0) goto fail; + /* Add SRV record */ + if (!(r = avahi_record_new_full(svc_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_SRV, AVAHI_DEFAULT_TTL_HOST_NAME))) { ret = avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY); goto fail; @@ -2005,6 +1984,8 @@ static int server_add_service_strlst_nocopy( if (ret < 0) goto fail; + /* Add TXT record */ + if (!(flags & AVAHI_PUBLISH_NO_COOKIE)) strlst = add_magic_cookie(s, strlst); @@ -2014,6 +1995,8 @@ static int server_add_service_strlst_nocopy( if (ret < 0) goto fail; + /* Add service type enumeration record */ + ret = avahi_server_add_ptr(s, g, interface, protocol, (flags & AVAHI_PUBLISH_IS_PROXY), AVAHI_DEFAULT_TTL, enum_ptr, ptr_name); fail: @@ -2024,6 +2007,8 @@ fail: return ret; } + + int avahi_server_add_service_strlst( AvahiServer *s, AvahiSEntryGroup *g, @@ -2091,6 +2076,49 @@ int avahi_server_add_service( return ret; } +int avahi_server_add_service_subtype( + AvahiServer *s, + AvahiSEntryGroup *g, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiPublishFlags flags, + const char *name, + const char *type, + const char *domain, + const char *subtype) { + + int ret = AVAHI_OK; + char svc_name[AVAHI_DOMAIN_NAME_MAX], ptr_name[AVAHI_DOMAIN_NAME_MAX]; + + assert(name); + assert(type); + assert(subtype); + + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_PROTO_VALID(interface), AVAHI_ERR_INVALID_PROTOCOL); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_NO_COOKIE|AVAHI_PUBLISH_IS_PROXY), AVAHI_ERR_INVALID_FLAGS); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_name(name), AVAHI_ERR_INVALID_SERVICE_NAME); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_type(type), AVAHI_ERR_INVALID_SERVICE_TYPE); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_type(subtype), AVAHI_ERR_INVALID_SERVICE_SUBTYPE); + + if (!domain) + domain = s->domain_name; + + if ((ret = avahi_service_name_join(svc_name, sizeof(svc_name), name, type, domain)) < 0 || + (ret = avahi_service_name_join(ptr_name, sizeof(ptr_name), NULL, subtype, domain)) < 0) { + avahi_server_set_errno(s, ret); + goto fail; + } + + if ((ret = avahi_server_add_ptr(s, g, interface, protocol, flags & AVAHI_PUBLISH_IS_PROXY, AVAHI_DEFAULT_TTL, ptr_name, svc_name)) < 0) + goto fail; + +fail: + + return ret; +} + static void hexstring(char *s, size_t sl, const void *p, size_t pl) { static const char hex[] = "0123456789abcdef"; int b = 0; diff --git a/avahi-core/server.h b/avahi-core/server.h index 300ae8b..e7e77a2 100644 --- a/avahi-core/server.h +++ b/avahi-core/server.h @@ -182,4 +182,11 @@ int avahi_server_set_errno(AvahiServer *s, int error); } \ } +#define AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(server, expression, error) {\ + if (!(expression)) { \ + ret = avahi_server_set_errno((server), (error)); \ + goto fail; \ + } \ +} + #endif diff --git a/examples/core-publish-service.c b/examples/core-publish-service.c index 62badf3..f826a5f 100644 --- a/examples/core-publish-service.c +++ b/examples/core-publish-service.c @@ -96,6 +96,12 @@ static void create_services(AvahiServer *s) { goto fail; } + /* Add an additional (hypothetic) subtype */ + if ((ret = avahi_server_add_service_subtype(s, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, "_printer._tcp", NULL, "_magic._sub._printer._tcp") < 0)) { + fprintf(stderr, "Failed to add subtype _magic._sub._printer._tcp: %s\n", avahi_strerror(ret)); + goto fail; + } + /* Tell the server to register the service */ if ((ret = avahi_s_entry_group_commit(group)) < 0) { fprintf(stderr, "Failed to commit entry_group: %s\n", avahi_strerror(ret)); -- 2.39.2