* rename avahi_is_valid_service_type() to avahi_is_valid_service_type_generic()
authorLennart Poettering <lennart@poettering.net>
Tue, 11 Oct 2005 00:58:04 +0000 (00:58 +0000)
committerLennart Poettering <lennart@poettering.net>
Tue, 11 Oct 2005 00:58:04 +0000 (00:58 +0000)
* add avahi_is_valid_service_type_strict() which doesn't allow subtypes and other strange things to pass
* fix protocol validity checks in server.c
* add new API function avahi_get_type_from_subtype()

git-svn-id: file:///home/lennart/svn/public/avahi/trunk@716 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe

avahi-common/domain-test.c
avahi-common/domain.c
avahi-common/domain.h
avahi-core/browse-service.c
avahi-core/resolve-service.c
avahi-core/server.c

index 444f553..f1313cb 100644 (file)
@@ -84,9 +84,27 @@ int main(int argc, char *argv[]) {
 
     assert(avahi_domain_ends_with("foo.bar.\\065\\\\\\.aaaa", "\\065\\\\\\.aaaa"));
 
-    assert(avahi_is_valid_service_type("_foo._bar._waldo"));
-    assert(!avahi_is_valid_service_type("_foo._bar.waldo"));
-    assert(!avahi_is_valid_service_type(""));
+    assert(avahi_is_valid_service_type_generic("_foo._bar._waldo"));
+    assert(!avahi_is_valid_service_type_strict("_foo._bar._waldo"));
+    assert(!avahi_is_valid_service_subtype("_foo._bar._waldo"));
+
+    assert(avahi_is_valid_service_type_generic("_foo._tcp"));
+    assert(avahi_is_valid_service_type_strict("_foo._tcp"));
+    assert(!avahi_is_valid_service_subtype("_foo._tcp"));
+
+    assert(!avahi_is_valid_service_type_generic("_foo._bar.waldo"));
+    assert(!avahi_is_valid_service_type_strict("_foo._bar.waldo"));
+    assert(!avahi_is_valid_service_subtype("_foo._bar.waldo"));
+    
+    assert(!avahi_is_valid_service_type_generic(""));
+    assert(!avahi_is_valid_service_type_strict(""));
+    assert(!avahi_is_valid_service_subtype(""));
+
+    assert(avahi_is_valid_service_type_generic("_foo._sub._bar._tcp"));
+    assert(!avahi_is_valid_service_type_strict("_foo._sub._bar._tcp"));
+    assert(avahi_is_valid_service_subtype("_foo._sub._bar._tcp"));
+
+    printf("%s\n", avahi_get_type_from_subtype("_foo._sub._bar._tcp"));
 
     assert(!avahi_is_valid_host_name("sf.ooo."));
     assert(avahi_is_valid_host_name("sfooo."));
index b72a898..f2e4395 100644 (file)
@@ -293,7 +293,7 @@ int avahi_binary_domain_cmp(const char *a, const char *b) {
     }
 }
 
-int avahi_is_valid_service_type(const char *t) {
+int avahi_is_valid_service_type_generic(const char *t) {
     assert(t);
 
     if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX || !*t)
@@ -313,6 +313,101 @@ int avahi_is_valid_service_type(const char *t) {
     return 1;
 }
 
+int avahi_is_valid_service_type_strict(const char *t) {
+    char label[AVAHI_LABEL_MAX];
+    assert(t);
+
+    if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX || !*t)
+        return 0;
+
+    /* Application name */
+    
+    if (!(avahi_unescape_label(&t, label, sizeof(label))))
+        return 0;
+
+    if (strlen(label) <= 2 || label[0] != '_')
+        return 0;
+
+    if (!*t)
+        return 0;
+
+    /* _tcp or _udp boilerplate */
+    
+    if (!(avahi_unescape_label(&t, label, sizeof(label))))
+        return 0;
+
+    if (strcasecmp(label, "_tcp") && strcasecmp(label, "_udp"))
+        return 0;
+
+    if (*t)
+        return 0;
+    
+    return 1;
+}
+
+const char *avahi_get_type_from_subtype(const char *t) {
+    char label[AVAHI_LABEL_MAX];
+    const char *ret;
+    assert(t);
+
+    if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX || !*t)
+        return NULL;
+
+    /* Subtype name */
+    
+    if (!(avahi_unescape_label(&t, label, sizeof(label))))
+        return NULL;
+
+    if (strlen(label) <= 2 || label[0] != '_')
+        return NULL;
+
+    if (!*t)
+        return NULL;
+
+    /* String "_sub" */
+    
+    if (!(avahi_unescape_label(&t, label, sizeof(label))))
+        return NULL;
+
+    if (strcasecmp(label, "_sub"))
+        return NULL;
+
+    if (!*t)
+        return NULL;
+
+    ret = t;
+    
+    /* Application name */
+
+    if (!(avahi_unescape_label(&t, label, sizeof(label))))
+        return NULL;
+
+    if (strlen(label) <= 2 || label[0] != '_')
+        return NULL;
+
+    if (!*t)
+        return NULL;
+    
+    /* _tcp or _udp boilerplate */
+    
+    if (!(avahi_unescape_label(&t, label, sizeof(label))))
+        return NULL;
+
+    if (strcasecmp(label, "_tcp") && strcasecmp(label, "_udp"))
+        return NULL;
+
+    if (*t)
+        return NULL;
+
+    return ret;
+}
+
+int avahi_is_valid_service_subtype(const char *t) {
+    assert(t);
+
+    return !!avahi_get_type_from_subtype(t);
+}
+
 int avahi_is_valid_domain_name(const char *t) {
     assert(t);
 
@@ -407,7 +502,7 @@ int avahi_service_name_join(char *p, size_t size, const char *name, const char *
     if ((name && !avahi_is_valid_service_name(name)))
         return AVAHI_ERR_INVALID_SERVICE_NAME;
 
-    if (!avahi_is_valid_service_type(type))
+    if (!avahi_is_valid_service_type_generic(type))
         return AVAHI_ERR_INVALID_SERVICE_TYPE;
         
     if (!avahi_is_valid_domain_name(domain))
index bcd036e..26f4b73 100644 (file)
@@ -75,8 +75,21 @@ char *avahi_unescape_label(const char **name, char *dest, size_t size);
 /** Escape the domain name in *src and write it to *ret_name */
 char *avahi_escape_label(const char* src, size_t src_length, char **ret_name, size_t *ret_size);
 
-/** Return 1 when the specified string contains a valid service type, 0 otherwise */
-int avahi_is_valid_service_type(const char *t);
+/** Return 1 when the specified string contains a valid generic
+ * service type (i.e. a series of words starting with "_"), 0
+ * otherwise */
+int avahi_is_valid_service_type_generic(const char *t);
+
+/** Return 1 when the specified string contains a valid strict service
+ * type (i.e. consisting of only two words, the latter being either
+ * _udp or _tcp), 0 otherwise */
+int avahi_is_valid_service_type_strict(const char *t);
+
+/** Return 1 when the specified string contains a valid service subtype, 0 otherwise */
+int avahi_is_valid_service_subtype(const char *t);
+
+/** Return a pointer to the type section of a subtype i.e. _foo._sub._bar._tcp => _bar._tcp */
+const char *avahi_get_type_from_subtype(const char *t);
 
 /** Return 1 when the specified string contains a valid domain name, 0 otherwise */
 int avahi_is_valid_domain_name(const char *t);
index d89ad7a..170a64f 100644 (file)
@@ -99,7 +99,7 @@ AvahiSServiceBrowser *avahi_s_service_browser_new(
     AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL);
     AVAHI_CHECK_VALIDITY_RETURN_NULL(server, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME);
     AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS);
-    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, avahi_is_valid_service_type(service_type), AVAHI_ERR_INVALID_SERVICE_TYPE);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, avahi_is_valid_service_type_generic(service_type), AVAHI_ERR_INVALID_SERVICE_TYPE);
 
     if (!domain)
         domain = server->domain_name;
index 43b61d2..85ac3d5 100644 (file)
@@ -409,7 +409,7 @@ AvahiSServiceResolver *avahi_s_service_resolver_new(
     AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_PROTO_VALID(aprotocol), AVAHI_ERR_INVALID_PROTOCOL);
     AVAHI_CHECK_VALIDITY_RETURN_NULL(server, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME);
     AVAHI_CHECK_VALIDITY_RETURN_NULL(server, !name || avahi_is_valid_service_name(name), AVAHI_ERR_INVALID_SERVICE_NAME);
-    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, avahi_is_valid_service_type(type), AVAHI_ERR_INVALID_SERVICE_TYPE);
+    AVAHI_CHECK_VALIDITY_RETURN_NULL(server, avahi_is_valid_service_type_strict(type), AVAHI_ERR_INVALID_SERVICE_TYPE);
     AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST|AVAHI_LOOKUP_NO_TXT|AVAHI_LOOKUP_NO_ADDRESS), AVAHI_ERR_INVALID_FLAGS);
 
     if (!domain)
index fdc53d5..0c47cf8 100644 (file)
@@ -1936,10 +1936,10 @@ static int server_add_service_strlst_nocopy(
     assert(name);
 
     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_PROTO_VALID(protocol), 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, avahi_is_valid_service_type_strict(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);
 
@@ -2007,8 +2007,6 @@ fail:
     return ret;
 }
 
-
-
 int avahi_server_add_service_strlst(
     AvahiServer *s,
     AvahiSEntryGroup *g,
@@ -2095,12 +2093,12 @@ int avahi_server_add_service_subtype(
     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_PROTO_VALID(protocol), 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, avahi_is_valid_service_type_strict(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);
+    AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_subtype(subtype), AVAHI_ERR_INVALID_SERVICE_SUBTYPE);
 
     if (!domain)
         domain = s->domain_name;
@@ -2610,7 +2608,7 @@ int avahi_server_is_service_local(AvahiServer *s, AvahiIfIndex interface, AvahiP
     if (!avahi_is_valid_service_name(name))
         return avahi_server_set_errno(s, AVAHI_ERR_INVALID_SERVICE_NAME);
 
-    if (!avahi_is_valid_service_type(type))
+    if (!avahi_is_valid_service_type_strict(type))
         return avahi_server_set_errno(s, AVAHI_ERR_INVALID_SERVICE_TYPE);
 
     if (domain && !avahi_is_valid_domain_name(domain))